Merge "Make icon visible on context menu"
diff --git a/ApiDocs.bp b/ApiDocs.bp
index a46ecce..90b6603 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -422,26 +422,27 @@
         "$(location merge_zips) $(out) $(location :ds-docs-java{.docs.zip}) $(genDir)/ds-docs-kt-moved.zip",
 }
 
-java_genrule {
-    name: "ds-docs-switched",
-    tools: [
-        "switcher4",
-        "soong_zip",
-    ],
-    srcs: [
-        ":ds-docs-java{.docs.zip}",
-        ":ds-docs-kt{.docs.zip}",
-    ],
-    out: ["ds-docs-switched.zip"],
-    dist: {
-        targets: ["docs"],
-    },
-    cmd: "unzip -q $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " +
-        "unzip -q $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " +
-        "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " +
-        "(cd $(genDir)/en/reference && $$SWITCHER --work platform) > /dev/null && " +
-        "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)",
-}
+// Disable doc generation until Doclava is migrated to JDK 17 (b/240421555).
+// java_genrule {
+//     name: "ds-docs-switched",
+//     tools: [
+//         "switcher4",
+//         "soong_zip",
+//     ],
+//     srcs: [
+//         ":ds-docs-java{.docs.zip}",
+//         ":ds-docs-kt{.docs.zip}",
+//     ],
+//     out: ["ds-docs-switched.zip"],
+//     dist: {
+//         targets: ["docs"],
+//     },
+//     cmd: "unzip -q $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " +
+//         "unzip -q $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " +
+//         "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " +
+//         "(cd $(genDir)/en/reference && $$SWITCHER --work platform) > /dev/null && " +
+//         "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)",
+// }
 
 droiddoc {
     name: "ds-static-docs",
diff --git a/PERFORMANCE_OWNERS b/PERFORMANCE_OWNERS
new file mode 100644
index 0000000..9452ea3
--- /dev/null
+++ b/PERFORMANCE_OWNERS
@@ -0,0 +1,5 @@
+timmurray@google.com
+edgararriaga@google.com
+dualli@google.com
+carmenjackson@google.com
+philipcuadra@google.com
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp
index 56d91b2..d8f693c 100644
--- a/ProtoLibraries.bp
+++ b/ProtoLibraries.bp
@@ -97,6 +97,8 @@
         ],
         type: "full",
     },
+    // b/267831518: Pin tradefed and dependencies to Java 11.
+    java_version: "11",
     // Protos have lots of MissingOverride and similar.
     errorprone: {
         enabled: false,
diff --git a/TEST_MAPPING b/TEST_MAPPING
index a48ce0c..9610f2c 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -198,5 +198,30 @@
        }
      ]
    }
+ ],
+ "auto-features-postsubmit": [
+   // Test tag for automotive feature targets. These are only running in postsubmit.
+   // This tag is used in targeted test features testing to limit resource use.
+   // TODO(b/256932212): this tag to be removed once the above is no longer in use.
+   {
+     "name": "FrameworksMockingServicesTests",
+     "options": [
+       {
+         "include-filter": "com.android.server.pm.UserVisibilityMediatorSUSDTest"
+       },
+       {
+         "include-filter": "com.android.server.pm.UserVisibilityMediatorMUMDTest"
+       },
+       {
+         "include-filter": "com.android.server.pm.UserVisibilityMediatorMUPANDTest"
+       },
+       {
+         "exclude-annotation": "androidx.test.filters.FlakyTest"
+       },
+       {
+         "exclude-annotation": "org.junit.Ignore"
+       }
+     ]
+   }
  ]
 }
diff --git a/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt b/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt
index 3d447ac..fabf889 100644
--- a/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt
+++ b/apct-tests/perftests/core/src/android/input/MotionPredictorBenchmark.kt
@@ -34,6 +34,7 @@
 
 import org.junit.After
 import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -89,7 +90,6 @@
     private val initialPropertyValue =
             SystemProperties.get("persist.input.enable_motion_prediction")
 
-    private var eventTime = Duration.ofMillis(1)
 
     @Before
     fun setUp() {
@@ -109,22 +109,31 @@
      */
     @Test
     fun timeRecordAndPredict() {
-        val offset = Duration.ofMillis(1)
+        val offset = Duration.ofMillis(20)
+        var eventTime = Duration.ofMillis(0)
+        val eventInterval = Duration.ofMillis(4) // 240 Hz
+
+        var eventPosition = 0f
+        val positionInterval = 10f
+
         val predictor = MotionPredictor(getPredictionContext(offset, /*enablePrediction=*/true))
         // ACTION_DOWN t=0 x=0 y=0
-        predictor.record(getStylusMotionEvent(eventTime, ACTION_DOWN, /*x=*/0f, /*y=*/0f))
+        predictor.record(getStylusMotionEvent(
+            eventTime, ACTION_DOWN, /*x=*/eventPosition, /*y=*/eventPosition))
 
         val state = perfStatusReporter.getBenchmarkState()
         while (state.keepRunning()) {
-            eventTime += Duration.ofMillis(1)
+            eventTime += eventInterval
+            eventPosition += positionInterval
 
             // Send MOVE event and then call .predict
-            val moveEvent = getStylusMotionEvent(eventTime, ACTION_MOVE, /*x=*/1f, /*y=*/2f)
+            val moveEvent = getStylusMotionEvent(
+                eventTime, ACTION_MOVE, /*x=*/eventPosition, /*y=*/eventPosition)
             predictor.record(moveEvent)
-            val predictionTime = eventTime + Duration.ofMillis(2)
+            val predictionTime = eventTime + eventInterval
             val predicted = predictor.predict(predictionTime.toNanos())
             assertEquals(1, predicted.size)
-            assertEquals((predictionTime + offset).toMillis(), predicted[0].eventTime)
+            assertTrue(predicted[0].eventTime <= (predictionTime + offset).toMillis())
         }
     }
 
@@ -135,7 +144,7 @@
     @Test
     fun timeCreatePredictor() {
         val context = getPredictionContext(
-                /*offset=*/Duration.ofMillis(1), /*enablePrediction=*/true)
+                /*offset=*/Duration.ofMillis(20), /*enablePrediction=*/true)
 
         val state = perfStatusReporter.getBenchmarkState()
         while (state.keepRunning()) {
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 5998ab7..051dde0 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -286,7 +286,7 @@
      * this test can be removed.
      */
     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
-    public void startUser_startOnceBefore() throws RemoteException {
+    public void startUser_startedOnceBefore() throws RemoteException {
         startUser_measuresAfterFirstIterations(/* numberOfIterationsToSkip */1);
     }
 
@@ -340,7 +340,7 @@
      * The next iterations take the expected time to start a user.
      */
     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
-    public void startUser_startTwiceBefore() throws RemoteException {
+    public void startUser_startedTwiceBefore() throws RemoteException {
         final int userId = createUserNoFlags();
 
         //TODO(b/266681181) Reduce iteration number by 1 after investigation and possible fix.
@@ -411,7 +411,7 @@
      * The next iterations take the expected time to start a user.
      */
     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
-    public void startAndUnlockUser_startTwiceBefore() throws RemoteException {
+    public void startAndUnlockUser_startedTwiceBefore() throws RemoteException {
         final int userId = createUserNoFlags();
 
         //TODO(b/266681181) Reduce iteration number by 1 after investigation and possible fix.
diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
index 7ed4d35..ec6a8b8 100644
--- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java
+++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java
@@ -36,7 +36,9 @@
 import android.os.HandlerExecutor;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.WorkSource;
 import android.text.TextUtils;
 import android.util.Log;
@@ -90,6 +92,14 @@
 public class AlarmManager {
     private static final String TAG = "AlarmManager";
 
+    /**
+     * Prefix used by {{@link #makeTag(long, WorkSource)}} to make a tag on behalf of the caller
+     * when the {@link #set(int, long, long, long, OnAlarmListener, Handler, WorkSource)} API is
+     * used. This prefix is a unique sequence of characters to differentiate with other tags that
+     * apps may provide to other APIs that accept a listener callback.
+     */
+    private static final String GENERATED_TAG_PREFIX = "$android.alarm.generated";
+
     /** @hide */
     @IntDef(prefix = { "RTC", "ELAPSED" }, value = {
             RTC_WAKEUP,
@@ -301,6 +311,15 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
     public static final long SCHEDULE_EXACT_ALARM_DOES_NOT_ELEVATE_BUCKET = 262645982L;
 
+    /**
+     * Exact alarms expecting a {@link OnAlarmListener} callback will be dropped when the calling
+     * app goes into cached state.
+     *
+     * @hide
+     */
+    @ChangeId
+    public static final long EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED = 265195908L;
+
     @UnsupportedAppUsage
     private final IAlarmManager mService;
     private final Context mContext;
@@ -667,7 +686,7 @@
      * than supplying a PendingIntent to be sent when the alarm time is reached, this variant
      * supplies an {@link OnAlarmListener} instance that will be invoked at that time.
      * <p>
-     * The OnAlarmListener {@link OnAlarmListener#onAlarm() onAlarm()} method will be
+     * The OnAlarmListener's {@link OnAlarmListener#onAlarm() onAlarm()} method will be
      * invoked via the specified target Executor.
      *
      * <p>
@@ -798,13 +817,24 @@
      * The OnAlarmListener's {@link OnAlarmListener#onAlarm() onAlarm()} method will be
      * invoked via the specified target Handler, or on the application's main looper
      * if {@code null} is passed as the {@code targetHandler} parameter.
+     * <p>
+     * This API should only be used to set alarms that are relevant in the context of the app's
+     * current lifecycle, as the {@link OnAlarmListener} instance supplied is only valid as long as
+     * the process is alive, and the system can clean up the app process as soon as it is out of
+     * lifecycle. To schedule alarms that fire reliably even after the current lifecycle completes,
+     * and wakes up the app if required, use any of the other scheduling APIs that accept a
+     * {@link PendingIntent} instance.
      *
-     * <p class="note"><strong>Note:</strong>
+     * <p>
      * On previous android versions {@link Build.VERSION_CODES#S} and
      * {@link Build.VERSION_CODES#TIRAMISU}, apps targeting SDK level 31 or higher needed to hold
      * the {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use
      * this API, unless the app was exempt from battery restrictions.
      *
+     * <p class="note"><strong>Note:</strong>
+     * Starting with android version {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the system will
+     * explicitly drop any alarms set via this API when the calling app goes out of lifecycle.
+     *
      */
     public void setExact(@AlarmType int type, long triggerAtMillis, @Nullable String tag,
             @NonNull OnAlarmListener listener, @Nullable Handler targetHandler) {
@@ -912,6 +942,24 @@
     }
 
     /**
+     * This is only used to make an identifying tag for the deprecated
+     * {@link #set(int, long, long, long, OnAlarmListener, Handler, WorkSource)} API which doesn't
+     * accept a tag. For all other APIs, the tag provided by the app is used, even if it is
+     * {@code null}.
+     */
+    private static String makeTag(long triggerMillis, WorkSource ws) {
+        final StringBuilder tagBuilder = new StringBuilder(GENERATED_TAG_PREFIX);
+
+        tagBuilder.append(":");
+        final int attributionUid =
+                (ws == null || ws.isEmpty()) ? Process.myUid() : ws.getAttributionUid();
+        tagBuilder.append(UserHandle.formatUid(attributionUid));
+        tagBuilder.append(":");
+        tagBuilder.append(triggerMillis);
+        return tagBuilder.toString();
+    }
+
+    /**
      * Direct callback version of {@link #set(int, long, long, long, PendingIntent, WorkSource)}.
      * Note that repeating alarms must use the PendingIntent variant, not an OnAlarmListener.
      * <p>
@@ -919,15 +967,26 @@
      * invoked via the specified target Handler, or on the application's main looper
      * if {@code null} is passed as the {@code targetHandler} parameter.
      *
+     * <p>The behavior of this API when {@code windowMillis < 0} is undefined.
+     *
+     * @deprecated Better alternative APIs exist for setting an alarm with this method:
+     * <ul>
+     *     <li>For alarms with {@code windowMillis > 0}, use
+     *     {@link #setWindow(int, long, long, String, Executor, WorkSource, OnAlarmListener)}</li>
+     *     <li>For alarms with {@code windowMillis = 0}, use
+     *     {@link #setExact(int, long, String, Executor, WorkSource, OnAlarmListener)}</li>
+     * </ul>
+     *
      * @hide
      */
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
     public void set(@AlarmType int type, long triggerAtMillis, long windowMillis,
             long intervalMillis, @NonNull OnAlarmListener listener, @Nullable Handler targetHandler,
             @Nullable WorkSource workSource) {
-        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, null, listener, null,
-                targetHandler, workSource, null);
+        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, null, listener,
+                makeTag(triggerAtMillis, workSource), targetHandler, workSource, null);
     }
 
     /**
@@ -945,6 +1004,10 @@
      * allowlist. This can be set, for example, by marking the app as {@code <allow-in-power-save>}
      * within the system config.
      *
+     * <p class="note"><strong>Note:</strong>
+     * Starting with android version {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the system will
+     * explicitly drop any alarms set via this API when the calling app goes out of lifecycle.
+     *
      * @param type            type of alarm
      * @param triggerAtMillis The exact time in milliseconds, that the alarm should be delivered,
      *                        expressed in the appropriate clock's units (depending on the alarm
@@ -1256,6 +1319,10 @@
      *
      * <p> See {@link #setExactAndAllowWhileIdle(int, long, PendingIntent)} for more details.
      *
+     * <p class="note"><strong>Note:</strong>
+     * Starting with android version {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, the system will
+     * explicitly drop any alarms set via this API when the calling app goes out of lifecycle.
+     *
      * @param type            type of alarm
      * @param triggerAtMillis The exact time in milliseconds, that the alarm should be delivered,
      *                        expressed in the appropriate clock's units (depending on the alarm
diff --git a/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java b/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
index 5d67c96..776d913 100644
--- a/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
+++ b/apex/jobscheduler/framework/java/android/app/JobSchedulerImpl.java
@@ -169,18 +169,18 @@
     }
 
     @Override
-    public boolean canRunLongJobs() {
+    public boolean canRunUserInitiatedJobs() {
         try {
-            return mBinder.canRunLongJobs(mContext.getOpPackageName());
+            return mBinder.canRunUserInitiatedJobs(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return false;
         }
     }
 
     @Override
-    public boolean hasRunLongJobsPermission(String packageName, int userId) {
+    public boolean hasRunUserInitiatedJobsPermission(String packageName, int userId) {
         try {
-            return mBinder.hasRunLongJobsPermission(packageName, userId);
+            return mBinder.hasRunUserInitiatedJobsPermission(packageName, userId);
         } catch (RemoteException e) {
             return false;
         }
@@ -230,9 +230,10 @@
             android.Manifest.permission.MANAGE_ACTIVITY_TASKS,
             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL})
     @Override
-    public void stopUserVisibleJobsForUser(@NonNull String packageName, int userId) {
+    public void notePendingUserRequestedAppStop(@NonNull String packageName, int userId,
+            @Nullable String debugReason) {
         try {
-            mBinder.stopUserVisibleJobsForUser(packageName, userId);
+            mBinder.notePendingUserRequestedAppStop(packageName, userId, debugReason);
         } catch (RemoteException e) {
         }
     }
diff --git a/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl b/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl
index a1f1954..416a2d8 100644
--- a/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl
+++ b/apex/jobscheduler/framework/java/android/app/job/IJobScheduler.aidl
@@ -39,8 +39,8 @@
     ParceledListSlice<JobInfo> getAllPendingJobsInNamespace(String namespace);
     JobInfo getPendingJob(String namespace, int jobId);
     int getPendingJobReason(String namespace, int jobId);
-    boolean canRunLongJobs(String packageName);
-    boolean hasRunLongJobsPermission(String packageName, int userId);
+    boolean canRunUserInitiatedJobs(String packageName);
+    boolean hasRunUserInitiatedJobsPermission(String packageName, int userId);
     List<JobInfo> getStartedJobs();
     ParceledListSlice getAllJobSnapshots();
     @EnforcePermission(allOf={"MANAGE_ACTIVITY_TASKS", "INTERACT_ACROSS_USERS_FULL"})
@@ -48,5 +48,5 @@
     @EnforcePermission(allOf={"MANAGE_ACTIVITY_TASKS", "INTERACT_ACROSS_USERS_FULL"})
     void unregisterUserVisibleJobObserver(in IUserVisibleJobObserver observer);
     @EnforcePermission(allOf={"MANAGE_ACTIVITY_TASKS", "INTERACT_ACROSS_USERS_FULL"})
-    void stopUserVisibleJobsForUser(String packageName, int userId);
+    void notePendingUserRequestedAppStop(String packageName, int userId, String debugReason);
 }
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index e0fffb4..11c13c4 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -1897,11 +1897,15 @@
          * <p>
          * All user-initiated jobs must have an associated notification, set via
          * {@link JobService#setNotification(JobParameters, int, Notification, int)}, and will be
-         * shown in the Task Manager when running.
+         * shown in the Task Manager when running. These jobs cannot be rescheduled by the app
+         * if the user stops the job via system provided affordance (such as the Task Manager).
+         * Thus, it is best practice and recommended to provide action buttons in the
+         * associated notification to allow the user to stop the job gracefully
+         * and allow for rescheduling.
          *
          * <p>
-         * If the app doesn't hold the {@link android.Manifest.permission#RUN_LONG_JOBS} permission
-         * when scheduling a user-initiated job, JobScheduler will throw a
+         * If the app doesn't hold the {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS}
+         * permission when scheduling a user-initiated job, JobScheduler will throw a
          * {@link SecurityException}.
          *
          * <p>
@@ -1910,7 +1914,7 @@
          *
          * @see JobInfo#isUserInitiated()
          */
-        @RequiresPermission(android.Manifest.permission.RUN_LONG_JOBS)
+        @RequiresPermission(android.Manifest.permission.RUN_USER_INITIATED_JOBS)
         @NonNull
         public Builder setUserInitiated(boolean userInitiated) {
             if (userInitiated) {
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
index 4be8766..242b52c 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
@@ -424,7 +424,7 @@
      * {@code true}. This will return {@code false} if the job wasn't requested to run as a
      * user-initiated job, or if it was requested to run as a user-initiated job but the app didn't
      * meet any of the requirements at the time of execution, such as having the
-     * {@link android.Manifest.permission#RUN_LONG_JOBS} permission.
+     * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission.
      *
      * @see JobInfo.Builder#setUserInitiated(boolean)
      */
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
index 4aec484..b8847ad 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
@@ -454,20 +454,23 @@
 
     /**
      * Returns {@code true} if the calling app currently holds the
-     * {@link android.Manifest.permission#RUN_LONG_JOBS} permission, allowing it to run long jobs.
+     * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run
+     * user-initiated jobs.
      */
-    public boolean canRunLongJobs() {
+    public boolean canRunUserInitiatedJobs() {
         return false;
     }
 
     /**
      * Returns {@code true} if the app currently holds the
-     * {@link android.Manifest.permission#RUN_LONG_JOBS} permission, allowing it to run long jobs.
+     * {@link android.Manifest.permission#RUN_USER_INITIATED_JOBS} permission, allowing it to run
+     * user-initiated jobs.
      * @hide
      * TODO(255371817): consider exposing this to apps who could call
      * {@link #scheduleAsPackage(JobInfo, String, int, String)}
      */
-    public boolean hasRunLongJobsPermission(@NonNull String packageName, @UserIdInt int userId) {
+    public boolean hasRunUserInitiatedJobsPermission(@NonNull String packageName,
+            @UserIdInt int userId) {
         return false;
     }
 
@@ -515,5 +518,6 @@
             android.Manifest.permission.MANAGE_ACTIVITY_TASKS,
             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL})
     @SuppressWarnings("HiddenAbstractMethod")
-    public abstract void stopUserVisibleJobsForUser(@NonNull String packageName, int userId);
+    public abstract void notePendingUserRequestedAppStop(@NonNull String packageName, int userId,
+            @Nullable String debugReason);
 }
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobService.java b/apex/jobscheduler/framework/java/android/app/job/JobService.java
index 1a205d0..2ab4324 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobService.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobService.java
@@ -156,6 +156,12 @@
      * a future idle maintenance window.
      * </p>
      *
+     * <p class="note">
+     * Any {@link JobInfo.Builder#setUserInitiated(boolean) user-initiated job}
+     * cannot be rescheduled when the user has asked to stop the app
+     * via a system provided affordance (such as the Task Manager).
+     * In such situations, the value of {@code wantsReschedule} is always treated as {@code false}.
+     *
      * @param params The parameters identifying this job, as supplied to
      *               the job in the {@link #onStartJob(JobParameters)} callback.
      * @param wantsReschedule {@code true} if this job should be rescheduled according
@@ -220,6 +226,12 @@
      * Once this method returns (or times out), the system releases the wakelock that it is holding
      * on behalf of the job.</p>
      *
+     * <p class="note">
+     * Any {@link JobInfo.Builder#setUserInitiated(boolean) user-initiated job}
+     * cannot be rescheduled when stopped by the user via a system provided affordance (such as
+     * the Task Manager). In such situations, the returned value from this method call is always
+     * treated as {@code false}.
+     *
      * <p class="caution"><strong>Note:</strong> When a job is stopped and rescheduled via this
      * method call, the deadline constraint is excluded from the rescheduled job's constraint set.
      * The rescheduled job will run again once all remaining constraints are satisfied.
diff --git a/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java b/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
index 217b8b6..c956bf5 100644
--- a/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java
@@ -17,9 +17,12 @@
 package com.android.server.job;
 
 import android.annotation.Nullable;
+import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.util.proto.ProtoOutputStream;
 
+import java.util.List;
+
 /**
  * JobScheduler local system service interface.
  * {@hide} Only for use within the system server.
@@ -27,6 +30,11 @@
 public interface JobSchedulerInternal {
 
     /**
+     * Returns a list of jobs scheduled by the system service for itself.
+     */
+    List<JobInfo> getSystemScheduledOwnJobs(@Nullable String namespace);
+
+    /**
      * Cancel the jobs for a given uid (e.g. when app data is cleared)
      *
      * @param includeProxiedJobs Include jobs scheduled for this UID by other apps
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index ad406a1..b7cf297 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -425,6 +425,12 @@
          */
         public void removeAlarmsForUid(int uid) {
         }
+
+        /**
+         * Called when a uid goes into cached, so its alarms using a listener should be removed.
+         */
+        public void removeListenerAlarmsForCachedUid(int uid) {
+        }
     }
 
     public AppStateTrackerImpl(Context context, Looper looper) {
@@ -496,7 +502,8 @@
                 mIActivityManager.registerUidObserver(new UidObserver(),
                         ActivityManager.UID_OBSERVER_GONE
                                 | ActivityManager.UID_OBSERVER_IDLE
-                                | ActivityManager.UID_OBSERVER_ACTIVE,
+                                | ActivityManager.UID_OBSERVER_ACTIVE
+                                | ActivityManager.UID_OBSERVER_CACHED,
                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
                 mAppOpsService.startWatchingMode(TARGET_OP, null,
                         new AppOpsWatcher());
@@ -731,6 +738,7 @@
 
         @Override
         public void onUidCachedChanged(int uid, boolean cached) {
+            mHandler.onUidCachedChanged(uid, cached);
         }
 
         @Override
@@ -800,6 +808,7 @@
         private static final int MSG_ON_UID_ACTIVE = 12;
         private static final int MSG_ON_UID_GONE = 13;
         private static final int MSG_ON_UID_IDLE = 14;
+        private static final int MSG_ON_UID_CACHED = 15;
 
         MyHandler(Looper looper) {
             super(looper);
@@ -860,6 +869,12 @@
             obtainMessage(MSG_ON_UID_IDLE, uid, disabled ? 1 : 0).sendToTarget();
         }
 
+        public void onUidCachedChanged(int uid, boolean cached) {
+            if (cached) {
+                obtainMessage(MSG_ON_UID_CACHED, uid, 0).sendToTarget();
+            }
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -953,6 +968,15 @@
                         handleUidDisabled(msg.arg1);
                     }
                     return;
+                case MSG_ON_UID_CACHED:
+                    handleUidCached(msg.arg1);
+                    return;
+            }
+        }
+
+        private void handleUidCached(int uid) {
+            for (Listener l : cloneListeners()) {
+                l.removeListenerAlarmsForCachedUid(uid);
             }
         }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 5599e54..f3f4fa1 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
 import static android.app.AlarmManager.ELAPSED_REALTIME;
 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
+import static android.app.AlarmManager.EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
@@ -57,6 +58,8 @@
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_ALARM_CANCELLED;
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_DATA_CLEARED;
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_EXACT_PERMISSION_REVOKED;
+import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_LISTENER_BINDER_DIED;
+import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_LISTENER_CACHED;
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_PI_CANCELLED;
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_UNDEFINED;
 
@@ -610,6 +613,8 @@
         static final int REMOVE_REASON_EXACT_PERMISSION_REVOKED = 2;
         static final int REMOVE_REASON_DATA_CLEARED = 3;
         static final int REMOVE_REASON_PI_CANCELLED = 4;
+        static final int REMOVE_REASON_LISTENER_BINDER_DIED = 5;
+        static final int REMOVE_REASON_LISTENER_CACHED = 6;
 
         final String mTag;
         final long mWhenRemovedElapsed;
@@ -639,6 +644,10 @@
                     return "data_cleared";
                 case REMOVE_REASON_PI_CANCELLED:
                     return "pi_cancelled";
+                case REMOVE_REASON_LISTENER_BINDER_DIED:
+                    return "listener_binder_died";
+                case REMOVE_REASON_LISTENER_CACHED:
+                    return "listener_cached";
                 default:
                     return "unknown:" + reason;
             }
@@ -1892,7 +1901,9 @@
             @Override
             public void binderDied(IBinder who) {
                 final IAlarmListener listener = IAlarmListener.Stub.asInterface(who);
-                removeImpl(null, listener);
+                synchronized (mLock) {
+                    removeLocked(null, listener, REMOVE_REASON_LISTENER_BINDER_DIED);
+                }
             }
         };
 
@@ -5444,6 +5455,24 @@
                 removeForStoppedLocked(uid);
             }
         }
+
+        @Override
+        public void removeListenerAlarmsForCachedUid(int uid) {
+            if (!CompatChanges.isChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, uid)) {
+                return;
+            }
+            synchronized (mLock) {
+                removeAlarmsInternalLocked(a -> {
+                    if (a.uid != uid || a.listener == null || a.windowLength != 0) {
+                        return false;
+                    }
+                    // TODO (b/265195908): Change to a .w once we have some data on breakages.
+                    Slog.wtf(TAG, "Alarm " + a.listenerTag + " being removed for " + a.packageName
+                            + " because the app went into cached state");
+                    return true;
+                }, REMOVE_REASON_LISTENER_CACHED);
+            }
+        }
     };
 
     private final BroadcastStats getStatsLocked(PendingIntent pi) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 62d97358..1022490 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -129,6 +129,10 @@
     static final String KEY_ENABLE_MAX_WAIT_TIME_BYPASS =
             CONFIG_KEY_PREFIX_CONCURRENCY + "enable_max_wait_time_bypass";
     private static final boolean DEFAULT_ENABLE_MAX_WAIT_TIME_BYPASS = true;
+    @VisibleForTesting
+    static final String KEY_MAX_WAIT_UI_MS = CONFIG_KEY_PREFIX_CONCURRENCY + "max_wait_ui_ms";
+    @VisibleForTesting
+    static final long DEFAULT_MAX_WAIT_UI_MS = 5 * MINUTE_IN_MILLIS;
     private static final String KEY_MAX_WAIT_EJ_MS =
             CONFIG_KEY_PREFIX_CONCURRENCY + "max_wait_ej_ms";
     @VisibleForTesting
@@ -433,6 +437,12 @@
     private boolean mMaxWaitTimeBypassEnabled = DEFAULT_ENABLE_MAX_WAIT_TIME_BYPASS;
 
     /**
+     * The maximum time a user-initiated job would have to be potentially waiting for an available
+     * slot before we would consider creating a new slot for it.
+     */
+    private long mMaxWaitUIMs = DEFAULT_MAX_WAIT_UI_MS;
+
+    /**
      * The maximum time an expedited job would have to be potentially waiting for an available
      * slot before we would consider creating a new slot for it.
      */
@@ -825,6 +835,13 @@
                 if (js.startedWithImmediacyPrivilege) {
                     info.numRunningImmediacyPrivileged++;
                 }
+                if (js.shouldTreatAsUserInitiatedJob()) {
+                    info.numRunningUi++;
+                } else if (js.startedAsExpeditedJob) {
+                    info.numRunningEj++;
+                } else {
+                    info.numRunningReg++;
+                }
             }
 
             assignment.preferredUid = jsc.getPreferredUid();
@@ -880,6 +897,13 @@
         JobStatus nextPending;
         int projectedRunningCount = activeServices.size();
         long minChangedWaitingTimeMs = Long.MAX_VALUE;
+        // Only allow the Context creation bypass for each type if one of that type isn't already
+        // running. That way, we don't run into issues (creating too many additional contexts)
+        // if new jobs become ready to run in rapid succession and we end up going through this
+        // loop many times before running jobs have had a decent chance to finish.
+        boolean allowMaxWaitContextBypassUi = info.numRunningUi == 0;
+        boolean allowMaxWaitContextBypassEj = info.numRunningEj == 0;
+        boolean allowMaxWaitContextBypassOthers = info.numRunningReg == 0;
         while ((nextPending = pendingJobQueue.next()) != null) {
             if (mRunningJobs.contains(nextPending)) {
                 // Should never happen.
@@ -957,7 +981,9 @@
                                         > (mWorkTypeConfig.getMaxTotal() / 2);
                     }
                     if (!canReplace && mMaxWaitTimeBypassEnabled) { // Case 5
-                        if (nextPending.shouldTreatAsExpeditedJob()) {
+                        if (nextPending.shouldTreatAsUserInitiatedJob()) {
+                            canReplace = minWaitingTimeMs >= mMaxWaitUIMs;
+                        } else if (nextPending.shouldTreatAsExpeditedJob()) {
                             canReplace = minWaitingTimeMs >= mMaxWaitEjMs;
                         } else {
                             canReplace = minWaitingTimeMs >= mMaxWaitRegularMs;
@@ -1055,9 +1081,25 @@
                             (workType != WORK_TYPE_NONE) ? workType : WORK_TYPE_TOP;
                 }
             } else if (selectedContext == null && mMaxWaitTimeBypassEnabled) {
-                final boolean wouldBeWaitingTooLong = nextPending.shouldTreatAsExpeditedJob()
-                        ? minWaitingTimeMs >= mMaxWaitEjMs
-                        : minWaitingTimeMs >= mMaxWaitRegularMs;
+                final boolean wouldBeWaitingTooLong;
+                if (nextPending.shouldTreatAsUserInitiatedJob() && allowMaxWaitContextBypassUi) {
+                    wouldBeWaitingTooLong = minWaitingTimeMs >= mMaxWaitUIMs;
+                    // We want to create at most one additional context for each type.
+                    allowMaxWaitContextBypassUi = !wouldBeWaitingTooLong;
+                } else if (nextPending.shouldTreatAsExpeditedJob() && allowMaxWaitContextBypassEj) {
+                    wouldBeWaitingTooLong = minWaitingTimeMs >= mMaxWaitEjMs;
+                    // We want to create at most one additional context for each type.
+                    allowMaxWaitContextBypassEj = !wouldBeWaitingTooLong;
+                } else if (allowMaxWaitContextBypassOthers) {
+                    // The way things are set up a UIJ or EJ could end up here and create a 2nd
+                    // context as if it were a "regular" job. That's fine for now since they would
+                    // still be subject to the higher waiting time threshold here.
+                    wouldBeWaitingTooLong = minWaitingTimeMs >= mMaxWaitRegularMs;
+                    // We want to create at most one additional context for each type.
+                    allowMaxWaitContextBypassOthers = !wouldBeWaitingTooLong;
+                } else {
+                    wouldBeWaitingTooLong = false;
+                }
                 if (wouldBeWaitingTooLong) {
                     if (DEBUG) {
                         Slog.d(TAG, "Allowing additional context because job would wait too long");
@@ -1282,17 +1324,20 @@
     }
 
     @GuardedBy("mLock")
-    void stopUserVisibleJobsLocked(int userId, @NonNull String packageName,
-            @JobParameters.StopReason int reason, int internalReasonCode) {
+    void markJobsForUserStopLocked(int userId, @NonNull String packageName,
+            @Nullable String debugReason) {
         for (int i = mActiveServices.size() - 1; i >= 0; --i) {
             final JobServiceContext jsc = mActiveServices.get(i);
             final JobStatus jobStatus = jsc.getRunningJobLocked();
 
-            if (jobStatus != null && userId == jobStatus.getSourceUserId()
-                    && jobStatus.getSourcePackageName().equals(packageName)
-                    && jobStatus.isUserVisibleJob()) {
-                jsc.cancelExecutingJobLocked(reason, internalReasonCode,
-                        JobParameters.getInternalReasonCodeDescription(internalReasonCode));
+            // Normally, we handle jobs primarily using the source package and userId,
+            // however, user-visible jobs are shown as coming from the calling app, so we
+            // need to operate on the jobs from that perspective here.
+            if (jobStatus != null && userId == jobStatus.getUserId()
+                    && jobStatus.getServiceComponent().getPackageName().equals(packageName)) {
+                jsc.markForProcessDeathLocked(JobParameters.STOP_REASON_USER,
+                        JobParameters.INTERNAL_STOP_REASON_USER_UI_STOP,
+                        debugReason);
             }
         }
     }
@@ -1490,10 +1535,14 @@
                     minWaitingTimeMs = Math.min(minWaitingTimeMs,
                             mActiveServices.get(i).getRemainingGuaranteedTimeMs(nowElapsed));
                 }
-                final boolean wouldBeWaitingTooLong =
-                        mWorkCountTracker.getPendingJobCount(WORK_TYPE_EJ) > 0
-                                ? minWaitingTimeMs >= mMaxWaitEjMs
-                                : minWaitingTimeMs >= mMaxWaitRegularMs;
+                final boolean wouldBeWaitingTooLong;
+                if (mWorkCountTracker.getPendingJobCount(WORK_TYPE_UI) > 0) {
+                    wouldBeWaitingTooLong = minWaitingTimeMs >= mMaxWaitUIMs;
+                } else if (mWorkCountTracker.getPendingJobCount(WORK_TYPE_EJ) > 0) {
+                    wouldBeWaitingTooLong = minWaitingTimeMs >= mMaxWaitEjMs;
+                } else {
+                    wouldBeWaitingTooLong = minWaitingTimeMs >= mMaxWaitRegularMs;
+                }
                 respectConcurrencyLimit = !wouldBeWaitingTooLong;
             }
             if (respectConcurrencyLimit) {
@@ -1908,8 +1957,11 @@
 
         mMaxWaitTimeBypassEnabled = properties.getBoolean(
                 KEY_ENABLE_MAX_WAIT_TIME_BYPASS, DEFAULT_ENABLE_MAX_WAIT_TIME_BYPASS);
-        // EJ max wait must be in the range [0, infinity).
-        mMaxWaitEjMs = Math.max(0, properties.getLong(KEY_MAX_WAIT_EJ_MS, DEFAULT_MAX_WAIT_EJ_MS));
+        // UI max wait must be in the range [0, infinity).
+        mMaxWaitUIMs = Math.max(0, properties.getLong(KEY_MAX_WAIT_UI_MS, DEFAULT_MAX_WAIT_UI_MS));
+        // EJ max wait must be in the range [UI max wait, infinity).
+        mMaxWaitEjMs = Math.max(mMaxWaitUIMs,
+                properties.getLong(KEY_MAX_WAIT_EJ_MS, DEFAULT_MAX_WAIT_EJ_MS));
         // Regular max wait must be in the range [EJ max wait, infinity).
         mMaxWaitRegularMs = Math.max(mMaxWaitEjMs,
                 properties.getLong(KEY_MAX_WAIT_REGULAR_MS, DEFAULT_MAX_WAIT_REGULAR_MS));
@@ -1928,6 +1980,7 @@
             pw.print(KEY_PKG_CONCURRENCY_LIMIT_EJ, mPkgConcurrencyLimitEj).println();
             pw.print(KEY_PKG_CONCURRENCY_LIMIT_REGULAR, mPkgConcurrencyLimitRegular).println();
             pw.print(KEY_ENABLE_MAX_WAIT_TIME_BYPASS, mMaxWaitTimeBypassEnabled).println();
+            pw.print(KEY_MAX_WAIT_UI_MS, mMaxWaitUIMs).println();
             pw.print(KEY_MAX_WAIT_EJ_MS, mMaxWaitEjMs).println();
             pw.print(KEY_MAX_WAIT_REGULAR_MS, mMaxWaitRegularMs).println();
             pw.println();
@@ -2790,10 +2843,16 @@
     static final class AssignmentInfo {
         public long minPreferredUidOnlyWaitingTimeMs;
         public int numRunningImmediacyPrivileged;
+        public int numRunningUi;
+        public int numRunningEj;
+        public int numRunningReg;
 
         void clear() {
             minPreferredUidOnlyWaitingTimeMs = 0;
             numRunningImmediacyPrivileged = 0;
+            numRunningUi = 0;
+            numRunningEj = 0;
+            numRunningReg = 0;
         }
     }
 
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 e8fcdd2..419111a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -953,8 +953,8 @@
                     properties.getLong(
                             KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
                             DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS));
-            // Data transfer requires RUN_LONG_JOBS permission, so the upper limit will be higher
-            // than other jobs.
+            // User-initiated requires RUN_USER_INITIATED_JOBS permission, so the upper limit will
+            // be higher than other jobs.
             // Max limit should be the min guarantee and the max of other user-initiated jobs.
             RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS = Math.max(
                     RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
@@ -1701,16 +1701,15 @@
     }
 
     @VisibleForTesting
-    void stopUserVisibleJobsInternal(@NonNull String packageName, int userId) {
+    void notePendingUserRequestedAppStopInternal(@NonNull String packageName, int userId,
+            @Nullable String debugReason) {
         final int packageUid = mLocalPM.getPackageUid(packageName, 0, userId);
         if (packageUid < 0) {
             Slog.wtf(TAG, "Asked to stop jobs of an unknown package");
             return;
         }
         synchronized (mLock) {
-            mConcurrencyManager.stopUserVisibleJobsLocked(userId, packageName,
-                    JobParameters.STOP_REASON_USER,
-                    JobParameters.INTERNAL_STOP_REASON_USER_UI_STOP);
+            mConcurrencyManager.markJobsForUserStopLocked(userId, packageName, debugReason);
             final ArraySet<JobStatus> jobs = mJobs.getJobsByUid(packageUid);
             for (int i = jobs.size() - 1; i >= 0; i--) {
                 final JobStatus job = jobs.valueAt(i);
@@ -2387,12 +2386,25 @@
      *
      * @param failureToReschedule Provided job status that we will reschedule.
      * @return A newly instantiated JobStatus with the same constraints as the last job except
-     * with adjusted timing constraints.
+     * with adjusted timing constraints, or {@code null} if the job shouldn't be rescheduled for
+     * some policy reason.
      * @see #maybeQueueReadyJobsForExecutionLocked
      */
+    @Nullable
     @VisibleForTesting
     JobStatus getRescheduleJobForFailureLocked(JobStatus failureToReschedule,
             @JobParameters.StopReason int stopReason, int internalStopReason) {
+        if (internalStopReason == JobParameters.INTERNAL_STOP_REASON_USER_UI_STOP
+                && failureToReschedule.isUserVisibleJob()) {
+            // If a user stops an app via Task Manager and the job was user-visible, then assume
+            // the user wanted to stop that task and not let it run in the future. It's in the
+            // app's best interests to provide action buttons in their notification to avoid this
+            // scenario.
+            Slog.i(TAG,
+                    "Dropping " + failureToReschedule.toShortString() + " because of user stop");
+            return null;
+        }
+
         final long elapsedNowMillis = sElapsedRealtimeClock.millis();
         final JobInfo job = failureToReschedule.getJob();
 
@@ -3293,7 +3305,8 @@
     public long getMinJobExecutionGuaranteeMs(JobStatus job) {
         synchronized (mLock) {
             if (job.shouldTreatAsUserInitiatedJob()
-                    && checkRunLongJobsPermission(job.getSourceUid(), job.getSourcePackageName())) {
+                    && checkRunUserInitiatedJobsPermission(
+                            job.getSourceUid(), job.getSourcePackageName())) {
                 if (job.getJob().isDataTransfer()) {
                     final long estimatedTransferTimeMs =
                             mConnectivityController.getEstimatedTransferTimeMs(job);
@@ -3331,7 +3344,8 @@
     public long getMaxJobExecutionTimeMs(JobStatus job) {
         synchronized (mLock) {
             final boolean allowLongerJob = job.shouldTreatAsUserInitiatedJob()
-                    && checkRunLongJobsPermission(job.getSourceUid(), job.getSourcePackageName());
+                    && checkRunUserInitiatedJobsPermission(
+                            job.getSourceUid(), job.getSourcePackageName());
             if (job.getJob().isDataTransfer() && allowLongerJob) { // UI+DT
                 return mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS;
             }
@@ -3524,6 +3538,21 @@
     final class LocalService implements JobSchedulerInternal {
 
         @Override
+        public List<JobInfo> getSystemScheduledOwnJobs(@Nullable String namespace) {
+            synchronized (mLock) {
+                final List<JobInfo> ownJobs = new ArrayList<>();
+                mJobs.forEachJob(Process.SYSTEM_UID, (job) -> {
+                    if (job.getSourceUid() == Process.SYSTEM_UID
+                            && Objects.equals(job.getNamespace(), namespace)
+                            && "android".equals(job.getSourcePackageName())) {
+                        ownJobs.add(job.getJob());
+                    }
+                });
+                return ownJobs;
+            }
+        }
+
+        @Override
         public void cancelJobsForUid(int uid, boolean includeProxiedJobs,
                 @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) {
             JobSchedulerService.this.cancelJobsForUid(uid,
@@ -3797,7 +3826,7 @@
                 if (sourceUid != -1) {
                     // Check the permission of the source app.
                     final int sourceResult =
-                            validateRunLongJobsPermission(sourceUid, sourcePkgName);
+                            validateRunUserInitiatedJobsPermission(sourceUid, sourcePkgName);
                     if (sourceResult != JobScheduler.RESULT_SUCCESS) {
                         return sourceResult;
                     }
@@ -3807,7 +3836,7 @@
                     // Source app is different from calling app. Make sure the calling app also has
                     // the permission.
                     final int callingResult =
-                            validateRunLongJobsPermission(callingUid, callingPkgName);
+                            validateRunUserInitiatedJobsPermission(callingUid, callingPkgName);
                     if (callingResult != JobScheduler.RESULT_SUCCESS) {
                         return callingResult;
                     }
@@ -3844,10 +3873,10 @@
             return JobScheduler.RESULT_SUCCESS;
         }
 
-        private int validateRunLongJobsPermission(int uid, String packageName) {
-            final int state = getRunLongJobsPermissionState(uid, packageName);
+        private int validateRunUserInitiatedJobsPermission(int uid, String packageName) {
+            final int state = getRunUserInitiatedJobsPermissionState(uid, packageName);
             if (state == PermissionChecker.PERMISSION_HARD_DENIED) {
-                throw new SecurityException(android.Manifest.permission.RUN_LONG_JOBS
+                throw new SecurityException(android.Manifest.permission.RUN_USER_INITIATED_JOBS
                         + " required to schedule user-initiated jobs.");
             }
             if (state == PermissionChecker.PERMISSION_SOFT_DENIED) {
@@ -4064,30 +4093,29 @@
             }
         }
 
-        @Override
-        public boolean canRunLongJobs(@NonNull String packageName) {
+        public boolean canRunUserInitiatedJobs(@NonNull String packageName) {
             final int callingUid = Binder.getCallingUid();
             final int userId = UserHandle.getUserId(callingUid);
             final int packageUid = mLocalPM.getPackageUid(packageName, 0, userId);
             if (callingUid != packageUid) {
                 throw new SecurityException("Uid " + callingUid
-                        + " cannot query canRunLongJobs for package " + packageName);
+                        + " cannot query canRunUserInitiatedJobs for package " + packageName);
             }
 
-            return checkRunLongJobsPermission(packageUid, packageName);
+            return checkRunUserInitiatedJobsPermission(packageUid, packageName);
         }
 
-        @Override
-        public boolean hasRunLongJobsPermission(@NonNull String packageName,
+        public boolean hasRunUserInitiatedJobsPermission(@NonNull String packageName,
                 @UserIdInt int userId) {
             final int uid = mLocalPM.getPackageUid(packageName, 0, userId);
             final int callingUid = Binder.getCallingUid();
             if (callingUid != uid && !UserHandle.isCore(callingUid)) {
                 throw new SecurityException("Uid " + callingUid
-                        + " cannot query hasRunLongJobsPermission for package " + packageName);
+                        + " cannot query hasRunUserInitiatedJobsPermission for package "
+                        + packageName);
             }
 
-            return checkRunLongJobsPermission(uid, packageName);
+            return checkRunUserInitiatedJobsPermission(uid, packageName);
         }
 
         /**
@@ -4225,12 +4253,13 @@
 
         @Override
         @EnforcePermission(allOf = {MANAGE_ACTIVITY_TASKS, INTERACT_ACROSS_USERS_FULL})
-        public void stopUserVisibleJobsForUser(@NonNull String packageName, int userId) {
-            super.stopUserVisibleJobsForUser_enforcePermission();
+        public void notePendingUserRequestedAppStop(@NonNull String packageName, int userId,
+                @Nullable String debugReason) {
+            super.notePendingUserRequestedAppStop_enforcePermission();
             if (packageName == null) {
                 throw new NullPointerException("packageName");
             }
-            JobSchedulerService.this.stopUserVisibleJobsInternal(packageName, userId);
+            notePendingUserRequestedAppStopInternal(packageName, userId, debugReason);
         }
     }
 
@@ -4466,14 +4495,14 @@
     }
 
     /** Returns true if both the appop and permission are granted. */
-    private boolean checkRunLongJobsPermission(int packageUid, String packageName) {
-        return getRunLongJobsPermissionState(packageUid, packageName)
+    private boolean checkRunUserInitiatedJobsPermission(int packageUid, String packageName) {
+        return getRunUserInitiatedJobsPermissionState(packageUid, packageName)
                 == PermissionChecker.PERMISSION_GRANTED;
     }
 
-    private int getRunLongJobsPermissionState(int packageUid, String packageName) {
+    private int getRunUserInitiatedJobsPermissionState(int packageUid, String packageName) {
         return PermissionChecker.checkPermissionForPreflight(getTestableContext(),
-                android.Manifest.permission.RUN_LONG_JOBS, PermissionChecker.PID_UNKNOWN,
+                android.Manifest.permission.RUN_USER_INITIATED_JOBS, PermissionChecker.PID_UNKNOWN,
                 packageUid, packageName);
     }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 514d984..cc9e517 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -190,6 +190,14 @@
 
     private Network mPendingNetworkChange;
 
+    /**
+     * The reason this job is marked for death. If it's not marked for death,
+     * then the value should be {@link JobParameters#STOP_REASON_UNDEFINED}.
+     */
+    private int mDeathMarkStopReason = JobParameters.STOP_REASON_UNDEFINED;
+    private int mDeathMarkInternalStopReason;
+    private String mDeathMarkDebugReason;
+
     // Debugging: reason this job was last stopped.
     public String mStoppedReason;
 
@@ -452,6 +460,7 @@
             mStoppedReason = null;
             mStoppedTime = 0;
             job.startedAsExpeditedJob = job.shouldTreatAsExpeditedJob();
+            job.startedAsUserInitiatedJob = job.shouldTreatAsUserInitiatedJob();
             return true;
         }
     }
@@ -502,6 +511,34 @@
         doCancelLocked(reason, internalStopReason, debugReason);
     }
 
+    /**
+     * Called when an app's process is about to be killed and we want to update the job's stop
+     * reasons without telling the job it's going to be stopped.
+     */
+    @GuardedBy("mLock")
+    void markForProcessDeathLocked(@JobParameters.StopReason int reason,
+            int internalStopReason, @NonNull String debugReason) {
+        if (mVerb == VERB_FINISHED) {
+            if (DEBUG) {
+                Slog.d(TAG, "Too late to mark for death (verb=" + mVerb + "), ignoring.");
+            }
+            return;
+        }
+        if (DEBUG) {
+            Slog.d(TAG,
+                    "Marking " + mRunningJob.toShortString() + " for death because "
+                            + reason + ":" + debugReason);
+        }
+        mDeathMarkStopReason = reason;
+        mDeathMarkInternalStopReason = internalStopReason;
+        mDeathMarkDebugReason = debugReason;
+        if (mParams.getStopReason() == JobParameters.STOP_REASON_UNDEFINED) {
+            // Only set the stop reason if we're not already trying to stop the job for some
+            // other reason in case that other stop is successful before the process dies.
+            mParams.setStopReason(reason, internalStopReason, debugReason);
+        }
+    }
+
     int getPreferredUid() {
         return mPreferredUid;
     }
@@ -754,6 +791,12 @@
     @Override
     public void onServiceDisconnected(ComponentName name) {
         synchronized (mLock) {
+            if (mDeathMarkStopReason != JobParameters.STOP_REASON_UNDEFINED) {
+                // Service "unexpectedly" disconnected, but we knew the process was going to die.
+                // Use that as the stop reason for logging/debugging purposes.
+                mParams.setStopReason(
+                        mDeathMarkStopReason, mDeathMarkInternalStopReason, mDeathMarkDebugReason);
+            }
             closeAndCleanupJobLocked(true /* needsReschedule */, "unexpectedly disconnected");
         }
     }
@@ -1182,29 +1225,51 @@
      * we want to clean up internally.
      */
     @GuardedBy("mLock")
-    private void closeAndCleanupJobLocked(boolean reschedule, @Nullable String reason) {
+    private void closeAndCleanupJobLocked(boolean reschedule, @Nullable String loggingDebugReason) {
         final JobStatus completedJob;
         if (mVerb == VERB_FINISHED) {
             return;
         }
         if (DEBUG) {
             Slog.d(TAG, "Cleaning up " + mRunningJob.toShortString()
-                    + " reschedule=" + reschedule + " reason=" + reason);
+                    + " reschedule=" + reschedule + " reason=" + loggingDebugReason);
         }
-        applyStoppedReasonLocked(reason);
+        applyStoppedReasonLocked(loggingDebugReason);
         completedJob = mRunningJob;
-        final int internalStopReason = mParams.getInternalStopReasonCode();
-        final int stopReason = mParams.getStopReason();
+        // Use the JobParameters stop reasons for logging and metric purposes,
+        // but if the job was marked for death, use that reason for rescheduling purposes.
+        // The discrepancy could happen if a job ends up stopping for some reason
+        // in the time between the job being marked and the process actually dying.
+        // Since the job stopped for another reason, we want to log the actual stop reason
+        // for the sake of accurate metrics and debugging,
+        // but we should use the death mark reasons when determining reschedule policy.
+        final int loggingStopReason = mParams.getStopReason();
+        final int loggingInternalStopReason = mParams.getInternalStopReasonCode();
+        final int reschedulingStopReason, reschedulingInternalStopReason;
+        if (mDeathMarkStopReason != JobParameters.STOP_REASON_UNDEFINED) {
+            if (DEBUG) {
+                Slog.d(TAG, "Job marked for death because of "
+                        + JobParameters.getInternalReasonCodeDescription(
+                                mDeathMarkInternalStopReason)
+                        + ": " + mDeathMarkDebugReason);
+            }
+            reschedulingStopReason = mDeathMarkStopReason;
+            reschedulingInternalStopReason = mDeathMarkInternalStopReason;
+        } else {
+            reschedulingStopReason = loggingStopReason;
+            reschedulingInternalStopReason = loggingInternalStopReason;
+        }
         mPreviousJobHadSuccessfulFinish =
-                (internalStopReason == JobParameters.INTERNAL_STOP_REASON_SUCCESSFUL_FINISH);
+                (loggingInternalStopReason == JobParameters.INTERNAL_STOP_REASON_SUCCESSFUL_FINISH);
         if (!mPreviousJobHadSuccessfulFinish) {
             mLastUnsuccessfulFinishElapsed = sElapsedRealtimeClock.millis();
         }
-        mJobPackageTracker.noteInactive(completedJob, internalStopReason, reason);
+        mJobPackageTracker.noteInactive(completedJob,
+                loggingInternalStopReason, loggingDebugReason);
         FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
                 completedJob.getSourceUid(), null, completedJob.getBatteryName(),
                 FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
-                internalStopReason, completedJob.getStandbyBucket(), completedJob.getJobId(),
+                loggingInternalStopReason, completedJob.getStandbyBucket(), completedJob.getJobId(),
                 completedJob.hasChargingConstraint(),
                 completedJob.hasBatteryNotLowConstraint(),
                 completedJob.hasStorageNotLowConstraint(),
@@ -1215,7 +1280,7 @@
                 completedJob.hasContentTriggerConstraint(),
                 completedJob.isRequestedExpeditedJob(),
                 completedJob.startedAsExpeditedJob,
-                stopReason,
+                loggingStopReason,
                 completedJob.getJob().isPrefetch(),
                 completedJob.getJob().getPriority(),
                 completedJob.getEffectivePriority(),
@@ -1235,11 +1300,11 @@
         }
         try {
             mBatteryStats.noteJobFinish(mRunningJob.getBatteryName(), mRunningJob.getSourceUid(),
-                    internalStopReason);
+                    loggingInternalStopReason);
         } catch (RemoteException e) {
             // Whatever.
         }
-        if (mParams.getStopReason() == JobParameters.STOP_REASON_TIMEOUT) {
+        if (loggingStopReason == JobParameters.STOP_REASON_TIMEOUT) {
             mEconomyManagerInternal.noteInstantaneousEvent(
                     mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(),
                     JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT,
@@ -1260,6 +1325,9 @@
         mCancelled = false;
         service = null;
         mAvailable = true;
+        mDeathMarkStopReason = JobParameters.STOP_REASON_UNDEFINED;
+        mDeathMarkInternalStopReason = 0;
+        mDeathMarkDebugReason = null;
         mPendingStopReason = JobParameters.STOP_REASON_UNDEFINED;
         mPendingInternalStopReason = 0;
         mPendingDebugStopReason = null;
@@ -1268,8 +1336,8 @@
         if (completedJob.isUserVisibleJob()) {
             mService.informObserversOfUserVisibleJobChange(this, completedJob, false);
         }
-        mCompletedListener.onJobCompletedLocked(completedJob, stopReason, internalStopReason,
-                reschedule);
+        mCompletedListener.onJobCompletedLocked(completedJob,
+                reschedulingStopReason, reschedulingInternalStopReason, reschedule);
         mJobConcurrencyManager.onJobCompletedLocked(this, completedJob, workType);
     }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index b87dec1..2a9186a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -434,7 +434,7 @@
         final UidStats uidStats =
                 getUidStats(jobStatus.getSourceUid(), jobStatus.getSourcePackageName(), true);
 
-        if (jobStatus.shouldTreatAsExpeditedJob() && jobStatus.shouldTreatAsUserInitiatedJob()) {
+        if (jobStatus.shouldTreatAsExpeditedJob() || jobStatus.shouldTreatAsUserInitiatedJob()) {
             if (!jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)) {
                 // Don't request a direct hole through any of the firewalls. Instead, mark the
                 // constraint as satisfied if the network is available, and the job will get
@@ -444,7 +444,9 @@
             }
             // Don't need to update constraint here if the network goes away. We'll do that as part
             // of regular processing when we're notified about the drop.
-        } else if (jobStatus.isRequestedExpeditedJob()
+        } else if (((jobStatus.isRequestedExpeditedJob() && !jobStatus.shouldTreatAsExpeditedJob())
+                || (jobStatus.getJob().isUserInitiated()
+                        && !jobStatus.shouldTreatAsUserInitiatedJob()))
                 && jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY)) {
             // Make sure we don't accidentally keep the constraint as satisfied if the job went
             // from being expedited-ready to not-expeditable.
@@ -1127,6 +1129,22 @@
 
         final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants);
 
+        if (!satisfied && jobStatus.network != null
+                && mService.isCurrentlyRunningLocked(jobStatus)
+                && isSatisfied(jobStatus, jobStatus.network,
+                        getNetworkCapabilities(jobStatus.network), mConstants)) {
+            // A new network became available for a currently running job
+            // (and most likely became the default network for the app),
+            // but it doesn't yet satisfy the requested constraints and the old network
+            // is still available and satisfies the constraints. Don't change the network
+            // given to the job for now and let it keep running. We will re-evaluate when
+            // the capabilities or connection state of the either network change.
+            if (DEBUG) {
+                Slog.i(TAG, "Not reassigning network for running job " + jobStatus);
+            }
+            return false;
+        }
+
         final boolean changed = jobStatus.setConnectivityConstraintSatisfied(nowElapsed, satisfied);
 
         if (jobStatus.getPreferUnmetered()) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index ce33a8e..1971a11 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -402,6 +402,11 @@
      * running. This isn't copied over when a job is rescheduled.
      */
     public boolean startedAsExpeditedJob = false;
+    /**
+     * Whether or not this particular JobStatus instance was treated as a user-initiated job
+     * when it started running. This isn't copied over when a job is rescheduled.
+     */
+    public boolean startedAsUserInitiatedJob = false;
 
     public boolean startedWithImmediacyPrivilege = false;
 
@@ -1407,7 +1412,7 @@
      * @return true if this is a job whose execution should be made visible to the user.
      */
     public boolean isUserVisibleJob() {
-        return shouldTreatAsUserInitiatedJob();
+        return shouldTreatAsUserInitiatedJob() || startedAsUserInitiatedJob;
     }
 
     /**
@@ -2568,6 +2573,13 @@
             pw.print(startedAsExpeditedJob);
             pw.println(")");
         }
+        if ((getFlags() & JobInfo.FLAG_USER_INITIATED) != 0) {
+            pw.print("userInitiatedApproved: ");
+            pw.print(shouldTreatAsUserInitiatedJob());
+            pw.print(" (started as UIJ: ");
+            pw.print(startedAsUserInitiatedJob);
+            pw.println(")");
+        }
         pw.decreaseIndent();
 
         if (changedAuthorities != null) {
diff --git a/boot/preloaded-classes b/boot/preloaded-classes
index 39b7385..b43421d 100644
--- a/boot/preloaded-classes
+++ b/boot/preloaded-classes
@@ -5525,6 +5525,8 @@
 android.nfc.NfcAdapter
 android.nfc.NfcControllerAlwaysOnListener
 android.nfc.NfcManager
+android.nfc.NfcServiceManager$ServiceRegisterer
+android.nfc.NfcServiceManager
 android.nfc.Tag$1
 android.nfc.Tag
 android.nfc.TechListParcel$1
diff --git a/core/api/current.txt b/core/api/current.txt
index dfc2602..7c92793 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -83,6 +83,7 @@
     field public static final String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
     field public static final String CONFIGURE_WIFI_DISPLAY = "android.permission.CONFIGURE_WIFI_DISPLAY";
     field public static final String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
+    field public static final String CREDENTIAL_MANAGER_SET_ORIGIN = "android.permission.CREDENTIAL_MANAGER_SET_ORIGIN";
     field public static final String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
     field public static final String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
     field public static final String DELIVER_COMPANION_MESSAGES = "android.permission.DELIVER_COMPANION_MESSAGES";
@@ -121,26 +122,85 @@
     field public static final String INTERACT_ACROSS_PROFILES = "android.permission.INTERACT_ACROSS_PROFILES";
     field public static final String INTERNET = "android.permission.INTERNET";
     field public static final String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";
+    field public static final String LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE = "android.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE";
     field public static final String LAUNCH_MULTI_PANE_SETTINGS_DEEP_LINK = "android.permission.LAUNCH_MULTI_PANE_SETTINGS_DEEP_LINK";
     field public static final String LOADER_USAGE_STATS = "android.permission.LOADER_USAGE_STATS";
     field public static final String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
     field public static final String MANAGE_DEVICE_LOCK_STATE = "android.permission.MANAGE_DEVICE_LOCK_STATE";
+    field public static final String MANAGE_DEVICE_POLICY_ACCESSIBILITY = "android.permission.MANAGE_DEVICE_POLICY_ACCESSIBILITY";
+    field public static final String MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT = "android.permission.MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT";
     field public static final String MANAGE_DEVICE_POLICY_ACROSS_USERS = "android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS";
     field public static final String MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL = "android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL";
     field public static final String MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL = "android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL";
+    field public static final String MANAGE_DEVICE_POLICY_AIRPLANE_MODE = "android.permission.MANAGE_DEVICE_POLICY_AIRPLANE_MODE";
     field public static final String MANAGE_DEVICE_POLICY_APPS_CONTROL = "android.permission.MANAGE_DEVICE_POLICY_APPS_CONTROL";
     field public static final String MANAGE_DEVICE_POLICY_APP_RESTRICTIONS = "android.permission.MANAGE_DEVICE_POLICY_APP_RESTRICTIONS";
+    field public static final String MANAGE_DEVICE_POLICY_APP_USER_DATA = "android.permission.MANAGE_DEVICE_POLICY_APP_USER_DATA";
+    field public static final String MANAGE_DEVICE_POLICY_AUDIO_OUTPUT = "android.permission.MANAGE_DEVICE_POLICY_AUDIO_OUTPUT";
+    field public static final String MANAGE_DEVICE_POLICY_AUTOFILL = "android.permission.MANAGE_DEVICE_POLICY_AUTOFILL";
     field public static final String MANAGE_DEVICE_POLICY_BACKUP_SERVICE = "android.permission.MANAGE_DEVICE_POLICY_BACKUP_SERVICE";
+    field public static final String MANAGE_DEVICE_POLICY_BLUETOOTH = "android.permission.MANAGE_DEVICE_POLICY_BLUETOOTH";
+    field public static final String MANAGE_DEVICE_POLICY_BUGREPORT = "android.permission.MANAGE_DEVICE_POLICY_BUGREPORT";
     field public static final String MANAGE_DEVICE_POLICY_CALLS = "android.permission.MANAGE_DEVICE_POLICY_CALLS";
+    field public static final String MANAGE_DEVICE_POLICY_CAMERA = "android.permission.MANAGE_DEVICE_POLICY_CAMERA";
+    field public static final String MANAGE_DEVICE_POLICY_CERTIFICATES = "android.permission.MANAGE_DEVICE_POLICY_CERTIFICATES";
+    field public static final String MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE = "android.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE";
     field public static final String MANAGE_DEVICE_POLICY_DEBUGGING_FEATURES = "android.permission.MANAGE_DEVICE_POLICY_DEBUGGING_FEATURES";
+    field public static final String MANAGE_DEVICE_POLICY_DEFAULT_SMS = "android.permission.MANAGE_DEVICE_POLICY_DEFAULT_SMS";
+    field public static final String MANAGE_DEVICE_POLICY_DISPLAY = "android.permission.MANAGE_DEVICE_POLICY_DISPLAY";
+    field public static final String MANAGE_DEVICE_POLICY_FACTORY_RESET = "android.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET";
+    field public static final String MANAGE_DEVICE_POLICY_FUN = "android.permission.MANAGE_DEVICE_POLICY_FUN";
+    field public static final String MANAGE_DEVICE_POLICY_INPUT_METHODS = "android.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS";
     field public static final String MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES = "android.permission.MANAGE_DEVICE_POLICY_INSTALL_UNKNOWN_SOURCES";
+    field public static final String MANAGE_DEVICE_POLICY_KEEP_UNINSTALLED_PACKAGES = "android.permission.MANAGE_DEVICE_POLICY_KEEP_UNINSTALLED_PACKAGES";
+    field public static final String MANAGE_DEVICE_POLICY_KEYGUARD = "android.permission.MANAGE_DEVICE_POLICY_KEYGUARD";
+    field public static final String MANAGE_DEVICE_POLICY_LOCALE = "android.permission.MANAGE_DEVICE_POLICY_LOCALE";
+    field public static final String MANAGE_DEVICE_POLICY_LOCATION = "android.permission.MANAGE_DEVICE_POLICY_LOCATION";
+    field public static final String MANAGE_DEVICE_POLICY_LOCK = "android.permission.MANAGE_DEVICE_POLICY_LOCK";
+    field public static final String MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS = "android.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS";
     field public static final String MANAGE_DEVICE_POLICY_LOCK_TASK = "android.permission.MANAGE_DEVICE_POLICY_LOCK_TASK";
+    field public static final String MANAGE_DEVICE_POLICY_METERED_DATA = "android.permission.MANAGE_DEVICE_POLICY_METERED_DATA";
+    field public static final String MANAGE_DEVICE_POLICY_MICROPHONE = "android.permission.MANAGE_DEVICE_POLICY_MICROPHONE";
+    field public static final String MANAGE_DEVICE_POLICY_MOBILE_NETWORK = "android.permission.MANAGE_DEVICE_POLICY_MOBILE_NETWORK";
     field public static final String MANAGE_DEVICE_POLICY_MODIFY_USERS = "android.permission.MANAGE_DEVICE_POLICY_MODIFY_USERS";
+    field public static final String MANAGE_DEVICE_POLICY_MTE = "android.permission.MANAGE_DEVICE_POLICY_MTE";
+    field public static final String MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION = "android.permission.MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION";
+    field public static final String MANAGE_DEVICE_POLICY_NETWORK_LOGGING = "android.permission.MANAGE_DEVICE_POLICY_NETWORK_LOGGING";
     field public static final String MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY = "android.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY";
+    field public static final String MANAGE_DEVICE_POLICY_OVERRIDE_APN = "android.permission.MANAGE_DEVICE_POLICY_OVERRIDE_APN";
+    field public static final String MANAGE_DEVICE_POLICY_PACKAGE_STATE = "android.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE";
+    field public static final String MANAGE_DEVICE_POLICY_PHYSICAL_MEDIA = "android.permission.MANAGE_DEVICE_POLICY_PHYSICAL_MEDIA";
+    field public static final String MANAGE_DEVICE_POLICY_PRINTING = "android.permission.MANAGE_DEVICE_POLICY_PRINTING";
+    field public static final String MANAGE_DEVICE_POLICY_PRIVATE_DNS = "android.permission.MANAGE_DEVICE_POLICY_PRIVATE_DNS";
+    field public static final String MANAGE_DEVICE_POLICY_PROFILES = "android.permission.MANAGE_DEVICE_POLICY_PROFILES";
+    field public static final String MANAGE_DEVICE_POLICY_PROFILE_INTERACTION = "android.permission.MANAGE_DEVICE_POLICY_PROFILE_INTERACTION";
+    field public static final String MANAGE_DEVICE_POLICY_PROXY = "android.permission.MANAGE_DEVICE_POLICY_PROXY";
+    field public static final String MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES = "android.permission.MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES";
+    field public static final String MANAGE_DEVICE_POLICY_RESET_PASSWORD = "android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD";
+    field public static final String MANAGE_DEVICE_POLICY_RESTRICT_PRIVATE_DNS = "android.permission.MANAGE_DEVICE_POLICY_RESTRICT_PRIVATE_DNS";
     field public static final String MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS = "android.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS";
+    field public static final String MANAGE_DEVICE_POLICY_RUN_IN_BACKGROUND = "android.permission.MANAGE_DEVICE_POLICY_RUN_IN_BACKGROUND";
     field public static final String MANAGE_DEVICE_POLICY_SAFE_BOOT = "android.permission.MANAGE_DEVICE_POLICY_SAFE_BOOT";
+    field public static final String MANAGE_DEVICE_POLICY_SCREEN_CAPTURE = "android.permission.MANAGE_DEVICE_POLICY_SCREEN_CAPTURE";
+    field public static final String MANAGE_DEVICE_POLICY_SCREEN_CONTENT = "android.permission.MANAGE_DEVICE_POLICY_SCREEN_CONTENT";
+    field public static final String MANAGE_DEVICE_POLICY_SECURITY_LOGGING = "android.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING";
+    field public static final String MANAGE_DEVICE_POLICY_SETTINGS = "android.permission.MANAGE_DEVICE_POLICY_SETTINGS";
+    field public static final String MANAGE_DEVICE_POLICY_SMS = "android.permission.MANAGE_DEVICE_POLICY_SMS";
+    field public static final String MANAGE_DEVICE_POLICY_STATUS_BAR = "android.permission.MANAGE_DEVICE_POLICY_STATUS_BAR";
     field public static final String MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE = "android.permission.MANAGE_DEVICE_POLICY_SUPPORT_MESSAGE";
+    field public static final String MANAGE_DEVICE_POLICY_SUSPEND_PERSONAL_APPS = "android.permission.MANAGE_DEVICE_POLICY_SUSPEND_PERSONAL_APPS";
+    field public static final String MANAGE_DEVICE_POLICY_SYSTEM_APPS = "android.permission.MANAGE_DEVICE_POLICY_SYSTEM_APPS";
+    field public static final String MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS = "android.permission.MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS";
+    field public static final String MANAGE_DEVICE_POLICY_SYSTEM_UPDATES = "android.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES";
     field public static final String MANAGE_DEVICE_POLICY_TIME = "android.permission.MANAGE_DEVICE_POLICY_TIME";
+    field public static final String MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING = "android.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING";
+    field public static final String MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER = "android.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER";
+    field public static final String MANAGE_DEVICE_POLICY_USERS = "android.permission.MANAGE_DEVICE_POLICY_USERS";
+    field public static final String MANAGE_DEVICE_POLICY_VPN = "android.permission.MANAGE_DEVICE_POLICY_VPN";
+    field public static final String MANAGE_DEVICE_POLICY_WALLPAPER = "android.permission.MANAGE_DEVICE_POLICY_WALLPAPER";
+    field public static final String MANAGE_DEVICE_POLICY_WIFI = "android.permission.MANAGE_DEVICE_POLICY_WIFI";
+    field public static final String MANAGE_DEVICE_POLICY_WINDOWS = "android.permission.MANAGE_DEVICE_POLICY_WINDOWS";
+    field public static final String MANAGE_DEVICE_POLICY_WIPE_DATA = "android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA";
     field public static final String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
     field public static final String MANAGE_EXTERNAL_STORAGE = "android.permission.MANAGE_EXTERNAL_STORAGE";
     field public static final String MANAGE_MEDIA = "android.permission.MANAGE_MEDIA";
@@ -208,7 +268,7 @@
     field public static final String REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE = "android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE";
     field public static final String REQUEST_PASSWORD_COMPLEXITY = "android.permission.REQUEST_PASSWORD_COMPLEXITY";
     field @Deprecated public static final String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
-    field public static final String RUN_LONG_JOBS = "android.permission.RUN_LONG_JOBS";
+    field public static final String RUN_USER_INITIATED_JOBS = "android.permission.RUN_USER_INITIATED_JOBS";
     field public static final String SCHEDULE_EXACT_ALARM = "android.permission.SCHEDULE_EXACT_ALARM";
     field public static final String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
     field public static final String SEND_SMS = "android.permission.SEND_SMS";
@@ -1988,17 +2048,17 @@
     field public static final int system_primary_container_light;
     field public static final int system_primary_dark;
     field public static final int system_primary_fixed_dark;
+    field public static final int system_primary_fixed_darker_dark;
     field public static final int system_primary_fixed_darker_light;
     field public static final int system_primary_fixed_light;
-    field public static final int system_primary_fixeder_dark;
     field public static final int system_primary_light;
     field public static final int system_secondary_container_dark;
     field public static final int system_secondary_container_light;
     field public static final int system_secondary_dark;
     field public static final int system_secondary_fixed_dark;
+    field public static final int system_secondary_fixed_darker_dark;
     field public static final int system_secondary_fixed_darker_light;
     field public static final int system_secondary_fixed_light;
-    field public static final int system_secondary_fixeder_dark;
     field public static final int system_secondary_light;
     field public static final int system_surface_bright_dark;
     field public static final int system_surface_bright_light;
@@ -2022,9 +2082,9 @@
     field public static final int system_tertiary_container_light;
     field public static final int system_tertiary_dark;
     field public static final int system_tertiary_fixed_dark;
+    field public static final int system_tertiary_fixed_darker_dark;
     field public static final int system_tertiary_fixed_darker_light;
     field public static final int system_tertiary_fixed_light;
-    field public static final int system_tertiary_fixeder_dark;
     field public static final int system_tertiary_light;
     field public static final int system_text_hint_inverse_dark;
     field public static final int system_text_hint_inverse_light;
@@ -4756,6 +4816,7 @@
     method public int getLaunchDisplayId();
     method public boolean getLockTaskMode();
     method public int getPendingIntentBackgroundActivityStartMode();
+    method public int getPendingIntentCreatorBackgroundActivityStartMode();
     method public int getSplashScreenStyle();
     method @Deprecated public boolean isPendingIntentBackgroundActivityLaunchAllowed();
     method public boolean isShareIdentityEnabled();
@@ -4776,6 +4837,7 @@
     method public android.app.ActivityOptions setLockTaskEnabled(boolean);
     method @Deprecated public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
     method @NonNull public android.app.ActivityOptions setPendingIntentBackgroundActivityStartMode(int);
+    method @NonNull public android.app.ActivityOptions setPendingIntentCreatorBackgroundActivityStartMode(int);
     method @NonNull public android.app.ActivityOptions setShareIdentityEnabled(boolean);
     method @NonNull public android.app.ActivityOptions setSplashScreenStyle(int);
     method public android.os.Bundle toBundle();
@@ -5150,6 +5212,8 @@
     field public static final int REASON_INITIALIZATION_FAILURE = 7; // 0x7
     field public static final int REASON_LOW_MEMORY = 3; // 0x3
     field public static final int REASON_OTHER = 13; // 0xd
+    field public static final int REASON_PACKAGE_STATE_CHANGE = 15; // 0xf
+    field public static final int REASON_PACKAGE_UPDATED = 16; // 0x10
     field public static final int REASON_PERMISSION_CHANGE = 8; // 0x8
     field public static final int REASON_SIGNALED = 2; // 0x2
     field public static final int REASON_UNKNOWN = 0; // 0x0
@@ -6712,6 +6776,7 @@
     method public boolean areNotificationsEnabled();
     method public boolean areNotificationsPaused();
     method public boolean canNotifyAsPackage(@NonNull String);
+    method public boolean canSendFullScreenIntent();
     method public void cancel(int);
     method public void cancel(@Nullable String, int);
     method public void cancelAll();
@@ -7197,6 +7262,7 @@
   }
 
   public class StatusBarManager {
+    method @RequiresPermission(android.Manifest.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE) public boolean canLaunchCaptureContentActivityForNote(@NonNull android.app.Activity);
     method public void requestAddTileService(@NonNull android.content.ComponentName, @NonNull CharSequence, @NonNull android.graphics.drawable.Icon, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     field public static final int TILE_ADD_REQUEST_ERROR_APP_NOT_IN_FOREGROUND = 1004; // 0x3ec
     field public static final int TILE_ADD_REQUEST_ERROR_BAD_COMPONENT = 1002; // 0x3ea
@@ -7275,6 +7341,7 @@
     method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
     method public android.os.ParcelFileDescriptor executeShellCommand(String);
     method @NonNull public android.os.ParcelFileDescriptor[] executeShellCommandRw(@NonNull String);
+    method @NonNull public android.os.ParcelFileDescriptor[] executeShellCommandRwe(@NonNull String);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -7700,7 +7767,7 @@
     method @RequiresPermission(value=android.Manifest.permission.READ_NEARBY_STREAMING_POLICY, conditional=true) public int getNearbyAppStreamingPolicy();
     method @RequiresPermission(value=android.Manifest.permission.READ_NEARBY_STREAMING_POLICY, conditional=true) public int getNearbyNotificationStreamingPolicy();
     method @Deprecated @ColorInt public int getOrganizationColor(@NonNull android.content.ComponentName);
-    method @Nullable public CharSequence getOrganizationName(@NonNull android.content.ComponentName);
+    method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY) public CharSequence getOrganizationName(@Nullable android.content.ComponentName);
     method public java.util.List<android.telephony.data.ApnSetting> getOverrideApns(@NonNull android.content.ComponentName);
     method @NonNull public android.app.admin.DevicePolicyManager getParentProfileInstance(@NonNull android.content.ComponentName);
     method @RequiresPermission(android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY) public int getPasswordComplexity();
@@ -7855,7 +7922,7 @@
     method public void setNetworkLoggingEnabled(@Nullable android.content.ComponentName, boolean);
     method @Deprecated public void setOrganizationColor(@NonNull android.content.ComponentName, int);
     method public void setOrganizationId(@NonNull String);
-    method public void setOrganizationName(@NonNull android.content.ComponentName, @Nullable CharSequence);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY) public void setOrganizationName(@Nullable android.content.ComponentName, @Nullable CharSequence);
     method public void setOverrideApnsEnabled(@NonNull android.content.ComponentName, boolean);
     method @NonNull public String[] setPackagesSuspended(@NonNull android.content.ComponentName, @NonNull String[], boolean);
     method public void setPasswordExpirationTimeout(@NonNull android.content.ComponentName, long);
@@ -8182,6 +8249,7 @@
     method public int getResultCode();
     field public static final int RESULT_FAILURE_CONFLICTING_ADMIN_POLICY = 1; // 0x1
     field public static final int RESULT_FAILURE_UNKNOWN = -1; // 0xffffffff
+    field public static final int RESULT_POLICY_CLEARED = 2; // 0x2
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
@@ -8686,7 +8754,7 @@
     method public android.app.job.JobInfo.Builder setTransientExtras(@NonNull android.os.Bundle);
     method public android.app.job.JobInfo.Builder setTriggerContentMaxDelay(long);
     method public android.app.job.JobInfo.Builder setTriggerContentUpdateDelay(long);
-    method @NonNull @RequiresPermission(android.Manifest.permission.RUN_LONG_JOBS) public android.app.job.JobInfo.Builder setUserInitiated(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.RUN_USER_INITIATED_JOBS) public android.app.job.JobInfo.Builder setUserInitiated(boolean);
   }
 
   public static final class JobInfo.TriggerContentUri implements android.os.Parcelable {
@@ -8738,7 +8806,7 @@
 
   public abstract class JobScheduler {
     ctor public JobScheduler();
-    method public boolean canRunLongJobs();
+    method public boolean canRunUserInitiatedJobs();
     method public abstract void cancel(int);
     method public abstract void cancelAll();
     method public void cancelInAllNamespaces();
@@ -9386,7 +9454,6 @@
   }
 
   public final class CompanionDeviceManager {
-    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void addOnAssociationsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
     method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull android.companion.CompanionDeviceManager.Callback, @Nullable android.os.Handler);
     method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.Callback);
     method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void attachSystemDataTransport(int, @NonNull java.io.InputStream, @NonNull java.io.OutputStream) throws android.companion.DeviceNotAssociatedException;
@@ -9397,11 +9464,9 @@
     method @Deprecated public void disassociate(@NonNull String);
     method public void disassociate(int);
     method public void enableSystemDataSync(int, int);
-    method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations();
     method @Deprecated @NonNull public java.util.List<java.lang.String> getAssociations();
     method @NonNull public java.util.List<android.companion.AssociationInfo> getMyAssociations();
     method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
-    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void removeOnAssociationsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
     method public void requestNotificationAccess(android.content.ComponentName);
     method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
     method public void startSystemDataTransfer(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.companion.CompanionException>) throws android.companion.DeviceNotAssociatedException;
@@ -9424,10 +9489,6 @@
     method public abstract void onFailure(@Nullable CharSequence);
   }
 
-  public static interface CompanionDeviceManager.OnAssociationsChangedListener {
-    method public void onAssociationsChanged(@NonNull java.util.List<android.companion.AssociationInfo>);
-  }
-
   public abstract class CompanionDeviceService extends android.app.Service {
     ctor public CompanionDeviceService();
     method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public final void attachSystemDataTransport(int, @NonNull java.io.InputStream, @NonNull java.io.OutputStream) throws android.companion.DeviceNotAssociatedException;
@@ -10711,6 +10772,7 @@
     field public static final String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
     field public static final String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
     field @Deprecated public static final String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
+    field @RequiresPermission(android.Manifest.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE) public static final String ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE = "android.intent.action.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE";
     field public static final String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
     field public static final String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final String ACTION_MAIN = "android.intent.action.MAIN";
@@ -10804,6 +10866,11 @@
     field public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
     field @Deprecated public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
     field public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
+    field public static final int CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN = 4; // 0x4
+    field public static final int CAPTURE_CONTENT_FOR_NOTE_FAILED = 1; // 0x1
+    field public static final int CAPTURE_CONTENT_FOR_NOTE_SUCCESS = 0; // 0x0
+    field public static final int CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED = 2; // 0x2
+    field public static final int CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED = 3; // 0x3
     field public static final String CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET = "android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET";
     field public static final String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE";
     field public static final String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER";
@@ -10859,13 +10926,14 @@
     field public static final String EXTRA_AUTO_LAUNCH_SINGLE_CHOICE = "android.intent.extra.AUTO_LAUNCH_SINGLE_CHOICE";
     field public static final String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
+    field public static final String EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE = "android.intent.extra.CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE";
     field public static final String EXTRA_CC = "android.intent.extra.CC";
     field @Deprecated public static final String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name";
     field public static final String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
     field public static final String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
     field public static final String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
     field public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS = "android.intent.extra.CHOOSER_CUSTOM_ACTIONS";
-    field public static final String EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION = "android.intent.extra.CHOOSER_PAYLOAD_RESELECTION_ACTION";
+    field public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION = "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION";
     field public static final String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER";
     field public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
     field public static final String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
@@ -12262,6 +12330,7 @@
     method public void setOriginatingUid(int);
     method public void setOriginatingUri(@Nullable android.net.Uri);
     method public void setPackageSource(int);
+    method @NonNull @RequiresPermission(value="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS", conditional=true) public android.content.pm.PackageInstaller.SessionParams setPermissionState(@NonNull String, int);
     method public void setReferrerUri(@Nullable android.net.Uri);
     method @RequiresPermission(android.Manifest.permission.ENFORCE_UPDATE_OWNERSHIP) public void setRequestUpdateOwnership(boolean);
     method public void setRequireUserAction(int);
@@ -12271,6 +12340,9 @@
     field public static final android.os.Parcelable.Creator<android.content.pm.PackageInstaller.SessionParams> CREATOR;
     field public static final int MODE_FULL_INSTALL = 1; // 0x1
     field public static final int MODE_INHERIT_EXISTING = 2; // 0x2
+    field public static final int PERMISSION_STATE_DEFAULT = 0; // 0x0
+    field public static final int PERMISSION_STATE_DENIED = 2; // 0x2
+    field public static final int PERMISSION_STATE_GRANTED = 1; // 0x1
     field @NonNull public static final java.util.Set<java.lang.String> RESTRICTED_PERMISSIONS_ALL;
     field public static final int USER_ACTION_NOT_REQUIRED = 2; // 0x2
     field public static final int USER_ACTION_REQUIRED = 1; // 0x1
@@ -12618,7 +12690,8 @@
     field public static final int FLAG_PERMISSION_WHITELIST_SYSTEM = 1; // 0x1
     field public static final int FLAG_PERMISSION_WHITELIST_UPGRADE = 4; // 0x4
     field public static final int GET_ACTIVITIES = 1; // 0x1
-    field public static final int GET_ATTRIBUTIONS = -2147483648; // 0x80000000
+    field @Deprecated public static final int GET_ATTRIBUTIONS = -2147483648; // 0x80000000
+    field public static final long GET_ATTRIBUTIONS_LONG = 2147483648L; // 0x80000000L
     field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
     field @Deprecated public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
     field @Deprecated public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
@@ -12659,6 +12732,7 @@
     field public static final int PERMISSION_DENIED = -1; // 0xffffffff
     field public static final int PERMISSION_GRANTED = 0; // 0x0
     field public static final String PROPERTY_MEDIA_CAPABILITIES = "android.media.PROPERTY_MEDIA_CAPABILITIES";
+    field public static final String PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES = "android.net.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES";
     field public static final String PROPERTY_SPECIAL_USE_FGS_SUBTYPE = "android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE";
     field public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; // 0xffffffff
     field public static final int SIGNATURE_MATCH = 0; // 0x0
@@ -13448,13 +13522,15 @@
     ctor public CreateCredentialException(@NonNull String);
     method @NonNull public String getType();
     field @NonNull public static final String TYPE_INTERRUPTED = "android.credentials.CreateCredentialException.TYPE_INTERRUPTED";
-    field @NonNull public static final String TYPE_NO_CREDENTIAL = "android.credentials.CreateCredentialException.TYPE_NO_CREDENTIAL";
+    field @NonNull public static final String TYPE_NO_CREATE_OPTIONS = "android.credentials.CreateCredentialException.TYPE_NO_CREATE_OPTIONS";
     field @NonNull public static final String TYPE_UNKNOWN = "android.credentials.CreateCredentialException.TYPE_UNKNOWN";
     field @NonNull public static final String TYPE_USER_CANCELED = "android.credentials.CreateCredentialException.TYPE_USER_CANCELED";
   }
 
   public final class CreateCredentialRequest implements android.os.Parcelable {
+    ctor public CreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean, boolean);
     ctor public CreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean);
+    method public boolean alwaysSendAppInfoToProvider();
     method public int describeContents();
     method @NonNull public android.os.Bundle getCandidateQueryData();
     method @NonNull public android.os.Bundle getCredentialData();
@@ -13495,11 +13571,26 @@
   public final class CredentialManager {
     method public void clearCredentialState(@NonNull android.credentials.ClearCredentialStateRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException>);
     method public void createCredential(@NonNull android.credentials.CreateCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CreateCredentialException>);
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN) public void createCredentialWithOrigin(@NonNull android.credentials.CreateCredentialRequest, @Nullable String, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.CreateCredentialResponse,android.credentials.CreateCredentialException>);
     method public void getCredential(@NonNull android.credentials.GetCredentialRequest, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>);
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN) public void getCredentialWithOrigin(@NonNull android.credentials.GetCredentialRequest, @Nullable String, @NonNull android.app.Activity, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.credentials.GetCredentialResponse,android.credentials.GetCredentialException>);
+    method public boolean isEnabledCredentialProviderService(@NonNull android.content.ComponentName);
     method public void registerCredentialDescription(@NonNull android.credentials.RegisterCredentialDescriptionRequest);
     method public void unregisterCredentialDescription(@NonNull android.credentials.UnregisterCredentialDescriptionRequest);
   }
 
+  public final class CredentialOption implements android.os.Parcelable {
+    ctor public CredentialOption(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean);
+    method public int describeContents();
+    method @NonNull public android.os.Bundle getCandidateQueryData();
+    method @NonNull public android.os.Bundle getCredentialRetrievalData();
+    method @NonNull public String getType();
+    method public boolean isSystemProviderRequired();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.credentials.CredentialOption> CREATOR;
+    field public static final String FLATTENED_REQUEST = "android.credentials.GetCredentialOption.FLATTENED_REQUEST_STRING";
+  }
+
   public class GetCredentialException extends java.lang.Exception {
     ctor public GetCredentialException(@NonNull String, @Nullable String);
     ctor public GetCredentialException(@NonNull String, @Nullable String, @Nullable Throwable);
@@ -13512,31 +13603,21 @@
     field @NonNull public static final String TYPE_USER_CANCELED = "android.credentials.GetCredentialException.TYPE_USER_CANCELED";
   }
 
-  public final class GetCredentialOption implements android.os.Parcelable {
-    ctor public GetCredentialOption(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean);
-    method public int describeContents();
-    method @NonNull public android.os.Bundle getCandidateQueryData();
-    method @NonNull public android.os.Bundle getCredentialRetrievalData();
-    method @NonNull public String getType();
-    method public boolean isSystemProviderRequired();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.credentials.GetCredentialOption> CREATOR;
-    field public static final String FLATTENED_REQUEST = "android.credentials.GetCredentialOption.FLATTENED_REQUEST_STRING";
-  }
-
   public final class GetCredentialRequest implements android.os.Parcelable {
+    method public boolean alwaysSendAppInfoToProvider();
     method public int describeContents();
+    method @NonNull public java.util.List<android.credentials.CredentialOption> getCredentialOptions();
     method @NonNull public android.os.Bundle getData();
-    method @NonNull public java.util.List<android.credentials.GetCredentialOption> getGetCredentialOptions();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.credentials.GetCredentialRequest> CREATOR;
   }
 
   public static final class GetCredentialRequest.Builder {
     ctor public GetCredentialRequest.Builder(@NonNull android.os.Bundle);
-    method @NonNull public android.credentials.GetCredentialRequest.Builder addGetCredentialOption(@NonNull android.credentials.GetCredentialOption);
+    method @NonNull public android.credentials.GetCredentialRequest.Builder addCredentialOption(@NonNull android.credentials.CredentialOption);
     method @NonNull public android.credentials.GetCredentialRequest build();
-    method @NonNull public android.credentials.GetCredentialRequest.Builder setGetCredentialOptions(@NonNull java.util.List<android.credentials.GetCredentialOption>);
+    method @NonNull public android.credentials.GetCredentialRequest.Builder setAlwaysSendAppInfoToProvider(boolean);
+    method @NonNull public android.credentials.GetCredentialRequest.Builder setCredentialOptions(@NonNull java.util.List<android.credentials.CredentialOption>);
   }
 
   public final class GetCredentialResponse implements android.os.Parcelable {
@@ -14886,7 +14967,9 @@
   public class BitmapShader extends android.graphics.Shader {
     ctor public BitmapShader(@NonNull android.graphics.Bitmap, @NonNull android.graphics.Shader.TileMode, @NonNull android.graphics.Shader.TileMode);
     method public int getFilterMode();
+    method public int getMaxAnisotropy();
     method public void setFilterMode(int);
+    method public void setMaxAnisotropy(@IntRange(from=1) int);
     field public static final int FILTER_MODE_DEFAULT = 0; // 0x0
     field public static final int FILTER_MODE_LINEAR = 2; // 0x2
     field public static final int FILTER_MODE_NEAREST = 1; // 0x1
@@ -15000,7 +15083,7 @@
     method public void drawLine(float, float, float, float, @NonNull android.graphics.Paint);
     method public void drawLines(@NonNull @Size(multiple=4) float[], int, int, @NonNull android.graphics.Paint);
     method public void drawLines(@NonNull @Size(multiple=4) float[], @NonNull android.graphics.Paint);
-    method public void drawMesh(@NonNull android.graphics.Mesh, android.graphics.BlendMode, @NonNull android.graphics.Paint);
+    method public void drawMesh(@NonNull android.graphics.Mesh, @Nullable android.graphics.BlendMode, @NonNull android.graphics.Paint);
     method public void drawOval(@NonNull android.graphics.RectF, @NonNull android.graphics.Paint);
     method public void drawOval(float, float, float, float, @NonNull android.graphics.Paint);
     method public void drawPaint(@NonNull android.graphics.Paint);
@@ -15602,10 +15685,10 @@
   }
 
   public class Mesh {
-    method @NonNull public static android.graphics.Mesh make(@NonNull android.graphics.MeshSpecification, int, @NonNull java.nio.Buffer, int, @NonNull android.graphics.Rect);
-    method @NonNull public static android.graphics.Mesh makeIndexed(@NonNull android.graphics.MeshSpecification, int, @NonNull java.nio.Buffer, int, @NonNull java.nio.ShortBuffer, @NonNull android.graphics.Rect);
-    method public void setColorUniform(@NonNull String, int);
-    method public void setColorUniform(@NonNull String, long);
+    ctor public Mesh(@NonNull android.graphics.MeshSpecification, int, @NonNull java.nio.Buffer, int, @NonNull android.graphics.RectF);
+    ctor public Mesh(@NonNull android.graphics.MeshSpecification, int, @NonNull java.nio.Buffer, int, @NonNull java.nio.ShortBuffer, @NonNull android.graphics.RectF);
+    method public void setColorUniform(@NonNull String, @ColorInt int);
+    method public void setColorUniform(@NonNull String, @ColorLong long);
     method public void setColorUniform(@NonNull String, @NonNull android.graphics.Color);
     method public void setFloatUniform(@NonNull String, float);
     method public void setFloatUniform(@NonNull String, float, float);
@@ -15622,26 +15705,31 @@
   }
 
   public class MeshSpecification {
-    method @NonNull public static android.graphics.MeshSpecification make(@NonNull java.util.List<android.graphics.MeshSpecification.Attribute>, int, @NonNull java.util.List<android.graphics.MeshSpecification.Varying>, @NonNull String, @NonNull String);
-    method @NonNull public static android.graphics.MeshSpecification make(@NonNull java.util.List<android.graphics.MeshSpecification.Attribute>, int, @NonNull java.util.List<android.graphics.MeshSpecification.Varying>, @NonNull String, @NonNull String, @NonNull android.graphics.ColorSpace);
-    method @NonNull public static android.graphics.MeshSpecification make(@NonNull java.util.List<android.graphics.MeshSpecification.Attribute>, int, @NonNull java.util.List<android.graphics.MeshSpecification.Varying>, @NonNull String, @NonNull String, @NonNull android.graphics.ColorSpace, int);
-    field public static final int FLOAT = 0; // 0x0
-    field public static final int FLOAT2 = 1; // 0x1
-    field public static final int FLOAT3 = 2; // 0x2
-    field public static final int FLOAT4 = 3; // 0x3
-    field public static final int OPAQUE = 1; // 0x1
-    field public static final int PREMUL = 2; // 0x2
-    field public static final int UBYTE4 = 4; // 0x4
-    field public static final int UNKNOWN = 0; // 0x0
-    field public static final int UNPREMULT = 3; // 0x3
+    method @NonNull public static android.graphics.MeshSpecification make(@NonNull @Size(max=8) android.graphics.MeshSpecification.Attribute[], @IntRange(from=1, to=1024) int, @NonNull @Size(max=6) android.graphics.MeshSpecification.Varying[], @NonNull String, @NonNull String);
+    method @NonNull public static android.graphics.MeshSpecification make(@NonNull @Size(max=8) android.graphics.MeshSpecification.Attribute[], @IntRange(from=1, to=1024) int, @NonNull @Size(max=6) android.graphics.MeshSpecification.Varying[], @NonNull String, @NonNull String, @NonNull android.graphics.ColorSpace);
+    method @NonNull public static android.graphics.MeshSpecification make(@NonNull @Size(max=8) android.graphics.MeshSpecification.Attribute[], @IntRange(from=1, to=1024) int, @NonNull @Size(max=6) android.graphics.MeshSpecification.Varying[], @NonNull String, @NonNull String, @NonNull android.graphics.ColorSpace, int);
+    field public static final int ALPHA_TYPE_OPAQUE = 1; // 0x1
+    field public static final int ALPHA_TYPE_PREMUL = 2; // 0x2
+    field public static final int ALPHA_TYPE_PREMULT = 3; // 0x3
+    field public static final int ALPHA_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int TYPE_FLOAT = 0; // 0x0
+    field public static final int TYPE_FLOAT2 = 1; // 0x1
+    field public static final int TYPE_FLOAT3 = 2; // 0x2
+    field public static final int TYPE_FLOAT4 = 3; // 0x3
+    field public static final int TYPE_UBYTE4 = 4; // 0x4
   }
 
   public static class MeshSpecification.Attribute {
     ctor public MeshSpecification.Attribute(int, int, @NonNull String);
+    method @NonNull public String getName();
+    method public int getOffset();
+    method public int getType();
   }
 
   public static class MeshSpecification.Varying {
     ctor public MeshSpecification.Varying(int, @NonNull String);
+    method @NonNull public String getName();
+    method public int getType();
   }
 
   @Deprecated public class Movie {
@@ -24021,6 +24109,7 @@
     method @Nullable public android.net.Uri getIconUri();
     method @NonNull public String getId();
     method @NonNull public CharSequence getName();
+    method public int getType();
     method public int getVolume();
     method public int getVolumeHandling();
     method public int getVolumeMax();
@@ -24037,6 +24126,22 @@
     field public static final String FEATURE_REMOTE_VIDEO_PLAYBACK = "android.media.route.feature.REMOTE_VIDEO_PLAYBACK";
     field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
     field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
+    field public static final int TYPE_BLE_HEADSET = 26; // 0x1a
+    field public static final int TYPE_BLUETOOTH_A2DP = 8; // 0x8
+    field public static final int TYPE_BUILTIN_SPEAKER = 2; // 0x2
+    field public static final int TYPE_DOCK = 13; // 0xd
+    field public static final int TYPE_GROUP = 2000; // 0x7d0
+    field public static final int TYPE_HDMI = 9; // 0x9
+    field public static final int TYPE_HEARING_AID = 23; // 0x17
+    field public static final int TYPE_REMOTE_AUDIO_VIDEO_RECEIVER = 1003; // 0x3eb
+    field public static final int TYPE_REMOTE_SPEAKER = 1002; // 0x3ea
+    field public static final int TYPE_REMOTE_TV = 1001; // 0x3e9
+    field public static final int TYPE_UNKNOWN = 0; // 0x0
+    field public static final int TYPE_USB_ACCESSORY = 12; // 0xc
+    field public static final int TYPE_USB_DEVICE = 11; // 0xb
+    field public static final int TYPE_USB_HEADSET = 22; // 0x16
+    field public static final int TYPE_WIRED_HEADPHONES = 4; // 0x4
+    field public static final int TYPE_WIRED_HEADSET = 3; // 0x3
   }
 
   public static final class MediaRoute2Info.Builder {
@@ -24052,6 +24157,7 @@
     method @NonNull public android.media.MediaRoute2Info.Builder setDescription(@Nullable CharSequence);
     method @NonNull public android.media.MediaRoute2Info.Builder setExtras(@Nullable android.os.Bundle);
     method @NonNull public android.media.MediaRoute2Info.Builder setIconUri(@Nullable android.net.Uri);
+    method @NonNull public android.media.MediaRoute2Info.Builder setType(int);
     method @NonNull public android.media.MediaRoute2Info.Builder setVisibilityPublic();
     method @NonNull public android.media.MediaRoute2Info.Builder setVisibilityRestricted(@NonNull java.util.Set<java.lang.String>);
     method @NonNull public android.media.MediaRoute2Info.Builder setVolume(int);
@@ -24624,15 +24730,20 @@
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteListingPreference.Item> CREATOR;
     field public static final int FLAG_ONGOING_SESSION = 1; // 0x1
-    field public static final int FLAG_SUGGESTED_ROUTE = 2; // 0x2
+    field public static final int FLAG_ONGOING_SESSION_MANAGED = 2; // 0x2
+    field public static final int FLAG_SUGGESTED = 4; // 0x4
     field public static final int SELECTION_BEHAVIOR_GO_TO_APP = 2; // 0x2
     field public static final int SELECTION_BEHAVIOR_NONE = 0; // 0x0
     field public static final int SELECTION_BEHAVIOR_TRANSFER = 1; // 0x1
-    field public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 3; // 0x3
+    field public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 4; // 0x4
     field public static final int SUBTEXT_CUSTOM = 10000; // 0x2710
-    field public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 2; // 0x2
+    field public static final int SUBTEXT_DEVICE_LOW_POWER = 5; // 0x5
+    field public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 3; // 0x3
+    field public static final int SUBTEXT_ERROR_UNKNOWN = 1; // 0x1
     field public static final int SUBTEXT_NONE = 0; // 0x0
-    field public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 1; // 0x1
+    field public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 2; // 0x2
+    field public static final int SUBTEXT_TRACK_UNSUPPORTED = 7; // 0x7
+    field public static final int SUBTEXT_UNAUTHORIZED = 6; // 0x6
   }
 
   public static final class RouteListingPreference.Item.Builder {
@@ -26318,8 +26429,23 @@
 
 package android.media.tv {
 
+  public final class AdBuffer implements android.os.Parcelable {
+    ctor public AdBuffer(int, @NonNull String, @NonNull android.os.SharedMemory, int, int, long, int);
+    method public int describeContents();
+    method public int getFlags();
+    method public int getId();
+    method public int getLength();
+    method @NonNull public String getMimeType();
+    method public int getOffset();
+    method public long getPresentationTimeUs();
+    method @NonNull public android.os.SharedMemory getSharedMemory();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.AdBuffer> CREATOR;
+  }
+
   public final class AdRequest implements android.os.Parcelable {
     ctor public AdRequest(int, int, @Nullable android.os.ParcelFileDescriptor, long, long, long, @Nullable String, @NonNull android.os.Bundle);
+    ctor public AdRequest(int, int, @Nullable android.net.Uri, long, long, long, @NonNull android.os.Bundle);
     method public int describeContents();
     method public long getEchoIntervalMillis();
     method @Nullable public android.os.ParcelFileDescriptor getFileDescriptor();
@@ -26329,6 +26455,7 @@
     method public int getRequestType();
     method public long getStartTimeMillis();
     method public long getStopTimeMillis();
+    method @Nullable public android.net.Uri getUri();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.AdRequest> CREATOR;
     field public static final int REQUEST_TYPE_START = 1; // 0x1
@@ -26343,6 +26470,7 @@
     method public int getResponseType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.AdResponse> CREATOR;
+    field public static final int RESPONSE_TYPE_BUFFERING = 5; // 0x5
     field public static final int RESPONSE_TYPE_ERROR = 4; // 0x4
     field public static final int RESPONSE_TYPE_FINISHED = 2; // 0x2
     field public static final int RESPONSE_TYPE_PLAYING = 1; // 0x1
@@ -26474,13 +26602,25 @@
     method public int getTableName();
     method public int getVersion();
     field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.TableRequest> CREATOR;
+    field public static final int TABLE_NAME_BAT = 4; // 0x4
+    field public static final int TABLE_NAME_CAT = 2; // 0x2
+    field public static final int TABLE_NAME_EIT = 6; // 0x6
+    field public static final int TABLE_NAME_NIT = 3; // 0x3
     field public static final int TABLE_NAME_PAT = 0; // 0x0
     field public static final int TABLE_NAME_PMT = 1; // 0x1
+    field public static final int TABLE_NAME_SDT = 5; // 0x5
+    field public static final int TABLE_NAME_SIT = 9; // 0x9
+    field public static final int TABLE_NAME_TDT = 7; // 0x7
+    field public static final int TABLE_NAME_TOT = 8; // 0x8
   }
 
   public final class TableResponse extends android.media.tv.BroadcastInfoResponse implements android.os.Parcelable {
     ctor public TableResponse(int, int, int, @Nullable android.net.Uri, int, int);
+    ctor public TableResponse(int, int, int, @NonNull byte[], int, int);
+    ctor public TableResponse(int, int, int, @NonNull android.os.SharedMemory, int, int);
     method public int getSize();
+    method @Nullable public byte[] getTableByteArray();
+    method @Nullable public android.os.SharedMemory getTableSharedMemory();
     method @Nullable public android.net.Uri getTableUri();
     method public int getVersion();
     field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.TableResponse> CREATOR;
@@ -26488,7 +26628,9 @@
 
   public final class TimelineRequest extends android.media.tv.BroadcastInfoRequest implements android.os.Parcelable {
     ctor public TimelineRequest(int, int, int);
+    ctor public TimelineRequest(int, int, int, @NonNull String);
     method public int getIntervalMillis();
+    method @Nullable public String getSelector();
     field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.TimelineRequest> CREATOR;
   }
 
@@ -27023,6 +27165,8 @@
     field public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; // 0x2
     field public static final int TIME_SHIFT_STATUS_UNKNOWN = 0; // 0x0
     field public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1; // 0x1
+    field public static final String TV_MESSAGE_TYPE_CLOSED_CAPTION = "CC";
+    field public static final String TV_MESSAGE_TYPE_WATERMARK = "Watermark";
     field public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 4; // 0x4
     field public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; // 0x3
     field public static final int VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT = 16; // 0x10
@@ -27096,6 +27240,7 @@
   public abstract static class TvInputService.Session implements android.view.KeyEvent.Callback {
     ctor public TvInputService.Session(android.content.Context);
     method public void layoutSurface(int, int, int, int);
+    method public void notifyAdBufferConsumed(@NonNull android.media.tv.AdBuffer);
     method public void notifyAdResponse(@NonNull android.media.tv.AdResponse);
     method public void notifyAitInfoUpdated(@NonNull android.media.tv.AitInfo);
     method public void notifyAudioPresentationChanged(@NonNull java.util.List<android.media.AudioPresentation>);
@@ -27109,8 +27254,10 @@
     method public void notifyTrackSelected(int, String);
     method public void notifyTracksChanged(java.util.List<android.media.tv.TvTrackInfo>);
     method public void notifyTuned(@NonNull android.net.Uri);
+    method public void notifyTvMessage(@NonNull String, @NonNull android.os.Bundle);
     method public void notifyVideoAvailable();
     method public void notifyVideoUnavailable(int);
+    method public void onAdBuffer(@NonNull android.media.tv.AdBuffer);
     method public void onAppPrivateCommand(@NonNull String, android.os.Bundle);
     method public android.view.View onCreateOverlayView();
     method public boolean onGenericMotionEvent(android.view.MotionEvent);
@@ -27129,6 +27276,7 @@
     method public void onSetInteractiveAppNotificationEnabled(boolean);
     method public abstract void onSetStreamVolume(@FloatRange(from=0.0, to=1.0) float);
     method public abstract boolean onSetSurface(@Nullable android.view.Surface);
+    method public void onSetTvMessageEnabled(@NonNull String, boolean);
     method public void onSurfaceChanged(int, int, int);
     method public long onTimeShiftGetCurrentPosition();
     method public long onTimeShiftGetStartPosition();
@@ -27268,6 +27416,7 @@
     method public void setOnUnhandledInputEventListener(android.media.tv.TvView.OnUnhandledInputEventListener);
     method public void setStreamVolume(@FloatRange(from=0.0, to=1.0) float);
     method public void setTimeShiftPositionCallback(@Nullable android.media.tv.TvView.TimeShiftPositionCallback);
+    method public void setTvMessageEnabled(@NonNull String, boolean);
     method public void setZOrderMediaOverlay(boolean);
     method public void setZOrderOnTop(boolean);
     method public void timeShiftPause();
@@ -27304,6 +27453,7 @@
     method public void onTrackSelected(String, int, String);
     method public void onTracksChanged(String, java.util.List<android.media.tv.TvTrackInfo>);
     method public void onTuned(@NonNull String, @NonNull android.net.Uri);
+    method public void onTvMessage(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
     method public void onVideoAvailable(String);
     method public void onVideoSizeChanged(String, int, int);
     method public void onVideoUnavailable(String, int);
@@ -27380,9 +27530,12 @@
     field public static final String COMMAND_PARAMETER_KEY_CHANGE_CHANNEL_QUIETLY = "command_change_channel_quietly";
     field public static final String COMMAND_PARAMETER_KEY_CHANNEL_URI = "command_channel_uri";
     field public static final String COMMAND_PARAMETER_KEY_INPUT_ID = "command_input_id";
+    field public static final String COMMAND_PARAMETER_KEY_STOP_MODE = "command_stop_mode";
     field public static final String COMMAND_PARAMETER_KEY_TRACK_ID = "command_track_id";
     field public static final String COMMAND_PARAMETER_KEY_TRACK_TYPE = "command_track_type";
     field public static final String COMMAND_PARAMETER_KEY_VOLUME = "command_volume";
+    field public static final int COMMAND_PARAMETER_VALUE_STOP_MODE_BLANK = 1; // 0x1
+    field public static final int COMMAND_PARAMETER_VALUE_STOP_MODE_FREEZE = 2; // 0x2
     field public static final String PLAYBACK_COMMAND_TYPE_SELECT_TRACK = "select_track";
     field public static final String PLAYBACK_COMMAND_TYPE_SET_STREAM_VOLUME = "set_stream_volume";
     field public static final String PLAYBACK_COMMAND_TYPE_STOP = "stop";
@@ -27397,9 +27550,11 @@
     ctor public TvInteractiveAppService.Session(@NonNull android.content.Context);
     method public boolean isMediaViewEnabled();
     method @CallSuper public void layoutSurface(int, int, int, int);
+    method @CallSuper public void notifyAdBuffer(@NonNull android.media.tv.AdBuffer);
     method @CallSuper public final void notifyBiInteractiveAppCreated(@NonNull android.net.Uri, @Nullable String);
     method @CallSuper public void notifySessionStateChanged(int, int);
     method @CallSuper public final void notifyTeletextAppStateChanged(int);
+    method public void onAdBufferConsumed(@NonNull android.media.tv.AdBuffer);
     method public void onAdResponse(@NonNull android.media.tv.AdResponse);
     method public void onBroadcastInfoResponse(@NonNull android.media.tv.BroadcastInfoResponse);
     method public void onContentAllowed();
@@ -27409,6 +27564,7 @@
     method public void onCurrentChannelLcn(int);
     method public void onCurrentChannelUri(@Nullable android.net.Uri);
     method public void onCurrentTvInputId(@Nullable String);
+    method public void onCurrentVideoBounds(@NonNull android.graphics.Rect);
     method public void onDestroyBiInteractiveAppRequest(@NonNull String);
     method public void onError(@NonNull String, @NonNull android.os.Bundle);
     method public boolean onGenericMotionEvent(@NonNull android.view.MotionEvent);
@@ -27435,6 +27591,7 @@
     method public boolean onTrackballEvent(@NonNull android.view.MotionEvent);
     method public void onTracksChanged(@NonNull java.util.List<android.media.tv.TvTrackInfo>);
     method public void onTuned(@NonNull android.net.Uri);
+    method public void onTvMessage(@NonNull String, @NonNull android.os.Bundle);
     method public void onTvRecordingInfo(@Nullable android.media.tv.TvRecordingInfo);
     method public void onTvRecordingInfoList(@NonNull java.util.List<android.media.tv.TvRecordingInfo>);
     method public void onVideoAvailable();
@@ -27445,6 +27602,7 @@
     method @CallSuper public void requestCurrentChannelLcn();
     method @CallSuper public void requestCurrentChannelUri();
     method @CallSuper public void requestCurrentTvInputId();
+    method @CallSuper public void requestCurrentVideoBounds();
     method @CallSuper public void requestSigning(@NonNull String, @NonNull String, @NonNull String, @NonNull byte[]);
     method @CallSuper public void requestStartRecording(@Nullable android.net.Uri);
     method @CallSuper public void requestStopRecording(@NonNull String);
@@ -27484,6 +27642,7 @@
     method public void notifyError(@NonNull String, @NonNull android.os.Bundle);
     method public void notifyRecordingStarted(@NonNull String);
     method public void notifyRecordingStopped(@NonNull String);
+    method public void notifyTvMessage(@NonNull String, @NonNull android.os.Bundle);
     method public void onAttachedToWindow();
     method public void onDetachedFromWindow();
     method public void onLayout(boolean, int, int, int, int);
@@ -27496,6 +27655,7 @@
     method public void sendCurrentChannelLcn(int);
     method public void sendCurrentChannelUri(@Nullable android.net.Uri);
     method public void sendCurrentTvInputId(@Nullable String);
+    method public void sendCurrentVideoBounds(@NonNull android.graphics.Rect);
     method public void sendSigningResult(@NonNull String, @NonNull byte[]);
     method public void sendStreamVolume(float);
     method public void sendTrackInfoList(@Nullable java.util.List<android.media.tv.TvTrackInfo>);
@@ -27526,6 +27686,7 @@
     method public void onRequestCurrentChannelLcn(@NonNull String);
     method public void onRequestCurrentChannelUri(@NonNull String);
     method public void onRequestCurrentTvInputId(@NonNull String);
+    method public void onRequestCurrentVideoBounds(@NonNull String);
     method public void onRequestSigning(@NonNull String, @NonNull String, @NonNull String, @NonNull String, @NonNull byte[]);
     method public void onRequestStartRecording(@NonNull String, @Nullable android.net.Uri);
     method public void onRequestStopRecording(@NonNull String, @NonNull String);
@@ -32140,7 +32301,6 @@
     method public void onEarlyReportFinished();
     method public void onError(int);
     method public void onFinished();
-    method public void onFinished(@NonNull String);
     method public void onProgress(@FloatRange(from=0.0f, to=100.0f) float);
     field public static final int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = 5; // 0x5
     field public static final int BUGREPORT_ERROR_INVALID_INPUT = 1; // 0x1
@@ -33124,9 +33284,12 @@
     method public int getCurrentThermalStatus();
     method public int getLocationPowerSaveMode();
     method public float getThermalHeadroom(@IntRange(from=0, to=60) int);
+    method public boolean isAllowedInLowPowerStandby(int);
+    method public boolean isAllowedInLowPowerStandby(@NonNull String);
     method public boolean isBatteryDischargePredictionPersonalized();
     method public boolean isDeviceIdleMode();
     method public boolean isDeviceLightIdleMode();
+    method public boolean isExemptFromLowPowerStandby();
     method public boolean isIgnoringBatteryOptimizations(String);
     method public boolean isInteractive();
     method public boolean isLowPowerStandbyEnabled();
@@ -33149,6 +33312,8 @@
     field public static final int LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF = 1; // 0x1
     field public static final int LOCATION_MODE_NO_CHANGE = 0; // 0x0
     field public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4; // 0x4
+    field public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1; // 0x1
+    field public static final String LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN = "com.android.lowpowerstandby.WAKE_ON_LAN";
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
     field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
     field public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; // 0x20
@@ -36694,6 +36859,7 @@
     field public static final String ACTION_MANAGE_ALL_SIM_PROFILES_SETTINGS = "android.settings.MANAGE_ALL_SIM_PROFILES_SETTINGS";
     field public static final String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
     field public static final String ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION = "android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION";
+    field public static final String ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT = "android.settings.MANAGE_APP_USE_FULL_SCREEN_INTENT";
     field public static final String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
     field public static final String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
     field public static final String ACTION_MANAGE_SUPERVISOR_RESTRICTED_SETTING = "android.settings.MANAGE_SUPERVISOR_RESTRICTED_SETTING";
@@ -39320,6 +39486,19 @@
 
 }
 
+package android.service.assist.classification {
+
+  public final class FieldClassification implements android.os.Parcelable {
+    ctor public FieldClassification(@NonNull android.view.autofill.AutofillId, @NonNull java.util.Set<java.lang.String>);
+    method public int describeContents();
+    method @NonNull public android.view.autofill.AutofillId getAutofillId();
+    method @NonNull public java.util.Set<java.lang.String> getHints();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.assist.classification.FieldClassification> CREATOR;
+  }
+
+}
+
 package android.service.autofill {
 
   public abstract class AutofillService extends android.app.Service {
@@ -39388,6 +39567,7 @@
     method @NonNull public android.service.autofill.Dataset build();
     method @NonNull public android.service.autofill.Dataset.Builder setAuthentication(@Nullable android.content.IntentSender);
     method @NonNull public android.service.autofill.Dataset.Builder setField(@NonNull android.view.autofill.AutofillId, @Nullable android.service.autofill.Field);
+    method @NonNull public android.service.autofill.Dataset.Builder setField(@NonNull String, @NonNull android.service.autofill.Field);
     method @NonNull public android.service.autofill.Dataset.Builder setId(@Nullable String);
     method @Deprecated @NonNull public android.service.autofill.Dataset.Builder setInlinePresentation(@NonNull android.service.autofill.InlinePresentation);
     method @Deprecated @NonNull public android.service.autofill.Dataset.Builder setInlinePresentation(@NonNull android.service.autofill.InlinePresentation, @NonNull android.service.autofill.InlinePresentation);
@@ -39496,6 +39676,7 @@
     method @Nullable public android.content.IntentSender getDelayedFillIntentSender();
     method @NonNull public java.util.List<android.service.autofill.FillContext> getFillContexts();
     method public int getFlags();
+    method @NonNull public java.util.List<java.lang.String> getHints();
     method public int getId();
     method @Nullable public android.view.inputmethod.InlineSuggestionsRequest getInlineSuggestionsRequest();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -39524,6 +39705,7 @@
     method @Deprecated @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.widget.RemoteViews, @Nullable android.service.autofill.InlinePresentation, @Nullable android.service.autofill.InlinePresentation);
     method @NonNull public android.service.autofill.FillResponse.Builder setAuthentication(@NonNull android.view.autofill.AutofillId[], @Nullable android.content.IntentSender, @Nullable android.service.autofill.Presentations);
     method @NonNull public android.service.autofill.FillResponse.Builder setClientState(@Nullable android.os.Bundle);
+    method @NonNull public android.service.autofill.FillResponse.Builder setDetectedFieldClassifications(@NonNull java.util.Set<android.service.assist.classification.FieldClassification>);
     method @NonNull public android.service.autofill.FillResponse.Builder setDialogHeader(@NonNull android.widget.RemoteViews);
     method @NonNull public android.service.autofill.FillResponse.Builder setFieldClassificationIds(@NonNull android.view.autofill.AutofillId...);
     method @NonNull public android.service.autofill.FillResponse.Builder setFillDialogTriggerIds(@NonNull android.view.autofill.AutofillId...);
@@ -40144,9 +40326,10 @@
   }
 
   public class BeginCreateCredentialRequest implements android.os.Parcelable {
-    ctor public BeginCreateCredentialRequest(@NonNull android.service.credentials.CallingAppInfo, @NonNull String, @NonNull android.os.Bundle);
+    ctor public BeginCreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle, @Nullable android.service.credentials.CallingAppInfo);
+    ctor public BeginCreateCredentialRequest(@NonNull String, @NonNull android.os.Bundle);
     method public int describeContents();
-    method @NonNull public android.service.credentials.CallingAppInfo getCallingAppInfo();
+    method @Nullable public android.service.credentials.CallingAppInfo getCallingAppInfo();
     method @NonNull public android.os.Bundle getData();
     method @NonNull public String getType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -40154,6 +40337,7 @@
   }
 
   public final class BeginCreateCredentialResponse implements android.os.Parcelable {
+    ctor public BeginCreateCredentialResponse();
     method public int describeContents();
     method @NonNull public java.util.List<android.service.credentials.CreateEntry> getCreateEntries();
     method @Nullable public android.service.credentials.CreateEntry getRemoteCreateEntry();
@@ -40170,9 +40354,10 @@
   }
 
   public class BeginGetCredentialOption implements android.os.Parcelable {
-    ctor public BeginGetCredentialOption(@NonNull String, @NonNull android.os.Bundle);
+    ctor public BeginGetCredentialOption(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
     method public int describeContents();
     method @NonNull public android.os.Bundle getCandidateQueryData();
+    method @NonNull public String getId();
     method @NonNull public String getType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginGetCredentialOption> CREATOR;
@@ -40181,28 +40366,42 @@
   public final class BeginGetCredentialRequest implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public java.util.List<android.service.credentials.BeginGetCredentialOption> getBeginGetCredentialOptions();
-    method @NonNull public android.service.credentials.CallingAppInfo getCallingAppInfo();
+    method @Nullable public android.service.credentials.CallingAppInfo getCallingAppInfo();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginGetCredentialRequest> CREATOR;
   }
 
   public static final class BeginGetCredentialRequest.Builder {
-    ctor public BeginGetCredentialRequest.Builder(@NonNull android.service.credentials.CallingAppInfo);
+    ctor public BeginGetCredentialRequest.Builder();
     method @NonNull public android.service.credentials.BeginGetCredentialRequest.Builder addBeginGetCredentialOption(@NonNull android.service.credentials.BeginGetCredentialOption);
     method @NonNull public android.service.credentials.BeginGetCredentialRequest build();
     method @NonNull public android.service.credentials.BeginGetCredentialRequest.Builder setBeginGetCredentialOptions(@NonNull java.util.List<android.service.credentials.BeginGetCredentialOption>);
+    method @NonNull public android.service.credentials.BeginGetCredentialRequest.Builder setCallingAppInfo(@Nullable android.service.credentials.CallingAppInfo);
   }
 
   public final class BeginGetCredentialResponse implements android.os.Parcelable {
-    method @NonNull public static android.service.credentials.BeginGetCredentialResponse createWithAuthentication(@NonNull android.service.credentials.Action);
-    method @NonNull public static android.service.credentials.BeginGetCredentialResponse createWithResponseContent(@NonNull android.service.credentials.CredentialsResponseContent);
+    ctor public BeginGetCredentialResponse();
     method public int describeContents();
-    method @Nullable public android.service.credentials.Action getAuthenticationAction();
-    method @Nullable public android.service.credentials.CredentialsResponseContent getCredentialsResponseContent();
+    method @NonNull public java.util.List<android.service.credentials.Action> getActions();
+    method @NonNull public java.util.List<android.service.credentials.Action> getAuthenticationActions();
+    method @NonNull public java.util.List<android.service.credentials.CredentialEntry> getCredentialEntries();
+    method @Nullable public android.service.credentials.CredentialEntry getRemoteCredentialEntry();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.BeginGetCredentialResponse> CREATOR;
   }
 
+  public static final class BeginGetCredentialResponse.Builder {
+    ctor public BeginGetCredentialResponse.Builder();
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder addAction(@NonNull android.service.credentials.Action);
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder addAuthenticationAction(@NonNull android.service.credentials.Action);
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder addCredentialEntry(@NonNull android.service.credentials.CredentialEntry);
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse build();
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setActions(@NonNull java.util.List<android.service.credentials.Action>);
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setAuthenticationActions(@NonNull java.util.List<android.service.credentials.Action>);
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setCredentialEntries(@NonNull java.util.List<android.service.credentials.CredentialEntry>);
+    method @NonNull public android.service.credentials.BeginGetCredentialResponse.Builder setRemoteCredentialEntry(@Nullable android.service.credentials.CredentialEntry);
+  }
+
   public final class CallingAppInfo implements android.os.Parcelable {
     ctor public CallingAppInfo(@NonNull String, @NonNull android.content.pm.SigningInfo);
     method public int describeContents();
@@ -40240,8 +40439,9 @@
   }
 
   public class CredentialEntry implements android.os.Parcelable {
-    ctor public CredentialEntry(@NonNull String, @NonNull android.app.slice.Slice);
+    ctor public CredentialEntry(@NonNull android.service.credentials.BeginGetCredentialOption, @NonNull android.app.slice.Slice);
     method public int describeContents();
+    method @NonNull public android.service.credentials.BeginGetCredentialOption getBeginGetCredentialOption();
     method @NonNull public android.app.slice.Slice getSlice();
     method @NonNull public String getType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -40256,40 +40456,21 @@
     method public abstract void onClearCredentialState(@NonNull android.service.credentials.ClearCredentialStateRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException>);
     field public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
     field public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST = "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";
+    field public static final String EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE = "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_RESPONSE";
     field public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION = "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";
     field public static final String EXTRA_CREATE_CREDENTIAL_REQUEST = "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
     field public static final String EXTRA_CREATE_CREDENTIAL_RESPONSE = "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE";
-    field public static final String EXTRA_CREDENTIALS_RESPONSE_CONTENT = "android.service.credentials.extra.CREDENTIALS_RESPONSE_CONTENT";
     field public static final String EXTRA_GET_CREDENTIAL_EXCEPTION = "android.service.credentials.extra.GET_CREDENTIAL_EXCEPTION";
     field public static final String EXTRA_GET_CREDENTIAL_REQUEST = "android.service.credentials.extra.GET_CREDENTIAL_REQUEST";
     field public static final String EXTRA_GET_CREDENTIAL_RESPONSE = "android.service.credentials.extra.GET_CREDENTIAL_RESPONSE";
     field public static final String SERVICE_INTERFACE = "android.service.credentials.CredentialProviderService";
   }
 
-  public final class CredentialsResponseContent implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public java.util.List<android.service.credentials.Action> getActions();
-    method @NonNull public java.util.List<android.service.credentials.CredentialEntry> getCredentialEntries();
-    method @Nullable public android.service.credentials.CredentialEntry getRemoteCredentialEntry();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.CredentialsResponseContent> CREATOR;
-  }
-
-  public static final class CredentialsResponseContent.Builder {
-    ctor public CredentialsResponseContent.Builder();
-    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder addAction(@NonNull android.service.credentials.Action);
-    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder addCredentialEntry(@NonNull android.service.credentials.CredentialEntry);
-    method @NonNull public android.service.credentials.CredentialsResponseContent build();
-    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setActions(@NonNull java.util.List<android.service.credentials.Action>);
-    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setCredentialEntries(@NonNull java.util.List<android.service.credentials.CredentialEntry>);
-    method @NonNull public android.service.credentials.CredentialsResponseContent.Builder setRemoteCredentialEntry(@Nullable android.service.credentials.CredentialEntry);
-  }
-
   public final class GetCredentialRequest implements android.os.Parcelable {
-    ctor public GetCredentialRequest(@NonNull android.service.credentials.CallingAppInfo, @NonNull android.credentials.GetCredentialOption);
+    ctor public GetCredentialRequest(@NonNull android.service.credentials.CallingAppInfo, @NonNull android.credentials.CredentialOption);
     method public int describeContents();
     method @NonNull public android.service.credentials.CallingAppInfo getCallingAppInfo();
-    method @NonNull public android.credentials.GetCredentialOption getGetCredentialOption();
+    method @NonNull public android.credentials.CredentialOption getCredentialOption();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.service.credentials.GetCredentialRequest> CREATOR;
   }
@@ -40713,12 +40894,12 @@
     method @Nullable public CharSequence getCardLabel();
     method @NonNull public int getCardType();
     method @NonNull public CharSequence getContentDescription();
+    method @Nullable public android.graphics.drawable.Icon getNonPaymentCardSecondaryImage();
     method @NonNull public android.app.PendingIntent getPendingIntent();
-    method @Nullable public android.graphics.drawable.Icon getValuableCardSecondaryImage();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CARD_TYPE_NON_PAYMENT = 2; // 0x2
     field public static final int CARD_TYPE_PAYMENT = 1; // 0x1
     field public static final int CARD_TYPE_UNKNOWN = 0; // 0x0
-    field public static final int CARD_TYPE_VALUABLE = 2; // 0x2
     field @NonNull public static final android.os.Parcelable.Creator<android.service.quickaccesswallet.WalletCard> CREATOR;
   }
 
@@ -40728,7 +40909,7 @@
     method @NonNull public android.service.quickaccesswallet.WalletCard build();
     method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setCardIcon(@Nullable android.graphics.drawable.Icon);
     method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setCardLabel(@Nullable CharSequence);
-    method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setValuableCardSecondaryImage(@Nullable android.graphics.drawable.Icon);
+    method @NonNull public android.service.quickaccesswallet.WalletCard.Builder setNonPaymentCardSecondaryImage(@Nullable android.graphics.drawable.Icon);
   }
 
   public final class WalletServiceEvent implements android.os.Parcelable {
@@ -40893,7 +41074,7 @@
     method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest);
     method public void onRequestConfirmation(android.service.voice.VoiceInteractionSession.ConfirmationRequest);
     method public void onRequestPickOption(android.service.voice.VoiceInteractionSession.PickOptionRequest);
-    method public void onShow(android.os.Bundle, int);
+    method public void onShow(@Nullable android.os.Bundle, int);
     method public void onTaskFinished(android.content.Intent, int);
     method public void onTaskStarted(android.content.Intent, int);
     method public void onTrimMemory(int);
@@ -41657,6 +41838,15 @@
     method public void startCallStreaming(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.telecom.CallException>);
   }
 
+  public interface CallControlCallback {
+    method public void onAnswer(int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method public void onCallStreamingStarted(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method public void onDisconnect(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method public void onReject(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method public void onSetActive(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+    method public void onSetInactive(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+  }
+
   public final class CallEndpoint implements android.os.Parcelable {
     ctor public CallEndpoint(@NonNull CharSequence, int, @NonNull android.os.ParcelUuid);
     method public int describeContents();
@@ -41686,16 +41876,10 @@
   }
 
   public interface CallEventCallback {
-    method public void onAnswer(int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onAvailableCallEndpointsChanged(@NonNull java.util.List<android.telecom.CallEndpoint>);
     method public void onCallEndpointChanged(@NonNull android.telecom.CallEndpoint);
     method public void onCallStreamingFailed(int);
-    method public void onCallStreamingStarted(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onDisconnect(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onMuteStateChanged(boolean);
-    method public void onReject(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onSetActive(@NonNull java.util.function.Consumer<java.lang.Boolean>);
-    method public void onSetInactive(@NonNull java.util.function.Consumer<java.lang.Boolean>);
   }
 
   public final class CallException extends java.lang.RuntimeException implements android.os.Parcelable {
@@ -42448,7 +42632,7 @@
     method @NonNull public String getDisplayName();
     method @NonNull public android.os.Bundle getExtras();
     method public int getState();
-    method public void setStreamingState(int);
+    method public void requestStreamingState(int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telecom.StreamingCall> CREATOR;
     field public static final int STATE_DISCONNECTED = 3; // 0x3
@@ -42460,7 +42644,7 @@
     method public void acceptHandover(android.net.Uri, int, android.telecom.PhoneAccountHandle);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ANSWER_PHONE_CALLS, android.Manifest.permission.MODIFY_PHONE_STATE}) public void acceptRingingCall(int);
-    method @RequiresPermission(android.Manifest.permission.MANAGE_OWN_CALLS) public void addCall(@NonNull android.telecom.CallAttributes, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telecom.CallControl,android.telecom.CallException>, @NonNull android.telecom.CallEventCallback);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_OWN_CALLS) public void addCall(@NonNull android.telecom.CallAttributes, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telecom.CallControl,android.telecom.CallException>, @NonNull android.telecom.CallControlCallback, @NonNull android.telecom.CallEventCallback);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
     method public void addNewIncomingConference(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.os.Bundle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void cancelMissedCallsNotification();
@@ -43291,7 +43475,7 @@
     field public static final String KEY_PREFIX = "imssms.";
     field public static final String KEY_SMS_CSFB_RETRY_ON_FAILURE_BOOL = "imssms.sms_csfb_retry_on_failure_bool";
     field public static final String KEY_SMS_MAX_RETRY_COUNT_INT = "imssms.sms_max_retry_count_int";
-    field public static final String KEY_SMS_MAX_RETRY_COUNT_OVER_IMS_INT = "imssms.sms_max_retry_count_over_ims_int";
+    field public static final String KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT = "imssms.sms_max_retry_over_ims_count_int";
     field public static final String KEY_SMS_OVER_IMS_FORMAT_INT = "imssms.sms_over_ims_format_int";
     field public static final String KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT = "imssms.sms_over_ims_send_retry_delay_millis_int";
     field public static final String KEY_SMS_OVER_IMS_SUPPORTED_BOOL = "imssms.sms_over_ims_supported_bool";
@@ -43925,6 +44109,7 @@
     field public static final int IWLAN_SEMANTIC_ERROR_IN_THE_TFT_OPERATION = 8241; // 0x2031
     field public static final int IWLAN_SYNTACTICAL_ERRORS_IN_PACKET_FILTERS = 8245; // 0x2035
     field public static final int IWLAN_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION = 8242; // 0x2032
+    field public static final int IWLAN_TUNNEL_NOT_FOUND = 16390; // 0x4006
     field public static final int IWLAN_UNAUTHENTICATED_EMERGENCY_NOT_SUPPORTED = 11055; // 0x2b2f
     field public static final int IWLAN_USER_UNKNOWN = 9001; // 0x2329
     field public static final int LIMITED_TO_IPV4 = 2234; // 0x8ba
@@ -45349,6 +45534,7 @@
     field public static final String EXTRA_HIDE_PUBLIC_SETTINGS = "android.telephony.extra.HIDE_PUBLIC_SETTINGS";
     field @Deprecated public static final String EXTRA_INCOMING_NUMBER = "incoming_number";
     field public static final String EXTRA_IS_REFRESH = "android.telephony.extra.IS_REFRESH";
+    field public static final String EXTRA_LAST_KNOWN_NETWORK_COUNTRY = "android.telephony.extra.LAST_KNOWN_NETWORK_COUNTRY";
     field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
     field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY";
     field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
@@ -51309,7 +51495,7 @@
     method public void onTransactionCommitted();
   }
 
-  public static class SurfaceControl.TrustedPresentationThresholds {
+  public static final class SurfaceControl.TrustedPresentationThresholds {
     ctor public SurfaceControl.TrustedPresentationThresholds(@FloatRange(from=0.0f, fromInclusive=false, to=1.0f) float, @FloatRange(from=0.0f, fromInclusive=false, to=1.0f) float, @IntRange(from=1) int);
   }
 
@@ -54675,6 +54861,7 @@
     method public final void notifyViewDisappeared(@NonNull android.view.autofill.AutofillId);
     method public final void notifyViewInsetsChanged(@NonNull android.graphics.Insets);
     method public final void notifyViewTextChanged(@NonNull android.view.autofill.AutofillId, @Nullable CharSequence);
+    method public final void notifyViewsAppeared(@NonNull java.util.List<android.view.ViewStructure>);
     method public final void notifyViewsDisappeared(@NonNull android.view.autofill.AutofillId, @NonNull long[]);
     method public final void setContentCaptureContext(@Nullable android.view.contentcapture.ContentCaptureContext);
   }
@@ -60323,7 +60510,7 @@
     method @UiThread public void remove();
   }
 
-  public class SurfaceSyncGroup {
+  public final class SurfaceSyncGroup {
     ctor public SurfaceSyncGroup(@NonNull String);
     method @UiThread public boolean add(@Nullable android.view.AttachedSurfaceControl, @Nullable Runnable);
     method public boolean add(@NonNull android.view.SurfaceControlViewHost.SurfacePackage, @Nullable Runnable);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index af35d96..5171027 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -316,6 +316,30 @@
 
 }
 
+package android.nfc {
+
+  public class NfcFrameworkInitializer {
+    method public static void registerServiceWrappers();
+    method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager);
+  }
+
+  public class NfcServiceManager {
+    method @NonNull public android.nfc.NfcServiceManager.ServiceRegisterer getNfcManagerServiceRegisterer();
+  }
+
+  public static class NfcServiceManager.ServiceNotFoundException extends java.lang.Exception {
+    ctor public NfcServiceManager.ServiceNotFoundException(@NonNull String);
+  }
+
+  public static final class NfcServiceManager.ServiceRegisterer {
+    method @Nullable public android.os.IBinder get();
+    method @NonNull public android.os.IBinder getOrThrow() throws android.nfc.NfcServiceManager.ServiceNotFoundException;
+    method public void register(@NonNull android.os.IBinder);
+    method @Nullable public android.os.IBinder tryGet();
+  }
+
+}
+
 package android.os {
 
   public class ArtModuleServiceManager {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index fe3605f..fde95bd 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -55,6 +55,7 @@
     field public static final String BIND_DOMAIN_VERIFICATION_AGENT = "android.permission.BIND_DOMAIN_VERIFICATION_AGENT";
     field public static final String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
     field public static final String BIND_EXTERNAL_STORAGE_SERVICE = "android.permission.BIND_EXTERNAL_STORAGE_SERVICE";
+    field public static final String BIND_FIELD_CLASSIFICATION_SERVICE = "android.permission.BIND_FIELD_CLASSIFICATION_SERVICE";
     field public static final String BIND_GBA_SERVICE = "android.permission.BIND_GBA_SERVICE";
     field public static final String BIND_HOTWORD_DETECTION_SERVICE = "android.permission.BIND_HOTWORD_DETECTION_SERVICE";
     field public static final String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
@@ -64,6 +65,7 @@
     field public static final String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
     field public static final String BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE = "android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE";
     field public static final String BIND_PRINT_RECOMMENDATION_SERVICE = "android.permission.BIND_PRINT_RECOMMENDATION_SERVICE";
+    field public static final String BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE = "android.permission.BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE";
     field public static final String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
     field public static final String BIND_RESUME_ON_REBOOT_SERVICE = "android.permission.BIND_RESUME_ON_REBOOT_SERVICE";
     field public static final String BIND_ROTATION_RESOLVER_SERVICE = "android.permission.BIND_ROTATION_RESOLVER_SERVICE";
@@ -99,6 +101,7 @@
     field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
     field public static final String CHANGE_APP_LAUNCH_TIME_ESTIMATE = "android.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE";
     field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
+    field public static final String CHECK_REMOTE_LOCKSCREEN = "android.permission.CHECK_REMOTE_LOCKSCREEN";
     field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
     field public static final String COMPANION_APPROVE_WIFI_CONNECTIONS = "android.permission.COMPANION_APPROVE_WIFI_CONNECTIONS";
     field public static final String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
@@ -245,6 +248,8 @@
     field public static final String PERFORM_IMS_SINGLE_REGISTRATION = "android.permission.PERFORM_IMS_SINGLE_REGISTRATION";
     field public static final String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION";
     field public static final String POWER_SAVER = "android.permission.POWER_SAVER";
+    field public static final String PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE = "android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE";
+    field public static final String PROVIDE_HYBRID_CREDENTIAL_SERVICE = "android.permission.PROVIDE_HYBRID_CREDENTIAL_SERVICE";
     field public static final String PROVIDE_RESOLVER_RANKER_SERVICE = "android.permission.PROVIDE_RESOLVER_RANKER_SERVICE";
     field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
     field public static final String PROVISION_DEMO_DEVICE = "android.permission.PROVISION_DEMO_DEVICE";
@@ -546,7 +551,7 @@
 
   public class AlarmManager {
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, @NonNull android.app.PendingIntent, @Nullable android.os.WorkSource);
-    method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, @NonNull android.app.AlarmManager.OnAlarmListener, @Nullable android.os.Handler, @Nullable android.os.WorkSource);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, @NonNull android.app.AlarmManager.OnAlarmListener, @Nullable android.os.Handler, @Nullable android.os.WorkSource);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void setExact(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void setExactAndAllowWhileIdle(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @Nullable android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
     method @RequiresPermission(android.Manifest.permission.SCHEDULE_PRIORITIZED_ALARM) public void setPrioritized(int, long, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.app.AlarmManager.OnAlarmListener);
@@ -907,6 +912,7 @@
 
   public class KeyguardManager {
     method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public long addWeakEscrowToken(@NonNull byte[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenActivatedListener);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.content.Intent createConfirmDeviceCredentialForRemoteValidationIntent(@NonNull android.app.StartLockscreenValidationRequest, @NonNull android.content.ComponentName, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence);
     method public android.content.Intent createConfirmFactoryResetCredentialIntent(CharSequence, CharSequence, CharSequence);
     method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public int getMinLockLength(boolean, int);
     method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public boolean getPrivateNotificationsAllowed();
@@ -918,7 +924,9 @@
     method @RequiresPermission(android.Manifest.permission.SHOW_KEYGUARD_MESSAGE) public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable CharSequence, @Nullable android.app.KeyguardManager.KeyguardDismissCallback);
     method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean setLock(int, @NonNull byte[], int);
     method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public void setPrivateNotificationsAllowed(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.StartLockscreenValidationRequest startRemoteLockscreenValidation();
     method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean unregisterWeakEscrowTokenRemovedListener(@NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener);
+    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.RemoteLockscreenValidationResult validateRemoteLockscreen(@NonNull byte[]);
     field public static final int PASSWORD = 0; // 0x0
     field public static final int PATTERN = 2; // 0x2
     field public static final int PIN = 1; // 0x1
@@ -995,6 +1003,25 @@
     field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL = "android.app.action.TOGGLE_NOTIFICATION_HANDLER_PANEL";
   }
 
+  public final class RemoteLockscreenValidationResult implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getResultCode();
+    method public long getTimeoutMillis();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.RemoteLockscreenValidationResult> CREATOR;
+    field public static final int RESULT_GUESS_INVALID = 2; // 0x2
+    field public static final int RESULT_GUESS_VALID = 1; // 0x1
+    field public static final int RESULT_LOCKOUT = 3; // 0x3
+    field public static final int RESULT_NO_REMAINING_ATTEMPTS = 4; // 0x4
+  }
+
+  public static final class RemoteLockscreenValidationResult.Builder {
+    ctor public RemoteLockscreenValidationResult.Builder();
+    method @NonNull public android.app.RemoteLockscreenValidationResult build();
+    method @NonNull public android.app.RemoteLockscreenValidationResult.Builder setResultCode(int);
+    method @NonNull public android.app.RemoteLockscreenValidationResult.Builder setTimeoutMillis(long);
+  }
+
   public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
     ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
     method public int describeContents();
@@ -1012,6 +1039,23 @@
     method public void launchAssist(@Nullable android.os.Bundle);
   }
 
+  public final class StartLockscreenValidationRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getLockscreenUiType();
+    method public int getRemainingAttempts();
+    method @NonNull public byte[] getSourcePublicKey();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.StartLockscreenValidationRequest> CREATOR;
+  }
+
+  public static final class StartLockscreenValidationRequest.Builder {
+    ctor public StartLockscreenValidationRequest.Builder();
+    method @NonNull public android.app.StartLockscreenValidationRequest build();
+    method @NonNull public android.app.StartLockscreenValidationRequest.Builder setLockscreenUiType(int);
+    method @NonNull public android.app.StartLockscreenValidationRequest.Builder setRemainingAttempts(int);
+    method @NonNull public android.app.StartLockscreenValidationRequest.Builder setSourcePublicKey(@NonNull byte[]);
+  }
+
   public class StatusBarManager {
     method @NonNull @RequiresPermission(android.Manifest.permission.STATUS_BAR) public android.app.StatusBarManager.DisableInfo getDisableInfo();
     method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public int getNavBarMode();
@@ -1157,6 +1201,15 @@
 
 package android.app.admin {
 
+  public abstract class Authority implements android.os.Parcelable {
+    method public int describeContents();
+  }
+
+  public final class DeviceAdminAuthority extends android.app.admin.Authority {
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DeviceAdminAuthority> CREATOR;
+  }
+
   public final class DevicePolicyDrawableResource implements android.os.Parcelable {
     ctor public DevicePolicyDrawableResource(@NonNull android.content.Context, @NonNull String, @NonNull String, @NonNull String, @DrawableRes int);
     ctor public DevicePolicyDrawableResource(@NonNull android.content.Context, @NonNull String, @NonNull String, @DrawableRes int);
@@ -1188,6 +1241,7 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public String getDeviceOwnerNameOnAnyUser();
     method @Nullable public CharSequence getDeviceOwnerOrganizationName();
     method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.UserHandle getDeviceOwnerUser();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public android.app.admin.DevicePolicyState getDevicePolicyState();
     method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_ADMIN_POLICY}) public java.util.List<java.lang.String> getPermittedAccessibilityServices(int);
     method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_ADMIN_POLICY}) public java.util.List<java.lang.String> getPermittedInputMethodsForCurrentUser();
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public java.util.List<android.os.UserHandle> getPolicyManagedProfiles(@NonNull android.os.UserHandle);
@@ -1229,7 +1283,9 @@
     field public static final String ACTION_SET_PROFILE_OWNER = "android.app.action.SET_PROFILE_OWNER";
     field @Deprecated public static final String ACTION_STATE_USER_SETUP_COMPLETE = "android.app.action.STATE_USER_SETUP_COMPLETE";
     field @RequiresPermission(android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP) public static final String ACTION_UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER = "android.app.action.UPDATE_DEVICE_POLICY_MANAGEMENT_ROLE_HOLDER";
+    field public static final int EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION = 2; // 0x2
     field public static final int EXEMPT_FROM_APP_STANDBY = 0; // 0x0
+    field public static final int EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS = 1; // 0x1
     field public static final String EXTRA_FORCE_UPDATE_ROLE_HOLDER = "android.app.extra.FORCE_UPDATE_ROLE_HOLDER";
     field public static final String EXTRA_LOST_MODE_LOCATION = "android.app.extra.LOST_MODE_LOCATION";
     field public static final String EXTRA_PROFILE_OWNER_NAME = "android.app.extra.PROFILE_OWNER_NAME";
@@ -1314,6 +1370,14 @@
     method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void setStrings(@NonNull java.util.Set<android.app.admin.DevicePolicyStringResource>);
   }
 
+  public final class DevicePolicyState implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.Map<android.os.UserHandle,java.util.Map<android.app.admin.PolicyKey,android.app.admin.PolicyState<?>>> getPoliciesForAllUsers();
+    method @NonNull public java.util.Map<android.app.admin.PolicyKey,android.app.admin.PolicyState<?>> getPoliciesForUser(@NonNull android.os.UserHandle);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DevicePolicyState> CREATOR;
+  }
+
   public final class DevicePolicyStringResource implements android.os.Parcelable {
     ctor public DevicePolicyStringResource(@NonNull android.content.Context, @NonNull String, @StringRes int);
     method public int describeContents();
@@ -1323,6 +1387,20 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DevicePolicyStringResource> CREATOR;
   }
 
+  public final class DpcAuthority extends android.app.admin.Authority {
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DpcAuthority> CREATOR;
+  }
+
+  public final class EnforcingAdmin implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.app.admin.Authority getAuthority();
+    method @NonNull public String getPackageName();
+    method @NonNull public android.os.UserHandle getUserHandle();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.EnforcingAdmin> CREATOR;
+  }
+
   public final class FullyManagedDeviceProvisioningParams implements android.os.Parcelable {
     method public boolean canDeviceOwnerGrantSensorsPermissions();
     method public int describeContents();
@@ -1350,6 +1428,21 @@
     method @NonNull public android.app.admin.FullyManagedDeviceProvisioningParams.Builder setTimeZone(@Nullable String);
   }
 
+  public final class IntentFilterPolicyKey extends android.app.admin.PolicyKey {
+    method public int describeContents();
+    method @NonNull public android.content.IntentFilter getIntentFilter();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.IntentFilterPolicyKey> CREATOR;
+  }
+
+  public final class LockTaskPolicy implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getFlags();
+    method @NonNull public java.util.Set<java.lang.String> getPackages();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.LockTaskPolicy> CREATOR;
+  }
+
   public final class ManagedProfileProvisioningParams implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.accounts.Account getAccountToMigrate();
@@ -1375,6 +1468,39 @@
     method @NonNull public android.app.admin.ManagedProfileProvisioningParams.Builder setProfileName(@Nullable String);
   }
 
+  public final class NoArgsPolicyKey extends android.app.admin.PolicyKey {
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.NoArgsPolicyKey> CREATOR;
+  }
+
+  public final class PackagePermissionPolicyKey extends android.app.admin.PolicyKey {
+    method public int describeContents();
+    method @NonNull public String getPackageName();
+    method @NonNull public String getPermissionName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PackagePermissionPolicyKey> CREATOR;
+  }
+
+  public final class PackagePolicyKey extends android.app.admin.PolicyKey {
+    method public int describeContents();
+    method @NonNull public String getPackageName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PackagePolicyKey> CREATOR;
+  }
+
+  public abstract class PolicyKey implements android.os.Parcelable {
+    method @NonNull public String getIdentifier();
+  }
+
+  public final class PolicyState<V> implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public V getCurrentResolvedPolicy();
+    method @NonNull public java.util.LinkedHashMap<android.app.admin.EnforcingAdmin,V> getPoliciesSetByAdmins();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PolicyState<?>> CREATOR;
+  }
+
   public class ProvisioningException extends android.util.AndroidException {
     ctor public ProvisioningException(@NonNull Exception, int);
     ctor public ProvisioningException(@NonNull Exception, int, @Nullable String);
@@ -1389,6 +1515,12 @@
     field public static final int ERROR_UNKNOWN = 0; // 0x0
   }
 
+  public final class RoleAuthority extends android.app.admin.Authority {
+    method @NonNull public java.util.Set<java.lang.String> getRoles();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.RoleAuthority> CREATOR;
+  }
+
   public class SecurityLog {
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURITY_LOG) public static int writeEvent(int, @NonNull java.lang.Object...);
   }
@@ -1403,6 +1535,11 @@
     method public int getType();
   }
 
+  public final class UnknownAuthority extends android.app.admin.Authority {
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.UnknownAuthority> CREATOR;
+  }
+
 }
 
 package android.app.ambientcontext {
@@ -2119,6 +2256,13 @@
     method protected void finalize();
     method public void notifyEvent(@NonNull android.app.search.Query, @NonNull android.app.search.SearchTargetEvent);
     method @Nullable public void query(@NonNull android.app.search.Query, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.app.search.SearchTarget>>);
+    method public void registerEmptyQueryResultUpdateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.app.search.SearchSession.Callback);
+    method public void requestEmptyQueryResultUpdate();
+    method public void unregisterEmptyQueryResultUpdateCallback(@NonNull android.app.search.SearchSession.Callback);
+  }
+
+  public static interface SearchSession.Callback {
+    method public void onTargetsAvailable(@NonNull java.util.List<android.app.search.SearchTarget>);
   }
 
   public final class SearchSessionId implements android.os.Parcelable {
@@ -2985,11 +3129,18 @@
   }
 
   public final class CompanionDeviceManager {
+    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void addOnAssociationsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
     method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate(@NonNull String, @NonNull android.net.MacAddress, @NonNull byte[]);
     method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
+    method @NonNull @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public java.util.List<android.companion.AssociationInfo> getAllAssociations();
     method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int);
     method @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int);
+    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void removeOnAssociationsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnAssociationsChangedListener);
+  }
+
+  public static interface CompanionDeviceManager.OnAssociationsChangedListener {
+    method public void onAssociationsChanged(@NonNull java.util.List<android.companion.AssociationInfo>);
   }
 
 }
@@ -3005,7 +3156,8 @@
 
   public static interface VirtualDeviceManager.ActivityListener {
     method public void onDisplayEmpty(int);
-    method public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
+    method @Deprecated public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
+    method public default void onTopActivityChanged(int, @NonNull android.content.ComponentName, int);
   }
 
   public static interface VirtualDeviceManager.IntentInterceptorCallback {
@@ -3264,6 +3416,7 @@
     field public static final String SAFETY_CENTER_SERVICE = "safety_center";
     field public static final String SEARCH_UI_SERVICE = "search_ui";
     field public static final String SECURE_ELEMENT_SERVICE = "secure_element";
+    field public static final String SHARED_CONNECTIVITY_SERVICE = "shared_connectivity";
     field public static final String SMARTSPACE_SERVICE = "smartspace";
     field public static final String STATS_MANAGER = "stats";
     field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
@@ -3643,7 +3796,7 @@
     method @RequiresPermission(allOf={android.Manifest.permission.INSTALL_PACKAGES, "com.android.permission.USE_INSTALLER_V2"}) public void setDataLoaderParams(@NonNull android.content.pm.DataLoaderParams);
     method public void setEnableRollback(boolean);
     method public void setEnableRollback(boolean, int);
-    method @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) public void setGrantedRuntimePermissions(String[]);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) public void setGrantedRuntimePermissions(String[]);
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
     method public void setInstallAsInstantApp(boolean);
     method public void setInstallAsVirtualPreload();
@@ -4885,8 +5038,8 @@
 
   public final class VirtualNavigationTouchpadConfig extends android.hardware.input.VirtualInputDeviceConfig implements android.os.Parcelable {
     method public int describeContents();
-    method public int getHeight();
-    method public int getWidth();
+    method @IntRange(from=1) public int getHeight();
+    method @IntRange(from=1) public int getWidth();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualNavigationTouchpadConfig> CREATOR;
   }
@@ -5824,6 +5977,7 @@
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public long getCurrentFunctions();
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_USB) public java.util.List<android.hardware.usb.UsbPort> getPorts();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void grantPermission(android.hardware.usb.UsbDevice, String);
+    method public static boolean isUvcSupportEnabled();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public boolean registerDisplayPortAltModeInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.usb.UsbManager.DisplayPortAltModeInfoListener);
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void resetUsbGadget();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setCurrentFunctions(long);
@@ -5845,6 +5999,7 @@
     field public static final long FUNCTION_NONE = 0L; // 0x0L
     field public static final long FUNCTION_PTP = 16L; // 0x10L
     field public static final long FUNCTION_RNDIS = 32L; // 0x20L
+    field public static final long FUNCTION_UVC = 128L; // 0x80L
     field public static final String USB_CONFIGURED = "configured";
     field public static final String USB_CONNECTED = "connected";
     field public static final String USB_FUNCTION_NCM = "ncm";
@@ -6746,6 +6901,7 @@
     field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
     field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
     field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+    field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
     field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
     field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
     field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
@@ -8903,6 +9059,10 @@
     field public static final int FRONTEND_STATUS_READINESS_UNSUPPORTED = 4; // 0x4
   }
 
+  public class IptvFrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
+    method public int getProtocolCapability();
+  }
+
   public class IptvFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.IptvFrontendSettings.Builder builder();
     method @IntRange(from=0) public long getBitrate();
@@ -9775,6 +9935,179 @@
 
 }
 
+package android.net.wifi.sharedconnectivity.app {
+
+  public final class DeviceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=0, to=100) public int getBatteryPercentage();
+    method @IntRange(from=0, to=3) public int getConnectionStrength();
+    method @NonNull public String getDeviceName();
+    method public int getDeviceType();
+    method @NonNull public String getModelName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.DeviceInfo> CREATOR;
+    field public static final int DEVICE_TYPE_LAPTOP = 3; // 0x3
+    field public static final int DEVICE_TYPE_PHONE = 1; // 0x1
+    field public static final int DEVICE_TYPE_TABLET = 2; // 0x2
+    field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class DeviceInfo.Builder {
+    ctor public DeviceInfo.Builder();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo build();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setBatteryPercentage(@IntRange(from=0, to=100) int);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setConnectionStrength(@IntRange(from=0, to=3) int);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setDeviceName(@NonNull String);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setDeviceType(int);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo.Builder setModelName(@NonNull String);
+  }
+
+  public final class KnownNetwork implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo getDeviceInfo();
+    method public int getNetworkSource();
+    method @NonNull public int[] getSecurityTypes();
+    method @NonNull public String getSsid();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.KnownNetwork> CREATOR;
+    field public static final int NETWORK_SOURCE_CLOUD_SELF = 1; // 0x1
+    field public static final int NETWORK_SOURCE_NEARBY_SELF = 0; // 0x0
+  }
+
+  public static final class KnownNetwork.Builder {
+    ctor public KnownNetwork.Builder();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork build();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setDeviceInfo(@NonNull android.net.wifi.sharedconnectivity.app.DeviceInfo);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setNetworkSource(int);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setSecurityTypes(@NonNull int[]);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setSsid(@NonNull String);
+  }
+
+  public final class KnownNetworkConnectionStatus implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.os.Bundle getExtras();
+    method public int getStatus();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CONNECTION_STATUS_SAVED = 1; // 0x1
+    field public static final int CONNECTION_STATUS_SAVE_FAILED = 2; // 0x2
+    field public static final int CONNECTION_STATUS_UNKNOWN = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus> CREATOR;
+  }
+
+  public static final class KnownNetworkConnectionStatus.Builder {
+    ctor public KnownNetworkConnectionStatus.Builder();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus build();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.Builder setExtras(@NonNull android.os.Bundle);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.Builder setStatus(int);
+  }
+
+  public interface SharedConnectivityClientCallback {
+    method public void onKnownNetworkConnectionStatusChanged(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus);
+    method public void onKnownNetworksUpdated(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.KnownNetwork>);
+    method public void onSharedConnectivitySettingsChanged(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState);
+    method public void onTetherNetworkConnectionStatusChanged(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus);
+    method public void onTetherNetworksUpdated(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.TetherNetwork>);
+  }
+
+  public class SharedConnectivityManager {
+    method public boolean connectKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
+    method public boolean connectTetherNetwork(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetwork);
+    method public boolean disconnectTetherNetwork();
+    method public boolean forgetKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
+    method public boolean registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
+    method public boolean unregisterCallback(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivityClientCallback);
+  }
+
+  public final class SharedConnectivitySettingsState implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.os.Bundle getExtras();
+    method public boolean isInstantTetherEnabled();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState> CREATOR;
+  }
+
+  public static final class SharedConnectivitySettingsState.Builder {
+    ctor public SharedConnectivitySettingsState.Builder();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState build();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setExtras(@NonNull android.os.Bundle);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setInstantTetherEnabled(boolean);
+  }
+
+  public final class TetherNetwork implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getDeviceId();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.DeviceInfo getDeviceInfo();
+    method @Nullable public String getHotspotBssid();
+    method @Nullable public int[] getHotspotSecurityTypes();
+    method @Nullable public String getHotspotSsid();
+    method @NonNull public String getNetworkName();
+    method public int getNetworkType();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.TetherNetwork> CREATOR;
+    field public static final int NETWORK_TYPE_CELLULAR = 1; // 0x1
+    field public static final int NETWORK_TYPE_ETHERNET = 3; // 0x3
+    field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int NETWORK_TYPE_WIFI = 2; // 0x2
+  }
+
+  public static final class TetherNetwork.Builder {
+    ctor public TetherNetwork.Builder();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork build();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setDeviceId(long);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setDeviceInfo(@NonNull android.net.wifi.sharedconnectivity.app.DeviceInfo);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setHotspotBssid(@NonNull String);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setHotspotSecurityTypes(@NonNull int[]);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setHotspotSsid(@NonNull String);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setNetworkName(@NonNull String);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetwork.Builder setNetworkType(int);
+  }
+
+  public final class TetherNetworkConnectionStatus implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.os.Bundle getExtras();
+    method public int getStatus();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED = 9; // 0x9
+    field public static final int CONNECTION_STATUS_ENABLING_HOTSPOT = 1; // 0x1
+    field public static final int CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED = 7; // 0x7
+    field public static final int CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT = 8; // 0x8
+    field public static final int CONNECTION_STATUS_NO_CELL_DATA = 6; // 0x6
+    field public static final int CONNECTION_STATUS_PROVISIONING_FAILED = 3; // 0x3
+    field public static final int CONNECTION_STATUS_TETHERING_TIMEOUT = 4; // 0x4
+    field public static final int CONNECTION_STATUS_TETHERING_UNSUPPORTED = 5; // 0x5
+    field public static final int CONNECTION_STATUS_UNKNOWN = 0; // 0x0
+    field public static final int CONNECTION_STATUS_UNKNOWN_ERROR = 2; // 0x2
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus> CREATOR;
+  }
+
+  public static final class TetherNetworkConnectionStatus.Builder {
+    ctor public TetherNetworkConnectionStatus.Builder();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus build();
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus.Builder setExtras(@NonNull android.os.Bundle);
+    method @NonNull public android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus.Builder setStatus(int);
+  }
+
+}
+
+package android.net.wifi.sharedconnectivity.service {
+
+  public abstract class SharedConnectivityService extends android.app.Service {
+    ctor public SharedConnectivityService();
+    ctor public SharedConnectivityService(@NonNull android.os.Handler);
+    method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onConnectKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
+    method public abstract void onConnectTetherNetwork(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetwork);
+    method public abstract void onDisconnectTetherNetwork();
+    method public abstract void onForgetKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
+    method public final void setKnownNetworks(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.KnownNetwork>);
+    method public final void setSettingsState(@NonNull android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState);
+    method public final void setTetherNetworks(@NonNull java.util.List<android.net.wifi.sharedconnectivity.app.TetherNetwork>);
+    method public final void updateKnownNetworkConnectionStatus(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus);
+    method public final void updateTetherNetworkConnectionStatus(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus);
+  }
+
+}
+
 package android.nfc {
 
   public final class NfcAdapter {
@@ -9936,6 +10269,10 @@
     method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void startBugreport(@NonNull android.os.ParcelFileDescriptor, @Nullable android.os.ParcelFileDescriptor, @NonNull android.os.BugreportParams, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback);
   }
 
+  public abstract static class BugreportManager.BugreportCallback {
+    method public void onFinished(@NonNull String);
+  }
+
   public final class BugreportParams {
     ctor public BugreportParams(int);
     ctor public BugreportParams(int, int);
@@ -10284,6 +10621,7 @@
     method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long);
     method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend();
     method @NonNull public android.os.BatterySaverPolicyConfig getFullPowerSavePolicy();
+    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public android.os.PowerManager.LowPowerStandbyPolicy getLowPowerStandbyPolicy();
     method public int getPowerSaveModeTrigger();
     method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isAmbientDisplayAvailable();
     method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isAmbientDisplaySuppressed();
@@ -10296,9 +10634,11 @@
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setFullPowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public void setLowPowerStandbyActiveDuringMaintenance(boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public void setLowPowerStandbyEnabled(boolean);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public void setLowPowerStandbyPolicy(@Nullable android.os.PowerManager.LowPowerStandbyPolicy);
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void suppressAmbientDisplay(@NonNull String, boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int);
+    field @RequiresPermission(android.Manifest.permission.MANAGE_LOW_POWER_STANDBY) public static final String ACTION_LOW_POWER_STANDBY_POLICY_CHANGED = "android.os.action.LOW_POWER_STANDBY_POLICY_CHANGED";
     field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
     field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
     field public static final String REBOOT_USERSPACE = "userspace";
@@ -10313,6 +10653,14 @@
     field public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1; // 0x1
   }
 
+  public static final class PowerManager.LowPowerStandbyPolicy {
+    ctor public PowerManager.LowPowerStandbyPolicy(@NonNull String, @NonNull java.util.Set<java.lang.String>, int, @NonNull java.util.Set<java.lang.String>);
+    method @NonNull public java.util.Set<java.lang.String> getAllowedFeatures();
+    method public int getAllowedReasons();
+    method @NonNull public java.util.Set<java.lang.String> getExemptPackages();
+    method @NonNull public String getIdentifier();
+  }
+
   @Deprecated public class PowerWhitelistManager {
     method @Deprecated @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToWhitelist(@NonNull String);
     method @Deprecated @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToWhitelist(@NonNull java.util.List<java.lang.String>);
@@ -11541,6 +11889,39 @@
 
 }
 
+package android.service.assist.classification {
+
+  public final class FieldClassification implements android.os.Parcelable {
+    ctor public FieldClassification(@NonNull android.view.autofill.AutofillId, @NonNull java.util.Set<java.lang.String>, @NonNull java.util.Set<java.lang.String>);
+    method @NonNull public java.util.Set<java.lang.String> getGroupHints();
+  }
+
+  public final class FieldClassificationRequest implements android.os.Parcelable {
+    ctor public FieldClassificationRequest(@NonNull android.app.assist.AssistStructure);
+    method public int describeContents();
+    method @NonNull public android.app.assist.AssistStructure getAssistStructure();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.assist.classification.FieldClassificationRequest> CREATOR;
+  }
+
+  public final class FieldClassificationResponse implements android.os.Parcelable {
+    ctor public FieldClassificationResponse(@NonNull java.util.Set<android.service.assist.classification.FieldClassification>);
+    method public int describeContents();
+    method @NonNull public java.util.Set<android.service.assist.classification.FieldClassification> getClassifications();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.service.assist.classification.FieldClassificationResponse> CREATOR;
+  }
+
+  public abstract class FieldClassificationService extends android.app.Service {
+    ctor public FieldClassificationService();
+    method public abstract void onClassificationRequest(@NonNull android.service.assist.classification.FieldClassificationRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.service.assist.classification.FieldClassificationResponse,java.lang.Exception>);
+    method public void onConnected();
+    method public void onDisconnected();
+    field public static final String SERVICE_INTERFACE = "android.service.assist.classification.FieldClassificationService";
+  }
+
+}
+
 package android.service.attention {
 
   public abstract class AttentionService extends android.app.Service {
@@ -12056,6 +12437,7 @@
     field public static final String KEY_NOT_CONVERSATION = "key_not_conversation";
     field public static final String KEY_PEOPLE = "key_people";
     field public static final String KEY_RANKING_SCORE = "key_ranking_score";
+    field public static final String KEY_SENSITIVE_CONTENT = "key_sensitive_content";
     field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
     field public static final String KEY_TEXT_REPLIES = "key_text_replies";
     field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
@@ -12095,6 +12477,7 @@
 
   public static class NotificationListenerService.Ranking {
     method public int getProposedImportance();
+    method public boolean hasSensitiveContent();
   }
 
   public final class NotificationStats implements android.os.Parcelable {
@@ -12184,6 +12567,17 @@
 
 }
 
+package android.service.remotelockscreenvalidation {
+
+  public abstract class RemoteLockscreenValidationService extends android.app.Service {
+    ctor public RemoteLockscreenValidationService();
+    method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onValidateLockscreenGuess(@NonNull byte[], @NonNull android.os.OutcomeReceiver<android.app.RemoteLockscreenValidationResult,java.lang.Exception>);
+    field public static final String SERVICE_INTERFACE = "android.service.remotelockscreenvalidation.RemoteLockscreenValidationService";
+  }
+
+}
+
 package android.service.resolver {
 
   public abstract class ResolverRankerService extends android.app.Service {
@@ -12268,7 +12662,11 @@
     method @MainThread public abstract void onDestroy(@NonNull android.app.search.SearchSessionId);
     method @MainThread public abstract void onNotifyEvent(@NonNull android.app.search.SearchSessionId, @NonNull android.app.search.Query, @NonNull android.app.search.SearchTargetEvent);
     method @MainThread public abstract void onQuery(@NonNull android.app.search.SearchSessionId, @NonNull android.app.search.Query, @NonNull java.util.function.Consumer<java.util.List<android.app.search.SearchTarget>>);
+    method @MainThread public void onRequestEmptyQueryResultUpdate(@NonNull android.app.search.SearchSessionId);
     method public void onSearchSessionCreated(@NonNull android.app.search.SearchContext, @NonNull android.app.search.SearchSessionId);
+    method @MainThread public void onStartUpdateEmptyQueryResult();
+    method @MainThread public void onStopUpdateEmptyQueryResult();
+    method public final void updateEmptyQueryResult(@NonNull android.app.search.SearchSessionId, @NonNull java.util.List<android.app.search.SearchTarget>);
   }
 
 }
@@ -15665,11 +16063,12 @@
   }
 
   public final class MediaQualityStatus implements android.os.Parcelable {
+    ctor public MediaQualityStatus(@NonNull String, int, int, @IntRange(from=0, to=100) int, @IntRange(from=0) int, @IntRange(from=0) long);
     method public int describeContents();
     method @NonNull public String getCallSessionId();
     method public int getMediaSessionType();
-    method public long getRtpInactivityMillis();
-    method public int getRtpJitterMillis();
+    method @IntRange(from=0) public long getRtpInactivityMillis();
+    method @IntRange(from=0) public int getRtpJitterMillis();
     method @IntRange(from=0, to=100) public int getRtpPacketLossRate();
     method public int getTransportType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -15678,14 +16077,6 @@
     field public static final int MEDIA_SESSION_TYPE_VIDEO = 2; // 0x2
   }
 
-  public static final class MediaQualityStatus.Builder {
-    ctor public MediaQualityStatus.Builder(@NonNull String, int, int);
-    method @NonNull public android.telephony.ims.MediaQualityStatus build();
-    method @NonNull public android.telephony.ims.MediaQualityStatus.Builder setRtpInactivityMillis(long);
-    method @NonNull public android.telephony.ims.MediaQualityStatus.Builder setRtpJitterMillis(int);
-    method @NonNull public android.telephony.ims.MediaQualityStatus.Builder setRtpPacketLossRate(@IntRange(from=0, to=100) int);
-  }
-
   public final class MediaThreshold implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public long[] getThresholdsRtpInactivityTimeMillis();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 62a1eb9..1abdbb9 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -144,8 +144,6 @@
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.DUMP) public void waitForBroadcastIdle();
     field public static final long LOCK_DOWN_CLOSE_SYSTEM_DIALOGS = 174664365L; // 0xa692aadL
-    field public static final int PROCESS_CAPABILITY_ALL = 15; // 0xf
-    field public static final int PROCESS_CAPABILITY_ALL_EXPLICIT = 1; // 0x1
     field public static final int PROCESS_CAPABILITY_ALL_IMPLICIT = 6; // 0x6
     field public static final int PROCESS_CAPABILITY_NETWORK = 8; // 0x8
     field public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; // 0x4
@@ -446,7 +444,6 @@
 
   public final class UiAutomation {
     method public void destroy();
-    method @NonNull public android.os.ParcelFileDescriptor[] executeShellCommandRwe(@NonNull String);
     method @NonNull public java.util.Set<java.lang.String> getAdoptedShellPermissions();
     method @Deprecated public boolean grantRuntimePermission(String, String, android.os.UserHandle);
     method public boolean injectInputEvent(@NonNull android.view.InputEvent, boolean, boolean);
@@ -547,6 +544,7 @@
     method public void setDeviceOwnerType(@NonNull android.content.ComponentName, int);
     method @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public void setNextOperationSafety(int, int);
     method @RequiresPermission(anyOf={android.Manifest.permission.MARK_DEVICE_ORGANIZATION_OWNED, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}, conditional=true) public void setProfileOwnerOnOrganizationOwnedDevice(@NonNull android.content.ComponentName, boolean);
+    method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public boolean triggerDevicePolicyEngineMigration(boolean);
     field public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED = "android.app.action.DATA_SHARING_RESTRICTION_APPLIED";
     field public static final String ACTION_DEVICE_POLICY_CONSTANTS_CHANGED = "android.app.action.DEVICE_POLICY_CONSTANTS_CHANGED";
     field public static final int DEVICE_OWNER_TYPE_DEFAULT = 0; // 0x0
@@ -595,10 +593,49 @@
     field @Deprecated public static final int STATUS_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER = 14; // 0xe
   }
 
+  public final class FlagUnion extends android.app.admin.ResolutionMechanism<java.lang.Integer> {
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.FlagUnion> CREATOR;
+  }
+
+  public final class MostRecent<V> extends android.app.admin.ResolutionMechanism<V> {
+    ctor public MostRecent();
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.MostRecent> CREATOR;
+  }
+
+  public final class MostRestrictive<V> extends android.app.admin.ResolutionMechanism<V> {
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.MostRestrictive<?>> CREATOR;
+  }
+
+  public final class PolicyState<V> implements android.os.Parcelable {
+    method @NonNull public android.app.admin.ResolutionMechanism<V> getResolutionMechanism();
+  }
+
+  public abstract class ResolutionMechanism<V> implements android.os.Parcelable {
+  }
+
   public static final class SecurityLog.SecurityEvent implements android.os.Parcelable {
     ctor public SecurityLog.SecurityEvent(long, byte[]);
   }
 
+  public final class StringSetUnion extends android.app.admin.ResolutionMechanism<java.util.Set<java.lang.String>> {
+    ctor public StringSetUnion();
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.StringSetUnion> CREATOR;
+  }
+
+  public final class TopPriority<V> extends android.app.admin.ResolutionMechanism<V> {
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.TopPriority<?>> CREATOR;
+  }
+
   public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
     ctor public UnsafeStateException(int, int);
     method public int getOperation();
@@ -822,7 +859,6 @@
     field public static final float OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE = 1.5f;
     field public static final long OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY = 203647190L; // 0xc2368d6L
     field public static final long OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN = 208648326L; // 0xc6fb886L
-    field public static final long OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS = 237531167L; // 0xe28701fL
     field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2
   }
 
@@ -923,7 +959,7 @@
     method public boolean isQuietModeEnabled();
     method public boolean isRestricted();
     method public boolean supportsSwitchTo();
-    method public boolean supportsSwitchToByUser();
+    method @Deprecated public boolean supportsSwitchToByUser();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.UserInfo> CREATOR;
     field public static final int FLAG_ADMIN = 2; // 0x2
@@ -997,6 +1033,22 @@
 
 package android.credentials.ui {
 
+  public final class AuthenticationEntry implements android.os.Parcelable {
+    ctor public AuthenticationEntry(@NonNull String, @NonNull String, @NonNull android.app.slice.Slice, int);
+    ctor public AuthenticationEntry(@NonNull String, @NonNull String, @NonNull android.app.slice.Slice, int, @NonNull android.content.Intent);
+    method public int describeContents();
+    method @Nullable public android.content.Intent getFrameworkExtrasIntent();
+    method @NonNull public String getKey();
+    method @NonNull public android.app.slice.Slice getSlice();
+    method @NonNull public int getStatus();
+    method @NonNull public String getSubkey();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.credentials.ui.AuthenticationEntry> CREATOR;
+    field public static final int STATUS_LOCKED = 0; // 0x0
+    field public static final int STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT = 1; // 0x1
+    field public static final int STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT = 2; // 0x2
+  }
+
   public final class CreateCredentialProviderData extends android.credentials.ui.ProviderData implements android.os.Parcelable {
     ctor public CreateCredentialProviderData(@NonNull String, @NonNull java.util.List<android.credentials.ui.Entry>, @Nullable android.credentials.ui.Entry);
     method @Nullable public android.credentials.ui.Entry getRemoteEntry();
@@ -1028,15 +1080,12 @@
     method @NonNull public String getSubkey();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.credentials.ui.Entry> CREATOR;
-    field @NonNull public static final String EXTRA_ENTRY_AUTHENTICATION_ACTION = "android.credentials.ui.extra.ENTRY_AUTHENTICATION_ACTION";
-    field @NonNull public static final String EXTRA_ENTRY_LIST_ACTION_CHIP = "android.credentials.ui.extra.ENTRY_LIST_ACTION_CHIP";
-    field @NonNull public static final String EXTRA_ENTRY_LIST_CREDENTIAL = "android.credentials.ui.extra.ENTRY_LIST_CREDENTIAL";
   }
 
   public final class GetCredentialProviderData extends android.credentials.ui.ProviderData implements android.os.Parcelable {
-    ctor public GetCredentialProviderData(@NonNull String, @NonNull java.util.List<android.credentials.ui.Entry>, @NonNull java.util.List<android.credentials.ui.Entry>, @Nullable android.credentials.ui.Entry, @Nullable android.credentials.ui.Entry);
+    ctor public GetCredentialProviderData(@NonNull String, @NonNull java.util.List<android.credentials.ui.Entry>, @NonNull java.util.List<android.credentials.ui.Entry>, @NonNull java.util.List<android.credentials.ui.AuthenticationEntry>, @Nullable android.credentials.ui.Entry);
     method @NonNull public java.util.List<android.credentials.ui.Entry> getActionChips();
-    method @Nullable public android.credentials.ui.Entry getAuthenticationEntry();
+    method @NonNull public java.util.List<android.credentials.ui.AuthenticationEntry> getAuthenticationEntries();
     method @NonNull public java.util.List<android.credentials.ui.Entry> getCredentialEntries();
     method @Nullable public android.credentials.ui.Entry getRemoteEntry();
     field @NonNull public static final android.os.Parcelable.Creator<android.credentials.ui.GetCredentialProviderData> CREATOR;
@@ -1046,7 +1095,7 @@
     ctor public GetCredentialProviderData.Builder(@NonNull String);
     method @NonNull public android.credentials.ui.GetCredentialProviderData build();
     method @NonNull public android.credentials.ui.GetCredentialProviderData.Builder setActionChips(@NonNull java.util.List<android.credentials.ui.Entry>);
-    method @NonNull public android.credentials.ui.GetCredentialProviderData.Builder setAuthenticationEntry(@Nullable android.credentials.ui.Entry);
+    method @NonNull public android.credentials.ui.GetCredentialProviderData.Builder setAuthenticationEntries(@NonNull java.util.List<android.credentials.ui.AuthenticationEntry>);
     method @NonNull public android.credentials.ui.GetCredentialProviderData.Builder setCredentialEntries(@NonNull java.util.List<android.credentials.ui.Entry>);
     method @NonNull public android.credentials.ui.GetCredentialProviderData.Builder setRemoteEntry(@Nullable android.credentials.ui.Entry);
   }
@@ -1363,6 +1412,7 @@
     method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public void setShouldAlwaysRespectAppRequestedMode(boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setUserDisabledHdrTypes(@NonNull int[]);
     method @RequiresPermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS) public boolean shouldAlwaysRespectAppRequestedMode();
+    field public static final String DISPLAY_CATEGORY_REAR = "android.hardware.display.category.REAR";
     field public static final int SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS = 2; // 0x2
     field public static final int SWITCHING_TYPE_NONE = 0; // 0x0
     field public static final int SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY = 3; // 0x3
@@ -1739,6 +1789,7 @@
 
   public final class MediaCas implements java.lang.AutoCloseable {
     method public void forceResourceLost();
+    method public boolean isAidlHal();
   }
 
   public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint {
@@ -1749,6 +1800,10 @@
     method public int getMaxMacroBlocks();
   }
 
+  public final class MediaDescrambler implements java.lang.AutoCloseable {
+    method public boolean isAidlHal();
+  }
+
   public final class MediaRoute2Info implements android.os.Parcelable {
     method @NonNull public String getOriginalId();
   }
@@ -1866,6 +1921,14 @@
 
 }
 
+package android.net.wifi.sharedconnectivity.app {
+
+  public class SharedConnectivityManager {
+    method public void setService(@Nullable android.os.IInterface);
+  }
+
+}
+
 package android.os {
 
   public final class BatteryStatsManager {
@@ -2409,6 +2472,8 @@
     field public static final String DISABLE_WINDOW_BLURS = "disable_window_blurs";
     field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
     field public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled";
+    field public static final String HDR_CONVERSION_MODE = "hdr_conversion_mode";
+    field public static final String HDR_FORCE_CONVERSION_TYPE = "hdr_force_conversion_type";
     field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
     field public static final String HIDDEN_API_POLICY = "hidden_api_policy";
     field public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs";
@@ -2518,6 +2583,7 @@
 
   public final class Dataset implements android.os.Parcelable {
     method @Nullable public android.content.IntentSender getAuthentication();
+    method @Nullable public java.util.ArrayList<java.lang.String> getAutofillDatatypes();
     method @Nullable public android.content.ClipData getFieldContent();
     method @Nullable public java.util.ArrayList<android.view.autofill.AutofillId> getFieldIds();
     method @Nullable public java.util.ArrayList<android.view.autofill.AutofillValue> getFieldValues();
@@ -2538,6 +2604,7 @@
   }
 
   public final class FillResponse implements android.os.Parcelable {
+    method @NonNull public java.util.Set<android.service.assist.classification.FieldClassification> getDetectedFieldClassifications();
     method public int getFlags();
   }
 
@@ -3146,6 +3213,9 @@
 
   public final class SurfaceControl implements android.os.Parcelable {
     ctor public SurfaceControl(@NonNull android.view.SurfaceControl, @NonNull String);
+    method @NonNull public android.view.Choreographer getChoreographer();
+    method @NonNull public android.view.Choreographer getChoreographer(@NonNull android.os.Looper);
+    method public boolean hasChoreographer();
     method public boolean isSameSurface(@NonNull android.view.SurfaceControl);
   }
 
@@ -3155,9 +3225,7 @@
   }
 
   @UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
-    method public void getBoundsOnScreen(@NonNull android.graphics.Rect, boolean);
     method public android.view.View getTooltipView();
-    method public void getWindowDisplayFrame(@NonNull android.graphics.Rect);
     method public boolean isAutofilled();
     method public static boolean isDefaultFocusHighlightEnabled();
     method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
@@ -3265,6 +3333,8 @@
     field public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_ENABLED = "autofill_credential_manager_enabled";
     field public static final String DEVICE_CONFIG_AUTOFILL_CREDENTIAL_MANAGER_IGNORE_VIEWS = "autofill_credential_manager_ignore_views";
     field public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED = "autofill_dialog_enabled";
+    field public static final String DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED = "pcc_classification_enabled";
+    field public static final String DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS = "pcc_classification_hints";
     field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
     field public static final String DEVICE_CONFIG_NON_AUTOFILLABLE_IME_ACTION_IDS = "non_autofillable_ime_action_ids";
     field public static final String DEVICE_CONFIG_PACKAGE_DENYLIST_FOR_UNIMPORTANT_VIEW = "package_deny_list_for_unimportant_view";
@@ -3760,6 +3830,7 @@
     method @NonNull public android.window.WindowContainerTransaction setHidden(@NonNull android.window.WindowContainerToken, boolean);
     method @NonNull public android.window.WindowContainerTransaction setLaunchAdjacentFlagRoot(@NonNull android.window.WindowContainerToken);
     method @NonNull public android.window.WindowContainerTransaction setLaunchRoot(@NonNull android.window.WindowContainerToken, @Nullable int[], @Nullable int[]);
+    method @NonNull public android.window.WindowContainerTransaction setRelativeBounds(@NonNull android.window.WindowContainerToken, @NonNull android.graphics.Rect);
     method @NonNull public android.window.WindowContainerTransaction setScreenSizeDp(@NonNull android.window.WindowContainerToken, int, int);
     method @NonNull public android.window.WindowContainerTransaction setSmallestScreenWidthDp(@NonNull android.window.WindowContainerToken, int);
     method @NonNull public android.window.WindowContainerTransaction setWindowingMode(@NonNull android.window.WindowContainerToken, int);
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index e849cdbc..4a97280 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -855,6 +855,10 @@
     New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_ENABLED:
     New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_ENABLED); use getters/setters in relevant manager class
+NoSettingsProvider: android.provider.Settings.Global#HDR_CONVERSION_MODE:
+    New setting keys are not allowed (Field: HDR_CONVERSION_MODE); use getters/setters in relevant manager class
+NoSettingsProvider: android.provider.Settings.Global#HDR_FORCE_CONVERSION_TYPE:
+    New setting keys are not allowed (Field: HDR_FORCE_CONVERSION_TYPE); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS:
     New setting keys are not allowed (Field: HIDDEN_API_BLACKLIST_EXEMPTIONS); use getters/setters in relevant manager class
 NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_POLICY:
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 48982b1..6422865 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -2560,6 +2560,10 @@
         IAccessibilityServiceConnection connection =
                 AccessibilityInteractionClient.getInstance(this).getConnection(mConnectionId);
         if (mInfo != null && connection != null) {
+            if (!mInfo.isWithinParcelableSize()) {
+                throw new IllegalStateException(
+                        "Cannot update service info: size is larger than safe parcelable limits.");
+            }
             try {
                 connection.setServiceInfo(mInfo);
                 mInfo = null;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index ae57959..6dcf331 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -41,6 +41,7 @@
 import android.graphics.drawable.Drawable;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -48,6 +49,7 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.util.Xml;
+import android.view.InputDevice;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -612,9 +614,29 @@
     private boolean mIsAccessibilityTool = false;
 
     /**
+     * {@link InputDevice} sources which may send {@link android.view.MotionEvent}s.
+     * @see #setMotionEventSources(int)
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "SOURCE_" }, value = {
+            InputDevice.SOURCE_MOUSE,
+            InputDevice.SOURCE_STYLUS,
+            InputDevice.SOURCE_BLUETOOTH_STYLUS,
+            InputDevice.SOURCE_TRACKBALL,
+            InputDevice.SOURCE_MOUSE_RELATIVE,
+            InputDevice.SOURCE_TOUCHPAD,
+            InputDevice.SOURCE_TOUCH_NAVIGATION,
+            InputDevice.SOURCE_ROTARY_ENCODER,
+            InputDevice.SOURCE_JOYSTICK,
+            InputDevice.SOURCE_SENSOR
+    })
+    public @interface MotionEventSources {}
+
+    /**
      * The bit mask of {@link android.view.InputDevice} sources that the accessibility
      * service wants to listen to for generic {@link android.view.MotionEvent}s.
      */
+    @MotionEventSources
     private int mMotionEventSources = 0;
 
     /**
@@ -966,6 +988,7 @@
      * Returns the bit mask of {@link android.view.InputDevice} sources that the accessibility
      * service wants to listen to for generic {@link android.view.MotionEvent}s.
      */
+    @MotionEventSources
     public int getMotionEventSources() {
         return mMotionEventSources;
     }
@@ -975,28 +998,29 @@
      * service wants to listen to for generic {@link android.view.MotionEvent}s.
      *
      * <p>
-     * Note: including an {@link android.view.InputDevice} source that does not send
+     * Including an {@link android.view.InputDevice} source that does not send
      * {@link android.view.MotionEvent}s is effectively a no-op for that source, since you will
      * not receive any events from that source.
      * </p>
+     *
      * <p>
-     * Allowed sources include:
-     * <li>{@link android.view.InputDevice#SOURCE_MOUSE}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_STYLUS}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_BLUETOOTH_STYLUS}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_TRACKBALL}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_MOUSE_RELATIVE}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_TOUCHPAD}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_TOUCH_NAVIGATION}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_ROTARY_ENCODER}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_JOYSTICK}</li>
-     * <li>{@link android.view.InputDevice#SOURCE_SENSOR}</li>
+     * See {@link android.view.InputDevice} for complete source definitions.
+     * Many input devices send {@link android.view.InputEvent}s from more than one type of source so
+     * you may need to include multiple {@link android.view.MotionEvent} sources here, in addition
+     * to using {@link AccessibilityService#onKeyEvent} to listen to {@link android.view.KeyEvent}s.
+     * </p>
+     *
+     * <p>
+     * <strong>Note:</strong> {@link android.view.InputDevice} sources contain source class bits
+     * that complicate bitwise flag removal operations. To remove a specific source you should
+     * rebuild the entire value using bitwise OR operations on the individual source constants.
      * </p>
      *
      * @param motionEventSources A bit mask of {@link android.view.InputDevice} sources.
      * @see AccessibilityService#onMotionEvent
+     * @see MotionEventSources
      */
-    public void setMotionEventSources(int motionEventSources) {
+    public void setMotionEventSources(@MotionEventSources int motionEventSources) {
         mMotionEventSources = motionEventSources;
     }
 
@@ -1202,6 +1226,15 @@
         return 0;
     }
 
+    /** @hide */
+    public final boolean isWithinParcelableSize() {
+        final Parcel parcel = Parcel.obtain();
+        writeToParcel(parcel, 0);
+        final boolean result = parcel.dataSize() <= IBinder.MAX_IPC_SIZE;
+        parcel.recycle();
+        return result;
+    }
+
     public void writeToParcel(Parcel parcel, int flagz) {
         parcel.writeInt(eventTypes);
         parcel.writeStringArray(packageNames);
diff --git a/core/java/android/accessibilityservice/MagnificationConfig.java b/core/java/android/accessibilityservice/MagnificationConfig.java
index 486dc50..5019aee 100644
--- a/core/java/android/accessibilityservice/MagnificationConfig.java
+++ b/core/java/android/accessibilityservice/MagnificationConfig.java
@@ -107,7 +107,7 @@
      * Returns the activated state of the controlling magnifier. The controlling magnifier can be
      * activated even if the scale returned by {@link MagnificationConfig#getScale()} equals to 1.0.
      *
-     * @return {@code true} if the magnifier is showing on screen,
+     * @return {@code true} if the magnifier is activated and showing on screen,
      *         {@code false} otherwise.
      */
     public boolean isActivated() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c4d6ad7..f408916 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -630,6 +630,8 @@
             PROCESS_CAPABILITY_FOREGROUND_LOCATION,
             PROCESS_CAPABILITY_FOREGROUND_CAMERA,
             PROCESS_CAPABILITY_FOREGROUND_MICROPHONE,
+            PROCESS_CAPABILITY_NETWORK,
+            PROCESS_CAPABILITY_BFSL,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProcessCapability {}
@@ -654,20 +656,36 @@
     @TestApi
     public static final int PROCESS_CAPABILITY_NETWORK = 1 << 3;
 
-    /** @hide all capabilities, the ORing of all flags in {@link ProcessCapability}*/
-    @TestApi
+    /**
+     * Flag used to indicate whether an app is allowed to start a foreground service from the
+     * background, decided by the procstates. ("BFSL" == "background foreground service launch")
+     *
+     * - BFSL has a number of exemptions -- e.g. when an app is power-allowlisted, including
+     *   temp-allowlist -- but this capability is *not* used to represent such exemptions.
+     *   This is set only based on the procstate and the foreground service type.
+     * - Basically, procstates <= BFGS (i.e. BFGS, FGS, BTOP, TOP, ...) are BFSL-allowed,
+     *   and that's how things worked on Android S/T.
+     *   However, Android U added a "SHORT_SERVICE" FGS type, which gets the FGS procstate
+     *   *but* can't start another FGS. So now we use this flag to decide whether FGS/BFGS
+     *   procstates are BFSL-allowed. (higher procstates, such as BTOP, will still always be
+     *   BFSL-allowed.)
+     *   We propagate this flag across via service bindings and provider references.
+     *
+     * @hide
+     */
+    public static final int PROCESS_CAPABILITY_BFSL = 1 << 4;
+
+    /**
+     * @hide all capabilities, the ORing of all flags in {@link ProcessCapability}.
+     *
+     * Don't expose it as TestApi -- we may add new capabilities any time, which could
+     * break CTS tests if they relied on it.
+     */
     public static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION
             | PROCESS_CAPABILITY_FOREGROUND_CAMERA
             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
-            | PROCESS_CAPABILITY_NETWORK;
-    /**
-     * All explicit capabilities. These are capabilities that need to be specified from manifest
-     * file.
-     * @hide
-     */
-    @TestApi
-    public static final int PROCESS_CAPABILITY_ALL_EXPLICIT =
-            PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+            | PROCESS_CAPABILITY_NETWORK
+            | PROCESS_CAPABILITY_BFSL;
 
     /**
      * All implicit capabilities. There are capabilities that process automatically have.
@@ -686,6 +704,7 @@
         pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0 ? 'C' : '-');
         pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0 ? 'M' : '-');
         pw.print((caps & PROCESS_CAPABILITY_NETWORK) != 0 ? 'N' : '-');
+        pw.print((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-');
     }
 
     /** @hide */
@@ -694,6 +713,7 @@
         sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0 ? 'C' : '-');
         sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0 ? 'M' : '-');
         sb.append((caps & PROCESS_CAPABILITY_NETWORK) != 0 ? 'N' : '-');
+        sb.append((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-');
     }
 
     /**
@@ -702,13 +722,10 @@
      */
     public static void printCapabilitiesFull(PrintWriter pw, @ProcessCapability int caps) {
         printCapabilitiesSummary(pw, caps);
-        final int remain = caps & ~(PROCESS_CAPABILITY_FOREGROUND_LOCATION
-                | PROCESS_CAPABILITY_FOREGROUND_CAMERA
-                | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
-                | PROCESS_CAPABILITY_NETWORK);
+        final int remain = caps & ~PROCESS_CAPABILITY_ALL;
         if (remain != 0) {
-            pw.print('+');
-            pw.print(remain);
+            pw.print("+0x");
+            pw.print(Integer.toHexString(remain));
         }
     }
 
@@ -4417,7 +4434,8 @@
                     "device does not support users on secondary displays");
         }
         try {
-            return getService().startUserInBackgroundVisibleOnDisplay(userId, displayId);
+            return getService().startUserInBackgroundVisibleOnDisplay(userId, displayId,
+                    /* unlockProgressListener= */ null);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index b57fb20..3b88257 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -343,6 +343,13 @@
             "android:activity.applyActivityFlagsForBubbles";
 
     /**
+     * Indicates to apply {@link Intent#FLAG_ACTIVITY_MULTIPLE_TASK} to the launching shortcut.
+     * @hide
+     */
+    private static final String KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT =
+            "android:activity.applyMultipleTaskFlagForShortcut";
+
+    /**
      * For Activity transitions, the calling Activity's TransitionListener used to
      * notify the called Activity when the shared element and the exit transitions
      * complete.
@@ -397,8 +404,8 @@
     /** See {@link #setDismissKeyguard()}. */
     private static final String KEY_DISMISS_KEYGUARD = "android.activity.dismissKeyguard";
 
-    private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE =
-            "android.activity.ignorePendingIntentCreatorForegroundState";
+    private static final String KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE =
+            "android.activity.pendingIntentCreatorBackgroundActivityStartMode";
 
     /**
      * @see #setLaunchCookie
@@ -476,6 +483,7 @@
     private boolean mShareIdentity = false;
     private boolean mDisallowEnterPictureInPictureWhileLaunching;
     private boolean mApplyActivityFlagsForBubbles;
+    private boolean mApplyMultipleTaskFlagForShortcut;
     private boolean mTaskAlwaysOnTop;
     private boolean mTaskOverlay;
     private boolean mTaskOverlayCanResume;
@@ -499,7 +507,9 @@
     private boolean mTransientLaunch;
     private PictureInPictureParams mLaunchIntoPipParams;
     private boolean mDismissKeyguard;
-    private boolean mIgnorePendingIntentCreatorForegroundState;
+    @BackgroundActivityStartMode
+    private int mPendingIntentCreatorBackgroundActivityStartMode =
+            MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
     private boolean mDisableStartingWindow;
 
     /**
@@ -1276,6 +1286,8 @@
                 KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING, false);
         mApplyActivityFlagsForBubbles = opts.getBoolean(
                 KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, false);
+        mApplyMultipleTaskFlagForShortcut = opts.getBoolean(
+                KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT, false);
         if (opts.containsKey(KEY_ANIM_SPECS)) {
             Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
             mAnimSpecs = new AppTransitionAnimationSpec[specs.length];
@@ -1307,8 +1319,9 @@
         mIsEligibleForLegacyPermissionPrompt =
                 opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
         mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD);
-        mIgnorePendingIntentCreatorForegroundState = opts.getBoolean(
-                KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE);
+        mPendingIntentCreatorBackgroundActivityStartMode = opts.getInt(
+                KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE,
+                MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
         mDisableStartingWindow = opts.getBoolean(KEY_DISABLE_STARTING_WINDOW);
     }
 
@@ -1903,6 +1916,16 @@
         return mApplyActivityFlagsForBubbles;
     }
 
+    /** @hide */
+    public void setApplyMultipleTaskFlagForShortcut(boolean apply) {
+        mApplyMultipleTaskFlagForShortcut = apply;
+    }
+
+    /** @hide */
+    public boolean isApplyMultipleTaskFlagForShortcut() {
+        return mApplyMultipleTaskFlagForShortcut;
+    }
+
     /**
      * Sets a launch cookie that can be used to track the activity and task that are launch as a
      * result of this option. If the launched activity is a trampoline that starts another activity
@@ -2009,19 +2032,38 @@
      * Sets background activity launch logic won't use pending intent creator foreground state.
      *
      * @hide
+     * @deprecated use {@link #setPendingIntentCreatorBackgroundActivityStartMode(int)} instead
      */
-    public ActivityOptions setIgnorePendingIntentCreatorForegroundState(boolean state) {
-        mIgnorePendingIntentCreatorForegroundState = state;
+    @Deprecated
+    public ActivityOptions setIgnorePendingIntentCreatorForegroundState(boolean ignore) {
+        mPendingIntentCreatorBackgroundActivityStartMode = ignore
+                ? MODE_BACKGROUND_ACTIVITY_START_DENIED : MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
         return this;
     }
 
     /**
-     * @return whether background activity launch logic should use pending intent creator
-     * foreground state.
-     * @hide
+     * Allow a {@link PendingIntent} to use the privilege of its creator to start background
+     * activities.
+     *
+     * @param mode the {@link android.app.ComponentOptions.BackgroundActivityStartMode} being set
+     * @throws IllegalArgumentException is the value is not a valid
+     * {@link android.app.ComponentOptions.BackgroundActivityStartMode}
      */
-    public boolean getIgnorePendingIntentCreatorForegroundState() {
-        return mIgnorePendingIntentCreatorForegroundState;
+    @NonNull
+    public ActivityOptions setPendingIntentCreatorBackgroundActivityStartMode(
+            @BackgroundActivityStartMode int mode) {
+        mPendingIntentCreatorBackgroundActivityStartMode = mode;
+        return this;
+    }
+
+    /**
+     * Returns the mode to start background activities granted by the creator of the
+     * {@link PendingIntent}.
+     *
+     * @return the {@link android.app.ComponentOptions.BackgroundActivityStartMode} currently set
+     */
+    public @BackgroundActivityStartMode int getPendingIntentCreatorBackgroundActivityStartMode() {
+        return mPendingIntentCreatorBackgroundActivityStartMode;
     }
 
     /**
@@ -2240,6 +2282,10 @@
         if (mApplyActivityFlagsForBubbles) {
             b.putBoolean(KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, mApplyActivityFlagsForBubbles);
         }
+        if (mApplyMultipleTaskFlagForShortcut) {
+            b.putBoolean(KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT,
+                    mApplyMultipleTaskFlagForShortcut);
+        }
         if (mAnimSpecs != null) {
             b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
         }
@@ -2295,9 +2341,10 @@
         if (mDismissKeyguard) {
             b.putBoolean(KEY_DISMISS_KEYGUARD, mDismissKeyguard);
         }
-        if (mIgnorePendingIntentCreatorForegroundState) {
-            b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE,
-                    mIgnorePendingIntentCreatorForegroundState);
+        if (mPendingIntentCreatorBackgroundActivityStartMode
+                != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
+            b.putInt(KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE,
+                    mPendingIntentCreatorBackgroundActivityStartMode);
         }
         if (mDisableStartingWindow) {
             b.putBoolean(KEY_DISABLE_STARTING_WINDOW, mDisableStartingWindow);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 170c0b4..f78f452 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -109,6 +109,8 @@
 import android.net.Proxy;
 import android.net.TrafficStats;
 import android.net.Uri;
+import android.nfc.NfcFrameworkInitializer;
+import android.nfc.NfcServiceManager;
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.BluetoothServiceManager;
@@ -505,6 +507,7 @@
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     static volatile Handler sMainThreadHandler;  // set once in main()
+    private long mStartSeq; // Only accesssed from the main thread
 
     Bundle mCoreSettings = null;
 
@@ -785,10 +788,10 @@
     static final class ReceiverData extends BroadcastReceiver.PendingResult {
         public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                 boolean ordered, boolean sticky, boolean assumeDelivered, IBinder token,
-                int sendingUser, int sentFromUid, String sentFromPackage) {
+                int sendingUser, int sendingUid, String sendingPackage) {
             super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
-                    assumeDelivered, token, sendingUser, intent.getFlags(), sentFromUid,
-                    sentFromPackage);
+                    assumeDelivered, token, sendingUser, intent.getFlags(), sendingUid,
+                    sendingPackage);
             this.intent = intent;
         }
 
@@ -925,6 +928,7 @@
         int samplingInterval;
         boolean autoStopProfiler;
         boolean streamingOutput;
+        int mClockType;
         boolean profiling;
         boolean handlingProfiling;
         public void setProfiler(ProfilerInfo profilerInfo) {
@@ -951,6 +955,7 @@
             samplingInterval = profilerInfo.samplingInterval;
             autoStopProfiler = profilerInfo.autoStopProfiler;
             streamingOutput = profilerInfo.streamingOutput;
+            mClockType = profilerInfo.clockType;
         }
         public void startProfiling() {
             if (profileFd == null || profiling) {
@@ -959,8 +964,8 @@
             try {
                 int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8);
                 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
-                        bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval,
-                        streamingOutput);
+                        bufferSize * 1024 * 1024, mClockType, samplingInterval != 0,
+                        samplingInterval, streamingOutput);
                 profiling = true;
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Profiling failed on path " + profileFile, e);
@@ -1044,11 +1049,11 @@
         public final void scheduleReceiver(Intent intent, ActivityInfo info,
                 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
                 boolean ordered, boolean assumeDelivered, int sendingUser, int processState,
-                int sentFromUid, String sentFromPackage) {
+                int sendingUid, String sendingPackage) {
             updateProcessState(processState, false);
             ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
                     ordered, false, assumeDelivered, mAppThread.asBinder(), sendingUser,
-                    sentFromUid, sentFromPackage);
+                    sendingUid, sendingPackage);
             r.info = info;
             sendMessage(H.RECEIVER, r);
         }
@@ -1060,12 +1065,12 @@
                     scheduleRegisteredReceiver(r.receiver, r.intent,
                             r.resultCode, r.data, r.extras, r.ordered, r.sticky,
                             r.assumeDelivered, r.sendingUser, r.processState,
-                            r.sentFromUid, r.sentFromPackage);
+                            r.sendingUid, r.sendingPackage);
                 } else {
                     scheduleReceiver(r.intent, r.activityInfo, r.compatInfo,
                             r.resultCode, r.data, r.extras, r.sync,
                             r.assumeDelivered, r.sendingUser, r.processState,
-                            r.sentFromUid, r.sentFromPackage);
+                            r.sendingUid, r.sendingPackage);
                 }
             }
         }
@@ -1296,7 +1301,7 @@
         public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
                 int resultCode, String dataStr, Bundle extras, boolean ordered,
                 boolean sticky, boolean assumeDelivered, int sendingUser, int processState,
-                int sentFromUid, String sentFromPackage)
+                int sendingUid, String sendingPackage)
                 throws RemoteException {
             updateProcessState(processState, false);
 
@@ -1307,16 +1312,16 @@
             if (receiver instanceof LoadedApk.ReceiverDispatcher.InnerReceiver) {
                 ((LoadedApk.ReceiverDispatcher.InnerReceiver) receiver).performReceive(intent,
                         resultCode, dataStr, extras, ordered, sticky, assumeDelivered, sendingUser,
-                        sentFromUid, sentFromPackage);
+                        sendingUid, sendingPackage);
             } else {
                 if (!assumeDelivered) {
                     Log.wtf(TAG, "scheduleRegisteredReceiver() called for " + receiver
                             + " and " + intent + " without mechanism to finish delivery");
                 }
-                if (sentFromUid != Process.INVALID_UID || sentFromPackage != null) {
+                if (sendingUid != Process.INVALID_UID || sendingPackage != null) {
                     Log.wtf(TAG,
                             "scheduleRegisteredReceiver() called for " + receiver + " and " + intent
-                                    + " from " + sentFromPackage + " (UID: " + sentFromUid
+                                    + " from " + sendingPackage + " (UID: " + sendingUid
                                     + ") without mechanism to propagate the sender's identity");
                 }
                 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky,
@@ -6685,6 +6690,7 @@
             mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
             mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
             mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
+            mProfiler.mClockType = data.initProfilerInfo.clockType;
             if (data.initProfilerInfo.attachAgentDuringBind) {
                 agent = data.initProfilerInfo.agent;
             }
@@ -6987,6 +6993,12 @@
                 throw e.rethrowFromSystemServer();
             }
         }
+
+        try {
+            mgr.finishAttachApplication(mStartSeq);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
     }
 
     @UnsupportedAppUsage
@@ -7791,6 +7803,8 @@
         sCurrentActivityThread = this;
         mConfigurationController = new ConfigurationController(this);
         mSystemThread = system;
+        mStartSeq = startSeq;
+
         if (!system) {
             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                     UserHandle.myUserId());
@@ -8126,6 +8140,7 @@
         BluetoothFrameworkInitializer.setBluetoothServiceManager(new BluetoothServiceManager());
         BluetoothFrameworkInitializer.setBinderCallsStatsInitializer(context -> {
             BinderCallsStats.startForBluetooth(context); });
+        NfcFrameworkInitializer.setNfcServiceManager(new NfcServiceManager());
     }
 
     private void purgePendingResources() {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 73f34eb..8263a4e3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1355,11 +1355,12 @@
             AppProtoEnums.APP_OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
 
     /**
-     * App can schedule long running jobs.
+     * App can schedule user-initiated jobs.
      *
      * @hide
      */
-    public static final int OP_RUN_LONG_JOBS = AppProtoEnums.APP_OP_RUN_LONG_JOBS;
+    public static final int OP_RUN_USER_INITIATED_JOBS =
+            AppProtoEnums.APP_OP_RUN_USER_INITIATED_JOBS;
 
     /**
      * Notify apps that they have been granted URI permission photos
@@ -1432,14 +1433,14 @@
                     .APP_OP_SYSTEM_EXEMPT_FROM_FGS_BG_START_WHILE_IN_USE_PERMISSION_RESTRICTION;
 
     /**
-     * Hide foreground service stop button in quick settings.
+     * Allows an application to start an activity while running in the background.
      *
      * Only to be used by the system.
      *
      * @hide
      */
-    public static final int OP_SYSTEM_EXEMPT_FROM_FGS_STOP_BUTTON =
-            AppProtoEnums.APP_OP_SYSTEM_EXEMPT_FROM_FGS_STOP_BUTTON;
+    public static final int OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION =
+            AppProtoEnums.APP_OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION;
 
     /**
      * Allows an application to capture bugreport directly without consent dialog when using the
@@ -1965,11 +1966,11 @@
             "android:receive_explicit_user_interaction_audio";
 
     /**
-     * App can schedule long running jobs.
+     * App can schedule user-initiated jobs.
      *
      * @hide
      */
-    public static final String OPSTR_RUN_LONG_JOBS = "android:run_long_jobs";
+    public static final String OPSTR_RUN_USER_INITIATED_JOBS = "android:run_user_initiated_jobs";
 
     /**
      * Prevent an app from being placed into app standby buckets.
@@ -2027,14 +2028,14 @@
             "android:system_exempt_from_fgs_bg_start_while_in_use_permission_restriction";
 
     /**
-     * Hide foreground service stop button in quick settings.
+     * Allows an application to start an activity while running in the background.
      *
      * Only to be used by the system.
      *
      * @hide
      */
-    public static final String OPSTR_SYSTEM_EXEMPT_FROM_FGS_STOP_BUTTON =
-            "android:system_exempt_from_fgs_stop_button";
+    public static final String OPSTR_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION =
+            "android:system_exempt_from_activity_bg_start_restriction";
 
     /**
      * Allows an application to capture bugreport directly without consent dialog when using the
@@ -2151,7 +2152,7 @@
             OP_SCHEDULE_EXACT_ALARM,
             OP_MANAGE_MEDIA,
             OP_TURN_SCREEN_ON,
-            OP_RUN_LONG_JOBS,
+            OP_RUN_USER_INITIATED_JOBS,
             OP_READ_MEDIA_VISUAL_USER_SELECTED,
             OP_FOREGROUND_SERVICE_SPECIAL_USE,
             OP_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
@@ -2537,8 +2538,9 @@
                 OPSTR_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
                 "RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO").setDefaultMode(
                 AppOpsManager.MODE_ALLOWED).build(),
-        new AppOpInfo.Builder(OP_RUN_LONG_JOBS, OPSTR_RUN_LONG_JOBS, "RUN_LONG_JOBS")
-                .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
+        new AppOpInfo.Builder(OP_RUN_USER_INITIATED_JOBS, OPSTR_RUN_USER_INITIATED_JOBS,
+                "RUN_USER_INITIATED_JOBS").setDefaultMode(AppOpsManager.MODE_ALLOWED)
+                .build(),
             new AppOpInfo.Builder(OP_READ_MEDIA_VISUAL_USER_SELECTED,
                     OPSTR_READ_MEDIA_VISUAL_USER_SELECTED, "READ_MEDIA_VISUAL_USER_SELECTED")
                     .setPermission(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)
@@ -2562,9 +2564,9 @@
                 OPSTR_SYSTEM_EXEMPT_FROM_FGS_BG_START_WHILE_IN_USE_PERMISSION_RESTRICTION,
                 "SYSTEM_EXEMPT_FROM_FGS_BG_START_WHILE_IN_USE_PERMISSION_RESTRICTION")
                 .build(),
-        new AppOpInfo.Builder(OP_SYSTEM_EXEMPT_FROM_FGS_STOP_BUTTON,
-                OPSTR_SYSTEM_EXEMPT_FROM_FGS_STOP_BUTTON,
-                "SYSTEM_EXEMPT_FROM_FGS_STOP_BUTTON").build(),
+        new AppOpInfo.Builder(OP_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION,
+                OPSTR_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION,
+                "SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION").build(),
         new AppOpInfo.Builder(
                 OP_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
                 OPSTR_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index 51ea04f..e93ce6b 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -133,6 +133,10 @@
      * Application process was killed because of the user request, for example,
      * user clicked the "Force stop" button of the application in the Settings,
      * or removed the application away from Recents.
+     * <p>
+     * Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, one of the uses of this
+     * reason was to indicate that an app was killed due to it being updated or any of its component
+     * states have changed without {@link android.content.pm.PackageManager#DONT_KILL_APP}
      */
     public static final int REASON_USER_REQUESTED = 10;
 
@@ -162,6 +166,23 @@
     public static final int REASON_FREEZER = 14;
 
     /**
+     * Application process was killed because the app was disabled, or any of its
+     * component states have changed without {@link android.content.pm.PackageManager#DONT_KILL_APP}
+     * <p>
+     * Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * {@link #REASON_USER_REQUESTED} was used to indicate that an app was updated.
+     */
+    public static final int REASON_PACKAGE_STATE_CHANGE = 15;
+
+    /**
+     * Application process was killed because it was updated.
+     * <p>
+     * Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * {@link #REASON_USER_REQUESTED} was used to indicate that an app was updated.
+     */
+    public static final int REASON_PACKAGE_UPDATED = 16;
+
+    /**
      * Application process kills subreason is unknown.
      *
      * For internal use only.
@@ -403,6 +424,11 @@
      * {@link #REASON_USER_REQUESTED}.
      *
      * For internal use only.
+     *
+     * @deprecated starting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * an app being killed due to a package update will have the reason
+     * {@link #REASON_PACKAGE_UPDATED}
+     *
      * @hide
      */
     public static final int SUBREASON_PACKAGE_UPDATE = 25;
@@ -566,6 +592,8 @@
         REASON_DEPENDENCY_DIED,
         REASON_OTHER,
         REASON_FREEZER,
+        REASON_PACKAGE_STATE_CHANGE,
+        REASON_PACKAGE_UPDATED,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Reason {}
@@ -1246,6 +1274,10 @@
                 return "OTHER KILLS BY SYSTEM";
             case REASON_FREEZER:
                 return "FREEZER";
+            case REASON_PACKAGE_STATE_CHANGE:
+                return "STATE CHANGE";
+            case REASON_PACKAGE_UPDATED:
+                return "PACKAGE UPDATED";
             default:
                 return "UNKNOWN";
         }
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index f6992c9..d3b03c0 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -774,7 +774,15 @@
         return this;
     }
 
-    /** @hide */
+    /**
+     * Returns if this broadcast should not run until the process is in an active process state.
+     *
+     * @return {@code true} if this broadcast should not run until the process is in an active
+     *                      process state. Otherwise, {@code false}.
+     * @see #setDeferUntilActive(boolean)
+     *
+     * @hide
+     */
     @SystemApi
     public boolean isDeferUntilActive() {
         return mIsDeferUntilActive;
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index 20d19c1..a7824a8 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -107,9 +107,8 @@
      *
      * @hide
      */
-    // TODO (b/254661666): Change to @EnabledAfter(T)
     @ChangeId
-    @Disabled
+    @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
     @Overridable
     public static final long FGS_TYPE_NONE_DISABLED_CHANGE_ID = 255038118L;
 
@@ -142,9 +141,8 @@
      *
      * @hide
      */
-    // TODO (b/254661666): Change to @EnabledAfter(T)
     @ChangeId
-    @Disabled
+    @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
     @Overridable
     public static final long FGS_TYPE_PERMISSION_CHANGE_ID = 254662522L;
 
@@ -286,10 +284,7 @@
             new ForegroundServiceTypePermissions(new ForegroundServiceTypePermission[] {
                 new RegularPermission(Manifest.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION)
             }, true),
-            new ForegroundServiceTypePermissions(new ForegroundServiceTypePermission[] {
-                new RegularPermission(Manifest.permission.CAPTURE_VIDEO_OUTPUT),
-                new AppOpPermission(AppOpsManager.OP_PROJECT_MEDIA)
-            }, false)
+            null
     );
 
     /**
@@ -388,7 +383,6 @@
                 new RegularPermission(Manifest.permission.SCHEDULE_EXACT_ALARM),
                 new RegularPermission(Manifest.permission.USE_EXACT_ALARM),
                 new AppOpPermission(AppOpsManager.OP_ACTIVATE_VPN),
-                new AppOpPermission(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN),
             }, false)
     );
 
@@ -1059,7 +1053,7 @@
             if (policy.isTypeDisabled(callerUid)) {
                 return FGS_TYPE_POLICY_CHECK_DISABLED;
             }
-            int permissionResult = PERMISSION_DENIED;
+            int permissionResult = PERMISSION_GRANTED;
             // Do we have the permission to start FGS with this type.
             if (policy.mAllOfPermissions != null) {
                 permissionResult = policy.mAllOfPermissions.checkPermissions(context,
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 058c389..c5c3d30 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -147,6 +147,7 @@
     oneway void finishReceiver(in IBinder who, int resultCode, in String resultData, in Bundle map,
             boolean abortBroadcast, int flags);
     void attachApplication(in IApplicationThread app, long startSeq);
+    void finishAttachApplication(long startSeq);
     List<ActivityManager.RunningTaskInfo> getTasks(int maxNum);
     @UnsupportedAppUsage
     void moveTaskToFront(in IApplicationThread caller, in String callingPackage, int task,
@@ -310,7 +311,8 @@
     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
             boolean requireFull, in String name, in String callerPackage);
     void addPackageDependency(in String packageName);
-    void killApplication(in String pkg, int appId, int userId, in String reason);
+    void killApplication(in String pkg, int appId, int userId, in String reason,
+            int exitInfoReason);
     @UnsupportedAppUsage
     void closeSystemDialogs(in String reason);
     @UnsupportedAppUsage
@@ -719,8 +721,8 @@
 
     /**
      * Control the app freezer state. Returns true in case of success, false if the operation
-     * didn't succeed (for example, when the app freezer isn't supported). 
-     * Handling the freezer state via this method is reentrant, that is it can be 
+     * didn't succeed (for example, when the app freezer isn't supported).
+     * Handling the freezer state via this method is reentrant, that is it can be
      * disabled and re-enabled multiple times in parallel. As long as there's a 1:1 disable to
      * enable match, the freezer is re-enabled at last enable only.
      * @param enable set it to true to enable the app freezer, false to disable it.
@@ -803,7 +805,7 @@
      */
     @JavaPassthrough(annotation=
             "@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}, conditional = true)")
-    boolean startUserInBackgroundVisibleOnDisplay(int userid, int displayId);
+    boolean startUserInBackgroundVisibleOnDisplay(int userid, int displayId, IProgressListener unlockProgressListener);
 
     /**
      * Similar to {@link #startProfile(int userId)}, but with a listener to report user unlock
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 70d8a5e..bb91ecd 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -2324,10 +2324,13 @@
                 mUiAutomation.connect(flags);
                 return mUiAutomation;
             }
+            final long startUptime = SystemClock.uptimeMillis();
             try {
                 mUiAutomation.connectWithTimeout(flags, CONNECT_TIMEOUT_MILLIS);
                 return mUiAutomation;
             } catch (TimeoutException e) {
+                final long waited = SystemClock.uptimeMillis() - startUptime;
+                Log.e(TAG, "Unable to connect to UiAutomation. Waited for " + waited + " ms", e);
                 mUiAutomation.destroy();
                 mUiAutomation = null;
             }
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 88c5064..be0d1c9 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -31,6 +31,7 @@
 import android.app.admin.PasswordMetrics;
 import android.app.trust.ITrustManager;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -109,6 +110,13 @@
             "android.app.action.CONFIRM_FRP_CREDENTIAL";
 
     /**
+     * Intent used to prompt user to to validate the credentials of a remote device.
+     * @hide
+     */
+    public static final String ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL =
+            "android.app.action.CONFIRM_REMOTE_DEVICE_CREDENTIAL";
+
+    /**
      * A CharSequence dialog title to show to the user when used with a
      * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
      * @hide
@@ -131,9 +139,26 @@
             "android.app.extra.ALTERNATE_BUTTON_LABEL";
 
     /**
+     * A CharSequence label for the checkbox when used with
+     * {@link #ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL}
+     * @hide
+     */
+    public static final String EXTRA_CHECKBOX_LABEL = "android.app.extra.CHECKBOX_LABEL";
+
+    /**
+     * A {@link StartLockscreenValidationRequest} extra to be sent along with
+     * {@link #ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL} containing the data needed to prompt for
+     * a remote device's lock screen.
+     * @hide
+     */
+    public static final String EXTRA_START_LOCKSCREEN_VALIDATION_REQUEST =
+            "android.app.extra.START_LOCKSCREEN_VALIDATION_REQUEST";
+
+    /**
      * Result code returned by the activity started by
-     * {@link #createConfirmFactoryResetCredentialIntent} indicating that the user clicked the
-     * alternate button.
+     * {@link #createConfirmFactoryResetCredentialIntent} or
+     * {@link #createConfirmDeviceCredentialForRemoteValidationIntent}
+     * indicating that the user clicked the alternate button.
      *
      * @hide
      */
@@ -332,6 +357,47 @@
     }
 
     /**
+     * Get an Intent to launch an activity to prompt the user to confirm the
+     * credentials (pin, pattern or password) of a remote device.
+     * @param startLockscreenValidationRequest contains information necessary to start remote device
+     *                                         credential validation.
+     * @param remoteLockscreenValidationServiceComponent
+     *          the {@link ComponentName} of the implementation of
+     *          {@link android.service.remotelockscreenvalidation.RemoteLockscreenValidationService}
+     * @param checkboxLabel if not empty, a checkbox is provided with the given label. When checked,
+     *                      the validated remote device credential will be set as the device lock of
+     *                      the current device.
+     * @param alternateButtonLabel if not empty, a button is provided with the given label. Upon
+     *                             clicking this button, the activity returns
+     *                             {@link #RESULT_ALTERNATE}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
+    @NonNull
+    public Intent createConfirmDeviceCredentialForRemoteValidationIntent(
+            @NonNull StartLockscreenValidationRequest startLockscreenValidationRequest,
+            @NonNull ComponentName remoteLockscreenValidationServiceComponent,
+            @Nullable CharSequence title,
+            @Nullable CharSequence description,
+            @Nullable CharSequence checkboxLabel,
+            @Nullable CharSequence alternateButtonLabel) {
+        Intent intent = new Intent(ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL)
+                .putExtra(
+                        EXTRA_START_LOCKSCREEN_VALIDATION_REQUEST, startLockscreenValidationRequest)
+                .putExtra(Intent.EXTRA_COMPONENT_NAME, remoteLockscreenValidationServiceComponent)
+                .putExtra(EXTRA_TITLE, title)
+                .putExtra(EXTRA_DESCRIPTION, description)
+                .putExtra(EXTRA_CHECKBOX_LABEL, checkboxLabel)
+                .putExtra(EXTRA_ALTERNATE_BUTTON_LABEL, alternateButtonLabel);
+
+        // explicitly set the package for security
+        intent.setPackage(getSettingsPackageForIntent(intent));
+
+        return intent;
+    }
+
+    /**
      * Controls whether notifications can be shown atop a securely locked screen in their full
      * private form (same as when the device is unlocked).
      *
@@ -1075,6 +1141,46 @@
         return response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK;
     }
 
+    /** Starts a session to verify lockscreen credentials provided by a remote device.
+     *
+     * The session and corresponding public key will be removed when
+     * {@code validateRemoteLockScreen} provides a correct guess or after 10 minutes of inactivity.
+     *
+     * @return information necessary to perform remote lock screen credentials check, including
+
+     * short lived public key used to send encrypted guess and lock screen type.
+     *
+     * @throws IllegalStateException if lock screen is not set
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
+    @NonNull
+    public StartLockscreenValidationRequest startRemoteLockscreenValidation() {
+        return mLockPatternUtils.startRemoteLockscreenValidation();
+    }
+
+    /**
+     * Verifies credentials guess from a remote device.
+     *
+     * <p>Secret must be encrypted using {@code SecureBox} library
+     * with public key from {@code StartLockscreenValidationRequest}
+     * and header set to {@code "encrypted_remote_credentials"} in UTF-8 encoding.
+     *
+     * @throws IllegalStateException if there is no active lock screen validation session or
+     * there was a decryption error.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
+    @NonNull
+    public RemoteLockscreenValidationResult validateRemoteLockscreen(
+            @NonNull byte[] encryptedCredential) {
+        return mLockPatternUtils.validateRemoteLockscreen(encryptedCredential);
+    }
+
     private LockscreenCredential createLockscreenCredential(
             @LockTypes int lockType, @Nullable byte[] password) {
         if (password == null) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index c13da0b..dd6b8b5 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1683,13 +1683,13 @@
                 performReceive(intent, resultCode, data, extras, ordered, sticky,
                         BroadcastReceiver.PendingResult.guessAssumeDelivered(
                                 BroadcastReceiver.PendingResult.TYPE_REGISTERED, ordered),
-                        sendingUser, /*sentFromUid=*/ Process.INVALID_UID,
-                        /*sentFromPackage=*/ null);
+                        sendingUser, /*sendingUid=*/ Process.INVALID_UID,
+                        /*sendingPackage=*/ null);
             }
 
             public void performReceive(Intent intent, int resultCode, String data,
                     Bundle extras, boolean ordered, boolean sticky, boolean assumeDelivered,
-                    int sendingUser, int sentFromUid, String sentFromPackage) {
+                    int sendingUser, int sendingUid, String sendingPackage) {
                 final LoadedApk.ReceiverDispatcher rd;
                 if (intent == null) {
                     Log.wtf(TAG, "Null intent received");
@@ -1705,7 +1705,7 @@
                 if (rd != null) {
                     rd.performReceive(intent, resultCode, data, extras,
                             ordered, sticky, assumeDelivered, sendingUser,
-                            sentFromUid, sentFromPackage);
+                            sendingUid, sendingPackage);
                 } else if (!assumeDelivered) {
                     // The activity manager dispatched a broadcast to a registered
                     // receiver in this process, but before it could be delivered the
@@ -1746,11 +1746,11 @@
 
             public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                     boolean ordered, boolean sticky, boolean assumeDelivered, int sendingUser,
-                    int sentFromUid, String sentFromPackage) {
+                    int sendingUid, String sendingPackage) {
                 super(resultCode, resultData, resultExtras,
                         mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
                         sticky, assumeDelivered, mAppThread.asBinder(), sendingUser,
-                        intent.getFlags(), sentFromUid, sentFromPackage);
+                        intent.getFlags(), sendingUid, sendingPackage);
                 mCurIntent = intent;
             }
 
@@ -1874,9 +1874,9 @@
 
         public void performReceive(Intent intent, int resultCode, String data,
                 Bundle extras, boolean ordered, boolean sticky, boolean assumeDelivered,
-                int sendingUser, int sentFromUid, String sentFromPackage) {
+                int sendingUser, int sendingUid, String sendingPackage) {
             final Args args = new Args(intent, resultCode, data, extras, ordered,
-                    sticky, assumeDelivered, sendingUser, sentFromUid, sentFromPackage);
+                    sticky, assumeDelivered, sendingUser, sendingUid, sendingPackage);
             if (intent == null) {
                 Log.wtf(TAG, "Null intent received");
             } else {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1345910..9974e29 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -703,6 +703,16 @@
      */
     public static final int FLAG_BUBBLE = 0x00001000;
 
+    /**
+     * Bit to be bitswised-ored into the {@link #flags} field that should be
+     * set by the system if this notification is not dismissible.
+     *
+     * This flag is for internal use only; applications cannot set this flag directly.
+     * @hide
+     */
+    public static final int FLAG_NO_DISMISS = 0x00002000;
+
+
     private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList(
             BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
             DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
@@ -6191,10 +6201,8 @@
         private RemoteViews generateActionButton(Action action, boolean emphasizedMode,
                 StandardTemplateParams p) {
             final boolean tombstone = (action.actionIntent == null);
-            RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(),
-                    emphasizedMode ? getEmphasizedActionLayoutResource()
-                            : tombstone ? getActionTombstoneLayoutResource()
-                                    : getActionLayoutResource());
+            final RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(),
+                    getActionButtonLayoutResource(emphasizedMode, tombstone));
             if (!tombstone) {
                 button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
             }
@@ -6206,6 +6214,12 @@
                 // change the background bgColor
                 CharSequence title = action.title;
                 int buttonFillColor = getColors(p).getSecondaryAccentColor();
+                if (tombstone) {
+                    buttonFillColor = setAlphaComponentByFloatDimen(mContext,
+                            ContrastColorUtil.resolveSecondaryColor(
+                                    mContext, getColors(p).getBackgroundColor(), mInNightMode),
+                            R.dimen.notification_action_disabled_container_alpha);
+                }
                 if (isLegacy()) {
                     title = ContrastColorUtil.clearColorSpans(title);
                 } else {
@@ -6221,8 +6235,14 @@
                     title = ensureColorSpanContrast(title, buttonFillColor);
                 }
                 button.setTextViewText(R.id.action0, processTextSpans(title));
-                final int textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
+                int textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
                         buttonFillColor, mInNightMode);
+                if (tombstone) {
+                    textColor = setAlphaComponentByFloatDimen(mContext,
+                            ContrastColorUtil.resolveSecondaryColor(
+                                    mContext, getColors(p).getBackgroundColor(), mInNightMode),
+                            R.dimen.notification_action_disabled_content_alpha);
+                }
                 button.setTextColor(R.id.action0, textColor);
                 // We only want about 20% alpha for the ripple
                 final int rippleColor = (textColor & 0x00ffffff) | 0x33000000;
@@ -6252,6 +6272,26 @@
             return button;
         }
 
+        private int getActionButtonLayoutResource(boolean emphasizedMode, boolean tombstone) {
+            if (emphasizedMode) {
+                return tombstone ? getEmphasizedTombstoneActionLayoutResource()
+                        : getEmphasizedActionLayoutResource();
+            } else {
+                return tombstone ? getActionTombstoneLayoutResource()
+                        : getActionLayoutResource();
+            }
+        }
+
+        /**
+         * Set the alpha component of {@code color} to be {@code alphaDimenResId}.
+         */
+        private static int setAlphaComponentByFloatDimen(Context context, @ColorInt int color,
+                @DimenRes int alphaDimenResId) {
+            final TypedValue alphaValue = new TypedValue();
+            context.getResources().getValue(alphaDimenResId, alphaValue, true);
+            return ColorUtils.setAlphaComponent(color, Math.round(alphaValue.getFloat() * 255));
+        }
+
         /**
          * Extract the color from a full-length span from the text.
          *
@@ -6731,6 +6771,10 @@
             return R.layout.notification_material_action_emphasized;
         }
 
+        private int getEmphasizedTombstoneActionLayoutResource() {
+            return R.layout.notification_material_action_emphasized_tombstone;
+        }
+
         private int getActionTombstoneLayoutResource() {
             return R.layout.notification_material_action_tombstone;
         }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index f6d27ad..4e94a1d 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -31,6 +31,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.PermissionChecker;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ShortcutInfo;
 import android.graphics.drawable.Icon;
@@ -855,6 +856,32 @@
     }
 
     /**
+     * Returns whether the calling app can send fullscreen intents.
+     * <p>From Android {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, apps may not have
+     * permission to use {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}. If permission
+     * is denied, notification will show up as an expanded heads up notification on lockscreen.
+     * <p> To request access, add the {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}
+     * permission to your manifest, and use
+     * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}.
+     */
+    public boolean canSendFullScreenIntent() {
+        final int result = PermissionChecker.checkPermissionForPreflight(mContext,
+                android.Manifest.permission.USE_FULL_SCREEN_INTENT,
+                mContext.getAttributionSource());
+
+        switch (result) {
+            case PermissionChecker.PERMISSION_GRANTED:
+                return true;
+            case PermissionChecker.PERMISSION_SOFT_DENIED:
+            case PermissionChecker.PERMISSION_HARD_DENIED:
+                return false;
+            default:
+                if (localLOGV) Log.v(TAG, "Unknown PermissionChecker result: " + result);
+                return false;
+        }
+    }
+
+    /**
      * Creates a group container for {@link NotificationChannel} objects.
      *
      * This can be used to rename an existing group.
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 6206f31..824c7cc 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -4,12 +4,12 @@
 
 # ActivityManager
 per-file ActivityManager* = file:/services/core/java/com/android/server/am/OWNERS
+per-file ApplicationStartInfo* = file:/services/core/java/com/android/server/am/OWNERS
 per-file ApplicationErrorReport* = file:/services/core/java/com/android/server/am/OWNERS
 per-file ApplicationExitInfo* = file:/services/core/java/com/android/server/am/OWNERS
 per-file Application.java = file:/services/core/java/com/android/server/am/OWNERS
 per-file ApplicationLoaders.java = file:/services/core/java/com/android/server/am/OWNERS
 per-file ApplicationThreadConstants.java = file:/services/core/java/com/android/server/am/OWNERS
-per-file BroadcastOptions.java = file:/services/core/java/com/android/server/am/OWNERS
 per-file ContentProviderHolder* = file:/services/core/java/com/android/server/am/OWNERS
 per-file *ForegroundService* = file:/services/core/java/com/android/server/am/OWNERS
 per-file IActivityController.aidl = file:/services/core/java/com/android/server/am/OWNERS
@@ -50,6 +50,10 @@
 # Backup and Restore
 per-file IBackupAgent.aidl = file:/services/backup/OWNERS
 
+# Broadcasts
+per-file Broadcast* = file:/BROADCASTS_OWNERS
+per-file ReceiverInfo* = file:/BROADCASTS_OWNERS
+
 # LocaleManager
 per-file *Locale* = file:/services/core/java/com/android/server/locales/OWNERS
 
diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java
index 854406c..f7a3d78 100644
--- a/core/java/android/app/ProfilerInfo.java
+++ b/core/java/android/app/ProfilerInfo.java
@@ -33,6 +33,17 @@
  */
 public class ProfilerInfo implements Parcelable {
 
+    // CLOCK_TYPE_DEFAULT chooses the default used by ART. ART uses CLOCK_TYPE_DUAL by default (see
+    // kDefaultTraceClockSource in art/runtime/runtime_globals.h).
+    public static final int CLOCK_TYPE_DEFAULT = 0x000;
+    // The values of these constants are chosen such that they correspond to the flags passed to
+    // VMDebug.startMethodTracing to choose the corresponding clock type (see
+    // core/java/android/app/ActivityThread.java).
+    // The flag values are defined in ART (see TraceFlag in art/runtime/trace.h).
+    public static final int CLOCK_TYPE_WALL = 0x010;
+    public static final int CLOCK_TYPE_THREAD_CPU = 0x100;
+    public static final int CLOCK_TYPE_DUAL = 0x110;
+
     private static final String TAG = "ProfilerInfo";
 
     /* Name of profile output file. */
@@ -66,13 +77,20 @@
      */
     public final boolean attachAgentDuringBind;
 
+    /**
+     * Indicates the clock source to be used for profiling. The source could be wallclock, thread
+     * cpu or both
+     */
+    public final int clockType;
+
     public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop,
-            boolean streaming, String agent, boolean attachAgentDuringBind) {
+            boolean streaming, String agent, boolean attachAgentDuringBind, int clockType) {
         profileFile = filename;
         profileFd = fd;
         samplingInterval = interval;
         autoStopProfiler = autoStop;
         streamingOutput = streaming;
+        this.clockType = clockType;
         this.agent = agent;
         this.attachAgentDuringBind = attachAgentDuringBind;
     }
@@ -85,6 +103,25 @@
         streamingOutput = in.streamingOutput;
         agent = in.agent;
         attachAgentDuringBind = in.attachAgentDuringBind;
+        clockType = in.clockType;
+    }
+
+    /**
+     * Get the value for the clock type corresponding to the option string passed to the activity
+     * manager. am profile start / am start-activity start-profiler commands accept clock-type
+     * option to choose the source of timestamps when profiling. This function maps the option
+     * string to the value of flags that is used when calling VMDebug.startMethodTracing
+     */
+    public static int getClockTypeFromString(String type) {
+        if ("thread-cpu".equals(type)) {
+            return CLOCK_TYPE_THREAD_CPU;
+        } else if ("wall".equals(type)) {
+            return CLOCK_TYPE_WALL;
+        } else if ("dual".equals(type)) {
+            return CLOCK_TYPE_DUAL;
+        } else {
+            return CLOCK_TYPE_DEFAULT;
+        }
     }
 
     /**
@@ -93,7 +130,8 @@
      */
     public ProfilerInfo setAgent(String agent, boolean attachAgentDuringBind) {
         return new ProfilerInfo(this.profileFile, this.profileFd, this.samplingInterval,
-                this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind);
+                this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind,
+                this.clockType);
     }
 
     /**
@@ -133,6 +171,7 @@
         out.writeInt(streamingOutput ? 1 : 0);
         out.writeString(agent);
         out.writeBoolean(attachAgentDuringBind);
+        out.writeInt(clockType);
     }
 
     /** @hide */
@@ -146,6 +185,7 @@
         proto.write(ProfilerInfoProto.AUTO_STOP_PROFILER, autoStopProfiler);
         proto.write(ProfilerInfoProto.STREAMING_OUTPUT, streamingOutput);
         proto.write(ProfilerInfoProto.AGENT, agent);
+        proto.write(ProfilerInfoProto.CLOCK_TYPE, clockType);
         proto.end(token);
     }
 
@@ -170,6 +210,7 @@
         streamingOutput = in.readInt() != 0;
         agent = in.readString();
         attachAgentDuringBind = in.readBoolean();
+        clockType = in.readInt();
     }
 
     @Override
@@ -186,7 +227,8 @@
                 && autoStopProfiler == other.autoStopProfiler
                 && samplingInterval == other.samplingInterval
                 && streamingOutput == other.streamingOutput
-                && Objects.equals(agent, other.agent);
+                && Objects.equals(agent, other.agent)
+                && clockType == other.clockType;
     }
 
     @Override
@@ -197,6 +239,7 @@
         result = 31 * result + (autoStopProfiler ? 1 : 0);
         result = 31 * result + (streamingOutput ? 1 : 0);
         result = 31 * result + Objects.hashCode(agent);
+        result = 31 * result + clockType;
         return result;
     }
 }
diff --git a/core/java/android/app/ReceiverInfo.aidl b/core/java/android/app/ReceiverInfo.aidl
index 7364d0f..6916f71 100644
--- a/core/java/android/app/ReceiverInfo.aidl
+++ b/core/java/android/app/ReceiverInfo.aidl
@@ -38,8 +38,8 @@
     int sendingUser;
     int processState;
     int resultCode;
-    int sentFromUid = -1;
-    String sentFromPackage;
+    int sendingUid = -1;
+    String sendingPackage;
 
     /**
      * True if this instance represents a registered receiver and false if this instance
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/core/java/android/app/RemoteLockscreenValidationResult.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to core/java/android/app/RemoteLockscreenValidationResult.aidl
index 497c272..504f78f 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/core/java/android/app/RemoteLockscreenValidationResult.aidl
@@ -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,12 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+/** {@hide} */
+parcelable RemoteLockscreenValidationResult;
diff --git a/core/java/android/app/RemoteLockscreenValidationResult.java b/core/java/android/app/RemoteLockscreenValidationResult.java
new file mode 100644
index 0000000..0245f8c
--- /dev/null
+++ b/core/java/android/app/RemoteLockscreenValidationResult.java
@@ -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 android.app;
+
+import android.annotation.DurationMillisLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+/**
+ * Result of lock screen credentials verification.
+ *
+ * @hide
+ */
+@SystemApi
+public final class RemoteLockscreenValidationResult implements Parcelable {
+
+    /**
+     * The guess was correct
+     */
+    public static final int RESULT_GUESS_VALID = 1;
+
+    /**
+     * Remote device provided incorrect credentials.
+     */
+    public static final int RESULT_GUESS_INVALID = 2;
+
+    /**
+     * The operation was canceled because the API is locked out due to too many attempts. It
+     * usually happens after 5 failed attempts and API may be called again after a short
+     * delay specified by {@code getTimeoutMillis}.
+     */
+    public static final int RESULT_LOCKOUT = 3;
+
+    /**
+     * There were too many invalid guesses.
+     */
+    public static final int RESULT_NO_REMAINING_ATTEMPTS = 4;
+
+    @IntDef({RESULT_GUESS_VALID,
+            RESULT_GUESS_INVALID,
+            RESULT_LOCKOUT,
+            RESULT_NO_REMAINING_ATTEMPTS})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ResultCode {}
+
+    private int mResultCode;
+    private long mTimeoutMillis;
+
+    public static final @NonNull Parcelable.Creator<RemoteLockscreenValidationResult> CREATOR =
+            new Parcelable.Creator<RemoteLockscreenValidationResult>() {
+        @Override
+        public RemoteLockscreenValidationResult createFromParcel(Parcel source) {
+            return new RemoteLockscreenValidationResult(source);
+        }
+
+        @Override
+        public RemoteLockscreenValidationResult[] newArray(int size) {
+            return new RemoteLockscreenValidationResult[size];
+        }
+    };
+
+    /**
+     * Builder for {@code RemoteLockscreenValidationResult}
+     */
+    public static final class Builder {
+        private RemoteLockscreenValidationResult mInstance = new RemoteLockscreenValidationResult();
+
+        /**
+         * Sets the result code.
+         */
+        public @NonNull Builder setResultCode(@ResultCode int resultCode) {
+            mInstance.mResultCode = resultCode;
+            return this;
+        }
+
+        /**
+         * Sets timeout for {@code RESULT_LOCKOUT}.
+         * Default value is {@code 0}.
+         */
+        public @NonNull Builder setTimeoutMillis(@DurationMillisLong long timeoutMillis) {
+            mInstance.mTimeoutMillis = timeoutMillis;
+            return this;
+        }
+
+        /**
+         * Creates {@code RemoteLockscreenValidationResult}.
+         *
+         * @throws IllegalStateException if result code was not set.
+         */
+        public @NonNull RemoteLockscreenValidationResult build() {
+            if (mInstance.mResultCode == 0) {
+                throw new IllegalStateException("Result code must be set");
+            }
+            return mInstance;
+        }
+    }
+
+    /**
+     * Gets the result code.
+     */
+    public @ResultCode int getResultCode() {
+        return mResultCode;
+    }
+
+    /**
+     * Delay before next attempt to verify credentials.
+     *
+     * Default value is {@code 0}.
+     */
+    public @DurationMillisLong long getTimeoutMillis() {
+        return mTimeoutMillis;
+    }
+
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(mResultCode);
+        out.writeLong(mTimeoutMillis);
+    }
+
+    private RemoteLockscreenValidationResult() {
+    }
+
+    private RemoteLockscreenValidationResult(Parcel in) {
+        mResultCode = in.readInt();
+        mTimeoutMillis = in.readLong();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index e485397..a155457 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -1140,6 +1140,22 @@
      * Callback called on timeout for {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}.
      * See {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE} for more details.
      *
+     * <p>If the foreground service of type
+     * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}
+     * doesn't finish even after it's timed out,
+     * the app will be declared an ANR after a short grace period of several seconds.
+     *
+     * <p>Note, even though
+     * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}
+     * was added
+     * on Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * it can be also used on
+     * on prior android versions (just like other new foreground service types can be used).
+     * However, because {@link android.app.Service#onTimeout(int)} did not exist on prior versions,
+     * it will never called on such versions.
+     * Because of this, developers must make sure to stop the foreground service even if
+     * {@link android.app.Service#onTimeout(int)} is not called on such versions.
+     *
      * @param startId the startId passed to {@link #onStartCommand(Intent, int, int)} when
      * the service started.
      */
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/core/java/android/app/StartLockscreenValidationRequest.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to core/java/android/app/StartLockscreenValidationRequest.aidl
index 497c272..367dfee 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/core/java/android/app/StartLockscreenValidationRequest.aidl
@@ -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,12 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+/** {@hide} */
+parcelable StartLockscreenValidationRequest;
diff --git a/core/java/android/app/StartLockscreenValidationRequest.java b/core/java/android/app/StartLockscreenValidationRequest.java
new file mode 100644
index 0000000..e818195
--- /dev/null
+++ b/core/java/android/app/StartLockscreenValidationRequest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.KeyguardManager.LockTypes;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Provides information necessary to perform remote lock screen credentials check.
+ *
+ * @hide
+ */
+@SystemApi
+public final class StartLockscreenValidationRequest implements Parcelable {
+
+    @LockTypes
+    private int mLockscreenUiType;
+
+    private byte[] mSourcePublicKey;
+
+    private int mRemainingAttempts;
+
+    public static final @NonNull Parcelable.Creator<StartLockscreenValidationRequest> CREATOR = new
+            Parcelable.Creator<StartLockscreenValidationRequest>() {
+        @Override
+        public StartLockscreenValidationRequest createFromParcel(Parcel source) {
+            return new StartLockscreenValidationRequest(source);
+        }
+
+        @Override
+        public StartLockscreenValidationRequest[] newArray(int size) {
+            return new StartLockscreenValidationRequest[size];
+        }
+    };
+
+
+    /**
+     * Builder for {@code StartLockscreenValidationRequest}
+     */
+    public static final class Builder {
+        private StartLockscreenValidationRequest mInstance = new StartLockscreenValidationRequest();
+
+        /**
+         * Sets UI type.
+         * Default value is {@code LockTypes.PASSWORD}
+         *
+         * @param lockscreenUiType The UI format
+         * @return This builder.
+         */
+        public @NonNull Builder setLockscreenUiType(@LockTypes int lockscreenUiType) {
+            mInstance.mLockscreenUiType = lockscreenUiType;
+            return this;
+        }
+
+        /**
+         * Sets public key using secure box encoding
+         * @return This builder.
+         */
+        public @NonNull Builder setSourcePublicKey(@NonNull byte[] publicKey) {
+            mInstance.mSourcePublicKey = publicKey;
+            return this;
+        }
+
+        /**
+         * Sets the number of remaining credentials check
+         * Default value is {@code 0}
+         *
+         * @return This builder.
+         */
+        public @NonNull Builder setRemainingAttempts(int remainingAttempts) {
+            mInstance.mRemainingAttempts = remainingAttempts;
+            return this;
+        }
+
+        /**
+         * Creates {@code StartLockscreenValidationRequest}
+         *
+         * @throws NullPointerException if required fields are not set.
+         */
+        public @NonNull StartLockscreenValidationRequest build() {
+            Objects.requireNonNull(mInstance.mSourcePublicKey);
+            return mInstance;
+        }
+    }
+
+    /**
+     * Specifies lock screen credential type.
+     */
+    public @LockTypes int getLockscreenUiType() {
+        return mLockscreenUiType;
+    }
+
+    /**
+     * Public key used to send encrypted credentials.
+     */
+    public @NonNull byte[] getSourcePublicKey() {
+        return mSourcePublicKey;
+    }
+
+    /**
+     * Number of remaining attempts to verify credentials.
+     *
+     * <p>After correct guess counter is reset to {@code 5}.
+     */
+    public int getRemainingAttempts() {
+        return mRemainingAttempts;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(mLockscreenUiType);
+        out.writeByteArray(mSourcePublicKey);
+        out.writeInt(mRemainingAttempts);
+    }
+
+    private StartLockscreenValidationRequest() {
+    }
+
+    private StartLockscreenValidationRequest(Parcel in) {
+        mLockscreenUiType = in.readInt();
+        mSourcePublicKey = in.createByteArray();
+        mRemainingAttempts = in.readInt();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 1c1a558..f74be22 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -30,6 +30,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.drawable.Icon;
 import android.media.INearbyMediaDevicesProvider;
 import android.media.INearbyMediaDevicesUpdateCallback;
@@ -47,6 +48,7 @@
 import android.util.Slog;
 import android.view.View;
 
+import com.android.internal.statusbar.AppClipsServiceConnector;
 import com.android.internal.statusbar.IAddTileResultCallback;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.IUndoMediaTransferCallback;
@@ -938,7 +940,7 @@
      * @param tileLabel label of the tile to show to the user.
      * @param icon icon to use in the tile shown to the user.
      * @param resultExecutor an executor to run the callback on
-     * @param resultCallback callback to indicate the {@link RequestResult}.
+     * @param resultCallback callback to indicate the result of the request.
      *
      * @see android.service.quicksettings.TileService
      */
@@ -1190,6 +1192,37 @@
         return CompatChanges.isChangeEnabled(MEDIA_CONTROL_SESSION_ACTIONS, packageName, user);
     }
 
+    /**
+     * Checks whether the supplied activity can {@link Activity#startActivityForResult(Intent, int)}
+     * a system activity that captures content on the screen to take a screenshot.
+     *
+     * <p>Note: The result should not be cached.
+     *
+     * <p>The system activity displays an editing tool that allows user to edit the screenshot, save
+     * it on device, and return the edited screenshot as {@link android.net.Uri} to the calling
+     * activity. User interaction is required to return the edited screenshot to the calling
+     * activity.
+     *
+     * <p>When {@code true}, callers can use {@link Activity#startActivityForResult(Intent, int)}
+     * to start start the content capture activity using
+     * {@link Intent#ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE}.
+     *
+     * @param activity Calling activity
+     * @return true if the activity supports launching the capture content activity for note.
+     *
+     * @see Intent#ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE
+     * @see Manifest.permission#LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE
+     * @see android.app.role.RoleManager#ROLE_NOTES
+     */
+    @RequiresPermission(Manifest.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE)
+    public boolean canLaunchCaptureContentActivityForNote(@NonNull Activity activity) {
+        Objects.requireNonNull(activity);
+        IBinder activityToken = activity.getActivityToken();
+        int taskId = ActivityClient.getInstance().getTaskForActivity(activityToken, false);
+        return new AppClipsServiceConnector(mContext)
+                .canLaunchCaptureContentActivityForNote(taskId);
+    }
+
     /** @hide */
     public static String windowStateToString(int state) {
         if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 031d351..64538ec 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -156,7 +156,8 @@
 import android.net.vcn.VcnManager;
 import android.net.wifi.WifiFrameworkInitializer;
 import android.net.wifi.nl80211.WifiNl80211Manager;
-import android.nfc.NfcManager;
+import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager;
+import android.nfc.NfcFrameworkInitializer;
 import android.ondevicepersonalization.OnDevicePersonalizationFrameworkInitializer;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
@@ -483,13 +484,6 @@
                 return new BatteryManager(ctx, stats, registrar);
             }});
 
-        registerService(Context.NFC_SERVICE, NfcManager.class,
-                new CachedServiceFetcher<NfcManager>() {
-            @Override
-            public NfcManager createService(ContextImpl ctx) {
-                return new NfcManager(ctx);
-            }});
-
         registerService(Context.DROPBOX_SERVICE, DropBoxManager.class,
                 new CachedServiceFetcher<DropBoxManager>() {
             @Override
@@ -1572,6 +1566,13 @@
                                                 Context.GRAMMATICAL_INFLECTION_SERVICE)));
                     }});
 
+        registerService(Context.SHARED_CONNECTIVITY_SERVICE, SharedConnectivityManager.class,
+                new CachedServiceFetcher<SharedConnectivityManager>() {
+                    @Override
+                    public SharedConnectivityManager createService(ContextImpl ctx) {
+                        return new SharedConnectivityManager(ctx);
+                    }
+                });
 
         sInitializing = true;
         try {
@@ -1581,6 +1582,7 @@
             JobSchedulerFrameworkInitializer.registerServiceWrappers();
             BlobStoreManagerFrameworkInitializer.initialize();
             BluetoothFrameworkInitializer.registerServiceWrappers();
+            NfcFrameworkInitializer.registerServiceWrappers();
             TelephonyFrameworkInitializer.registerServiceWrappers();
             AppSearchManagerFrameworkInitializer.initialize();
             HealthServicesInitializer.registerServiceWrappers();
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index e75b503..249937a 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1447,10 +1447,7 @@
      *
      * @param command The command to execute.
      * @return File descriptors (out, in, err) to the standard output/input/error streams.
-     *
-     * @hide
      */
-    @TestApi
     @SuppressLint("ArrayReturn") // For consistency with other APIs
     public @NonNull ParcelFileDescriptor[] executeShellCommandRwe(@NonNull String command) {
         return executeShellCommandInternal(command, true /* includeStderr */);
diff --git a/core/java/android/app/admin/Authority.java b/core/java/android/app/admin/Authority.java
new file mode 100644
index 0000000..52f79cf
--- /dev/null
+++ b/core/java/android/app/admin/Authority.java
@@ -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 android.app.admin;
+
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.os.Parcelable;
+
+/**
+ * Abstract class used to identify the authority of the {@link EnforcingAdmin}.
+ *
+ * @hide
+ */
+// This is ok as the constructor is package-protected and all subclasses have implemented
+// Parcelable.
+@SuppressLint({"ParcelNotFinal", "ParcelCreator"})
+@SystemApi
+public abstract class Authority implements Parcelable {
+
+    /**
+     * @hide
+     */
+    protected Authority() {}
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        return o != null && getClass() == o.getClass();
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/app/admin/BooleanPolicyValue.java b/core/java/android/app/admin/BooleanPolicyValue.java
new file mode 100644
index 0000000..aa6f4a4
--- /dev/null
+++ b/core/java/android/app/admin/BooleanPolicyValue.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class BooleanPolicyValue extends PolicyValue<Boolean> {
+
+    public BooleanPolicyValue(boolean value) {
+        super(value);
+    }
+
+    private BooleanPolicyValue(Parcel source) {
+        this(source.readBoolean());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        BooleanPolicyValue other = (BooleanPolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public String toString() {
+        return "BooleanPolicyValue { mValue= " + getValue() + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeBoolean(getValue());
+    }
+
+    @NonNull
+    public static final Creator<BooleanPolicyValue> CREATOR =
+            new Creator<BooleanPolicyValue>() {
+                @Override
+                public BooleanPolicyValue createFromParcel(Parcel source) {
+                    return new BooleanPolicyValue(source);
+                }
+
+                @Override
+                public BooleanPolicyValue[] newArray(int size) {
+                    return new BooleanPolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/BundlePolicyValue.java b/core/java/android/app/admin/BundlePolicyValue.java
new file mode 100644
index 0000000..f9653a4
--- /dev/null
+++ b/core/java/android/app/admin/BundlePolicyValue.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class BundlePolicyValue extends PolicyValue<Bundle> {
+
+    public BundlePolicyValue(Bundle value) {
+        super(value);
+    }
+
+    private BundlePolicyValue(Parcel source) {
+        this(source.readBundle());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        BundlePolicyValue other = (BundlePolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public String toString() {
+        return "BundlePolicyValue { mValue= " + getValue() + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeBundle(getValue());
+    }
+
+    @NonNull
+    public static final Creator<BundlePolicyValue> CREATOR =
+            new Creator<BundlePolicyValue>() {
+                @Override
+                public BundlePolicyValue createFromParcel(Parcel source) {
+                    return new BundlePolicyValue(source);
+                }
+
+                @Override
+                public BundlePolicyValue[] newArray(int size) {
+                    return new BundlePolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/ComponentNamePolicyValue.java b/core/java/android/app/admin/ComponentNamePolicyValue.java
new file mode 100644
index 0000000..635e582
--- /dev/null
+++ b/core/java/android/app/admin/ComponentNamePolicyValue.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.os.Parcel;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class ComponentNamePolicyValue extends PolicyValue<ComponentName> {
+
+    public ComponentNamePolicyValue(@NonNull ComponentName value) {
+        super(value);
+    }
+
+    private ComponentNamePolicyValue(Parcel source) {
+        this((ComponentName) source.readParcelable(ComponentName.class.getClassLoader()));
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ComponentNamePolicyValue other = (ComponentNamePolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public String toString() {
+        return "ComponentNamePolicyValue { mValue= " + getValue() + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(getValue(), flags);
+    }
+
+    @NonNull
+    public static final Creator<ComponentNamePolicyValue> CREATOR =
+            new Creator<ComponentNamePolicyValue>() {
+                @Override
+                public ComponentNamePolicyValue createFromParcel(Parcel source) {
+                    return new ComponentNamePolicyValue(source);
+                }
+
+                @Override
+                public ComponentNamePolicyValue[] newArray(int size) {
+                    return new ComponentNamePolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/DeviceAdminAuthority.java b/core/java/android/app/admin/DeviceAdminAuthority.java
new file mode 100644
index 0000000..5d1ff11
--- /dev/null
+++ b/core/java/android/app/admin/DeviceAdminAuthority.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+
+/**
+ * Class used to identify that authority of the {@link EnforcingAdmin} setting a policy is a non-DPC
+ * device admin.
+ *
+ * @hide
+ */
+@SystemApi
+public final class DeviceAdminAuthority extends Authority {
+
+    /**
+     * @hide
+     */
+    public static final DeviceAdminAuthority DEVICE_ADMIN_AUTHORITY = new DeviceAdminAuthority();
+
+    private DeviceAdminAuthority() {}
+
+    @Override
+    public String toString() {
+        return "DeviceAdminAuthority {}";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        return super.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Creator<DeviceAdminAuthority> CREATOR =
+            new Creator<DeviceAdminAuthority>() {
+                @Override
+                public DeviceAdminAuthority createFromParcel(Parcel source) {
+                    return new DeviceAdminAuthority();
+                }
+
+                @Override
+                public DeviceAdminAuthority[] newArray(int size) {
+                    return new DeviceAdminAuthority[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d8ec7cc..e7f6990 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY;
 import static android.Manifest.permission.QUERY_ADMIN_POLICY;
 import static android.Manifest.permission.SET_TIME;
 import static android.Manifest.permission.SET_TIME_ZONE;
@@ -39,6 +40,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.StringDef;
+import android.annotation.SupportsCoexistence;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
@@ -3876,13 +3878,33 @@
     public static final int EXEMPT_FROM_APP_STANDBY =  0;
 
     /**
+     * Prevent an app from dismissible notifications. Starting from Android U, notifications with
+     * the ongoing parameter can be dismissed by a user on an unlocked device. An app with
+     * this exemption can create non-dismissable notifications.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS =  1;
+
+    /**
+     * Allows an application to start an activity while running in the background.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION = 2;
+
+    /**
      * Exemptions to platform restrictions, given to an application through
      * {@link #setApplicationExemptions(String, Set)}.
      *
      * @hide
      */
     @IntDef(prefix = { "EXEMPT_FROM_"}, value = {
-            EXEMPT_FROM_APP_STANDBY
+            EXEMPT_FROM_APP_STANDBY,
+            EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS,
+            EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ApplicationExemptionConstants {}
@@ -4008,18 +4030,8 @@
     /**
      * @hide
      */
-    public static final String PERMISSION_GRANT_POLICY_KEY = "permissionGrant";
+    public static final String PERMISSION_GRANT_POLICY = "permissionGrant";
 
-    // TODO: Expose this as SystemAPI once we add the query API
-    /**
-     * @hide
-     */
-    public static String PERMISSION_GRANT_POLICY(
-            @NonNull String packageName, @NonNull String permission) {
-        Objects.requireNonNull(packageName);
-        Objects.requireNonNull(permission);
-        return PERMISSION_GRANT_POLICY_KEY + "_" + packageName + "_" + permission;
-    }
 
     // TODO: Expose this as SystemAPI once we add the query API
     /**
@@ -4048,6 +4060,12 @@
      */
     public static final String PACKAGE_UNINSTALL_BLOCKED_POLICY = "packageUninstallBlocked";
 
+    // TODO: Expose this as SystemAPI once we add the query API
+    /**
+     * @hide
+     */
+    public static final String APPLICATION_RESTRICTIONS_POLICY = "applicationRestrictions";
+
     /**
      * This object is a single place to tack on invalidation and disable calls.  All
      * binder caches in this class derive from this Config, so all can be invalidated or
@@ -8476,7 +8494,8 @@
      * higher, to set whether auto time is required. If auto time is required, no user will be able
      * set the date and time and network date and time will be used.
      * <p>
-     * Note: if auto time is required the user can still manually set the time zone.
+     * Note: If auto time is required the user can still manually set the time zone. Staring from
+     * Android 11, if auto time is required, the user cannot manually set the time zone.
      * <p>
      * The calling device admin must be a device owner, or alternatively a profile owner from
      * Android 8.0 (API level 26) or higher. If it is not, a security exception will be thrown.
@@ -8596,6 +8615,7 @@
      * primary user, or a profile owner of an organization-owned managed profile or a holder of the
      * permission {@link android.Manifest.permission#SET_TIME_ZONE}.
      */
+    @SupportsCoexistence
     @RequiresPermission(value = SET_TIME_ZONE, conditional = true)
     public void setAutoTimeZoneEnabled(@NonNull ComponentName admin, boolean enabled) {
         throwIfParentInstance("setAutoTimeZone");
@@ -9665,6 +9685,7 @@
      * @param activity The Activity that is added as default intent handler.
      * @throws SecurityException if {@code admin} is not a device or profile owner.
      */
+    @SupportsCoexistence
     public void addPersistentPreferredActivity(@NonNull ComponentName admin, IntentFilter filter,
             @NonNull ComponentName activity) {
         throwIfParentInstance("addPersistentPreferredActivity");
@@ -10624,6 +10645,7 @@
      *                           profile owner of an organization-owned managed profile and the
      *                           list of permitted input method package names is not null or empty.
      */
+    @SupportsCoexistence
     public boolean setPermittedInputMethods(
             @NonNull ComponentName admin, List<String> packageNames) {
         if (mService != null) {
@@ -11696,6 +11718,7 @@
      * @see DeviceAdminReceiver#onLockTaskModeExiting(Context, Intent)
      * @see UserManager#DISALLOW_CREATE_WINDOWS
      */
+    @SupportsCoexistence
     public void setLockTaskPackages(@NonNull ComponentName admin, @NonNull String[] packages)
             throws SecurityException {
         throwIfParentInstance("setLockTaskPackages");
@@ -11764,6 +11787,7 @@
      * affiliated user or profile, or the profile owner when no device owner is set.
      * @see #isAffiliatedUser
      **/
+    @SupportsCoexistence
     public void setLockTaskFeatures(@NonNull ComponentName admin, @LockTaskFeature int flags) {
         throwIfParentInstance("setLockTaskFeatures");
         if (mService != null) {
@@ -12267,6 +12291,7 @@
      * @see #setDelegatedScopes
      * @see #DELEGATION_BLOCK_UNINSTALL
      */
+    @SupportsCoexistence
     public void setUninstallBlocked(@Nullable ComponentName admin, String packageName,
             boolean uninstallBlocked) {
         throwIfParentInstance("setUninstallBlocked");
@@ -12755,6 +12780,7 @@
      * @see #setDelegatedScopes
      * @see #DELEGATION_PERMISSION_GRANT
      */
+    @SupportsCoexistence
     public boolean setPermissionGrantState(@NonNull ComponentName admin,
             @NonNull String packageName, @NonNull String permission,
             @PermissionGrantState int grantState) {
@@ -13466,18 +13492,24 @@
     }
 
     /**
-     * Called by the device owner (since API 26) or profile owner (since API 24) to set the name of
-     * the organization under management.
+     * Called by the device owner (since API 26) or profile owner (since API 24) or, starting from
+     * Android {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY} to set the
+     * name of the organization under management.
      *
-     * <p>If the organization name needs to be localized, it is the responsibility of the {@link
-     * DeviceAdminReceiver} to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast and set
-     * a new version of this string accordingly.
+     * <p>If the organization name needs to be localized, it is the responsibility of the caller
+     * to listen to the {@link Intent#ACTION_LOCALE_CHANGED} broadcast and set a new version of this
+     * string accordingly.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with or can be
+     * {@code null} if accessing with a permission without association with a DeviceAdminReceiver.
      * @param title The organization name or {@code null} to clear a previously set name.
-     * @throws SecurityException if {@code admin} is not a device or profile owner.
+     * @throws SecurityException if {@code admin} is not a device or profile owner or holder of the
+     * permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY}.
      */
-    public void setOrganizationName(@NonNull ComponentName admin, @Nullable CharSequence title) {
+    @RequiresPermission(MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY)
+    public void setOrganizationName(@Nullable ComponentName admin, @Nullable CharSequence title) {
         throwIfParentInstance("setOrganizationName");
         try {
             mService.setOrganizationName(admin, title);
@@ -13487,14 +13519,21 @@
     }
 
     /**
-     * Called by a profile owner of a managed profile to retrieve the name of the organization under
-     * management.
+     * Called by the device owner (since API 26) or profile owner (since API 24) or, starting from
+     * Android {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * holders of the permission
+     * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY
+     * to retrieve the name of the organization under management.
      *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with or can be
+     * {@code null} if accessing with a permission without association with a DeviceAdminReceiver.
      * @return The organization name or {@code null} if none is set.
-     * @throws SecurityException if {@code admin} is not a profile owner.
+     * @throws SecurityException if {@code admin} if {@code admin} is not a device or profile
+     * owner or holder of the
+     * permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY}.
      */
-    public @Nullable CharSequence getOrganizationName(@NonNull ComponentName admin) {
+    @RequiresPermission(MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY)
+    public @Nullable CharSequence getOrganizationName(@Nullable ComponentName admin) {
         throwIfParentInstance("getOrganizationName");
         try {
             return mService.getOrganizationName(admin);
@@ -15301,6 +15340,7 @@
      * @param packages The package names for the apps.
      * @throws SecurityException if {@code admin} is not a device owner or a profile owner.
      */
+    @SupportsCoexistence
     public void setUserControlDisabledPackages(@NonNull ComponentName admin,
             @NonNull List<String> packages) {
         throwIfParentInstance("setUserControlDisabledPackages");
@@ -16279,4 +16319,47 @@
         }
         return false;
     }
+
+    /**
+     * Returns a {@link DevicePolicyState} object containing information about the current state
+     * of device policies (e.g. values set by different admins, info about the enforcing admins,
+     * resolved policy, etc).
+     *
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @RequiresPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+    public DevicePolicyState getDevicePolicyState() {
+        if (mService != null) {
+            try {
+                return mService.getDevicePolicyState();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Triggers the data migration of device policies for existing DPCs to the Device Policy Engine.
+     * If {@code forceMigration} is set to {@code true} it skips the prerequisite checks before
+     * triggering the migration.
+     *
+     * <p>Returns {@code true} if migration was completed successfully, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+    public boolean triggerDevicePolicyEngineMigration(boolean forceMigration) {
+        if (mService != null) {
+            try {
+                return mService.triggerDevicePolicyEngineMigration(forceMigration);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return false;
+    }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 3a61ca1..8076615 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -21,9 +21,11 @@
 import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.os.Bundle;
 import android.os.UserHandle;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -304,4 +306,15 @@
      * True if either the entire device or the user is organization managed.
      */
     public abstract boolean isUserOrganizationManaged(@UserIdInt int userId);
+
+    /**
+     * Returns whether the application exemptions feature flag is enabled.
+     */
+    public abstract boolean isApplicationExemptionsFlagEnabled();
+
+    /**
+    * Returns the application restrictions set by each admin for the given {@code packageName}.
+     */
+    public abstract Map<String, Bundle> getApplicationRestrictionsPerAdmin(
+            String packageName, int userId);
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/core/java/android/app/admin/DevicePolicyState.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to core/java/android/app/admin/DevicePolicyState.aidl
index 497c272..0eac33f 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/core/java/android/app/admin/DevicePolicyState.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.app.admin;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable DevicePolicyState;
\ No newline at end of file
diff --git a/core/java/android/app/admin/DevicePolicyState.java b/core/java/android/app/admin/DevicePolicyState.java
new file mode 100644
index 0000000..ee33b00
--- /dev/null
+++ b/core/java/android/app/admin/DevicePolicyState.java
@@ -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 android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * A class containing information about the current state of device policies (e.g. values set by
+ * different admins, info about the enforcing admins, resolved policy, etc).
+ *
+ * @hide
+ */
+@SystemApi
+public final class DevicePolicyState implements Parcelable {
+    private final Map<UserHandle, Map<PolicyKey, PolicyState<?>>> mPolicies;
+
+    /**
+     * @hide
+     */
+    public DevicePolicyState(Map<UserHandle, Map<PolicyKey, PolicyState<?>>> policies) {
+        mPolicies = Objects.requireNonNull(policies);
+    }
+
+    private DevicePolicyState(Parcel source) {
+        mPolicies = new HashMap<>();
+        int usersSize = source.readInt();
+        for (int i = 0; i < usersSize; i++) {
+            UserHandle userHandle = UserHandle.of(source.readInt());
+            mPolicies.put(userHandle, new HashMap<>());
+            int policiesSize = source.readInt();
+            for (int j = 0; j < policiesSize; j++) {
+                PolicyKey policyKey =
+                        source.readParcelable(PolicyKey.class.getClassLoader());
+                PolicyState<?> policyState =
+                        source.readParcelable(PolicyState.class.getClassLoader());
+                mPolicies.get(userHandle).put(policyKey, policyState);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@link Map} of current policies for each {@link UserHandle}, note that users
+     * that do not have any policies set will not be included in the returned map.
+     *
+     * <p> If the device has global policies affecting all users, it will be returned under
+     * {@link UserHandle#ALL}.
+     */
+    @NonNull
+    public Map<UserHandle, Map<PolicyKey, PolicyState<?>>> getPoliciesForAllUsers() {
+        return mPolicies;
+    }
+
+    /**
+     * Returns a {@link Map} of current policies for the provided {@code user}, use
+     * {@link UserHandle#ALL} to get global policies affecting all users on the device.
+     */
+    @NonNull
+    public Map<PolicyKey, PolicyState<?>> getPoliciesForUser(@NonNull UserHandle user) {
+        return mPolicies.containsKey(user) ? mPolicies.get(user) : new HashMap<>();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mPolicies.size());
+        for (UserHandle user : mPolicies.keySet()) {
+            dest.writeInt(user.getIdentifier());
+            dest.writeInt(mPolicies.get(user).size());
+            for (PolicyKey key : mPolicies.get(user).keySet()) {
+                dest.writeParcelable(key, flags);
+                dest.writeParcelable(mPolicies.get(user).get(key), flags);
+            }
+        }
+    }
+
+    public static final @NonNull Parcelable.Creator<DevicePolicyState> CREATOR =
+            new Parcelable.Creator<DevicePolicyState>() {
+                @Override
+                public DevicePolicyState createFromParcel(Parcel source) {
+                    return new DevicePolicyState(source);
+                }
+
+                @Override
+                public DevicePolicyState[] newArray(int size) {
+                    return new DevicePolicyState[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/DpcAuthority.java b/core/java/android/app/admin/DpcAuthority.java
new file mode 100644
index 0000000..72c16bc
--- /dev/null
+++ b/core/java/android/app/admin/DpcAuthority.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+
+/**
+ * Class used to identify that authority of the {@link EnforcingAdmin} setting a policy is a DPC or
+ * an app acting as a DPC (e.g. delegate apps).
+ *
+ * @hide
+ */
+@SystemApi
+public final class DpcAuthority extends Authority {
+
+    /**
+     * @hide
+     */
+    public static final DpcAuthority DPC_AUTHORITY = new DpcAuthority();
+
+    private DpcAuthority() {}
+
+    @Override
+    public String toString() {
+        return "DpcAuthority {}";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        return super.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Creator<DpcAuthority> CREATOR =
+            new Creator<DpcAuthority>() {
+                @Override
+                public DpcAuthority createFromParcel(Parcel source) {
+                    return new DpcAuthority();
+                }
+
+                @Override
+                public DpcAuthority[] newArray(int size) {
+                    return new DpcAuthority[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/EnforcingAdmin.java b/core/java/android/app/admin/EnforcingAdmin.java
new file mode 100644
index 0000000..1786467
--- /dev/null
+++ b/core/java/android/app/admin/EnforcingAdmin.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+
+import java.util.Objects;
+
+/**
+ * Class containing info about the admin enforcing a certain policy, e.g. its {@code packageName}
+ * and {@link Authority}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class EnforcingAdmin implements Parcelable {
+    private final String mPackageName;
+    private final Authority mAuthority;
+    private final UserHandle mUserHandle;
+
+    /**
+     * @hide
+     */
+    public EnforcingAdmin(
+            @NonNull String packageName, @NonNull Authority authority,
+            @NonNull UserHandle userHandle) {
+        mPackageName = Objects.requireNonNull(packageName);
+        mAuthority = Objects.requireNonNull(authority);
+        mUserHandle = Objects.requireNonNull(userHandle);
+    }
+
+    private EnforcingAdmin(Parcel source) {
+        mPackageName = Objects.requireNonNull(source.readString());
+        mUserHandle = new UserHandle(source.readInt());
+        mAuthority = Objects.requireNonNull(
+                source.readParcelable(Authority.class.getClassLoader()));
+    }
+
+    /**
+     * Returns the {@link Authority} on which the admin is acting on, e.g. DPC, DeviceAdmin, etc.
+     */
+    @NonNull
+    public Authority getAuthority() {
+        return mAuthority;
+    }
+
+    /**
+     * Returns the package name of the admin.
+     */
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the {@link UserHandle} on which the admin is installed on.
+     */
+    @NonNull
+    public UserHandle getUserHandle() {
+        return mUserHandle;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EnforcingAdmin other = (EnforcingAdmin) o;
+        return Objects.equals(mPackageName, other.mPackageName)
+                && Objects.equals(mAuthority, other.mAuthority)
+                && Objects.equals(mUserHandle, other.mUserHandle);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPackageName, mAuthority, mUserHandle);
+    }
+
+    @Override
+    public String toString() {
+        return "EnforcingAdmin { mPackageName= " + mPackageName + ", mAuthority= " + mAuthority
+                + ", mUserHandle= " + mUserHandle + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mPackageName);
+        dest.writeInt(mUserHandle.getIdentifier());
+        dest.writeParcelable(mAuthority, flags);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<EnforcingAdmin> CREATOR =
+            new Parcelable.Creator<EnforcingAdmin>() {
+                @Override
+                public EnforcingAdmin createFromParcel(Parcel source) {
+                    return new EnforcingAdmin(source);
+                }
+
+                @Override
+                public EnforcingAdmin[] newArray(int size) {
+                    return new EnforcingAdmin[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/FlagUnion.java b/core/java/android/app/admin/FlagUnion.java
new file mode 100644
index 0000000..be924d8
--- /dev/null
+++ b/core/java/android/app/admin/FlagUnion.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Class to identify a union resolution mechanism for flag policies, it's used to resolve the
+ * enforced policy when being set by multiple admins (see
+ * {@link PolicyState#getResolutionMechanism()}).
+ *
+ * @hide
+ */
+@TestApi
+public final class FlagUnion extends ResolutionMechanism<Integer> {
+
+    /**
+     * @hide
+     */
+    public static final FlagUnion FLAG_UNION = new FlagUnion();
+
+    private FlagUnion(){};
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        return o != null && getClass() == o.getClass();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this);
+    }
+
+    @Override
+    public String toString() {
+        return "FlagUnion {}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Parcelable.Creator<FlagUnion> CREATOR =
+            new Parcelable.Creator<FlagUnion>() {
+                @Override
+                public FlagUnion createFromParcel(Parcel source) {
+                    return new FlagUnion();
+                }
+
+                @Override
+                public FlagUnion[] newArray(int size) {
+                    return new FlagUnion[size];
+                }
+            };
+
+}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 1ed39c5..c86852a 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -53,6 +53,7 @@
 import android.security.keystore.ParcelableKeyGenParameterSpec;
 import android.telephony.data.ApnSetting;
 import com.android.internal.infra.AndroidFuture;
+import android.app.admin.DevicePolicyState;
 
 import java.util.List;
 
@@ -591,4 +592,8 @@
 
     void setManagedSubscriptionsPolicy(in ManagedSubscriptionsPolicy policy);
     ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy();
+
+    DevicePolicyState getDevicePolicyState();
+
+    boolean triggerDevicePolicyEngineMigration(boolean forceMigration);
 }
diff --git a/core/java/android/app/admin/IntegerPolicyValue.java b/core/java/android/app/admin/IntegerPolicyValue.java
new file mode 100644
index 0000000..6fa6180
--- /dev/null
+++ b/core/java/android/app/admin/IntegerPolicyValue.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class IntegerPolicyValue extends PolicyValue<Integer> {
+
+    public IntegerPolicyValue(int value) {
+        super(value);
+    }
+
+    private IntegerPolicyValue(Parcel source) {
+        this(source.readInt());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        IntegerPolicyValue other = (IntegerPolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public String toString() {
+        return "IntegerPolicyValue { mValue= " + getValue() + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(getValue());
+    }
+
+    @NonNull
+    public static final Creator<IntegerPolicyValue> CREATOR =
+            new Creator<IntegerPolicyValue>() {
+                @Override
+                public IntegerPolicyValue createFromParcel(Parcel source) {
+                    return new IntegerPolicyValue(source);
+                }
+
+                @Override
+                public IntegerPolicyValue[] newArray(int size) {
+                    return new IntegerPolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/IntentFilterPolicyKey.java b/core/java/android/app/admin/IntentFilterPolicyKey.java
new file mode 100644
index 0000000..d7eb101
--- /dev/null
+++ b/core/java/android/app/admin/IntentFilterPolicyKey.java
@@ -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 android.app.admin;
+
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_INTENT_FILTER;
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Class used to identify a policy that relates to a certain {@link IntentFilter}
+ * (e.g. {@link DevicePolicyManager#addPersistentPreferredActivity}).
+ *
+ * @hide
+ */
+@SystemApi
+public final class IntentFilterPolicyKey extends PolicyKey {
+    private final IntentFilter mFilter;
+
+    /**
+     * @hide
+     */
+    public IntentFilterPolicyKey(@NonNull String identifier, @NonNull IntentFilter filter) {
+        super(identifier);
+        mFilter = Objects.requireNonNull(filter);
+    }
+
+    /**
+     * @hide
+     */
+    public IntentFilterPolicyKey(@NonNull String identifier) {
+        super(identifier);
+        mFilter = null;
+    }
+
+    private IntentFilterPolicyKey(Parcel source) {
+        super(source.readString());
+        mFilter = source.readTypedObject(IntentFilter.CREATOR);
+    }
+
+    /**
+     * Returns the {@link IntentFilter} this policy relates to.
+     */
+    @NonNull
+    public IntentFilter getIntentFilter() {
+        return mFilter;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void saveToXml(TypedXmlSerializer serializer) throws IOException {
+        serializer.attribute(/* namespace= */ null, ATTR_POLICY_IDENTIFIER, getIdentifier());
+        mFilter.writeToXml(serializer);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public IntentFilterPolicyKey readFromXml(TypedXmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        String identifier = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_IDENTIFIER);
+        IntentFilter filter = new IntentFilter();
+        filter.readFromXml(parser);
+        return new IntentFilterPolicyKey(identifier, filter);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToBundle(Bundle bundle) {
+        super.writeToBundle(bundle);
+        Bundle extraPolicyParams = new Bundle();
+        extraPolicyParams.putParcelable(EXTRA_INTENT_FILTER, mFilter);
+        bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        IntentFilterPolicyKey other = (IntentFilterPolicyKey) o;
+        return Objects.equals(getIdentifier(), other.getIdentifier())
+                && IntentFilter.filterEquals(mFilter, other.mFilter);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getIdentifier(), mFilter);
+    }
+
+    @Override
+    public String toString() {
+        return "IntentFilterPolicyKey{mKey= " + getIdentifier() + "; mFilter= " + mFilter + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getIdentifier());
+        mFilter.writeToParcel(dest, flags);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<IntentFilterPolicyKey> CREATOR =
+            new Parcelable.Creator<IntentFilterPolicyKey>() {
+                @Override
+                public IntentFilterPolicyKey createFromParcel(Parcel source) {
+                    return new IntentFilterPolicyKey(source);
+                }
+
+                @Override
+                public IntentFilterPolicyKey[] newArray(int size) {
+                    return new IntentFilterPolicyKey[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/LockTaskPolicy.java b/core/java/android/app/admin/LockTaskPolicy.java
new file mode 100644
index 0000000..28757df
--- /dev/null
+++ b/core/java/android/app/admin/LockTaskPolicy.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Class to represent a lock task policy, this is a combination of lock task packages (see
+ * {@link DevicePolicyManager#setLockTaskPackages}) and lock task features (see
+ * {@link DevicePolicyManager#setLockTaskFeatures}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class LockTaskPolicy extends PolicyValue<LockTaskPolicy> {
+    /**
+     * @hide
+     */
+    public static final int DEFAULT_LOCK_TASK_FLAG =
+            DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
+
+    private Set<String> mPackages = new HashSet<>();
+    private int mFlags = DEFAULT_LOCK_TASK_FLAG;
+
+    /**
+     * Returns the list of packages allowed to start the lock task mode.
+     */
+    @NonNull
+    public Set<String> getPackages() {
+        return mPackages;
+    }
+
+    /**
+     * Returns which system features are enabled for LockTask mode.
+     */
+    public @DevicePolicyManager.LockTaskFeature int getFlags() {
+        return mFlags;
+    }
+
+    // Overriding to hide
+    /**
+     * @hide
+     */
+    @Override
+    @NonNull
+    public LockTaskPolicy getValue() {
+        return super.getValue();
+    }
+
+    /**
+     * @hide
+     */
+    public LockTaskPolicy(@NonNull Set<String> packages) {
+        Objects.requireNonNull(packages);
+        mPackages.addAll(packages);
+    }
+
+    /**
+     * @hide
+     */
+    public LockTaskPolicy(@NonNull Set<String> packages, int flags) {
+        Objects.requireNonNull(packages);
+        mPackages = new HashSet<>(packages);
+        mFlags = flags;
+        setValue(this);
+    }
+
+    private LockTaskPolicy(Parcel source) {
+        String[] packages = Objects.requireNonNull(source.readStringArray());
+        mPackages = new HashSet<>(Arrays.stream(packages).toList());
+        mFlags = source.readInt();
+    }
+
+    /**
+     * @hide
+     */
+    public LockTaskPolicy(LockTaskPolicy policy) {
+        mPackages = new HashSet<>(policy.mPackages);
+        mFlags = policy.mFlags;
+    }
+
+    /**
+     * @hide
+     */
+    public void setPackages(@NonNull Set<String> packages) {
+        Objects.requireNonNull(packages);
+        mPackages = new HashSet<>(packages);
+    }
+
+    /**
+     * @hide
+     */
+    public void setFlags(int flags) {
+        mFlags = flags;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        LockTaskPolicy other = (LockTaskPolicy) o;
+        return Objects.equals(mPackages, other.mPackages)
+                && mFlags == other.mFlags;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPackages, mFlags);
+    }
+
+    @Override
+    public String toString() {
+        return "LockTaskPolicy {mPackages= " + String.join(", ", mPackages) + "; mFlags= "
+                + mFlags + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeArray(mPackages.toArray(new String[0]));
+        dest.writeInt(mFlags);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<LockTaskPolicy> CREATOR =
+            new Parcelable.Creator<LockTaskPolicy>() {
+                @Override
+                public LockTaskPolicy createFromParcel(Parcel source) {
+                    return new LockTaskPolicy(source);
+                }
+
+                @Override
+                public LockTaskPolicy[] newArray(int size) {
+                    return new LockTaskPolicy[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/MostRecent.java b/core/java/android/app/admin/MostRecent.java
new file mode 100644
index 0000000..ac1657189
--- /dev/null
+++ b/core/java/android/app/admin/MostRecent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Class to identify a most-recent-setter wins resolution mechanism that is used to resolve the
+ * enforced policy when being set by multiple admins (see
+ * {@link PolicyState#getResolutionMechanism()}).
+ *
+ * @hide
+ */
+@TestApi
+public final class MostRecent<V> extends ResolutionMechanism<V> {
+
+    @Override
+    public String toString() {
+        return "MostRecent {}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Parcelable.Creator<MostRecent> CREATOR =
+            new Parcelable.Creator<MostRecent>() {
+                @Override
+                public MostRecent createFromParcel(Parcel source) {
+                    return new MostRecent();
+                }
+
+                @Override
+                public MostRecent[] newArray(int size) {
+                    return new MostRecent[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/MostRestrictive.java b/core/java/android/app/admin/MostRestrictive.java
new file mode 100644
index 0000000..adb4744
--- /dev/null
+++ b/core/java/android/app/admin/MostRestrictive.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Class to identify a most restrictive resolution mechanism that is used to resolve the enforced
+ * policy when being set by multiple admins (see {@link PolicyState#getResolutionMechanism()}).
+ *
+ * @hide
+ */
+@TestApi
+public final class MostRestrictive<V> extends ResolutionMechanism<V> {
+
+    private final List<PolicyValue<V>> mMostToLeastRestrictive;
+
+    /**
+     * @hide
+     */
+    public MostRestrictive(@NonNull List<PolicyValue<V>> mostToLeastRestrictive) {
+        mMostToLeastRestrictive = new ArrayList<>(mostToLeastRestrictive);
+    }
+
+    /**
+     * Returns an ordered list of most to least restrictive values for a certain policy.
+     */
+    List<V> getMostToLeastRestrictiveValues() {
+        return mMostToLeastRestrictive.stream().map(PolicyValue::getValue).toList();
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        MostRestrictive other = (MostRestrictive) o;
+        return Objects.equals(mMostToLeastRestrictive, other.mMostToLeastRestrictive);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mMostToLeastRestrictive);
+    }
+
+    /**
+     * @hide
+     */
+    public MostRestrictive(Parcel source) {
+        mMostToLeastRestrictive = new ArrayList<>();
+        int size = source.readInt();
+        for (int i = 0; i < size; i++) {
+            mMostToLeastRestrictive.add(source.readParcelable(PolicyValue.class.getClassLoader()));
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "MostRestrictive { mMostToLeastRestrictive= " + mMostToLeastRestrictive + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mMostToLeastRestrictive.size());
+        for (PolicyValue<V> entry : mMostToLeastRestrictive) {
+            dest.writeParcelable(entry, flags);
+        }
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<MostRestrictive<?>> CREATOR =
+            new Parcelable.Creator<MostRestrictive<?>>() {
+                @Override
+                public MostRestrictive<?> createFromParcel(Parcel source) {
+                    return new MostRestrictive<>(source);
+                }
+
+                @Override
+                public MostRestrictive<?>[] newArray(int size) {
+                    return new MostRestrictive[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/NoArgsPolicyKey.java b/core/java/android/app/admin/NoArgsPolicyKey.java
new file mode 100644
index 0000000..57b67d5
--- /dev/null
+++ b/core/java/android/app/admin/NoArgsPolicyKey.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Default implementation for {@link PolicyKey} used to identify a policy that doesn't require any
+ * additional arguments to be represented.
+ *
+ * @hide
+ */
+@SystemApi
+public final class NoArgsPolicyKey extends PolicyKey {
+
+    /**
+     * @hide
+     */
+    public NoArgsPolicyKey(@NonNull String identifier) {
+        super(identifier);
+    }
+
+    private NoArgsPolicyKey(Parcel source) {
+        this(source.readString());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getIdentifier());
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<NoArgsPolicyKey> CREATOR =
+            new Parcelable.Creator<NoArgsPolicyKey>() {
+                @Override
+                public NoArgsPolicyKey createFromParcel(Parcel source) {
+                    return new NoArgsPolicyKey(source);
+                }
+
+                @Override
+                public NoArgsPolicyKey[] newArray(int size) {
+                    return new NoArgsPolicyKey[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return "DefaultPolicyKey " + getIdentifier();
+    }
+}
diff --git a/core/java/android/app/admin/PackagePermissionPolicyKey.java b/core/java/android/app/admin/PackagePermissionPolicyKey.java
new file mode 100644
index 0000000..4aa2e38
--- /dev/null
+++ b/core/java/android/app/admin/PackagePermissionPolicyKey.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PACKAGE_NAME;
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PERMISSION_NAME;
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Class used to identify a policy that relates to a certain package and permission
+ * (e.g. {@link DevicePolicyManager#setPermissionGrantState}).
+ *
+ * @hide
+ */
+@SystemApi
+public final class PackagePermissionPolicyKey extends PolicyKey {
+    private static final String ATTR_PACKAGE_NAME = "package-name";
+    private static final String ATTR_PERMISSION_NAME = "permission-name";
+
+    private final String mPackageName;
+    private final String mPermissionName;
+
+    /**
+     * @hide
+     */
+    public PackagePermissionPolicyKey(@NonNull String identifier, @NonNull String packageName,
+            @NonNull String permissionName) {
+        super(identifier);
+        mPackageName = Objects.requireNonNull((packageName));
+        mPermissionName = Objects.requireNonNull((permissionName));
+    }
+
+    /**
+     * @hide
+     */
+    public PackagePermissionPolicyKey(@NonNull String identifier) {
+        super(identifier);
+        mPackageName = null;
+        mPermissionName = null;
+    }
+
+    private PackagePermissionPolicyKey(Parcel source) {
+        super(source.readString());
+        mPackageName = source.readString();
+        mPermissionName = source.readString();
+    }
+
+    /**
+     * Returns the package name this policy relates to.
+     */
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the permission name this policy relates to.
+     */
+    @NonNull
+    public String getPermissionName() {
+        return mPermissionName;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void saveToXml(TypedXmlSerializer serializer) throws IOException {
+        serializer.attribute(/* namespace= */ null, ATTR_POLICY_IDENTIFIER, getIdentifier());
+        serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName);
+        serializer.attribute(/* namespace= */ null, ATTR_PERMISSION_NAME, mPermissionName);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public PackagePermissionPolicyKey readFromXml(TypedXmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        String identifier = parser.getAttributeValue(
+                /* namespace= */ null, ATTR_POLICY_IDENTIFIER);
+        String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME);
+        String permissionName = parser.getAttributeValue(
+                /* namespace= */ null, ATTR_PERMISSION_NAME);
+        return new PackagePermissionPolicyKey(identifier, packageName, permissionName);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToBundle(Bundle bundle) {
+        super.writeToBundle(bundle);
+        Bundle extraPolicyParams = new Bundle();
+        extraPolicyParams.putString(EXTRA_PACKAGE_NAME, mPackageName);
+        extraPolicyParams.putString(EXTRA_PERMISSION_NAME, mPermissionName);
+        bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PackagePermissionPolicyKey other = (PackagePermissionPolicyKey) o;
+        return Objects.equals(getIdentifier(), other.getIdentifier())
+                && Objects.equals(mPackageName, other.mPackageName)
+                && Objects.equals(mPermissionName, other.mPermissionName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getIdentifier(), mPackageName, mPermissionName);
+    }
+
+    @Override
+    public String toString() {
+        return "PackagePermissionPolicyKey{mIdentifier= " + getIdentifier() + "; mPackageName= "
+                + mPackageName + "; mPermissionName= " + mPermissionName + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getIdentifier());
+        dest.writeString(mPackageName);
+        dest.writeString(mPermissionName);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<PackagePermissionPolicyKey> CREATOR =
+            new Parcelable.Creator<PackagePermissionPolicyKey>() {
+                @Override
+                public PackagePermissionPolicyKey createFromParcel(Parcel source) {
+                    return new PackagePermissionPolicyKey(source);
+                }
+
+                @Override
+                public PackagePermissionPolicyKey[] newArray(int size) {
+                    return new PackagePermissionPolicyKey[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/PackagePolicyKey.java b/core/java/android/app/admin/PackagePolicyKey.java
new file mode 100644
index 0000000..3469970
--- /dev/null
+++ b/core/java/android/app/admin/PackagePolicyKey.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PACKAGE_NAME;
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Class used to identify a policy that relates to a certain package
+ * (e.g. {@link DevicePolicyManager#setUninstallBlocked}).
+ *
+ * @hide
+ */
+@SystemApi
+public final class PackagePolicyKey extends PolicyKey {
+    private static final String ATTR_PACKAGE_NAME = "package-name";
+
+    private final String mPackageName;
+
+    /**
+     * @hide
+     */
+    public PackagePolicyKey(@NonNull String key, @NonNull String packageName) {
+        super(key);
+        mPackageName = Objects.requireNonNull((packageName));
+    }
+
+    private PackagePolicyKey(Parcel source) {
+        super(source.readString());
+        mPackageName = source.readString();
+    }
+
+    /**
+     * @hide
+     */
+    public PackagePolicyKey(String key) {
+        super(key);
+        mPackageName = null;
+    }
+
+    /**
+     * Returns the package name this policy relates to.
+     */
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void saveToXml(TypedXmlSerializer serializer) throws IOException {
+        serializer.attribute(/* namespace= */ null, ATTR_POLICY_IDENTIFIER, getIdentifier());
+        serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public PackagePolicyKey readFromXml(TypedXmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        String policyKey = parser.getAttributeValue(/* namespace= */ null,
+                ATTR_POLICY_IDENTIFIER);
+        String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME);
+        return new PackagePolicyKey(policyKey, packageName);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToBundle(Bundle bundle) {
+        super.writeToBundle(bundle);
+        Bundle extraPolicyParams = new Bundle();
+        extraPolicyParams.putString(EXTRA_PACKAGE_NAME, mPackageName);
+        bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PackagePolicyKey other = (PackagePolicyKey) o;
+        return Objects.equals(getIdentifier(), other.getIdentifier())
+                && Objects.equals(mPackageName, other.mPackageName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getIdentifier(), mPackageName);
+    }
+
+    @Override
+    public String toString() {
+        return "PackagePolicyKey{mPolicyKey= " + getIdentifier()
+                + "; mPackageName= " + mPackageName + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getIdentifier());
+        dest.writeString(mPackageName);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<PackagePolicyKey> CREATOR =
+            new Parcelable.Creator<PackagePolicyKey>() {
+                @Override
+                public PackagePolicyKey createFromParcel(Parcel source) {
+                    return new PackagePolicyKey(source);
+                }
+
+                @Override
+                public PackagePolicyKey[] newArray(int size) {
+                    return new PackagePolicyKey[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/PolicyKey.java b/core/java/android/app/admin/PolicyKey.java
new file mode 100644
index 0000000..a35f634
--- /dev/null
+++ b/core/java/android/app/admin/PolicyKey.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_KEY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcelable;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Abstract class used to identify a policy returned from
+ * {@link DevicePolicyManager#getDevicePolicyState()}.
+ *
+ * @hide
+ */
+// This is ok as the constructor is hidden and all subclasses have implemented
+// Parcelable.
+@SuppressLint({"ParcelNotFinal", "ParcelCreator"})
+@SystemApi
+public abstract class PolicyKey implements Parcelable {
+    /**
+     * @hide
+     */
+    static final String ATTR_POLICY_IDENTIFIER = "policy-identifier";
+
+    private final String mIdentifier;
+
+    /**
+     * @hide
+     */
+    protected PolicyKey(@NonNull String identifier) {
+        mIdentifier = Objects.requireNonNull(identifier);
+    }
+
+    /**
+     * Returns the string identifier for this policy.
+     */
+    @NonNull
+    public String getIdentifier() {
+        return mIdentifier;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean hasSameIdentifierAs(PolicyKey other) {
+        if (other == null) {
+            return false;
+        }
+        return mIdentifier.equals(other.mIdentifier);
+    }
+
+    /**
+     * @hide
+     */
+    public static PolicyKey readGenericPolicyKeyFromXml(TypedXmlPullParser parser) {
+        String identifier = parser.getAttributeValue(
+                /* namespace= */ null, ATTR_POLICY_IDENTIFIER);
+        return new NoArgsPolicyKey(identifier);
+    }
+
+    /**
+     * @hide
+     */
+    public void saveToXml(TypedXmlSerializer serializer) throws IOException {
+        serializer.attribute(/* namespace= */ null, ATTR_POLICY_IDENTIFIER, mIdentifier);
+    }
+
+    /**
+     * @hide
+     */
+    public PolicyKey readFromXml(TypedXmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        // No need to read anything
+        return this;
+    }
+
+    /**
+     * @hide
+     */
+    public void writeToBundle(Bundle bundle) {
+        bundle.putString(EXTRA_POLICY_KEY, mIdentifier);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PolicyKey other = (PolicyKey) o;
+        return Objects.equals(mIdentifier, other.mIdentifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIdentifier);
+    }
+}
diff --git a/core/java/android/app/admin/PolicyState.java b/core/java/android/app/admin/PolicyState.java
new file mode 100644
index 0000000..da71bb1
--- /dev/null
+++ b/core/java/android/app/admin/PolicyState.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.LinkedHashMap;
+import java.util.Objects;
+
+/**
+ * Class containing the state of a certain policy (e.g. all values set by different admins,
+ * current resolved policy, etc).
+ *
+ * <p>Note that the value returned from {@link #getCurrentResolvedPolicy()} might not match any
+ * of the values in {@link #getPoliciesSetByAdmins()} as some policies might be affected by a
+ * conflicting global policy set on the device (retrieved using
+ * {@link DevicePolicyState#getPoliciesForUser} with {@link android.os.UserHandle#ALL}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PolicyState<V> implements Parcelable {
+    private final LinkedHashMap<EnforcingAdmin, PolicyValue<V>> mPoliciesSetByAdmins =
+            new LinkedHashMap<>();
+    private PolicyValue<V> mCurrentResolvedPolicy;
+    private ResolutionMechanism<V> mResolutionMechanism;
+
+    /**
+     * @hide
+     */
+    public PolicyState(
+            @NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<V>> policiesSetByAdmins,
+            PolicyValue<V> currentEnforcedPolicy,
+            @NonNull ResolutionMechanism<V> resolutionMechanism) {
+        Objects.requireNonNull(policiesSetByAdmins);
+        Objects.requireNonNull(resolutionMechanism);
+
+        mPoliciesSetByAdmins.putAll(policiesSetByAdmins);
+        mCurrentResolvedPolicy = currentEnforcedPolicy;
+        mResolutionMechanism = resolutionMechanism;
+    }
+
+    private PolicyState(Parcel source) {
+        int size = source.readInt();
+        for (int i = 0; i < size; i++) {
+            EnforcingAdmin admin = source.readParcelable(EnforcingAdmin.class.getClassLoader());
+            PolicyValue<V> policyValue = source.readParcelable(PolicyValue.class.getClassLoader());
+            mPoliciesSetByAdmins.put(admin, policyValue);
+        }
+        mCurrentResolvedPolicy = source.readParcelable((PolicyValue.class.getClassLoader()));
+        mResolutionMechanism = source.readParcelable(ResolutionMechanism.class.getClassLoader());
+    }
+
+    /**
+     * Returns all values set by admins for this policy
+     */
+    @NonNull
+    public LinkedHashMap<EnforcingAdmin, V> getPoliciesSetByAdmins() {
+        LinkedHashMap<EnforcingAdmin, V> policies = new LinkedHashMap<>();
+        for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
+            policies.put(admin, mPoliciesSetByAdmins.get(admin).getValue());
+        }
+        return policies;
+    }
+
+    /**
+     * Returns the current resolved policy value.
+     */
+    @Nullable
+    public V getCurrentResolvedPolicy() {
+        return mCurrentResolvedPolicy.getValue();
+    }
+
+    /**
+     * Returns the resolution mechanism used to resolve the enforced policy when the policy has
+     * been set by multiple enforcing admins {@link EnforcingAdmin}.
+     *
+     * @hide
+     */
+    @TestApi
+    @NonNull
+    public ResolutionMechanism<V> getResolutionMechanism() {
+        return mResolutionMechanism;
+    }
+
+    @Override
+    public String toString() {
+        return "PolicyState { mPoliciesSetByAdmins= "
+                + mPoliciesSetByAdmins + ", mCurrentResolvedPolicy= " + mCurrentResolvedPolicy
+                + ", mResolutionMechanism= " + mResolutionMechanism + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mPoliciesSetByAdmins.size());
+        for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
+            dest.writeParcelable(admin, flags);
+            dest.writeParcelable(mPoliciesSetByAdmins.get(admin), flags);
+        }
+        dest.writeParcelable(mCurrentResolvedPolicy, flags);
+        dest.writeParcelable(mResolutionMechanism, flags);
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<PolicyState<?>> CREATOR =
+            new Parcelable.Creator<PolicyState<?>>() {
+                @Override
+                public PolicyState<?> createFromParcel(Parcel source) {
+                    return new PolicyState<>(source);
+                }
+
+                @Override
+                public PolicyState<?>[] newArray(int size) {
+                    return new PolicyState[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/PolicyUpdateResult.java b/core/java/android/app/admin/PolicyUpdateResult.java
index 9e13e00..a6d0ebf 100644
--- a/core/java/android/app/admin/PolicyUpdateResult.java
+++ b/core/java/android/app/admin/PolicyUpdateResult.java
@@ -48,6 +48,14 @@
     public static final int RESULT_FAILURE_CONFLICTING_ADMIN_POLICY = 1;
 
     /**
+     * Result code to indicate that the policy set by the admin has been successfully cleared,
+     * admins will no longer receive policy updates for this policy after this point.
+     *
+     * <p>Note that the policy can still be enforced by some other admin.
+     */
+    public static final int RESULT_POLICY_CLEARED = 2;
+
+    /**
      * Reason codes for {@link #getResultCode()}.
      *
      * @hide
@@ -56,7 +64,8 @@
     @IntDef(flag = true, prefix = { "RESULT_" }, value = {
             RESULT_FAILURE_UNKNOWN,
             RESULT_SUCCESS,
-            RESULT_FAILURE_CONFLICTING_ADMIN_POLICY
+            RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
+            RESULT_POLICY_CLEARED
     })
     public @interface ResultCode {}
 
diff --git a/core/java/android/app/admin/PolicyValue.java b/core/java/android/app/admin/PolicyValue.java
new file mode 100644
index 0000000..b0a884b
--- /dev/null
+++ b/core/java/android/app/admin/PolicyValue.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Wrapper class to ensure that all policy values stored in the policy engine are parcelable.
+ *
+ * @hide
+ */
+public abstract class PolicyValue<V> implements Parcelable {
+    private V mValue;
+
+    public PolicyValue(V value) {
+        mValue = Objects.requireNonNull(value);
+    }
+
+    PolicyValue() {}
+
+    @NonNull
+    public V getValue() {
+        return mValue;
+    }
+
+    void setValue(V value) {
+        mValue = value;
+    }
+}
diff --git a/core/java/android/app/admin/ResolutionMechanism.java b/core/java/android/app/admin/ResolutionMechanism.java
new file mode 100644
index 0000000..a7c6842
--- /dev/null
+++ b/core/java/android/app/admin/ResolutionMechanism.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
+import android.os.Parcelable;
+
+/**
+ * Abstract class to identify a resolution mechanism that is used to resolve the enforced
+ * policy when being set by multiple admins (see {@link PolicyState#getResolutionMechanism()}).
+ *
+ * @hide
+ */
+// This is ok as the constructor is hidden and all subclasses have implemented
+// Parcelable.
+@SuppressLint({"ParcelNotFinal", "ParcelCreator"})
+@TestApi
+public abstract class ResolutionMechanism<V> implements Parcelable {
+    /**
+     * @hide
+     */
+    ResolutionMechanism(){}
+}
diff --git a/core/java/android/app/admin/RoleAuthority.java b/core/java/android/app/admin/RoleAuthority.java
new file mode 100644
index 0000000..7fdd118
--- /dev/null
+++ b/core/java/android/app/admin/RoleAuthority.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Class used to identify the authority of the {@link EnforcingAdmin} based on a certain role/roles
+ * it holds.
+ *
+ * @hide
+ */
+@SystemApi
+public final class RoleAuthority extends Authority {
+    private final Set<String> mRoles;
+
+    /**
+     * @hide
+     */
+    public RoleAuthority(@NonNull Set<String> roles) {
+        mRoles = new HashSet<>(Objects.requireNonNull(roles));
+    }
+
+    private RoleAuthority(Parcel source) {
+        String[] roles = source.readStringArray();
+        mRoles = roles == null ? new HashSet<>() : new HashSet<>(Arrays.stream(roles).toList());
+    }
+
+    /**
+     * Returns the list of roles held by the associated admin.
+     */
+    @NonNull
+    public Set<String> getRoles() {
+        return mRoles;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeArray(mRoles.toArray());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RoleAuthority other = (RoleAuthority) o;
+        return Objects.equals(mRoles, other.mRoles);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRoles);
+    }
+
+    @Override
+    public String toString() {
+        return "RoleAuthority { mRoles= " + mRoles + " }";
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<RoleAuthority> CREATOR =
+            new Parcelable.Creator<RoleAuthority>() {
+                @Override
+                public RoleAuthority createFromParcel(Parcel source) {
+                    return new RoleAuthority(source);
+                }
+
+                @Override
+                public RoleAuthority[] newArray(int size) {
+                    return new RoleAuthority[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/StringPolicyValue.java b/core/java/android/app/admin/StringPolicyValue.java
new file mode 100644
index 0000000..14b6dab
--- /dev/null
+++ b/core/java/android/app/admin/StringPolicyValue.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public final class StringPolicyValue extends PolicyValue<String> {
+
+    public StringPolicyValue(@NonNull String value) {
+        super(value);
+    }
+
+    private StringPolicyValue(Parcel source) {
+        super(source.readString());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        StringPolicyValue other = (StringPolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "StringPolicyValue { " + getValue() + " }";
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(getValue());
+    }
+
+    @NonNull
+    public static final Creator<StringPolicyValue> CREATOR = new Creator<StringPolicyValue>() {
+                @Override
+                public StringPolicyValue createFromParcel(Parcel source) {
+                    return new StringPolicyValue(source);
+                }
+
+                @Override
+                public StringPolicyValue[] newArray(int size) {
+                    return new StringPolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/StringSetPolicyValue.java b/core/java/android/app/admin/StringSetPolicyValue.java
new file mode 100644
index 0000000..cbfc604
--- /dev/null
+++ b/core/java/android/app/admin/StringSetPolicyValue.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * @hide
+ */
+public final class StringSetPolicyValue extends PolicyValue<Set<String>> {
+
+    public StringSetPolicyValue(@NonNull Set<String> value) {
+        super(value);
+    }
+
+    public StringSetPolicyValue(Parcel source) {
+        this(readValues(source));
+    }
+
+    private static Set<String> readValues(Parcel source) {
+        Set<String> values = new HashSet<>();
+        int size = source.readInt();
+        for (int i = 0; i < size; i++) {
+            values.add(source.readString());
+        }
+        return values;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        StringSetPolicyValue other = (StringSetPolicyValue) o;
+        return Objects.equals(getValue(), other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getValue());
+    }
+
+    @Override
+    public String toString() {
+        return "StringSetPolicyValue { " + getValue() + " }";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(getValue().size());
+        for (String entry : getValue()) {
+            dest.writeString(entry);
+        }
+    }
+
+    @NonNull
+    public static final Creator<StringSetPolicyValue> CREATOR =
+            new Creator<StringSetPolicyValue>() {
+                @Override
+                public StringSetPolicyValue createFromParcel(Parcel source) {
+                    return new StringSetPolicyValue(source);
+                }
+
+                @Override
+                public StringSetPolicyValue[] newArray(int size) {
+                    return new StringSetPolicyValue[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/StringSetUnion.java b/core/java/android/app/admin/StringSetUnion.java
new file mode 100644
index 0000000..730e6a2
--- /dev/null
+++ b/core/java/android/app/admin/StringSetUnion.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Set;
+
+/**
+ * Class to identify a union resolution mechanism for {@code Set<String>} policies, it's used to
+ * resolve the enforced policy when being set by multiple admins (see
+ * {@link PolicyState#getResolutionMechanism()}).
+ *
+ * @hide
+ */
+@TestApi
+public final class StringSetUnion extends ResolutionMechanism<Set<String>> {
+
+    @Override
+    public String toString() {
+        return "StringSetUnion {}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Parcelable.Creator<StringSetUnion> CREATOR =
+            new Parcelable.Creator<StringSetUnion>() {
+                @Override
+                public StringSetUnion createFromParcel(Parcel source) {
+                    return new StringSetUnion();
+                }
+
+                @Override
+                public StringSetUnion[] newArray(int size) {
+                    return new StringSetUnion[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/TopPriority.java b/core/java/android/app/admin/TopPriority.java
new file mode 100644
index 0000000..e712274
--- /dev/null
+++ b/core/java/android/app/admin/TopPriority.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Class to identify a top priority resolution mechanism that is used to resolve the enforced
+ * policy when being set by multiple admins (see {@link PolicyState#getResolutionMechanism()}).
+ *
+ * <p>Priorities are defined based on the calling admin's {@link Authority}.
+ *
+ * @hide
+ */
+@TestApi
+public final class TopPriority<V> extends ResolutionMechanism<V> {
+
+    private final List<String> mHighestToLowestPriorityAuthorities;
+
+    /**
+     * @hide
+     */
+    public TopPriority(@NonNull List<String> highestToLowestPriorityAuthorities) {
+        mHighestToLowestPriorityAuthorities = Objects.requireNonNull(
+                highestToLowestPriorityAuthorities);
+    }
+
+    /**
+     * Returns an ordered list of authorities from highest priority to lowest priority for a
+     * certain policy.
+     */
+    @NonNull
+    List<String> getHighestToLowestPriorityAuthorities() {
+        return mHighestToLowestPriorityAuthorities;
+    }
+
+    @Override
+    public String toString() {
+        return "TopPriority { mHighestToLowestPriorityAuthorities= "
+                + mHighestToLowestPriorityAuthorities + " }";
+    }
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeStringArray(mHighestToLowestPriorityAuthorities.toArray(new String[0]));
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<TopPriority<?>> CREATOR =
+            new Parcelable.Creator<TopPriority<?>>() {
+                @Override
+                public TopPriority<?> createFromParcel(Parcel source) {
+                    String[] highestToLowestPriorityAuthorities = source.readStringArray();
+                    return new TopPriority<>(
+                            Arrays.stream(highestToLowestPriorityAuthorities).toList());
+                }
+
+                @Override
+                public TopPriority<?>[] newArray(int size) {
+                    return new TopPriority[size];
+                }
+            };
+
+}
diff --git a/core/java/android/app/admin/UnknownAuthority.java b/core/java/android/app/admin/UnknownAuthority.java
new file mode 100644
index 0000000..4492b96
--- /dev/null
+++ b/core/java/android/app/admin/UnknownAuthority.java
@@ -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 android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+
+/**
+ * Class used to identify a default value for the authority of the {@link EnforcingAdmin} setting
+ * a policy, meaning it is not one of the other known subclasses of {@link Authority}, this would be
+ * the case for example for a system component setting the policy.
+ *
+ * @hide
+ */
+@SystemApi
+public final class UnknownAuthority extends Authority {
+
+    /**
+     * @hide
+     */
+    public static final UnknownAuthority UNKNOWN_AUTHORITY = new UnknownAuthority();
+
+    private UnknownAuthority() {}
+
+    @Override
+    public String toString() {
+        return "DefaultAuthority {}";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        return super.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Creator<UnknownAuthority> CREATOR =
+            new Creator<UnknownAuthority>() {
+                @Override
+                public UnknownAuthority createFromParcel(Parcel source) {
+                    return new UnknownAuthority();
+                }
+
+                @Override
+                public UnknownAuthority[] newArray(int size) {
+                    return new UnknownAuthority[size];
+                }
+            };
+}
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 6e49e95..b7ec7b5 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -545,6 +545,7 @@
         int resolveViewAutofillFlags(Context context, int fillRequestFlags) {
             return (fillRequestFlags & FillRequest.FLAG_MANUAL_REQUEST) != 0
                         || context.isAutofillCompatibilityEnabled()
+                        || (fillRequestFlags & FillRequest.FLAG_PCC_DETECTION) != 0
                     ? View.AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS : 0;
         }
 
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index e323e89..909073e 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -265,15 +265,9 @@
     public void onCreate() {
     }
 
-    /**
-     * Provided as a convenience for agent implementations that need an opportunity
-     * to do one-time initialization before the actual backup or restore operation
-     * is begun with information about the calling user.
-     * <p>
-     *
-     * @hide
-     */
+    /** @hide */
     public void onCreate(UserHandle user) {
+        mUser = user;
         onCreate();
     }
 
@@ -284,7 +278,6 @@
      */
     @Deprecated
     public void onCreate(UserHandle user, @BackupDestination int backupDestination) {
-        mUser = user;
         mBackupDestination = backupDestination;
 
         onCreate(user);
@@ -295,7 +288,6 @@
     */
     public void onCreate(UserHandle user, @BackupDestination int backupDestination,
             @OperationType int operationType) {
-        mUser = user;
         mBackupDestination = backupDestination;
         mLogger = new BackupRestoreEventLogger(operationType);
 
diff --git a/core/java/android/app/search/ISearchUiManager.aidl b/core/java/android/app/search/ISearchUiManager.aidl
index a298a2c..fefbd5a 100644
--- a/core/java/android/app/search/ISearchUiManager.aidl
+++ b/core/java/android/app/search/ISearchUiManager.aidl
@@ -36,5 +36,11 @@
 
     void notifyEvent(in SearchSessionId sessionId, in Query input, in SearchTargetEvent event);
 
+    void registerEmptyQueryResultUpdateCallback(in SearchSessionId sessionId, in ISearchCallback callback);
+
+    void requestEmptyQueryResultUpdate(in SearchSessionId sessionId);
+
+    void unregisterEmptyQueryResultUpdateCallback(in SearchSessionId sessionId, in ISearchCallback callback);
+
     void destroySearchSession(in SearchSessionId sessionId);
 }
diff --git a/core/java/android/app/search/SearchSession.java b/core/java/android/app/search/SearchSession.java
index 10db337..9e0a1d0 100644
--- a/core/java/android/app/search/SearchSession.java
+++ b/core/java/android/app/search/SearchSession.java
@@ -28,8 +28,11 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
 import dalvik.system.CloseGuard;
 
 import java.util.List;
@@ -83,6 +86,8 @@
 
     private final SearchSessionId mSessionId;
     private final IBinder mToken = new Binder();
+    @GuardedBy("itself")
+    private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>();
 
     /**
      * Creates a new search ui client.
@@ -156,6 +161,94 @@
             e.rethrowFromSystemServer();
         }
     }
+    /**
+     * Request the search ui service provide continuous updates of {@link SearchTarget} list
+     * via the provided callback to render for zero state, until the given callback is
+     * unregistered. Zero state means when user entered search ui but not issued any query yet.
+     *
+     * @see SearchSession.Callback#onTargetsAvailable(List).
+     *
+     * @param callbackExecutor The callback executor to use when calling the callback.
+     * @param callback The Callback to be called when updates of search targets for zero state
+     *                 are available.
+     */
+    public void registerEmptyQueryResultUpdateCallback(
+            @NonNull @CallbackExecutor Executor callbackExecutor,
+            @NonNull Callback callback) {
+        synchronized (mRegisteredCallbacks) {
+            if (mIsClosed.get()) {
+                throw new IllegalStateException("This client has already been destroyed.");
+            }
+            if (mRegisteredCallbacks.containsKey(callback)) {
+                // Skip if this callback is already registered
+                return;
+            }
+            try {
+                final CallbackWrapper callbackWrapper = new CallbackWrapper(callbackExecutor,
+                        callback::onTargetsAvailable);
+                mInterface.registerEmptyQueryResultUpdateCallback(mSessionId, callbackWrapper);
+                mRegisteredCallbacks.put(callback, callbackWrapper);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to register for empty query result updates", e);
+                e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Requests the search ui service to stop providing continuous updates of {@link SearchTarget}
+     * to the provided callback for zero state until the callback is re-registered. Zero state
+     * means when user entered search ui but not issued any query yet.
+     *
+     * @see {@link SearchSession#registerEmptyQueryResultUpdateCallback(Executor, Callback)}
+     * @param callback The callback to be unregistered.
+     */
+    public void unregisterEmptyQueryResultUpdateCallback(
+            @NonNull Callback callback) {
+        synchronized (mRegisteredCallbacks) {
+            if (mIsClosed.get()) {
+                throw new IllegalStateException("This client has already been destroyed.");
+            }
+
+            if (!mRegisteredCallbacks.containsKey(callback)) {
+                // Skip if this callback was never registered
+                return;
+            }
+            try {
+                final CallbackWrapper callbackWrapper = mRegisteredCallbacks.remove(callback);
+                mInterface.unregisterEmptyQueryResultUpdateCallback(mSessionId, callbackWrapper);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to unregister for empty query result updates", e);
+                e.rethrowAsRuntimeException();
+            }
+        }
+    }
+
+    /**
+     * Requests the search ui service to dispatch a new set of search targets to the pre-registered
+     * callback for zero state. Zero state means when user entered search ui but not issued any
+     * query yet. This method can be used for client to sync up with server data if they think data
+     * might be out of sync, for example, after restart.
+     * Pre-register a callback with
+     * {@link SearchSession#registerEmptyQueryResultUpdateCallback(Executor, Callback)}
+     * is required before calling this method. Otherwise this is no-op.
+     *
+     * @see {@link SearchSession#registerEmptyQueryResultUpdateCallback(Executor, Callback)}
+     * @see {@link SearchSession.Callback#onTargetsAvailable(List)}.
+     */
+    public void requestEmptyQueryResultUpdate() {
+        if (mIsClosed.get()) {
+            throw new IllegalStateException("This client has already been destroyed.");
+        }
+
+        try {
+            mInterface.requestEmptyQueryResultUpdate(mSessionId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to request empty query result update", e);
+            e.rethrowAsRuntimeException();
+        }
+    }
+
 
     /**
      * Destroys the client and unregisters the callback. Any method on this class after this call
@@ -213,6 +306,19 @@
         }
     }
 
+    /**
+     *  Callback for receiving {@link SearchTarget} updates for zero state. Zero state
+     *  means when user entered search ui but not issued any query yet.
+     */
+    public interface Callback {
+
+        /**
+         * Called when a new set of {@link SearchTarget} are available for zero state.
+         * @param targets Sorted list of search targets.
+         */
+        void onTargetsAvailable(@NonNull List<SearchTarget> targets);
+    }
+
     static class CallbackWrapper extends Stub {
 
         private final Consumer<List<SearchTarget>> mCallback;
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 15f3f34..8842955 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -718,7 +718,9 @@
      * @return the associations list
      * @see #addOnAssociationsChangedListener(Executor, OnAssociationsChangedListener)
      * @see #removeOnAssociationsChangedListener(OnAssociationsChangedListener)
+     * @hide
      */
+    @SystemApi
     @UserHandleAware
     @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
     public @NonNull List<AssociationInfo> getAllAssociations() {
@@ -732,7 +734,10 @@
 
     /**
      * Listener for any changes to {@link AssociationInfo}.
+     *
+     * @hide
      */
+    @SystemApi
     public interface OnAssociationsChangedListener {
         /**
          * Invoked when a change occurs to any of the associations for the user (including adding
@@ -747,7 +752,9 @@
      * Register listener for any changes to {@link AssociationInfo}.
      *
      * @see #getAllAssociations()
+     * @hide
      */
+    @SystemApi
     @UserHandleAware
     @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
     public void addOnAssociationsChangedListener(
@@ -769,7 +776,9 @@
      * Unregister listener for any changes to {@link AssociationInfo}.
      *
      * @see #getAllAssociations()
+     * @hide
      */
+    @SystemApi
     @UserHandleAware
     @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
     public void removeOnAssociationsChangedListener(
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
index 01c5fa1..f660377 100644
--- a/core/java/android/companion/CompanionDeviceService.java
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -210,6 +210,10 @@
      * As an example, it's valid to provide streams obtained from a
      * {@link BluetoothSocket} to this method, since {@link BluetoothSocket}
      * meets the API contract described above.
+     * <p>
+     * This method passes through to
+     * {@link CompanionDeviceManager#attachSystemDataTransport(int, InputStream, OutputStream)}
+     * for your convenience if you get callbacks in this class.
      *
      * @param associationId id of the associated device
      * @param in already connected stream of data incoming from remote
@@ -229,6 +233,10 @@
     /**
      * Detach any bidirectional communication streams previously configured
      * through {@link #attachSystemDataTransport}.
+     * <p>
+     * This method passes through to
+     * {@link CompanionDeviceManager#detachSystemDataTransport(int)}
+     * for your convenience if you get callbacks in this class.
      *
      * @param associationId id of the associated device
      */
diff --git a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
index a46dc53..fc7f85c 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
@@ -30,8 +30,9 @@
      *
      * @param displayId The display ID on which the activity change happened.
      * @param topActivity The component name of the top activity.
+     * @param userId The user ID associated with the top activity.
      */
-    void onTopActivityChanged(int displayId, in ComponentName topActivity);
+    void onTopActivityChanged(int displayId, in ComponentName topActivity, in int userId);
 
     /**
      * Called when the display becomes empty (e.g. if the user hits back on the last
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index d585e8f..3e6b380 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -27,6 +27,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 import android.companion.AssociationInfo;
 import android.companion.virtual.audio.VirtualAudioDevice;
@@ -378,13 +379,16 @@
                 new IVirtualDeviceActivityListener.Stub() {
 
                     @Override
-                    public void onTopActivityChanged(int displayId, ComponentName topActivity) {
+                    public void onTopActivityChanged(int displayId, ComponentName topActivity,
+                            @UserIdInt int userId) {
                         final long token = Binder.clearCallingIdentity();
                         try {
                             synchronized (mActivityListenersLock) {
                                 for (int i = 0; i < mActivityListeners.size(); i++) {
                                     mActivityListeners.valueAt(i)
                                             .onTopActivityChanged(displayId, topActivity);
+                                    mActivityListeners.valueAt(i)
+                                          .onTopActivityChanged(displayId, topActivity, userId);
                                 }
                             }
                         } finally {
@@ -1087,10 +1091,25 @@
          *
          * @param displayId The display ID on which the activity change happened.
          * @param topActivity The component name of the top activity.
+         * @deprecated Use {@link #onTopActivityChanged(int, ComponentName, int)} instead
          */
         void onTopActivityChanged(int displayId, @NonNull ComponentName topActivity);
 
         /**
+         * Called when the top activity is changed.
+         *
+         * <p>Note: When there are no activities running on the virtual display, the
+         * {@link #onDisplayEmpty(int)} will be called. If the value topActivity is cached, it
+         * should be cleared when {@link #onDisplayEmpty(int)} is called.
+         *
+         * @param displayId   The display ID on which the activity change happened.
+         * @param topActivity The component name of the top activity.
+         * @param userId      The user ID associated with the top activity.
+         */
+        default void onTopActivityChanged(int displayId, @NonNull ComponentName topActivity,
+                @UserIdInt int userId) {}
+
+        /**
          * Called when the display becomes empty (e.g. if the user hits back on the last
          * activity of the root task).
          *
@@ -1115,6 +1134,12 @@
             mExecutor.execute(() -> mActivityListener.onTopActivityChanged(displayId, topActivity));
         }
 
+        public void onTopActivityChanged(int displayId, ComponentName topActivity,
+                @UserIdInt int userId) {
+            mExecutor.execute(() ->
+                    mActivityListener.onTopActivityChanged(displayId, topActivity, userId));
+        }
+
         public void onDisplayEmpty(int displayId) {
             mExecutor.execute(() -> mActivityListener.onDisplayEmpty(displayId));
         }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a6e074c..0d330ce 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -6232,12 +6232,24 @@
     public static final String SATELLITE_SERVICE = "satellite";
 
     /**
+     * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.net.wifi.sharedconnectivity.app.SharedConnectivityManager} for accessing
+     * shared connectivity services.
+     *
+     * @see #getSystemService(String)
+     * @see android.net.wifi.sharedconnectivity.app.SharedConnectivityManager
+     * @hide
+     */
+    @SystemApi
+    public static final String SHARED_CONNECTIVITY_SERVICE = "shared_connectivity";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
      * @param permission The name of the permission being checked.
      * @param pid The process ID being checked against.  Must be > 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      *
      * @return {@link PackageManager#PERMISSION_GRANTED} if the given
@@ -6327,7 +6339,7 @@
      *
      * @param permission The name of the permission being checked.
      * @param pid The process ID being checked against.  Must be &gt; 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      * @param message A message to include in the exception if it is thrown.
      *
@@ -6471,7 +6483,7 @@
      *
      * @param uri The uri that is being checked.
      * @param pid The process ID being checked against.  Must be &gt; 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      * @param modeFlags The access modes to check.
      *
@@ -6499,7 +6511,7 @@
      *
      * @param uris The list of URIs that is being checked.
      * @param pid The process ID being checked against.  Must be &gt; 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      * @param modeFlags The access modes to check for the list of uris
      *
@@ -6625,7 +6637,7 @@
      * @param writePermission The permission that provides overall write
      * access, or null to not do this check.
      * @param pid The process ID being checked against.  Must be &gt; 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      * @param modeFlags The access modes to check.
      *
@@ -6649,7 +6661,7 @@
      *
      * @param uri The uri that is being checked.
      * @param pid The process ID being checked against.  Must be &gt; 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      * @param modeFlags The access modes to enforce.
      * @param message A message to include in the exception if it is thrown.
@@ -6708,7 +6720,7 @@
      * @param writePermission The permission that provides overall write
      * access, or null to not do this check.
      * @param pid The process ID being checked against.  Must be &gt; 0.
-     * @param uid The user ID being checked against.  A uid of 0 is the root
+     * @param uid The UID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      * @param modeFlags The access modes to enforce.
      * @param message A message to include in the exception if it is thrown.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 30984b2..5818ed7 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -31,8 +31,10 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
+import android.app.StatusBarManager;
 import android.bluetooth.BluetoothDevice;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
@@ -576,6 +578,13 @@
  *     <li> {@link #ACTION_SHUTDOWN}
  * </ul>
  *
+ * <p class="note"><strong>Note: </strong>If your app targets Android 11
+ * (API level 30) or higher, registering broadcast such as
+ * {@link #ACTION_PACKAGES_SUSPENDED} that includes package details in the
+ * extras receives a filtered list of apps or nothing. Learn more about how to
+ * <a href="/training/basics/intents/package-visibility">manage package visibility</a>.
+ * </p>
+ *
  * <h3>Standard Categories</h3>
  *
  * <p>These are the current standard categories that can be used to further
@@ -4549,8 +4558,8 @@
      * @see #EXTRA_SIM_LOCKED_REASON
      * @see #EXTRA_REBROADCAST_ON_UNLOCK
      *
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED} or
-     * {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED} or
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      *
      * @hide
      */
@@ -4573,42 +4582,42 @@
      * @see #SIM_STATE_IMSI
      * @see #SIM_STATE_LOADED
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String EXTRA_SIM_STATE = "ss";
 
     /**
      * The intent value UNKNOWN represents the SIM state unknown
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_UNKNOWN = "UNKNOWN";
 
     /**
      * The intent value NOT_READY means that the SIM is not ready eg. radio is off or powering on
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_NOT_READY = "NOT_READY";
 
     /**
      * The intent value ABSENT means the SIM card is missing
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_ABSENT = "ABSENT";
 
     /**
      * The intent value PRESENT means the device has a SIM card inserted
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_PRESENT = "PRESENT";
 
     /**
      * The intent value CARD_IO_ERROR means for three consecutive times there was SIM IO error
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     static public final String SIM_STATE_CARD_IO_ERROR = "CARD_IO_ERROR";
 
@@ -4616,35 +4625,35 @@
      * The intent value CARD_RESTRICTED means card is present but not usable due to carrier
      * restrictions
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     static public final String SIM_STATE_CARD_RESTRICTED = "CARD_RESTRICTED";
 
     /**
      * The intent value LOCKED means the SIM is locked by PIN or by network
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_LOCKED = "LOCKED";
 
     /**
      * The intent value READY means the SIM is ready to be accessed
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_READY = "READY";
 
     /**
      * The intent value IMSI means the SIM IMSI is ready in property
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_IMSI = "IMSI";
 
     /**
      * The intent value LOADED means all SIM records, including IMSI, are loaded
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED}
      */
     public static final String SIM_STATE_LOADED = "LOADED";
 
@@ -4658,21 +4667,24 @@
      * @see #SIM_ABSENT_ON_PERM_DISABLED
      *
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      */
     public static final String EXTRA_SIM_LOCKED_REASON = "reason";
 
     /**
      * The intent value PIN means the SIM is locked on PIN1
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      */
     public static final String SIM_LOCKED_ON_PIN = "PIN";
 
     /**
      * The intent value PUK means the SIM is locked on PUK1
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      */
     /* PUK means ICC is locked on PUK1 */
     public static final String SIM_LOCKED_ON_PUK = "PUK";
@@ -4680,14 +4692,16 @@
     /**
      * The intent value NETWORK means the SIM is locked on NETWORK PERSONALIZATION
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      */
     public static final String SIM_LOCKED_NETWORK = "NETWORK";
 
     /**
      * The intent value PERM_DISABLED means SIM is permanently disabled due to puk fails
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      */
     public static final String SIM_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
 
@@ -4696,8 +4710,8 @@
      * is a rebroadcast on unlock. Defaults to {@code false} if not specified.
      *
      * @hide
-     * @deprecated Use {@link #ACTION_SIM_CARD_STATE_CHANGED} or
-     * {@link #ACTION_SIM_APPLICATION_STATE_CHANGED}
+     * @deprecated Use {@link android.telephony.TelephonyManager#ACTION_SIM_CARD_STATE_CHANGED} or
+     * {@link android.telephony.TelephonyManager#ACTION_SIM_APPLICATION_STATE_CHANGED}
      */
     public static final String EXTRA_REBROADCAST_ON_UNLOCK = "rebroadcastOnUnlock";
 
@@ -5137,6 +5151,86 @@
     public static final String EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE";
 
     /**
+     * Activity Action: Use with startActivityForResult to start a system activity that captures
+     * content on the screen to take a screenshot and present it to the user for editing. The
+     * edited screenshot is saved on device and returned to the calling activity as a {@link Uri}
+     * through {@link #getData()}. User interaction is required to return the edited screenshot to
+     * the calling activity.
+     *
+     * <p>This intent action requires the permission
+     * {@link android.Manifest.permission#LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE}.
+     *
+     * <p>Callers should query
+     * {@link StatusBarManager#canLaunchCaptureContentActivityForNote(Activity)} before showing a UI
+     * element that allows users to trigger this flow.
+     */
+    @RequiresPermission(Manifest.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE)
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE =
+            "android.intent.action.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE";
+
+    /**
+     * An int extra used by activity started with
+     * {@link #ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE} to indicate status of the response.
+     * This extra is used along with result code set to {@link android.app.Activity#RESULT_OK}.
+     *
+     * <p>The value for this extra can be one of the following:
+     * <ul>
+     *     <li>{@link #CAPTURE_CONTENT_FOR_NOTE_SUCCESS}</li>
+     *     <li>{@link #CAPTURE_CONTENT_FOR_NOTE_FAILED}</li>
+     *     <li>{@link #CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED}</li>
+     *     <li>{@link #CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED}</li>
+     *     <li>{@link #CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN}</li>
+     * </ul>
+     */
+    public static final String EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE =
+            "android.intent.extra.CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE";
+
+    /**
+     * A response code used with {@link #EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE} to indicate
+     * that the request was a success.
+     *
+     * <p>This code will only be returned after the user has interacted with the system screenshot
+     * activity to consent to sharing the data with the note.
+     *
+     * <p>The captured screenshot is returned as a {@link Uri} through {@link #getData()}.
+     */
+    public static final int CAPTURE_CONTENT_FOR_NOTE_SUCCESS = 0;
+
+    /**
+     * A response code used with {@link #EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE} to indicate
+     * that something went wrong.
+     */
+    public static final int CAPTURE_CONTENT_FOR_NOTE_FAILED = 1;
+
+    /**
+     * A response code used with {@link #EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE} to indicate
+     * that user canceled the content capture flow.
+     */
+    public static final int CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED = 2;
+
+    /**
+     * A response code used with {@link #EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE} to indicate
+     * that the intent action {@link #ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE} was started
+     * by an activity that is running in a non-supported window mode.
+     */
+    public static final int CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED = 3;
+
+    /**
+     * A response code used with {@link #EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE} to indicate
+     * that screenshot is blocked by IT admin.
+     */
+    public static final int CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN = 4;
+
+    /** @hide */
+    @IntDef(value = {
+            CAPTURE_CONTENT_FOR_NOTE_SUCCESS, CAPTURE_CONTENT_FOR_NOTE_FAILED,
+            CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED,
+            CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CaptureContentForNoteStatusCodes {}
+
+    /**
      * Broadcast Action: Sent to the integrity component when a package
      * needs to be verified. The data contains the package URI along with other relevant
      * information.
@@ -5825,13 +5919,12 @@
 
     /**
      * Optional argument to be used with {@link #ACTION_CHOOSER}.
-     * A {@link android.app.PendingIntent} to be sent when the user wants to do payload reselection
-     * in the sharesheet.
-     * A reselection action allows the user to return to the source app to change the content being
-     * shared.
+     * A {@link android.app.PendingIntent} to be sent when the user wants to modify the content that
+     * they're sharing. This can be used to allow the user to return to the source app to, for
+     * example, select different media.
      */
-    public static final String EXTRA_CHOOSER_PAYLOAD_RESELECTION_ACTION =
-            "android.intent.extra.CHOOSER_PAYLOAD_RESELECTION_ACTION";
+    public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION =
+            "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION";
 
     /**
      * An {@code ArrayList} of {@code String} annotations describing content for
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 611ad88..d4d323e 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -3039,4 +3039,81 @@
         ArrayList<String> list = getHostsList();
         return list.toArray(new String[list.size()]);
     }
+
+    /**
+     * @hide
+     */
+    public static boolean filterEquals(IntentFilter f1, IntentFilter f2) {
+        int s1 = f1.countActions();
+        int s2 = f2.countActions();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasAction(f1.getAction(i))) {
+                return false;
+            }
+        }
+        s1 = f1.countCategories();
+        s2 = f2.countCategories();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasCategory(f1.getCategory(i))) {
+                return false;
+            }
+        }
+        s1 = f1.countDataTypes();
+        s2 = f2.countDataTypes();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasExactDataType(f1.getDataType(i))) {
+                return false;
+            }
+        }
+        s1 = f1.countDataSchemes();
+        s2 = f2.countDataSchemes();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasDataScheme(f1.getDataScheme(i))) {
+                return false;
+            }
+        }
+        s1 = f1.countDataAuthorities();
+        s2 = f2.countDataAuthorities();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasDataAuthority(f1.getDataAuthority(i))) {
+                return false;
+            }
+        }
+        s1 = f1.countDataPaths();
+        s2 = f2.countDataPaths();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasDataPath(f1.getDataPath(i))) {
+                return false;
+            }
+        }
+        s1 = f1.countDataSchemeSpecificParts();
+        s2 = f2.countDataSchemeSpecificParts();
+        if (s1 != s2) {
+            return false;
+        }
+        for (int i=0; i<s1; i++) {
+            if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 8853b70..ccb53cf 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -18,9 +18,10 @@
 
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityManager.PendingIntentInfo;
+import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.IApplicationThread;
-import android.app.ActivityManager.PendingIntentInfo;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Handler;
@@ -160,7 +161,7 @@
      */
     public void sendIntent(Context context, int code, Intent intent,
             OnFinished onFinished, Handler handler) throws SendIntentException {
-        sendIntent(context, code, intent, onFinished, handler, null);
+        sendIntent(context, code, intent, onFinished, handler, null, null /* options */);
     }
 
     /**
@@ -192,6 +193,42 @@
     public void sendIntent(Context context, int code, Intent intent,
             OnFinished onFinished, Handler handler, String requiredPermission)
             throws SendIntentException {
+        sendIntent(context, code, intent, onFinished, handler, requiredPermission,
+                null /* options */);
+    }
+
+    /**
+     * Perform the operation associated with this IntentSender, allowing the
+     * caller to specify information about the Intent to use and be notified
+     * when the send has completed.
+     *
+     * @param context The Context of the caller.  This may be null if
+     * <var>intent</var> is also null.
+     * @param code Result code to supply back to the IntentSender's target.
+     * @param intent Additional Intent data.  See {@link Intent#fillIn
+     * Intent.fillIn()} for information on how this is applied to the
+     * original Intent.  Use null to not modify the original Intent.
+     * @param onFinished The object to call back on when the send has
+     * completed, or null for no callback.
+     * @param handler Handler identifying the thread on which the callback
+     * should happen.  If null, the callback will happen from the thread
+     * pool of the process.
+     * @param requiredPermission Name of permission that a recipient of the PendingIntent
+     * is required to hold.  This is only valid for broadcast intents, and
+     * corresponds to the permission argument in
+     * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
+     * If null, no permission is required.
+     * @param options Additional options the caller would like to provide to modify the sending
+     * behavior.  May be built from an {@link ActivityOptions} to apply to an activity start.
+     *
+     * @throws SendIntentException Throws CanceledIntentException if the IntentSender
+     * is no longer allowing more intents to be sent through it.
+     * @hide
+     */
+    public void sendIntent(Context context, int code, Intent intent,
+            OnFinished onFinished, Handler handler, String requiredPermission,
+            @Nullable Bundle options)
+            throws SendIntentException {
         try {
             String resolvedType = intent != null ?
                     intent.resolveTypeIfNeeded(context.getContentResolver())
@@ -203,7 +240,7 @@
                     onFinished != null
                             ? new FinishedDispatcher(this, onFinished, handler)
                             : null,
-                    requiredPermission, null);
+                    requiredPermission, options);
             if (res < 0) {
                 throw new SendIntentException();
             }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index fd73719..db72e29 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1103,6 +1103,17 @@
     public static final long ALWAYS_SANDBOX_DISPLAY_APIS = 185004937L; // buganizer id
 
     /**
+     * This change id excludes the packages it is applied to from ignoreOrientationRequest behaviour
+     * that can be enabled by the device manufacturers for the com.android.server.wm.DisplayArea
+     * or for the whole display.
+     * @hide
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    public static final long OVERRIDE_RESPECT_REQUESTED_ORIENTATION = 236283604L; // buganizer id
+
+    /**
      * This change id excludes the packages it is applied to from the camera compat force rotation
      * treatment. See com.android.server.wm.DisplayRotationCompatPolicy for context.
      * @hide
@@ -1138,34 +1149,6 @@
             264301586L; // buganizer id
 
     /**
-     * This change id forces the packages it is applied to sandbox {@link android.view.View} API to
-     * an activity bounds for:
-     *
-     * <p>{@link android.view.View#getLocationOnScreen},
-     * {@link android.view.View#getWindowVisibleDisplayFrame},
-     * {@link android.view.View}#getWindowDisplayFrame,
-     * {@link android.view.View}#getBoundsOnScreen.
-     *
-     * <p>For {@link android.view.View#getWindowVisibleDisplayFrame} and
-     * {@link android.view.View}#getWindowDisplayFrame this sandboxing is happening indirectly
-     * through
-     * {@link android.view.ViewRootImpl}#getWindowVisibleDisplayFrame,
-     * {@link android.view.ViewRootImpl}#getDisplayFrame respectively.
-     *
-     * <p>Some applications assume that they occupy the whole screen and therefore use the display
-     * coordinates in their calculations as if an activity is  positioned in the top-left corner of
-     * the screen, with left coordinate equal to 0. This may not be the case of applications in
-     * multi-window and in letterbox modes. This can lead to shifted or out of bounds UI elements in
-     * case the activity is Letterboxed or is in multi-window mode.
-     * @hide
-     */
-    @ChangeId
-    @Overridable
-    @Disabled
-    @TestApi
-    public static final long OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS = 237531167L; // buganizer id
-
-    /**
      * This change id is the gatekeeper for all treatments that force a given min aspect ratio.
      * Enabling this change will allow the following min aspect ratio treatments to be applied:
      * OVERRIDE_MIN_ASPECT_RATIO_MEDIUM
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 94c5e25..ffe73d6 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2576,7 +2576,7 @@
     /**
      * Returns whether attributions provided by the application are meant to be user-visible.
      * Defaults to false if application info is retrieved without
-     * {@link PackageManager#GET_ATTRIBUTIONS}.
+     * {@link PackageManager#GET_ATTRIBUTIONS_LONG}.
      */
     public boolean areAttributionsUserVisible() {
         return (privateFlagsExt & PRIVATE_FLAG_EXT_ATTRIBUTIONS_ARE_USER_VISIBLE) != 0;
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 9c1318e..081f263 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -69,4 +69,5 @@
 
     ParcelFileDescriptor getAppMetadataFd();
     ParcelFileDescriptor openWriteAppMetadata();
+    void removeAppMetadata();
 }
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 4259600..a89d17b 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -221,7 +221,7 @@
     /**
      * Array of all {@link android.R.styleable#AndroidManifestAttribution
      * &lt;attribution&gt;} tags included under &lt;manifest&gt;, or null if there were none. This
-     * is only filled if the flag {@link PackageManager#GET_ATTRIBUTIONS} was set.
+     * is only filled if the flag {@link PackageManager#GET_ATTRIBUTIONS_LONG} was set.
      */
     @SuppressWarnings({"ArrayReturn", "NullableCollection"})
     public @Nullable Attribution[] attributions;
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 45100be..8f864f4 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -30,6 +30,8 @@
 import static android.content.pm.PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
 import static android.content.pm.PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL;
 
+import static com.android.internal.util.XmlUtils.writeStringAttribute;
+
 import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.CurrentTimeMillisLong;
@@ -79,14 +81,18 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.ExceptionUtils;
+import android.util.Log;
 
 import com.android.internal.content.InstallLocationUtils;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DataClass;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.modules.utils.TypedXmlSerializer;
 
 import java.io.Closeable;
 import java.io.File;
@@ -101,6 +107,7 @@
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -1956,16 +1963,22 @@
         /**
          * Optionally set the app metadata. The size of this data cannot exceed the maximum allowed.
          * Any existing data from the previous install will not be retained even if no data is set
-         * for the current install session.
+         * for the current install session. Setting data to null or an empty PersistableBundle will
+         * remove any metadata that has previously been set in the same session.
          *
-         * @param data a PersistableBundle containing the app metadata. If this is set to null then
-         *     any existing app metadata will be removed.
+         * @param data a PersistableBundle containing the app metadata.
          * @throws IOException if writing the data fails.
          */
         public void setAppMetadata(@Nullable PersistableBundle data) throws IOException {
-            if (data == null) {
+            if (data == null || data.isEmpty()) {
+                try {
+                    mSession.removeAppMetadata();
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
                 return;
             }
+            Objects.requireNonNull(data);
             try (OutputStream outputStream = openWriteAppMetadata()) {
                 data.writeToStream(outputStream);
             }
@@ -2197,6 +2210,38 @@
          */
         public static final int USER_ACTION_NOT_REQUIRED = 2;
 
+        /** @hide */
+        @IntDef(prefix = {"PERMISSION_STATE_"}, value = {
+                PERMISSION_STATE_DEFAULT,
+                PERMISSION_STATE_GRANTED,
+                PERMISSION_STATE_DENIED,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface PermissionState {}
+
+        /**
+         * Value is passed by the installer to {@link #setPermissionState(String, int)} to set
+         * the state of a permission. This indicates no preference by the installer, relying on
+         * the device's default policy to set the grant state of the permission.
+         */
+        public static final int PERMISSION_STATE_DEFAULT = 0;
+
+        /**
+         * Value is passed by the installer to {@link #setPermissionState(String, int)} to set
+         * the state of a permission. This indicates the installers wants to automatically grant
+         * the permission to the package being installed. The user and other actors in the system
+         * may still be able to deny the permission after installation.
+         */
+        public static final int PERMISSION_STATE_GRANTED = 1;
+
+        /**
+         * Value is passed by the installer to {@link #setPermissionState(String, int)} to set
+         * the state of a permission. This indicates the installers wants to deny the permission
+         * by default to the package being installed. The user and other actors in the system may
+         * still be able to grant the permission after installation.
+         */
+        public static final int PERMISSION_STATE_DENIED = 2;
+
         /** {@hide} */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
         public int mode = MODE_INVALID;
@@ -2241,8 +2286,6 @@
         /** {@hide} */
         public String volumeUuid;
         /** {@hide} */
-        public String[] grantedRuntimePermissions;
-        /** {@hide} */
         public List<String> whitelistedRestrictedPermissions;
         /** {@hide} */
         public int autoRevokePermissionsMode = MODE_DEFAULT;
@@ -2267,6 +2310,13 @@
         /** {@hide} */
         public boolean applicationEnabledSettingPersistent = false;
 
+        private final ArrayMap<String, Integer> mPermissionStates;
+
+        /**
+         * @see #getFinalPermissionStates()
+         */
+        private ArrayMap<String, Integer> mFinalPermissionStates;
+
         /**
          * Construct parameters for a new package install session.
          *
@@ -2276,6 +2326,7 @@
          */
         public SessionParams(int mode) {
             this.mode = mode;
+            mPermissionStates = new ArrayMap<>();
         }
 
         /** {@hide} */
@@ -2294,7 +2345,8 @@
             referrerUri = source.readParcelable(null, android.net.Uri.class);
             abiOverride = source.readString();
             volumeUuid = source.readString();
-            grantedRuntimePermissions = source.readStringArray();
+            mPermissionStates = new ArrayMap<>();
+            source.readMap(mPermissionStates, null, String.class, Integer.class);
             whitelistedRestrictedPermissions = source.createStringArrayList();
             autoRevokePermissionsMode = source.readInt();
             installerPackageName = source.readString();
@@ -2329,7 +2381,7 @@
             ret.referrerUri = referrerUri;  // not a copy, but immutable.
             ret.abiOverride = abiOverride;
             ret.volumeUuid = volumeUuid;
-            ret.grantedRuntimePermissions = grantedRuntimePermissions;
+            ret.mPermissionStates.putAll(mPermissionStates);
             ret.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
             ret.autoRevokePermissionsMode = autoRevokePermissionsMode;
             ret.installerPackageName = installerPackageName;
@@ -2453,13 +2505,93 @@
          * @param permissions The permissions to grant or null to grant all runtime
          *     permissions.
          *
+         * @deprecated Prefer {@link #setPermissionState(String, int)} instead starting in
+         * {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}.
          * @hide
          */
+        @Deprecated
         @SystemApi
         @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
         public void setGrantedRuntimePermissions(String[] permissions) {
-            installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
-            this.grantedRuntimePermissions = permissions;
+            if (permissions == null) {
+                // The new API has no mechanism to grant all requested permissions
+                installFlags |= PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS;
+                mPermissionStates.clear();
+            } else {
+                installFlags &= ~PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS;
+                // Otherwise call the new API to grant the permissions specified
+                for (String permission : permissions) {
+                    setPermissionState(permission, PERMISSION_STATE_GRANTED);
+                }
+            }
+        }
+
+        /**
+         * Sets the state of permissions for the package at installation.
+         * <p/>
+         * Granting any runtime permissions require the
+         * {@link android.Manifest.permission#INSTALL_GRANT_RUNTIME_PERMISSIONS} permission to be
+         * held by the caller. Revoking runtime permissions is not allowed, even during app update
+         * sessions.
+         * <p/>
+         * Holders without the permission are allowed to change the following special permissions:
+         * <p/>
+         * On platform {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE UPSIDE_DOWN_CAKE}:
+         * <ul>
+         *     <li>{@link Manifest.permission#USE_FULL_SCREEN_INTENT}</li>
+         * </ul>
+         * Install time permissions, which cannot be revoked by the user, cannot be changed by the
+         * installer.
+         * <p/>
+         * See <a href="https://developer.android.com/guide/topics/permissions/overview">
+         * Permissions on Android</a> for more information.
+         *
+         * @param permissionName The permission to change state for.
+         * @param state          Either {@link #PERMISSION_STATE_DEFAULT},
+         *                       {@link #PERMISSION_STATE_GRANTED},
+         *                       or {@link #PERMISSION_STATE_DENIED} to set the permission to.
+         *
+         * @return This object for easier chaining.
+         */
+        @RequiresPermission(value = android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS,
+                conditional = true)
+        @NonNull
+        public SessionParams setPermissionState(@NonNull String permissionName,
+                @PermissionState int state) {
+            if (TextUtils.isEmpty(permissionName)) {
+                throw new IllegalArgumentException("Provided permissionName cannot be "
+                        + (permissionName == null ? "null" : "empty"));
+            }
+
+            if (mFinalPermissionStates != null) {
+                Log.wtf(TAG, "Requested permission " + permissionName + " but final permissions"
+                        + " were already decided for this session: " + mFinalPermissionStates);
+            }
+
+            switch (state) {
+                case PERMISSION_STATE_DEFAULT:
+                    mPermissionStates.remove(permissionName);
+                    break;
+                case PERMISSION_STATE_GRANTED:
+                case PERMISSION_STATE_DENIED:
+                    mPermissionStates.put(permissionName, state);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unexpected permission state int: " + state);
+            }
+
+            return this;
+        }
+
+        /** @hide */
+        public void setPermissionStates(Collection<String> grantPermissions,
+                Collection<String> denyPermissions) {
+            for (String grantPermission : grantPermissions) {
+                mPermissionStates.put(grantPermission, PERMISSION_STATE_GRANTED);
+            }
+            for (String denyPermission : denyPermissions) {
+                mPermissionStates.put(denyPermission, PERMISSION_STATE_DENIED);
+            }
         }
 
         /**
@@ -2876,6 +3008,69 @@
             }
         }
 
+        /**
+         * This is only for use by system server. If you need the actual grant state, use
+         * {@link #getFinalPermissionStates()}.
+         * <p/>
+         * This is implemented here to avoid exposing the raw permission sets to external callers,
+         * so that enforcement done in the either of the final methods is the single source of truth
+         * for default grant/deny policy.
+         *
+         * @hide
+         */
+        public void writePermissionStateXml(@NonNull TypedXmlSerializer out,
+                @NonNull String grantTag, @NonNull String denyTag, @NonNull String attrName)
+                throws IOException {
+            for (int index = 0; index < mPermissionStates.size(); index++) {
+                var permissionName = mPermissionStates.keyAt(index);
+                var state = mPermissionStates.valueAt(index);
+                String tag = state == PERMISSION_STATE_GRANTED ? grantTag : denyTag;
+                out.startTag(null, tag);
+                writeStringAttribute(out, attrName, permissionName);
+                out.endTag(null, tag);
+            }
+        }
+
+        /**
+         * Snapshot of final permission states taken when this method is first called, to separate
+         * what the caller wanted and the effective state that should be applied to the session.
+         *
+         * This prevents someone from adding more permissions after the fact.
+         *
+         * @hide
+         */
+        @NonNull
+        public ArrayMap<String, Integer> getFinalPermissionStates() {
+            if (mFinalPermissionStates == null) {
+                mFinalPermissionStates = new ArrayMap<>(mPermissionStates);
+                if (!mFinalPermissionStates.containsKey(
+                        Manifest.permission.USE_FULL_SCREEN_INTENT)) {
+                    mFinalPermissionStates.put(Manifest.permission.USE_FULL_SCREEN_INTENT,
+                            PERMISSION_STATE_GRANTED);
+                }
+            }
+            return mFinalPermissionStates;
+        }
+
+        /** @hide */
+        @Nullable
+        public String[] getLegacyGrantedRuntimePermissions() {
+            if ((installFlags & PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS) != 0) {
+                return null;
+            }
+
+            var grantedPermissions = new ArrayList<String>();
+            for (int index = 0; index < mPermissionStates.size(); index++) {
+                var permissionName = mPermissionStates.keyAt(index);
+                var state = mPermissionStates.valueAt(index);
+                if (state == PERMISSION_STATE_GRANTED) {
+                    grantedPermissions.add(permissionName);
+                }
+            }
+
+            return grantedPermissions.toArray(ArrayUtils.emptyArray(String.class));
+        }
+
         /** {@hide} */
         public void dump(IndentingPrintWriter pw) {
             pw.printPair("mode", mode);
@@ -2892,7 +3087,7 @@
             pw.printPair("referrerUri", referrerUri);
             pw.printPair("abiOverride", abiOverride);
             pw.printPair("volumeUuid", volumeUuid);
-            pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
+            pw.printPair("mPermissionStates", mPermissionStates);
             pw.printPair("packageSource", packageSource);
             pw.printPair("whitelistedRestrictedPermissions", whitelistedRestrictedPermissions);
             pw.printPair("autoRevokePermissions", autoRevokePermissionsMode);
@@ -2930,7 +3125,7 @@
             dest.writeParcelable(referrerUri, flags);
             dest.writeString(abiOverride);
             dest.writeString(volumeUuid);
-            dest.writeStringArray(grantedRuntimePermissions);
+            dest.writeMap(mPermissionStates);
             dest.writeStringList(whitelistedRestrictedPermissions);
             dest.writeInt(autoRevokePermissionsMode);
             dest.writeString(installerPackageName);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 09b68e2..23cce6a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -49,6 +49,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
+import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.dex.ArtManager;
 import android.content.pm.pkg.FrameworkPackageUserState;
 import android.content.pm.verify.domain.DomainVerificationManager;
@@ -151,6 +152,29 @@
             "android.media.PROPERTY_MEDIA_CAPABILITIES";
 
     /**
+     * &lt;application&gt; level {@link android.content.pm.PackageManager.Property} tag
+     * specifying the XML resource ID containing the declaration of the self-certified network
+     * capabilities used by the application.
+     *
+     * <p> Starting from Android 14, usage of some network capabilities in
+     * {@link android.net.ConnectivityManager#requestNetwork} require the application to
+     * declare its usage of that particular capability in this resource. Only some capabilities
+     * require a declaration. Please look up the specific capability you want to use in
+     * {@link android.net.NetworkCapabilities} to see if it needs declaration in this property.
+     *
+     * For example:
+     * &lt;application&gt;
+     *   &lt;property android:name="android.net.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES"
+     *     android:resource="@xml/self_certified_network_capabilities"&gt;
+     * &lt;application&gt;
+     *
+     * <p> The detail format of self_certified_network_capabilities.xml is described in
+     * {@link android.net.NetworkRequest}
+     */
+    public static final String PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES =
+            "android.net.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES";
+
+    /**
      * Application level property that an app can specify to opt-out from having private data
      * directories both on the internal and external storages.
      *
@@ -717,7 +741,7 @@
             GET_DISABLED_UNTIL_USED_COMPONENTS,
             GET_UNINSTALLED_PACKAGES,
             MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
-            GET_ATTRIBUTIONS,
+            GET_ATTRIBUTIONS_LONG,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface PackageInfoFlagsBits {}
@@ -1127,8 +1151,9 @@
     public static final int MATCH_CLONE_PROFILE = 0x20000000;
 
     /**
-     * {@link PackageInfo} flag: return all attributions declared in the package manifest
+     * @deprecated Use {@link #GET_ATTRIBUTIONS_LONG} to avoid unintended sign extension.
      */
+    @Deprecated
     public static final int GET_ATTRIBUTIONS = 0x80000000;
 
     /** @hide */
@@ -1153,6 +1178,11 @@
     public static final int MATCH_APEX = 0x40000000;
 
     /**
+     * {@link PackageInfo} flag: return all attributions declared in the package manifest
+     */
+    public static final long GET_ATTRIBUTIONS_LONG = 0x80000000L;
+
+    /**
      * Flag for {@link #addCrossProfileIntentFilter}: if this flag is set: when
      * resolving an intent that matches the {@code CrossProfileIntentFilter},
      * the current profile will be skipped. Only activities in the target user
@@ -1356,7 +1386,7 @@
             INSTALL_FROM_ADB,
             INSTALL_ALL_USERS,
             INSTALL_REQUEST_DOWNGRADE,
-            INSTALL_GRANT_RUNTIME_PERMISSIONS,
+            INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS,
             INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
             INSTALL_FORCE_VOLUME_UUID,
             INSTALL_FORCE_PERMISSION_PROMPT,
@@ -1433,14 +1463,16 @@
     public static final int INSTALL_REQUEST_DOWNGRADE = 0x00000080;
 
     /**
-     * Flag parameter for {@link #installPackage} to indicate that all runtime
-     * permissions should be granted to the package. If {@link #INSTALL_ALL_USERS}
-     * is set the runtime permissions will be granted to all users, otherwise
-     * only to the owner.
+     * Flag parameter for package install to indicate that all requested permissions should be
+     * granted to the package. If {@link #INSTALL_ALL_USERS} is set the runtime permissions will
+     * be granted to all users, otherwise only to the owner.
+     * <p/>
+     * If this flag is set, {@link SessionParams#setPermissionState(String, int)} should not be
+     * called.
      *
      * @hide
      */
-    public static final int INSTALL_GRANT_RUNTIME_PERMISSIONS = 0x00000100;
+    public static final int INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS = 0x00000100;
 
     /** {@hide} */
     public static final int INSTALL_FORCE_VOLUME_UUID = 0x00000200;
@@ -1569,7 +1601,7 @@
     public static final int INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK = 0x01000000;
 
     /**
-     * Flag parameter for {@link PackageInstaller.SessionParams} to indicate that the
+     * Flag parameter for {@link SessionParams} to indicate that the
      * update ownership enforcement is requested.
      * @hide
      */
@@ -10923,10 +10955,13 @@
 
     /**
      * Attempt to relinquish the update ownership of the given package. Only the current
-     * update owner of the given package can use this API or a SecurityException will be
-     * thrown.
+     * update owner of the given package can use this API.
      *
      * @param targetPackage The installed package whose update owner will be changed.
+     * @throws IllegalArgumentException if the given package is invalid.
+     * @throws SecurityException if you are not the current update owner of the given package.
+     *
+     * @see PackageInstaller.SessionParams#setRequestUpdateOwnership
      */
     public void relinquishUpdateOwnership(@NonNull String targetPackage) {
         throw new UnsupportedOperationException(
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index f3209f9..49d21da 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -401,8 +401,9 @@
      *
      *         <p>If the service isn't stopped within the timeout,
      *         {@link android.app.Service#onTimeout(int)} will be called.
-     *         If the service is still not stopped after the callback,
-     *         the app will be declared an ANR.
+     *
+     *         <p>If the service is still not stopped after the callback,
+     *         the app will be declared an ANR after a short grace period of several seconds.
      *
      *     <li>
      *         A foreground service of this type cannot be made "sticky"
@@ -419,6 +420,17 @@
      *         </a>
      * </ul>
      *
+     * <p>Note, even though
+     * {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}
+     * was added
+     * on Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * it can be also used on
+     * on prior android versions (just like other new foreground service types can be used).
+     * However, because {@link android.app.Service#onTimeout(int)} did not exist on prior versions,
+     * it will never called on such versions.
+     * Because of this, developers must make sure to stop the foreground service even if
+     * {@link android.app.Service#onTimeout(int)} is not called on such versions.
+     *
      * @see android.app.Service#onTimeout(int)
      */
     public static final int FOREGROUND_SERVICE_TYPE_SHORT_SERVICE = 1 << 11;
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index e38cb65..6386f75 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -22,6 +22,7 @@
 import android.annotation.TestApi;
 import android.annotation.UserIdInt;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
@@ -418,16 +419,25 @@
             // Don't support switching to pre-created users until they become "real" users.
             return false;
         }
-        return !isProfile();
+        return isFull() || canSwitchToHeadlessSystemUser();
+    }
+
+    /**
+     * @return true if user is of type {@link UserManager#USER_TYPE_SYSTEM_HEADLESS} and
+     * {@link com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser} is true.
+     */
+    private boolean canSwitchToHeadlessSystemUser() {
+        return UserManager.USER_TYPE_SYSTEM_HEADLESS.equals(userType) && Resources.getSystem()
+                .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser);
     }
 
     /**
      * @return true if this user can be switched to by end user through UI.
+     * @deprecated Use {@link UserInfo#supportsSwitchTo} instead.
      */
+    @Deprecated
     public boolean supportsSwitchToByUser() {
-        // Hide the system user when it does not represent a human user.
-        boolean hideSystemUser = UserManager.isHeadlessSystemUserMode();
-        return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
+        return supportsSwitchTo();
     }
 
     // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType))
@@ -436,11 +446,7 @@
         if (isProfile() || isGuest() || isRestricted()) {
             return false;
         }
-        if (UserManager.isHeadlessSystemUserMode()) {
-            return id != UserHandle.USER_SYSTEM;
-        } else {
-            return id == UserHandle.USER_SYSTEM;
-        }
+        return isMain();
     }
 
     // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible.
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 335975b..1c8276c 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -1107,7 +1107,7 @@
         } else {
             sb.append("?mcc");
         }
-        if (mnc != 0) {
+        if (mnc != MNC_ZERO) {
             sb.append(mnc);
             sb.append("mnc");
         } else {
@@ -1998,7 +1998,7 @@
             changed |= ActivityInfo.CONFIG_FONT_WEIGHT_ADJUSTMENT;
         }
 
-        if (!publicOnly && mGrammaticalGender != delta.mGrammaticalGender) {
+        if (mGrammaticalGender != delta.mGrammaticalGender) {
             changed |= ActivityInfo.CONFIG_GRAMMATICAL_GENDER;
         }
         return changed;
diff --git a/core/java/android/credentials/CreateCredentialException.java b/core/java/android/credentials/CreateCredentialException.java
index 84cc9a8..c344004 100644
--- a/core/java/android/credentials/CreateCredentialException.java
+++ b/core/java/android/credentials/CreateCredentialException.java
@@ -40,13 +40,13 @@
             "android.credentials.CreateCredentialException.TYPE_UNKNOWN";
 
     /**
-     * The error type value for when no credential is available for the given {@link
-     * CredentialManager#createCredential(CreateCredentialRequest, Activity,
+     * The error type value for when no create options are available from any provider(s),
+     * for the given {@link CredentialManager#createCredential(CreateCredentialRequest, Activity,
      * CancellationSignal, Executor, OutcomeReceiver)} request.
      */
     @NonNull
-    public static final String TYPE_NO_CREDENTIAL =
-            "android.credentials.CreateCredentialException.TYPE_NO_CREDENTIAL";
+    public static final String TYPE_NO_CREATE_OPTIONS =
+            "android.credentials.CreateCredentialException.TYPE_NO_CREATE_OPTIONS";
     /**
      * The error type value for when the user intentionally cancelled the request.
      *
diff --git a/core/java/android/credentials/CreateCredentialRequest.java b/core/java/android/credentials/CreateCredentialRequest.java
index 26f8831..aec88b9 100644
--- a/core/java/android/credentials/CreateCredentialRequest.java
+++ b/core/java/android/credentials/CreateCredentialRequest.java
@@ -33,6 +33,18 @@
 public final class CreateCredentialRequest implements Parcelable {
 
     /**
+     * True/false value to determine if the calling app info should be
+     * sent to the provider at every stage.
+     *
+     * Developers must set this to false if they wish to remove the
+     * {@link android.service.credentials.CallingAppInfo} from the query phase request
+     * that providers receive. Note, that providers will still receive the app info in
+     * the final phase after the user has selected the entry.
+     */
+    private final boolean mAlwaysSendAppInfoToProvider;
+
+
+    /**
      * The requested credential type.
      */
     @NonNull
@@ -103,12 +115,21 @@
         return mIsSystemProviderRequired;
     }
 
+    /**
+     * Return true/false value to determine if the calling app info should always be sent
+     * to providers (if true), or removed from the query phase (if false).
+     */
+    public boolean alwaysSendAppInfoToProvider() {
+        return mAlwaysSendAppInfoToProvider;
+    }
+
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeString8(mType);
         dest.writeBundle(mCredentialData);
         dest.writeBundle(mCandidateQueryData);
         dest.writeBoolean(mIsSystemProviderRequired);
+        dest.writeBoolean(mAlwaysSendAppInfoToProvider);
     }
 
     @Override
@@ -123,6 +144,8 @@
                 + ", credentialData=" + mCredentialData
                 + ", candidateQueryData=" + mCandidateQueryData
                 + ", isSystemProviderRequired=" + mIsSystemProviderRequired
+                + ", alwaysSendAppInfoToProvider="
+                + mAlwaysSendAppInfoToProvider
                 + "}";
     }
 
@@ -135,6 +158,39 @@
      *                           during the initial creation candidate query stage
      * @param isSystemProviderRequired whether the request must only be fulfilled by a system
      *                                provider
+     * @param alwaysSendAppInfoToProvider whether the
+     * {@link android.service.credentials.CallingAppInfo} should be propagated to the provider
+     *                                    at every stage of the request. If set to false,
+     *                                    the calling app info will be removed from
+     *                                    the query phase, and will only be sent along
+     *                                    with the final request, after the user has selected
+     *                                    an entry on the UI.
+     *
+     * @throws IllegalArgumentException If type is empty.
+     */
+    public CreateCredentialRequest(
+            @NonNull String type,
+            @NonNull Bundle credentialData,
+            @NonNull Bundle candidateQueryData,
+            boolean isSystemProviderRequired,
+            boolean alwaysSendAppInfoToProvider) {
+        mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
+        mCredentialData = requireNonNull(credentialData, "credentialData must not be null");
+        mCandidateQueryData = requireNonNull(candidateQueryData,
+                "candidateQueryData must not be null");
+        mIsSystemProviderRequired = isSystemProviderRequired;
+        mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
+    }
+
+    /**
+     * Constructs a {@link CreateCredentialRequest}.
+     *
+     * @param type the requested credential type
+     * @param credentialData the full credential creation request data
+     * @param candidateQueryData the partial request data that will be sent to the provider
+     *                           during the initial creation candidate query stage
+     * @param isSystemProviderRequired whether the request must only be fulfilled by a system
+     *                                provider
      *
      * @throws IllegalArgumentException If type is empty.
      */
@@ -143,11 +199,8 @@
             @NonNull Bundle credentialData,
             @NonNull Bundle candidateQueryData,
             boolean isSystemProviderRequired) {
-        mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
-        mCredentialData = requireNonNull(credentialData, "credentialData must not be null");
-        mCandidateQueryData = requireNonNull(candidateQueryData,
-                "candidateQueryData must not be null");
-        mIsSystemProviderRequired = isSystemProviderRequired;
+        this(type, credentialData, candidateQueryData, isSystemProviderRequired,
+                /*mAlwaysSendAppInfoToProvider=*/true);
     }
 
     private CreateCredentialRequest(@NonNull Parcel in) {
@@ -155,6 +208,7 @@
         Bundle credentialData = in.readBundle();
         Bundle candidateQueryData = in.readBundle();
         boolean isSystemProviderRequired = in.readBoolean();
+        boolean alwaysSendAppInfoToProvider = in.readBoolean();
 
         mType = type;
         AnnotationValidations.validate(NonNull.class, null, mType);
@@ -163,6 +217,7 @@
         mCandidateQueryData = candidateQueryData;
         AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
         mIsSystemProviderRequired = isSystemProviderRequired;
+        mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
     }
 
     public static final @NonNull Parcelable.Creator<CreateCredentialRequest> CREATOR =
diff --git a/core/java/android/credentials/CredentialDescription.java b/core/java/android/credentials/CredentialDescription.java
index c67d37e..f9db5e8 100644
--- a/core/java/android/credentials/CredentialDescription.java
+++ b/core/java/android/credentials/CredentialDescription.java
@@ -48,7 +48,7 @@
     private final String mFlattenedRequestString;
 
     /**
-     * The entry to be used in the UI.
+     * The credential entries to be used in the UI.
      */
     @NonNull
     private final List<CredentialEntry> mCredentialEntries;
@@ -128,16 +128,25 @@
         dest.writeTypedList(mCredentialEntries, flags);
     }
 
+    /**
+     * Returns the type of the Credential described.
+     */
     @NonNull
     public String getType() {
         return mType;
     }
 
+    /**
+     * Returns the flattened JSON string that will be matched with requests.
+     */
     @NonNull
     public String getFlattenedRequestString() {
         return mFlattenedRequestString;
     }
 
+    /**
+     * Returns the credential entries to be used in the UI.
+     */
     @NonNull
     public List<CredentialEntry> getCredentialEntries() {
         return mCredentialEntries;
@@ -151,6 +160,7 @@
     @Override
     public boolean equals(Object obj) {
         return Objects.equals(mType, ((CredentialDescription) obj).getType())
-                && Objects.equals(mFlattenedRequestString, ((CredentialDescription) obj).getType());
+                && Objects.equals(mFlattenedRequestString, ((CredentialDescription) obj)
+                .getFlattenedRequestString());
     }
 }
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 1db14a3..54909aa 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -16,6 +16,8 @@
 
 package android.credentials;
 
+import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;
+
 import static java.util.Objects.requireNonNull;
 
 import android.annotation.CallbackExecutor;
@@ -25,6 +27,7 @@
 import android.annotation.SystemService;
 import android.app.Activity;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentSender;
 import android.os.CancellationSignal;
@@ -123,6 +126,57 @@
     }
 
     /**
+     * Launches the necessary flows to retrieve an app credential from the user, for the given
+     * origin.
+     *
+     * <p>The execution can potentially launch UI flows to collect user consent to using a
+     * credential, display a picker when multiple credentials exist, etc.
+     *
+     * @param request the request specifying type(s) of credentials to get from the user
+     * @param origin the origin of the calling app. Callers of this special API (e.g. browsers)
+     * can set this origin for an app different from their own, to be able to get credentials
+     * on behalf of that app.
+     * @param activity the activity used to launch any UI needed
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this {@link Executor}
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
+    public void getCredentialWithOrigin(
+            @NonNull GetCredentialRequest request,
+            @Nullable String origin,
+            @NonNull Activity activity,
+            @Nullable CancellationSignal cancellationSignal,
+            @CallbackExecutor @NonNull Executor executor,
+            @NonNull OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback) {
+        requireNonNull(request, "request must not be null");
+        requireNonNull(activity, "activity must not be null");
+        requireNonNull(executor, "executor must not be null");
+        requireNonNull(callback, "callback must not be null");
+
+        if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+            Log.w(TAG, "getCredential already canceled");
+            return;
+        }
+
+        ICancellationSignal cancelRemote = null;
+        try {
+            cancelRemote =
+                mService.executeGetCredentialWithOrigin(
+                    request,
+                    new GetCredentialTransport(activity, executor, callback),
+                    mContext.getOpPackageName(),
+                    origin);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        if (cancellationSignal != null && cancelRemote != null) {
+            cancellationSignal.setRemote(cancelRemote);
+        }
+    }
+
+    /**
      * Launches the necessary flows to register an app credential for the user.
      *
      * <p>The execution can potentially launch UI flows to collect user consent to creating or
@@ -168,6 +222,58 @@
     }
 
     /**
+     * Launches the necessary flows to register an app credential for the user.
+     *
+     * <p>The execution can potentially launch UI flows to collect user consent to creating or
+     * storing the new credential, etc.
+     *
+     * @param request the request specifying type(s) of credentials to get from the user, for the
+     * given origin
+     * @param origin the origin of the calling app. Callers of this special API (e.g. browsers)
+     * can set this origin for an app different from their own, to be able to get credentials
+     * on behalf of that app.
+     * @param activity the activity used to launch any UI needed
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this {@link Executor}
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresPermission(CREDENTIAL_MANAGER_SET_ORIGIN)
+    public void createCredentialWithOrigin(
+            @NonNull CreateCredentialRequest request,
+            @Nullable String origin,
+            @NonNull Activity activity,
+            @Nullable CancellationSignal cancellationSignal,
+            @CallbackExecutor @NonNull Executor executor,
+            @NonNull
+            OutcomeReceiver<CreateCredentialResponse, CreateCredentialException> callback) {
+        requireNonNull(request, "request must not be null");
+        requireNonNull(activity, "activity must not be null");
+        requireNonNull(executor, "executor must not be null");
+        requireNonNull(callback, "callback must not be null");
+
+        if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+            Log.w(TAG, "createCredential already canceled");
+            return;
+        }
+
+        ICancellationSignal cancelRemote = null;
+        try {
+            cancelRemote =
+                mService.executeCreateCredentialWithOrigin(
+                    request,
+                    new CreateCredentialTransport(activity, executor, callback),
+                    mContext.getOpPackageName(),
+                    origin);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        if (cancellationSignal != null && cancelRemote != null) {
+            cancellationSignal.setRemote(cancelRemote);
+        }
+    }
+
+    /**
      * Clears the current user credential state from all credential providers.
      *
      * <p>You should invoked this api after your user signs out of your app to notify all credential
@@ -222,7 +328,7 @@
      * @param callback the callback invoked when the request succeeds or fails
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
     public void listEnabledProviders(
             @Nullable CancellationSignal cancellationSignal,
             @CallbackExecutor @NonNull Executor executor,
@@ -280,13 +386,32 @@
     }
 
     /**
+     * Returns {@code true} if the calling application provides a CredentialProviderService that is
+     * enabled for the current user, or {@code false} otherwise. CredentialProviderServices are
+     * enabled on a per-service basis so the individual component name of the service should be
+     * passed in here.
+     *
+     * @param componentName the component name to check is enabled
+     */
+    public boolean isEnabledCredentialProviderService(@NonNull ComponentName componentName) {
+        requireNonNull(componentName, "componentName must not be null");
+
+        try {
+            return mService.isEnabledCredentialProviderService(
+                    componentName, mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns whether the service is enabled.
      *
      * @hide
      */
     public static boolean isServiceEnabled(Context context) {
         if (context == null) {
-	    return false;
+            return false;
         }
         CredentialManager credentialManager =
                 (CredentialManager) context.getSystemService(Context.CREDENTIAL_SERVICE);
@@ -298,8 +423,7 @@
 
     private boolean isServiceEnabled() {
         return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER,
-                true);
+                DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER, true);
     }
 
     /**
@@ -313,22 +437,19 @@
     }
 
     /**
-     * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential}
-     * a CredentialProvider has. This registry will then be used to determine where to
-     * fetch the requested {@link Credential} from. Not all credential types will be supported.
-     * The distinction will be made by the JetPack layer. For the types that are supported,
-     * JetPack will add a new key-value pair into {@link GetCredentialRequest}. These will not
-     * be persistent on the device. The Credential Providers will need to call this API again
-     * upon device reboot.
+     * Registers a {@link CredentialDescription} for an actively provisioned {@link Credential} a
+     * CredentialProvider has. This registry will then be used to determine where to fetch the
+     * requested {@link Credential} from. Not all credential types will be supported. The
+     * distinction will be made by the JetPack layer. For the types that are supported, JetPack will
+     * add a new key-value pair into {@link GetCredentialRequest}. These will not be persistent on
+     * the device. The Credential Providers will need to call this API again upon device reboot.
      *
      * @param request the request data
-     *
-     * @throws {@link  UnsupportedOperationException} if the feature has not been enabled.
-     * @throws {@link  com.android.server.credentials.NonCredentialProviderCallerException}
-     * if the calling package name is not also listed as a Credential Provider.
-     * @throws {@link  IllegalArgumentException} if the calling Credential Provider can not handle
-     * one or more of the Credential Types that are sent for registration.
-     *
+     * @throws {@link UnsupportedOperationException} if the feature has not been enabled.
+     * @throws {@link com.android.server.credentials.NonCredentialProviderCallerException} if the
+     *     calling package name is not also listed as a Credential Provider.
+     * @throws {@link IllegalArgumentException} if the calling Credential Provider can not handle
+     *     one or more of the Credential Types that are sent for registration.
      */
     public void registerCredentialDescription(
             @NonNull RegisterCredentialDescriptionRequest request) {
@@ -346,16 +467,12 @@
         }
     }
 
-
     /**
-     *  Unregisters a {@link CredentialDescription} for an actively provisioned {@link Credential}
+     * Unregisters a {@link CredentialDescription} for an actively provisioned {@link Credential}
      * that has been registered previously.
      *
-     *
      * @param request the request data
-     *
-     * @throws {@link  UnsupportedOperationException} if the feature has not been enabled.
-     *
+     * @throws {@link UnsupportedOperationException} if the feature has not been enabled.
      */
     public void unregisterCredentialDescription(
             @NonNull UnregisterCredentialDescriptionRequest request) {
@@ -371,7 +488,6 @@
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
-
     }
 
     private static class GetCredentialTransport extends IGetCredentialCallback.Stub {
diff --git a/core/java/android/credentials/GetCredentialOption.java b/core/java/android/credentials/CredentialOption.java
similarity index 79%
rename from core/java/android/credentials/GetCredentialOption.java
rename to core/java/android/credentials/CredentialOption.java
index f2895c7..9a3b46d 100644
--- a/core/java/android/credentials/GetCredentialOption.java
+++ b/core/java/android/credentials/CredentialOption.java
@@ -27,9 +27,11 @@
 import com.android.internal.util.Preconditions;
 
 /**
- * A specific type of credential request.
+ * Information about a specific type of credential to be requested during a {@link
+ * CredentialManager#getCredential(GetCredentialRequest, Activity, CancellationSignal, Executor,
+ * OutcomeReceiver)} operation.
  */
-public final class GetCredentialOption implements Parcelable {
+public final class CredentialOption implements Parcelable {
 
     /**
      * Bundle key to the flattened version of the JSON request string. Framework will use this key
@@ -118,7 +120,7 @@
 
     @Override
     public String toString() {
-        return "GetCredentialOption {"
+        return "CredentialOption {"
                 + "type=" + mType
                 + ", requestData=" + mCredentialRetrievalData
                 + ", candidateQueryData=" + mCandidateQueryData
@@ -127,17 +129,17 @@
     }
 
     /**
-     * Constructs a {@link GetCredentialOption}.
+     * Constructs a {@link CredentialOption}.
      *
-     * @param type                    the requested credential type
-     * @param credentialRetrievalData the request data
-     * @param candidateQueryData      the partial request data that will be sent to the provider
-     *                                during the initial credential candidate query stage
-     * @param isSystemProviderRequired   whether the request must only be fulfilled by a system
-     *                                provider
+     * @param type                     the requested credential type
+     * @param credentialRetrievalData  the request data
+     * @param candidateQueryData       the partial request data that will be sent to the provider
+     *                                 during the initial credential candidate query stage
+     * @param isSystemProviderRequired whether the request must only be fulfilled by a system
+     *                                 provider
      * @throws IllegalArgumentException If type is empty.
      */
-    public GetCredentialOption(
+    public CredentialOption(
             @NonNull String type,
             @NonNull Bundle credentialRetrievalData,
             @NonNull Bundle candidateQueryData,
@@ -150,7 +152,7 @@
         mIsSystemProviderRequired = isSystemProviderRequired;
     }
 
-    private GetCredentialOption(@NonNull Parcel in) {
+    private CredentialOption(@NonNull Parcel in) {
         String type = in.readString8();
         Bundle data = in.readBundle();
         Bundle candidateQueryData = in.readBundle();
@@ -165,16 +167,16 @@
         mIsSystemProviderRequired = isSystemProviderRequired;
     }
 
-    public static final @NonNull Parcelable.Creator<GetCredentialOption> CREATOR =
-            new Parcelable.Creator<GetCredentialOption>() {
-                @Override
-                public GetCredentialOption[] newArray(int size) {
-                    return new GetCredentialOption[size];
-                }
+    @NonNull
+    public static final Parcelable.Creator<CredentialOption> CREATOR = new Parcelable.Creator<>() {
+        @Override
+        public CredentialOption[] newArray(int size) {
+            return new CredentialOption[size];
+        }
 
-                @Override
-                public GetCredentialOption createFromParcel(@NonNull Parcel in) {
-                    return new GetCredentialOption(in);
-                }
-            };
+        @Override
+        public CredentialOption createFromParcel(@NonNull Parcel in) {
+            return new CredentialOption(in);
+        }
+    };
 }
diff --git a/core/java/android/credentials/GetCredentialRequest.java b/core/java/android/credentials/GetCredentialRequest.java
index 85b4468..bc92c7c 100644
--- a/core/java/android/credentials/GetCredentialRequest.java
+++ b/core/java/android/credentials/GetCredentialRequest.java
@@ -19,6 +19,7 @@
 import static java.util.Objects.requireNonNull;
 
 import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -39,7 +40,7 @@
      * The list of credential requests.
      */
     @NonNull
-    private final List<GetCredentialOption> mGetCredentialOptions;
+    private final List<CredentialOption> mCredentialOptions;
 
     /**
      * The top request level data.
@@ -48,11 +49,22 @@
     private final Bundle mData;
 
     /**
+     * True/False value to determine if the calling app info should be
+     * removed from the request that is sent to the providers.
+     * Developers must set this to false if they wish to remove the
+     * {@link android.service.credentials.CallingAppInfo} from the query phases requests that
+     * providers receive.
+     * If not set, the default value will be true and the calling app info will be
+     * propagated to the providers.
+     */
+    private final boolean mAlwaysSendAppInfoToProvider;
+
+    /**
      * Returns the list of credential options to be requested.
      */
     @NonNull
-    public List<GetCredentialOption> getGetCredentialOptions() {
-        return mGetCredentialOptions;
+    public List<CredentialOption> getCredentialOptions() {
+        return mCredentialOptions;
     }
 
     /**
@@ -63,10 +75,21 @@
         return mData;
     }
 
+    /**
+     * Returns a value to determine if the calling app info should be always
+     * sent to the provider in every phase (if true), or should be removed
+     * from the query phase, and only sent as part of the request in the final phase,
+     * after the user has made a selection on the UI (if false).
+     */
+    public boolean alwaysSendAppInfoToProvider() {
+        return mAlwaysSendAppInfoToProvider;
+    }
+
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeTypedList(mGetCredentialOptions, flags);
+        dest.writeTypedList(mCredentialOptions, flags);
         dest.writeBundle(mData);
+        dest.writeBoolean(mAlwaysSendAppInfoToProvider);
     }
 
     @Override
@@ -76,38 +99,43 @@
 
     @Override
     public String toString() {
-        return "GetCredentialRequest {getCredentialOption=" + mGetCredentialOptions
+        return "GetCredentialRequest {credentialOption=" + mCredentialOptions
                 + ", data=" + mData
+                + ", alwaysSendAppInfoToProvider="
+                + mAlwaysSendAppInfoToProvider
                 + "}";
     }
 
-    private GetCredentialRequest(@NonNull List<GetCredentialOption> getCredentialOptions,
-            @NonNull Bundle data) {
+    private GetCredentialRequest(@NonNull List<CredentialOption> credentialOptions,
+            @NonNull Bundle data, @NonNull boolean alwaysSendAppInfoToProvider) {
         Preconditions.checkCollectionNotEmpty(
-                getCredentialOptions,
-                /*valueName=*/ "getCredentialOptions");
+                credentialOptions,
+                /*valueName=*/ "credentialOptions");
         Preconditions.checkCollectionElementsNotNull(
-                getCredentialOptions,
-                /*valueName=*/ "getCredentialOptions");
-        mGetCredentialOptions = getCredentialOptions;
+                credentialOptions,
+                /*valueName=*/ "credentialOptions");
+        mCredentialOptions = credentialOptions;
         mData = requireNonNull(data,
                 "data must not be null");
+        mAlwaysSendAppInfoToProvider = alwaysSendAppInfoToProvider;
     }
 
     private GetCredentialRequest(@NonNull Parcel in) {
-        List<GetCredentialOption> getCredentialOptions = new ArrayList<GetCredentialOption>();
-        in.readTypedList(getCredentialOptions, GetCredentialOption.CREATOR);
-        mGetCredentialOptions = getCredentialOptions;
-        AnnotationValidations.validate(NonNull.class, null, mGetCredentialOptions);
+        List<CredentialOption> credentialOptions = new ArrayList<CredentialOption>();
+        in.readTypedList(credentialOptions, CredentialOption.CREATOR);
+        mCredentialOptions = credentialOptions;
+        AnnotationValidations.validate(NonNull.class, null, mCredentialOptions);
 
 
         Bundle data = in.readBundle();
         mData = data;
         AnnotationValidations.validate(NonNull.class, null, mData);
+
+        mAlwaysSendAppInfoToProvider = in.readBoolean();
     }
 
-    public static final @NonNull Parcelable.Creator<GetCredentialRequest> CREATOR =
-            new Parcelable.Creator<GetCredentialRequest>() {
+    @NonNull public static final Parcelable.Creator<GetCredentialRequest> CREATOR =
+            new Parcelable.Creator<>() {
                 @Override
                 public GetCredentialRequest[] newArray(int size) {
                     return new GetCredentialRequest[size];
@@ -123,11 +151,14 @@
     public static final class Builder {
 
         @NonNull
-        private List<GetCredentialOption> mGetCredentialOptions = new ArrayList<>();
+        private List<CredentialOption> mCredentialOptions = new ArrayList<>();
 
         @NonNull
         private final Bundle mData;
 
+        @NonNull
+        private boolean mAlwaysSendAppInfoToProvider = true;
+
         /**
          * @param data the top request level data
          */
@@ -136,43 +167,62 @@
         }
 
         /**
-         * Adds a specific type of {@link GetCredentialOption}.
+         * Adds a specific type of {@link CredentialOption}.
          */
         @NonNull
-        public Builder addGetCredentialOption(
-                @NonNull GetCredentialOption getCredentialOption) {
-            mGetCredentialOptions.add(requireNonNull(
-                    getCredentialOption, "getCredentialOption must not be null"));
+        public Builder addCredentialOption(@NonNull CredentialOption credentialOption) {
+            mCredentialOptions.add(requireNonNull(
+                    credentialOption, "credentialOption must not be null"));
             return this;
         }
 
         /**
-         * Sets the list of {@link GetCredentialOption}.
+         * Sets a true/false value to determine if the calling app info should be
+         * removed from the request that is sent to the providers.
+         *
+         * Developers must set this to false if they wish to remove the
+         * {@link android.service.credentials.CallingAppInfo} from the query phases requests that
+         * providers receive. Note that the calling app info will still be sent in the
+         * final phase after the user has made a selection on the UI.
+         *
+         * If not set, the default value will be true and the calling app info will be
+         * propagated to the providers in every phase.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder")
+        @NonNull
+        public Builder setAlwaysSendAppInfoToProvider(boolean value) {
+            mAlwaysSendAppInfoToProvider = value;
+            return this;
+        }
+
+        /**
+         * Sets the list of {@link CredentialOption}.
          */
         @NonNull
-        public Builder setGetCredentialOptions(
-                @NonNull List<GetCredentialOption> getCredentialOptions) {
+        public Builder setCredentialOptions(
+                @NonNull List<CredentialOption> credentialOptions) {
             Preconditions.checkCollectionElementsNotNull(
-                    getCredentialOptions,
-                    /*valueName=*/ "getCredentialOptions");
-            mGetCredentialOptions = new ArrayList<>(getCredentialOptions);
+                    credentialOptions,
+                    /*valueName=*/ "credentialOptions");
+            mCredentialOptions = new ArrayList<>(credentialOptions);
             return this;
         }
 
         /**
          * Builds a {@link GetCredentialRequest}.
          *
-         * @throws IllegalArgumentException If getCredentialOptions is empty.
+         * @throws IllegalArgumentException If credentialOptions is empty.
          */
         @NonNull
         public GetCredentialRequest build() {
             Preconditions.checkCollectionNotEmpty(
-                    mGetCredentialOptions,
-                    /*valueName=*/ "getCredentialOptions");
+                    mCredentialOptions,
+                    /*valueName=*/ "credentialOptions");
             Preconditions.checkCollectionElementsNotNull(
-                    mGetCredentialOptions,
-                    /*valueName=*/ "getCredentialOptions");
-            return new GetCredentialRequest(mGetCredentialOptions, mData);
+                    mCredentialOptions,
+                    /*valueName=*/ "credentialOptions");
+            return new GetCredentialRequest(mCredentialOptions, mData,
+                    mAlwaysSendAppInfoToProvider);
         }
     }
 }
diff --git a/core/java/android/credentials/ICredentialManager.aidl b/core/java/android/credentials/ICredentialManager.aidl
index 4ca3124..604e56b 100644
--- a/core/java/android/credentials/ICredentialManager.aidl
+++ b/core/java/android/credentials/ICredentialManager.aidl
@@ -28,6 +28,7 @@
 import android.credentials.IGetCredentialCallback;
 import android.credentials.IListEnabledProvidersCallback;
 import android.credentials.ISetEnabledProvidersCallback;
+import android.content.ComponentName;
 import android.os.ICancellationSignal;
 
 /**
@@ -39,8 +40,12 @@
 
     @nullable ICancellationSignal executeGetCredential(in GetCredentialRequest request, in IGetCredentialCallback callback, String callingPackage);
 
+    @nullable ICancellationSignal executeGetCredentialWithOrigin(in GetCredentialRequest request, in IGetCredentialCallback callback, String callingPackage, String origin);
+
     @nullable ICancellationSignal executeCreateCredential(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage);
 
+    @nullable ICancellationSignal executeCreateCredentialWithOrigin(in CreateCredentialRequest request, in ICreateCredentialCallback callback, String callingPackage, String origin);
+
     @nullable ICancellationSignal clearCredentialState(in ClearCredentialStateRequest request, in IClearCredentialStateCallback callback, String callingPackage);
 
     @nullable ICancellationSignal listEnabledProviders(in IListEnabledProvidersCallback callback);
@@ -50,5 +55,7 @@
     void registerCredentialDescription(in RegisterCredentialDescriptionRequest request, String callingPackage);
 
     void unregisterCredentialDescription(in UnregisterCredentialDescriptionRequest request, String callingPackage);
+
+    boolean isEnabledCredentialProviderService(in ComponentName componentName, String callingPackage);
 }
 
diff --git a/core/java/android/credentials/ui/AuthenticationEntry.java b/core/java/android/credentials/ui/AuthenticationEntry.java
new file mode 100644
index 0000000..b1a382c
--- /dev/null
+++ b/core/java/android/credentials/ui/AuthenticationEntry.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.credentials.ui;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
+import android.app.slice.Slice;
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.AnnotationValidations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An authentication entry.
+ *
+ * @hide
+ */
+@TestApi
+public final class AuthenticationEntry implements Parcelable {
+    @NonNull private final String mKey;
+    @NonNull private final String mSubkey;
+    @NonNull private final @Status int mStatus;
+    @Nullable private Intent mFrameworkExtrasIntent;
+    @NonNull private final Slice mSlice;
+
+    /** @hide **/
+    @IntDef(prefix = {"STATUS_"}, value = {
+            STATUS_LOCKED,
+            STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT,
+            STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Status {}
+
+    /** This entry is still locked, as initially supplied by the provider. */
+    public static final int STATUS_LOCKED = 0;
+    /** This entry was unlocked but didn't contain any credential. Meanwhile, "less recent" means
+     *  there is another such entry that was unlocked more recently. */
+    public static final int STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT = 1;
+    /** This is the most recent entry that was unlocked but didn't contain any credential.
+     *  There should be at most one authentication entry with this status. */
+    public static final int STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT = 2;
+
+    private AuthenticationEntry(@NonNull Parcel in) {
+        mKey = in.readString8();
+        mSubkey = in.readString8();
+        mStatus = in.readInt();
+        mSlice = in.readTypedObject(Slice.CREATOR);
+        mFrameworkExtrasIntent = in.readTypedObject(Intent.CREATOR);
+
+        AnnotationValidations.validate(NonNull.class, null, mKey);
+        AnnotationValidations.validate(NonNull.class, null, mSubkey);
+        AnnotationValidations.validate(NonNull.class, null, mSlice);
+    }
+
+    /** Constructor to be used for an entry that does not require further activities
+     * to be invoked when selected.
+     */
+    public AuthenticationEntry(@NonNull String key, @NonNull String subkey, @NonNull Slice slice,
+            @Status int status) {
+        mKey = key;
+        mSubkey = subkey;
+        mSlice = slice;
+        mStatus = status;
+    }
+
+    /** Constructor to be used for an entry that requires a pending intent to be invoked
+     * when clicked.
+     */
+    public AuthenticationEntry(@NonNull String key, @NonNull String subkey, @NonNull Slice slice,
+            @Status int status, @NonNull Intent intent) {
+        this(key, subkey, slice, status);
+        mFrameworkExtrasIntent = intent;
+    }
+
+    /**
+    * Returns the identifier of this entry that's unique within the context of the CredentialManager
+    * request.
+    */
+    @NonNull
+    public String getKey() {
+        return mKey;
+    }
+
+    /**
+     * Returns the sub-identifier of this entry that's unique within the context of the {@code key}.
+     */
+    @NonNull
+    public String getSubkey() {
+        return mSubkey;
+    }
+
+    /**
+    * Returns the Slice to be rendered.
+    */
+    @NonNull
+    public Slice getSlice() {
+        return mSlice;
+    }
+
+    /**
+     * Returns the entry status.
+     */
+    @NonNull
+    @Status
+    public int getStatus() {
+        return mStatus;
+    }
+
+    @Nullable
+    @SuppressLint("IntentBuilderName") // Not building a new intent.
+    public Intent getFrameworkExtrasIntent() {
+        return mFrameworkExtrasIntent;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString8(mKey);
+        dest.writeString8(mSubkey);
+        dest.writeInt(mStatus);
+        dest.writeTypedObject(mSlice, flags);
+        dest.writeTypedObject(mFrameworkExtrasIntent, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Creator<AuthenticationEntry> CREATOR = new Creator<>() {
+        @Override
+        public AuthenticationEntry createFromParcel(@NonNull Parcel in) {
+            return new AuthenticationEntry(in);
+        }
+
+        @Override
+        public AuthenticationEntry[] newArray(int size) {
+            return new AuthenticationEntry[size];
+        }
+    };
+}
diff --git a/core/java/android/credentials/ui/Entry.java b/core/java/android/credentials/ui/Entry.java
index 37a5724..12665ba 100644
--- a/core/java/android/credentials/ui/Entry.java
+++ b/core/java/android/credentials/ui/Entry.java
@@ -29,30 +29,12 @@
 import com.android.internal.util.AnnotationValidations;
 
 /**
- * A credential, save, or action entry to be rendered.
+ * A credential, create, or action entry to be rendered.
  *
  * @hide
  */
 @TestApi
 public final class Entry implements Parcelable {
-    /**
-    * The intent extra key for the action chip {@code Entry} list when launching the UX activities.
-    */
-    @NonNull public static final String EXTRA_ENTRY_LIST_ACTION_CHIP =
-            "android.credentials.ui.extra.ENTRY_LIST_ACTION_CHIP";
-    /**
-    * The intent extra key for the credential / save {@code Entry} list when launching the UX
-    * activities.
-    */
-    @NonNull public static final String EXTRA_ENTRY_LIST_CREDENTIAL =
-            "android.credentials.ui.extra.ENTRY_LIST_CREDENTIAL";
-    /**
-    * The intent extra key for the authentication action {@code Entry} when launching the UX
-    * activities.
-    */
-    @NonNull public static final String EXTRA_ENTRY_AUTHENTICATION_ACTION =
-            "android.credentials.ui.extra.ENTRY_AUTHENTICATION_ACTION";
-
     @NonNull private final String mKey;
     @NonNull private final String mSubkey;
     @Nullable private PendingIntent mPendingIntent;
diff --git a/core/java/android/credentials/ui/GetCredentialProviderData.java b/core/java/android/credentials/ui/GetCredentialProviderData.java
index 5fe1441..e4688a84 100644
--- a/core/java/android/credentials/ui/GetCredentialProviderData.java
+++ b/core/java/android/credentials/ui/GetCredentialProviderData.java
@@ -38,19 +38,20 @@
     private final List<Entry> mCredentialEntries;
     @NonNull
     private final List<Entry> mActionChips;
-    @Nullable
-    private final Entry mAuthenticationEntry;
+    @NonNull
+    private final List<AuthenticationEntry> mAuthenticationEntries;
     @Nullable
     private final Entry mRemoteEntry;
 
     public GetCredentialProviderData(
             @NonNull String providerFlattenedComponentName, @NonNull List<Entry> credentialEntries,
-            @NonNull List<Entry> actionChips, @Nullable Entry authenticationEntry,
+            @NonNull List<Entry> actionChips,
+            @NonNull List<AuthenticationEntry> authenticationEntries,
             @Nullable Entry remoteEntry) {
         super(providerFlattenedComponentName);
         mCredentialEntries = credentialEntries;
         mActionChips = actionChips;
-        mAuthenticationEntry = authenticationEntry;
+        mAuthenticationEntries = authenticationEntries;
         mRemoteEntry = remoteEntry;
     }
 
@@ -64,9 +65,9 @@
         return mActionChips;
     }
 
-    @Nullable
-    public Entry getAuthenticationEntry() {
-        return mAuthenticationEntry;
+    @NonNull
+    public List<AuthenticationEntry> getAuthenticationEntries() {
+        return mAuthenticationEntries;
     }
 
     @Nullable
@@ -87,8 +88,10 @@
         mActionChips = actionChips;
         AnnotationValidations.validate(NonNull.class, null, mActionChips);
 
-        Entry authenticationEntry = in.readTypedObject(Entry.CREATOR);
-        mAuthenticationEntry = authenticationEntry;
+        List<AuthenticationEntry> authenticationEntries  = new ArrayList<>();
+        in.readTypedList(authenticationEntries, AuthenticationEntry.CREATOR);
+        mAuthenticationEntries = authenticationEntries;
+        AnnotationValidations.validate(NonNull.class, null, mAuthenticationEntries);
 
         Entry remoteEntry = in.readTypedObject(Entry.CREATOR);
         mRemoteEntry = remoteEntry;
@@ -99,7 +102,7 @@
         super.writeToParcel(dest, flags);
         dest.writeTypedList(mCredentialEntries);
         dest.writeTypedList(mActionChips);
-        dest.writeTypedObject(mAuthenticationEntry, flags);
+        dest.writeTypedList(mAuthenticationEntries);
         dest.writeTypedObject(mRemoteEntry, flags);
     }
 
@@ -131,7 +134,7 @@
         @NonNull private String mProviderFlattenedComponentName;
         @NonNull private List<Entry> mCredentialEntries = new ArrayList<>();
         @NonNull private List<Entry> mActionChips = new ArrayList<>();
-        @Nullable private Entry mAuthenticationEntry = null;
+        @NonNull private List<AuthenticationEntry> mAuthenticationEntries = new ArrayList<>();
         @Nullable private Entry mRemoteEntry = null;
 
         /** Constructor with required properties. */
@@ -155,8 +158,9 @@
 
         /** Sets the authentication entry to be displayed to the user. */
         @NonNull
-        public Builder setAuthenticationEntry(@Nullable Entry authenticationEntry) {
-            mAuthenticationEntry = authenticationEntry;
+        public Builder setAuthenticationEntries(
+                @NonNull List<AuthenticationEntry> authenticationEntry) {
+            mAuthenticationEntries = authenticationEntry;
             return this;
         }
 
@@ -171,7 +175,7 @@
         @NonNull
         public GetCredentialProviderData build() {
             return new GetCredentialProviderData(mProviderFlattenedComponentName,
-                    mCredentialEntries, mActionChips, mAuthenticationEntry, mRemoteEntry);
+                    mCredentialEntries, mActionChips, mAuthenticationEntries, mRemoteEntry);
         }
     }
 }
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index 535b551..d786d9a 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -465,7 +465,7 @@
             @Override
             public void onSensorPrivacyChanged(SensorPrivacyChangedParams params) {
                 if (params.getSensor() == sensor) {
-                    listener.onSensorPrivacyChanged(params.getSensor(), params.isEnabled());
+                    listener.onSensorPrivacyChanged(params);
                 }
             }
             @Override
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 6c3233c..fa678fc 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -188,6 +188,19 @@
         }
 
         /**
+         * Shows a default subtitle for the prompt if the subtitle would otherwise be
+         * null or empty. Currently for internal use only.
+         * @return This builder.
+         * @hide
+         */
+        @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+        @NonNull
+        public Builder setUseDefaultSubtitle() {
+            mPromptInfo.setUseDefaultSubtitle(true);
+            return this;
+        }
+
+        /**
          * Optional: Sets a description that will be shown on the prompt.
          * @param description The description to display.
          * @return This builder.
@@ -629,6 +642,16 @@
     }
 
     /**
+     * Whether to use a default subtitle. For internal use only.
+     * @return See {@link Builder#setUseDefaultSubtitle()}.
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public boolean shouldUseDefaultSubtitle() {
+        return mPromptInfo.isUseDefaultSubtitle();
+    }
+
+    /**
      * Gets the description for the prompt, as set by {@link Builder#setDescription(CharSequence)}.
      * @return The description for the prompt, or null if the prompt has no description.
      */
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index a6b8096..02aad1d 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -33,6 +33,7 @@
     @NonNull private CharSequence mTitle;
     private boolean mUseDefaultTitle;
     @Nullable private CharSequence mSubtitle;
+    private boolean mUseDefaultSubtitle;
     @Nullable private CharSequence mDescription;
     @Nullable private CharSequence mDeviceCredentialTitle;
     @Nullable private CharSequence mDeviceCredentialSubtitle;
@@ -56,6 +57,7 @@
         mTitle = in.readCharSequence();
         mUseDefaultTitle = in.readBoolean();
         mSubtitle = in.readCharSequence();
+        mUseDefaultSubtitle = in.readBoolean();
         mDescription = in.readCharSequence();
         mDeviceCredentialTitle = in.readCharSequence();
         mDeviceCredentialSubtitle = in.readCharSequence();
@@ -94,6 +96,7 @@
         dest.writeCharSequence(mTitle);
         dest.writeBoolean(mUseDefaultTitle);
         dest.writeCharSequence(mSubtitle);
+        dest.writeBoolean(mUseDefaultSubtitle);
         dest.writeCharSequence(mDescription);
         dest.writeCharSequence(mDeviceCredentialTitle);
         dest.writeCharSequence(mDeviceCredentialSubtitle);
@@ -128,6 +131,8 @@
             return true;
         } else if (mUseDefaultTitle) {
             return true;
+        } else if (mUseDefaultSubtitle) {
+            return true;
         } else if (mDeviceCredentialTitle != null) {
             return true;
         } else if (mDeviceCredentialSubtitle != null) {
@@ -154,6 +159,10 @@
         mSubtitle = subtitle;
     }
 
+    public void setUseDefaultSubtitle(boolean useDefaultSubtitle) {
+        mUseDefaultSubtitle = useDefaultSubtitle;
+    }
+
     public void setDescription(CharSequence description) {
         mDescription = description;
     }
@@ -227,6 +236,10 @@
         return mSubtitle;
     }
 
+    public boolean isUseDefaultSubtitle() {
+        return mUseDefaultSubtitle;
+    }
+
     public CharSequence getDescription() {
         return mDescription;
     }
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index c9fc722..e9df553 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -124,7 +124,7 @@
      *
      * <p>Note that if 2 surfaces share the same stream via {@link
      * OutputConfiguration#enableSurfaceSharing} and {@link OutputConfiguration#addSurface},
-     * prepare() only needs to be called on one surface, and {link
+     * prepare() only needs to be called on one surface, and {@link
      * StateCallback#onSurfacePrepared} will be triggered for both surfaces.</p>
      *
      * <p>{@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index f20b25f..8e6576a 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -3635,7 +3635,7 @@
      * <p>An array of mandatory stream combinations which are applicable when device support the
      * 10-bit output capability
      * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT }
-     * This is an app-readable conversion of the maximum resolution mandatory stream combination
+     * This is an app-readable conversion of the 10 bit output mandatory stream combination
      * {@link android.hardware.camera2.CameraDevice#createCaptureSession tables}.</p>
      * <p>The array of
      * {@link android.hardware.camera2.params.MandatoryStreamCombination combinations} is
@@ -3660,7 +3660,7 @@
     /**
      * <p>An array of mandatory stream combinations which are applicable when device lists
      * {@code PREVIEW_STABILIZATION} in {@link CameraCharacteristics#CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES android.control.availableVideoStabilizationModes}.
-     * This is an app-readable conversion of the maximum resolution mandatory stream combination
+     * This is an app-readable conversion of the preview stabilization mandatory stream combination
      * {@link android.hardware.camera2.CameraDevice#createCaptureSession tables}.</p>
      * <p>The array of
      * {@link android.hardware.camera2.params.MandatoryStreamCombination combinations} is
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index d49cc44..7164dc3 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -128,6 +128,7 @@
      * @see #getDisplays(String)
      * @hide
      */
+    @TestApi
     public static final String DISPLAY_CATEGORY_REAR =
             "android.hardware.display.category.REAR";
 
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 9a092a5..2bd0606 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -412,6 +412,11 @@
     public abstract HostUsiVersion getHostUsiVersion(int displayId);
 
     /**
+     * Get all available DisplayGroupIds.
+     */
+    public abstract IntArray getDisplayGroupIds();
+
+    /**
      * Describes the requested power state of the display.
      *
      * This object is intended to describe the general characteristics of the
diff --git a/core/java/android/hardware/display/HdrConversionMode.java b/core/java/android/hardware/display/HdrConversionMode.java
index 1accd17..da2b016 100644
--- a/core/java/android/hardware/display/HdrConversionMode.java
+++ b/core/java/android/hardware/display/HdrConversionMode.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -119,4 +120,40 @@
         dest.writeInt(mConversionMode);
         dest.writeInt(mPreferredHdrOutputType);
     }
-}
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        return o instanceof HdrConversionMode && equals((HdrConversionMode) o);
+    }
+
+    @Override
+    public int hashCode() {
+        return 0; // don't care
+    }
+
+    @Override
+    public String toString() {
+        return "HdrConversionMode{ConversionMode=" + hdrConversionModeString(getConversionMode())
+                + ", PreferredHdrOutputType="
+                + Display.HdrCapabilities.hdrTypeToString(getPreferredHdrOutputType()) + "}";
+    }
+
+    private boolean equals(HdrConversionMode other) {
+        return other != null
+                && mConversionMode == other.getConversionMode()
+                && mPreferredHdrOutputType == other.getPreferredHdrOutputType();
+    }
+
+    private static String hdrConversionModeString(int hdrConversionMode) {
+        switch (hdrConversionMode) {
+            case HDR_CONVERSION_PASSTHROUGH:
+                return "HDR_CONVERSION_PASSTHROUGH";
+            case HDR_CONVERSION_SYSTEM:
+                return "HDR_CONVERSION_SYSTEM";
+            case HDR_CONVERSION_FORCE:
+                return "HDR_CONVERSION_FORCE";
+            default:
+                return "HDR_CONVERSION_UNKNOWN";
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl b/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl
index 8587348..7844b40 100644
--- a/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl
+++ b/core/java/android/hardware/fingerprint/IUdfpsRefreshRateRequestCallback.aidl
@@ -39,5 +39,15 @@
      *        {@link android.view.Display#getDisplayId()}.
      */
     void onRequestDisabled(int displayId);
+
+    /**
+     * To avoid delay in switching refresh rate when activating LHBM, allow screens to request
+     * higher refersh rate if auth is possible on particular screen
+     *
+     * @param displayId The displayId for which the refresh rate should be unset. See
+     *        {@link android.view.Display#getDisplayId()}.
+     * @param isPossible If authentication is possible on particualr screen
+     */
+    void onAuthenticationPossible(int displayId, boolean isPossible);
 }
 
diff --git a/core/java/android/hardware/input/VirtualNavigationTouchpadConfig.java b/core/java/android/hardware/input/VirtualNavigationTouchpadConfig.java
index 5ad5fd9..8935efa 100644
--- a/core/java/android/hardware/input/VirtualNavigationTouchpadConfig.java
+++ b/core/java/android/hardware/input/VirtualNavigationTouchpadConfig.java
@@ -49,12 +49,12 @@
     }
 
     /** Returns the touchpad height. */
-    public int getHeight() {
+    @IntRange(from = 1) public int getHeight() {
         return mHeight;
     }
 
     /** Returns the touchpad width. */
-    public int getWidth() {
+    @IntRange(from = 1) public int getWidth() {
         return mWidth;
     }
 
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 0483b71..71ec1c6 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -45,6 +45,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
@@ -99,6 +100,8 @@
      * audio source function is enabled
      * <li> {@link #USB_FUNCTION_MIDI} boolean extra indicating whether the
      * MIDI function is enabled
+     * <li> {@link #USB_FUNCTION_UVC} boolean extra indicating whether the
+     * UVC function is enabled
      * </ul>
      * If the sticky intent has not been found, that indicates USB is disconnected,
      * USB is not configured, MTP function is enabled, and all the other functions are disabled.
@@ -314,6 +317,14 @@
     public static final String USB_FUNCTION_NCM = "ncm";
 
     /**
+     * Name of the UVC USB function.
+     * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+     *
+     * @hide
+     */
+    public static final String USB_FUNCTION_UVC = "uvc";
+
+    /**
      * Name of Gadget Hal Not Present;
      *
      * @hide
@@ -683,8 +694,17 @@
     @SystemApi
     public static final long FUNCTION_NCM = 1 << 10;
 
+    /**
+     * Code for the uvc usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
+     * Only supported if {@link #isUvcSupportEnabled()} returns true.
+     * Must be equal to {@link GadgetFunction#UVC}
+     * @hide
+     */
+    @SystemApi
+    public static final long FUNCTION_UVC = 1 << 7;
+
     private static final long SETTABLE_FUNCTIONS = FUNCTION_MTP | FUNCTION_PTP | FUNCTION_RNDIS
-            | FUNCTION_MIDI | FUNCTION_NCM;
+            | FUNCTION_MIDI | FUNCTION_NCM | FUNCTION_UVC;
 
     private static final Map<String, Long> FUNCTION_NAME_TO_CODE = new HashMap<>();
 
@@ -702,6 +722,7 @@
         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_AUDIO_SOURCE, FUNCTION_AUDIO_SOURCE);
         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_ADB, FUNCTION_ADB);
         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_NCM, FUNCTION_NCM);
+        FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_UVC, FUNCTION_UVC);
     }
 
     /** @hide */
@@ -715,6 +736,7 @@
             FUNCTION_AUDIO_SOURCE,
             FUNCTION_ADB,
             FUNCTION_NCM,
+            FUNCTION_UVC,
     })
     public @interface UsbFunctionMode {}
 
@@ -1337,6 +1359,21 @@
     }
 
     /**
+     * Returns whether UVC is advertised to be supported or not. SELinux
+     * enforces that this function returns {@code false} when called from a
+     * process that doesn't belong either to a system app, or the
+     * DeviceAsWebcam Service.
+     *
+     * @return true if UVC is supported, false if UVC is not supported or if
+     *         called from a non-system app that isn't DeviceAsWebcam Service.
+     * @hide
+     */
+    @SystemApi
+    public static boolean isUvcSupportEnabled() {
+        return SystemProperties.getBoolean("ro.usb.uvc.enabled", false);
+    }
+
+    /**
      * Enable/Disable the USB data signaling.
      * <p>
      * Enables/Disables USB data path of all USB ports.
@@ -1716,7 +1753,7 @@
 
     /**
      * Returns whether the given functions are valid inputs to UsbManager.
-     * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI, NCM are accepted.
+     * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI, NCM, UVC are accepted.
      *
      * Only one function may be set at a time, except for RNDIS and NCM, which can be set together
      * because from a user perspective they are the same function (tethering).
@@ -1762,6 +1799,9 @@
         if ((functions & FUNCTION_NCM) != 0) {
             joiner.add(UsbManager.USB_FUNCTION_NCM);
         }
+        if ((functions & FUNCTION_UVC) != 0) {
+            joiner.add(UsbManager.USB_FUNCTION_UVC);
+        }
         if ((functions & FUNCTION_ADB) != 0) {
             joiner.add(UsbManager.USB_FUNCTION_ADB);
         }
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index d55367f..ed6a88f 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -223,11 +223,13 @@
                 final SomeArgs args = (SomeArgs) msg.obj;
                 final ImeTracker.Token statsToken = (ImeTracker.Token) args.arg3;
                 if (isValid(inputMethod, target, "DO_SHOW_SOFT_INPUT")) {
-                    ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+                    ImeTracker.forLogging().onProgress(
+                            statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
                     inputMethod.showSoftInputWithToken(
                             msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1, statsToken);
                 } else {
-                    ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+                    ImeTracker.forLogging().onFailed(
+                            statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
                 }
                 args.recycle();
                 return;
@@ -236,11 +238,13 @@
                 final SomeArgs args = (SomeArgs) msg.obj;
                 final ImeTracker.Token statsToken = (ImeTracker.Token) args.arg3;
                 if (isValid(inputMethod, target, "DO_HIDE_SOFT_INPUT")) {
-                    ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+                    ImeTracker.forLogging().onProgress(
+                            statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
                     inputMethod.hideSoftInputWithToken(msg.arg1, (ResultReceiver) args.arg2,
                             (IBinder) args.arg1, statsToken);
                 } else {
-                    ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+                    ImeTracker.forLogging().onFailed(
+                            statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
                 }
                 args.recycle();
                 return;
@@ -428,7 +432,7 @@
     @Override
     public void showSoftInput(IBinder showInputToken, @Nullable ImeTracker.Token statsToken,
             int flags, ResultReceiver resultReceiver) {
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
         mCaller.executeOrSendMessage(mCaller.obtainMessageIOOO(DO_SHOW_SOFT_INPUT,
                 flags, showInputToken, resultReceiver, statsToken));
     }
@@ -437,7 +441,7 @@
     @Override
     public void hideSoftInput(IBinder hideInputToken, @Nullable ImeTracker.Token statsToken,
             int flags, ResultReceiver resultReceiver) {
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
         mCaller.executeOrSendMessage(mCaller.obtainMessageIOOO(DO_HIDE_SOFT_INPUT,
                 flags, hideInputToken, resultReceiver, statsToken));
     }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 872414a..ee9d8a4 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -896,7 +896,8 @@
         @MainThread
         @Override
         public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
-            ImeTracker.get().onProgress(mCurStatsToken, ImeTracker.PHASE_IME_HIDE_SOFT_INPUT);
+            ImeTracker.forLogging().onProgress(
+                    mCurStatsToken, ImeTracker.PHASE_IME_HIDE_SOFT_INPUT);
             if (DEBUG) Log.v(TAG, "hideSoftInput()");
             if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R
                     && !mSystemCallingHideSoftInput) {
@@ -950,7 +951,8 @@
         @MainThread
         @Override
         public void showSoftInput(int flags, ResultReceiver resultReceiver) {
-            ImeTracker.get().onProgress(mCurStatsToken, ImeTracker.PHASE_IME_SHOW_SOFT_INPUT);
+            ImeTracker.forLogging().onProgress(
+                    mCurStatsToken, ImeTracker.PHASE_IME_SHOW_SOFT_INPUT);
             if (DEBUG) Log.v(TAG, "showSoftInput()");
             // TODO(b/148086656): Disallow IME developers from calling InputMethodImpl methods.
             if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R
@@ -966,11 +968,11 @@
                     null /* icProto */);
             final boolean wasVisible = isInputViewShown();
             if (dispatchOnShowInputRequested(flags, false)) {
-                ImeTracker.get().onProgress(mCurStatsToken,
+                ImeTracker.forLogging().onProgress(mCurStatsToken,
                         ImeTracker.PHASE_IME_ON_SHOW_SOFT_INPUT_TRUE);
                 showWindow(true);
             } else {
-                ImeTracker.get().onFailed(mCurStatsToken,
+                ImeTracker.forLogging().onFailed(mCurStatsToken,
                         ImeTracker.PHASE_IME_ON_SHOW_SOFT_INPUT_TRUE);
             }
             setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
@@ -2979,7 +2981,7 @@
         ImeTracing.getInstance().triggerServiceDump(
                 "InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", mDumper,
                 null /* icProto */);
-        ImeTracker.get().onProgress(mCurStatsToken,
+        ImeTracker.forLogging().onProgress(mCurStatsToken,
                 ImeTracker.PHASE_IME_APPLY_VISIBILITY_INSETS_CONSUMER);
         mPrivOps.applyImeVisibilityAsync(setVisible
                 ? mCurShowInputToken : mCurHideInputToken, setVisible, mCurStatsToken);
diff --git a/core/java/android/net/vcn/VcnConfig.java b/core/java/android/net/vcn/VcnConfig.java
index dcf0026..6f9c9dd 100644
--- a/core/java/android/net/vcn/VcnConfig.java
+++ b/core/java/android/net/vcn/VcnConfig.java
@@ -22,6 +22,7 @@
 import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_DESERIALIZER;
 import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_SERIALIZER;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -37,6 +38,10 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.vcn.util.PersistableBundleUtils;
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -54,6 +59,17 @@
 public final class VcnConfig implements Parcelable {
     @NonNull private static final String TAG = VcnConfig.class.getSimpleName();
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            prefix = {"TRANSPORT_"},
+            value = {
+                NetworkCapabilities.TRANSPORT_CELLULAR,
+                NetworkCapabilities.TRANSPORT_WIFI,
+            })
+    @Target({ElementType.TYPE_USE})
+    public @interface VcnUnderlyingNetworkTransport {}
+
     private static final Set<Integer> ALLOWED_TRANSPORTS = new ArraySet<>();
 
     static {
@@ -164,7 +180,7 @@
      * @see Builder#setRestrictedUnderlyingNetworkTransports(Set)
      */
     @NonNull
-    public Set<Integer> getRestrictedUnderlyingNetworkTransports() {
+    public Set<@VcnUnderlyingNetworkTransport Integer> getRestrictedUnderlyingNetworkTransports() {
         return Collections.unmodifiableSet(mRestrictedTransports);
     }
 
@@ -308,16 +324,20 @@
         /**
          * Sets transports that will be restricted by the VCN.
          *
-         * @param transports transports that will be restricted by VCN. Networks that include any
-         *     of the transports will be marked as restricted. Only {@link
-         *     NetworkCapabilities#TRANSPORT_WIFI} and {@link
-         *     NetworkCapabilities#TRANSPORT_CELLULAR} are allowed. {@link
+         * <p>In general, apps will not be able to bind to, or use a restricted network. In other
+         * words, unless the network type is marked restricted, any app can opt to use underlying
+         * networks, instead of through the VCN.
+         *
+         * @param transports transports that will be restricted by VCN. Networks that include any of
+         *     the transports will be marked as restricted. {@link
          *     NetworkCapabilities#TRANSPORT_WIFI} is marked restricted by default.
          * @return this {@link Builder} instance, for chaining
          * @throws IllegalArgumentException if the input contains unsupported transport types.
+         * @see NetworkCapabilities#NET_CAPABILITY_NOT_RESTRICTED
          */
         @NonNull
-        public Builder setRestrictedUnderlyingNetworkTransports(@NonNull Set<Integer> transports) {
+        public Builder setRestrictedUnderlyingNetworkTransports(
+                @NonNull Set<@VcnUnderlyingNetworkTransport Integer> transports) {
             validateRestrictedTransportsOrThrow(transports);
 
             mRestrictedTransports.clear();
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index a980158..1bb44af 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -32,7 +32,6 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.IntentFilter;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.nfc.tech.MifareClassic;
@@ -44,7 +43,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.IOException;
@@ -427,6 +425,7 @@
     // recovery
     @UnsupportedAppUsage
     static INfcAdapter sService;
+    static NfcServiceManager.ServiceRegisterer sServiceRegisterer;
     static INfcTag sTagService;
     static INfcCardEmulation sCardEmulationService;
     static INfcFCardEmulation sNfcFCardEmulationService;
@@ -572,66 +571,6 @@
     }
 
     /**
-     * Helper to check if this device has FEATURE_NFC_BEAM, but without using
-     * a context.
-     * Equivalent to
-     * context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)
-     */
-    private static boolean hasBeamFeature() {
-        IPackageManager pm = ActivityThread.getPackageManager();
-        if (pm == null) {
-            Log.e(TAG, "Cannot get package manager, assuming no Android Beam feature");
-            return false;
-        }
-        try {
-            return pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM, 0);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Package manager query failed, assuming no Android Beam feature", e);
-            return false;
-        }
-    }
-
-    /**
-     * Helper to check if this device has FEATURE_NFC, but without using
-     * a context.
-     * Equivalent to
-     * context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)
-     */
-    private static boolean hasNfcFeature() {
-        IPackageManager pm = ActivityThread.getPackageManager();
-        if (pm == null) {
-            Log.e(TAG, "Cannot get package manager, assuming no NFC feature");
-            return false;
-        }
-        try {
-            return pm.hasSystemFeature(PackageManager.FEATURE_NFC, 0);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Package manager query failed, assuming no NFC feature", e);
-            return false;
-        }
-    }
-
-    /**
-     * Helper to check if this device is NFC HCE capable, by checking for
-     * FEATURE_NFC_HOST_CARD_EMULATION and/or FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
-     * but without using a context.
-     */
-    private static boolean hasNfcHceFeature() {
-        IPackageManager pm = ActivityThread.getPackageManager();
-        if (pm == null) {
-            Log.e(TAG, "Cannot get package manager, assuming no NFC feature");
-            return false;
-        }
-        try {
-            return pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION, 0)
-                || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF, 0);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Package manager query failed, assuming no NFC feature", e);
-            return false;
-        }
-    }
-
-    /**
      * Return list of Secure Elements which support off host card emulation.
      *
      * @return List<String> containing secure elements on the device which supports
@@ -640,23 +579,21 @@
      * @hide
      */
     public @NonNull List<String> getSupportedOffHostSecureElements() {
+        if (mContext == null) {
+            throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
+                    + " getSupportedOffHostSecureElements APIs");
+        }
         List<String> offHostSE = new ArrayList<String>();
-        IPackageManager pm = ActivityThread.getPackageManager();
+        PackageManager pm = mContext.getPackageManager();
         if (pm == null) {
             Log.e(TAG, "Cannot get package manager, assuming no off-host CE feature");
             return offHostSE;
         }
-        try {
-            if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC, 0)) {
-                offHostSE.add("SIM");
-            }
-            if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE, 0)) {
-                offHostSE.add("eSE");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Package manager query failed, assuming no off-host CE feature", e);
-            offHostSE.clear();
-            return offHostSE;
+        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)) {
+            offHostSE.add("SIM");
+        }
+        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE)) {
+            offHostSE.add("eSE");
         }
         return offHostSE;
     }
@@ -668,15 +605,31 @@
      */
     @UnsupportedAppUsage
     public static synchronized NfcAdapter getNfcAdapter(Context context) {
+        if (context == null) {
+            if (sNullContextNfcAdapter == null) {
+                sNullContextNfcAdapter = new NfcAdapter(null);
+            }
+            return sNullContextNfcAdapter;
+        }
         if (!sIsInitialized) {
-            sHasNfcFeature = hasNfcFeature();
-            sHasBeamFeature = hasBeamFeature();
-            boolean hasHceFeature = hasNfcHceFeature();
+            PackageManager pm;
+            pm = context.getPackageManager();
+            sHasNfcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC);
+            sHasBeamFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC_BEAM);
+            boolean hasHceFeature =
+                    pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
+                    || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF);
             /* is this device meant to have NFC */
             if (!sHasNfcFeature && !hasHceFeature) {
                 Log.v(TAG, "this device does not have NFC support");
                 throw new UnsupportedOperationException();
             }
+            NfcServiceManager manager = NfcFrameworkInitializer.getNfcServiceManager();
+            if (manager == null) {
+                Log.e(TAG, "NfcServiceManager is null");
+                throw new UnsupportedOperationException();
+            }
+            sServiceRegisterer = manager.getNfcManagerServiceRegisterer();
             sService = getServiceInterface();
             if (sService == null) {
                 Log.e(TAG, "could not retrieve NFC service");
@@ -707,12 +660,6 @@
 
             sIsInitialized = true;
         }
-        if (context == null) {
-            if (sNullContextNfcAdapter == null) {
-                sNullContextNfcAdapter = new NfcAdapter(null);
-            }
-            return sNullContextNfcAdapter;
-        }
         NfcAdapter adapter = sNfcAdapters.get(context);
         if (adapter == null) {
             adapter = new NfcAdapter(context);
@@ -724,7 +671,7 @@
     /** get handle to NFC service interface */
     private static INfcAdapter getServiceInterface() {
         /* get a handle to NFC service */
-        IBinder b = ServiceManager.getService("nfc");
+        IBinder b = sServiceRegisterer.get();
         if (b == null) {
             return null;
         }
@@ -754,12 +701,13 @@
                     "context not associated with any application (using a mock context?)");
         }
 
-        if (getServiceInterface() == null) {
-            // NFC is not available
-            return null;
+        if (sIsInitialized && sServiceRegisterer.tryGet() == null) {
+            synchronized (NfcAdapter.class) {
+                /* Stale sService pointer */
+                if (sIsInitialized) sIsInitialized = false;
+            }
         }
-
-        /* use getSystemService() for consistency */
+        /* Try to initialize the service */
         NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
         if (manager == null) {
             // NFC not available
@@ -2510,8 +2458,18 @@
      *
      * <p>This returns a mapping of package names for this user id to whether we dispatch Tag
      * intents to the package. {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
-    *  {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
-    *  disallowed.
+     * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+     * mapped to {@code false}.
+     * <p>There are three different possible cases:
+     * <p>A package not being in the preference list.
+     * It does not contain any Tag intent filters or the user never triggers a Tag detection that
+     * matches the intent filter of the package.
+     * <p>A package being mapped to {@code true}.
+     * When a package has been launched by a tag detection for the first time, the package name is
+     * put to the map and by default mapped to {@code true}. The package will receive Tag intents as
+     * usual.
+     * <p>A package being mapped to {@code false}.
+     * The user chooses to disable this package and it will not receive any Tag intents anymore.
      *
      * @param userId the user to whom this preference list will belong to
      * @return a map of the UserId which indicates the mapping from package name to
diff --git a/core/java/android/nfc/NfcFrameworkInitializer.java b/core/java/android/nfc/NfcFrameworkInitializer.java
new file mode 100644
index 0000000..1ab8a1e
--- /dev/null
+++ b/core/java/android/nfc/NfcFrameworkInitializer.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.nfc;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * Class for performing registration for Nfc service.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public class NfcFrameworkInitializer {
+    private NfcFrameworkInitializer() {}
+
+    private static volatile NfcServiceManager sNfcServiceManager;
+
+    /**
+     * Sets an instance of {@link NfcServiceManager} that allows
+     * the nfc mainline module to register/obtain nfc binder services. This is called
+     * by the platform during the system initialization.
+     *
+     * @param nfcServiceManager instance of {@link NfcServiceManager} that allows
+     * the nfc mainline module to register/obtain nfcd binder services.
+     */
+    public static void setNfcServiceManager(
+            @NonNull NfcServiceManager nfcServiceManager) {
+        if (sNfcServiceManager != null) {
+            throw new IllegalStateException("setNfcServiceManager called twice!");
+        }
+
+        if (nfcServiceManager == null) {
+            throw new IllegalArgumentException("nfcServiceManager must not be null");
+        }
+
+        sNfcServiceManager = nfcServiceManager;
+    }
+
+    /** @hide */
+    public static NfcServiceManager getNfcServiceManager() {
+        return sNfcServiceManager;
+    }
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers NFC service
+     * to {@link Context}, so that {@link Context#getSystemService} can return them.
+     *
+     * @throws IllegalStateException if this is called from anywhere besides
+     * {@link SystemServiceRegistry}
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(Context.NFC_SERVICE,
+                NfcManager.class, context -> new NfcManager(context));
+    }
+}
diff --git a/core/java/android/nfc/NfcServiceManager.java b/core/java/android/nfc/NfcServiceManager.java
new file mode 100644
index 0000000..5582f11
--- /dev/null
+++ b/core/java/android/nfc/NfcServiceManager.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**********************************************************************
+ * This file is not a part of the NFC mainline modure                 *
+ * *******************************************************************/
+
+package android.nfc;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.SystemApi.Client;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.ServiceManager;
+
+/**
+ * Provides a way to register and obtain the system service binder objects managed by the nfc
+ * service.
+ *
+ * @hide
+ */
+@SystemApi(client = Client.MODULE_LIBRARIES)
+public class NfcServiceManager {
+
+    /**
+     * @hide
+     */
+    public NfcServiceManager() {
+    }
+
+    /**
+     * A class that exposes the methods to register and obtain each system service.
+     */
+    public static final class ServiceRegisterer {
+        private final String mServiceName;
+
+        /**
+         * @hide
+         */
+        public ServiceRegisterer(String serviceName) {
+            mServiceName = serviceName;
+        }
+
+        /**
+         * Register a system server binding object for a service.
+         */
+        public void register(@NonNull IBinder service) {
+            ServiceManager.addService(mServiceName, service);
+        }
+
+        /**
+         * Get the system server binding object for a service.
+         *
+         * <p>This blocks until the service instance is ready,
+         * or a timeout happens, in which case it returns null.
+         */
+        @Nullable
+        public IBinder get() {
+            return ServiceManager.getService(mServiceName);
+        }
+
+        /**
+         * Get the system server binding object for a service.
+         *
+         * <p>This blocks until the service instance is ready,
+         * or a timeout happens, in which case it throws {@link ServiceNotFoundException}.
+         */
+        @NonNull
+        public IBinder getOrThrow() throws ServiceNotFoundException {
+            try {
+                return ServiceManager.getServiceOrThrow(mServiceName);
+            } catch (ServiceManager.ServiceNotFoundException e) {
+                throw new ServiceNotFoundException(mServiceName);
+            }
+        }
+
+        /**
+         * Get the system server binding object for a service. If the specified service is
+         * not available, it returns null.
+         */
+        @Nullable
+        public IBinder tryGet() {
+            return ServiceManager.checkService(mServiceName);
+        }
+    }
+
+    /**
+     * See {@link ServiceRegisterer#getOrThrow}.
+     *
+     */
+    public static class ServiceNotFoundException extends ServiceManager.ServiceNotFoundException {
+        /**
+         * Constructor.
+         *
+         * @param name the name of the binder service that cannot be found.
+         *
+         */
+        public ServiceNotFoundException(@NonNull String name) {
+            super(name);
+        }
+    }
+
+    /**
+     * Returns {@link ServiceRegisterer} for the "nfc" service.
+     */
+    @NonNull
+    public ServiceRegisterer getNfcManagerServiceRegisterer() {
+        return new ServiceRegisterer(Context.NFC_SERVICE);
+    }
+}
diff --git a/core/java/android/nfc/OWNERS b/core/java/android/nfc/OWNERS
index 9a2e446..35e9713 100644
--- a/core/java/android/nfc/OWNERS
+++ b/core/java/android/nfc/OWNERS
@@ -1,5 +1,2 @@
 # Bug component: 48448
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 0b56d19..ac3344e 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -22,11 +22,9 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.app.Activity;
-import android.app.ActivityThread;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.nfc.INfcCardEmulation;
 import android.nfc.NfcAdapter;
@@ -158,18 +156,13 @@
             throw new UnsupportedOperationException();
         }
         if (!sIsInitialized) {
-            IPackageManager pm = ActivityThread.getPackageManager();
+            PackageManager pm = context.getPackageManager();
             if (pm == null) {
                 Log.e(TAG, "Cannot get PackageManager");
                 throw new UnsupportedOperationException();
             }
-            try {
-                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION, 0)) {
-                    Log.e(TAG, "This device does not support card emulation");
-                    throw new UnsupportedOperationException();
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "PackageManager query failed.");
+            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+                Log.e(TAG, "This device does not support card emulation");
                 throw new UnsupportedOperationException();
             }
             sIsInitialized = true;
@@ -272,12 +265,16 @@
      * @return whether AIDs in the category can be handled by a service
      *         specified by the foreground app.
      */
+    @SuppressWarnings("NonUserGetterCalled")
     public boolean categoryAllowsForegroundPreference(String category) {
         if (CATEGORY_PAYMENT.equals(category)) {
             boolean preferForeground = false;
+            Context contextAsUser = mContext.createContextAsUser(
+                    UserHandle.of(UserHandle.myUserId()), 0);
             try {
-                preferForeground = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.NFC_PAYMENT_FOREGROUND, UserHandle.myUserId()) != 0;
+                preferForeground = Settings.Secure.getInt(
+                        contextAsUser.getContentResolver(),
+                        Settings.Secure.NFC_PAYMENT_FOREGROUND) != 0;
             } catch (SettingNotFoundException e) {
             }
             return preferForeground;
diff --git a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
index 3c92455..48bbf5b6 100644
--- a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
+++ b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
@@ -17,10 +17,8 @@
 package android.nfc.cardemulation;
 
 import android.app.Activity;
-import android.app.ActivityThread;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.nfc.INfcFCardEmulation;
 import android.nfc.NfcAdapter;
@@ -70,18 +68,13 @@
             throw new UnsupportedOperationException();
         }
         if (!sIsInitialized) {
-            IPackageManager pm = ActivityThread.getPackageManager();
+            PackageManager pm = context.getPackageManager();
             if (pm == null) {
                 Log.e(TAG, "Cannot get PackageManager");
                 throw new UnsupportedOperationException();
             }
-            try {
-                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF, 0)) {
-                    Log.e(TAG, "This device does not support NFC-F card emulation");
-                    throw new UnsupportedOperationException();
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "PackageManager query failed.");
+            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+                Log.e(TAG, "This device does not support NFC-F card emulation");
                 throw new UnsupportedOperationException();
             }
             sIsInitialized = true;
diff --git a/core/java/android/nfc/cardemulation/OWNERS b/core/java/android/nfc/cardemulation/OWNERS
index 9a2e446..35e9713 100644
--- a/core/java/android/nfc/cardemulation/OWNERS
+++ b/core/java/android/nfc/cardemulation/OWNERS
@@ -1,5 +1,2 @@
 # Bug component: 48448
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/core/java/android/nfc/dta/OWNERS b/core/java/android/nfc/dta/OWNERS
index 9a2e446..35e9713 100644
--- a/core/java/android/nfc/dta/OWNERS
+++ b/core/java/android/nfc/dta/OWNERS
@@ -1,5 +1,2 @@
 # Bug component: 48448
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/core/java/android/nfc/tech/OWNERS b/core/java/android/nfc/tech/OWNERS
index 9a2e446..35e9713 100644
--- a/core/java/android/nfc/tech/OWNERS
+++ b/core/java/android/nfc/tech/OWNERS
@@ -1,5 +1,2 @@
 # Bug component: 48448
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 607d73c..2bad670 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -4356,13 +4356,6 @@
         }
     }
 
-    /**
-     * Temporary for settings.
-     */
-    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
-        dumpCheckinLocked(context, pw, which, reqUid, checkWifiOnly(context));
-    }
-
     private static final String[] CHECKIN_POWER_COMPONENT_LABELS =
             new String[BatteryConsumer.POWER_COMPONENT_COUNT];
     static {
@@ -7477,22 +7470,8 @@
     public static final int DUMP_DEVICE_WIFI_ONLY = 1<<6;
 
     private void dumpHistory(PrintWriter pw, int flags, long histStart, boolean checkin) {
-        if (!checkin) {
-            synchronized (this) {
-                final long historyTotalSize = getHistoryTotalSize();
-                final long historyUsedSize = getHistoryUsedSize();
-                pw.print("Battery History (");
-                pw.print((100 * historyUsedSize) / historyTotalSize);
-                pw.print("% used, ");
-                printSizeValue(pw, historyUsedSize);
-                pw.print(" used of ");
-                printSizeValue(pw, historyTotalSize);
-                pw.print(", ");
-                pw.print(getHistoryStringPoolSize());
-                pw.print(" strings using ");
-                printSizeValue(pw, getHistoryStringPoolBytes());
-                pw.println("):");
-            }
+        synchronized (this) {
+            dumpHistoryTagPoolLocked(pw, checkin);
         }
 
         final HistoryPrinter hprinter = new HistoryPrinter();
@@ -7586,6 +7565,43 @@
         }
     }
 
+    private void dumpHistoryTagPoolLocked(PrintWriter pw, boolean checkin) {
+        if (checkin) {
+            for (int i = 0; i < getHistoryStringPoolSize(); i++) {
+                pw.print(BATTERY_STATS_CHECKIN_VERSION);
+                pw.print(',');
+                pw.print(HISTORY_STRING_POOL);
+                pw.print(',');
+                pw.print(i);
+                pw.print(",");
+                pw.print(getHistoryTagPoolUid(i));
+                pw.print(",\"");
+                String str = getHistoryTagPoolString(i);
+                if (str != null) {
+                    str = str.replace("\\", "\\\\");
+                    str = str.replace("\"", "\\\"");
+                    pw.print(str);
+                }
+                pw.print("\"");
+                pw.println();
+            }
+        } else {
+            final long historyTotalSize = getHistoryTotalSize();
+            final long historyUsedSize = getHistoryUsedSize();
+            pw.print("Battery History (");
+            pw.print((100 * historyUsedSize) / historyTotalSize);
+            pw.print("% used, ");
+            printSizeValue(pw, historyUsedSize);
+            pw.print(" used of ");
+            printSizeValue(pw, historyTotalSize);
+            pw.print(", ");
+            pw.print(getHistoryStringPoolSize());
+            pw.print(" strings using ");
+            printSizeValue(pw, getHistoryStringPoolBytes());
+            pw.println("):");
+        }
+    }
+
     private void dumpDailyLevelStepSummary(PrintWriter pw, String prefix, String label,
             LevelStepTracker steps, StringBuilder tmpSb, int[] tmpOutInt) {
         if (steps == null) {
@@ -7804,33 +7820,17 @@
 
     // This is called from BatteryStatsService.
     @SuppressWarnings("unused")
-    public void dumpCheckinLocked(Context context, PrintWriter pw,
+    public void dumpCheckin(Context context, PrintWriter pw,
             List<ApplicationInfo> apps, int flags, long histStart) {
-        prepareForDumpLocked();
+        synchronized (this) {
+            prepareForDumpLocked();
 
-        dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
-                CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
-                getEndPlatformVersion());
+            dumpLine(pw, 0 /* uid */, "i" /* category */, VERSION_DATA,
+                    CHECKIN_VERSION, getParcelVersion(), getStartPlatformVersion(),
+                    getEndPlatformVersion());
+        }
 
         if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
-            for (int i = 0; i < getHistoryStringPoolSize(); i++) {
-                pw.print(BATTERY_STATS_CHECKIN_VERSION);
-                pw.print(',');
-                pw.print(HISTORY_STRING_POOL);
-                pw.print(',');
-                pw.print(i);
-                pw.print(",");
-                pw.print(getHistoryTagPoolUid(i));
-                pw.print(",\"");
-                String str = getHistoryTagPoolString(i);
-                if (str != null) {
-                    str = str.replace("\\", "\\\\");
-                    str = str.replace("\"", "\\\"");
-                    pw.print(str);
-                }
-                pw.print("\"");
-                pw.println();
-            }
             dumpHistory(pw, flags, histStart, true);
         }
 
@@ -7838,6 +7838,13 @@
             return;
         }
 
+        synchronized (this) {
+            dumpCheckinLocked(context, pw, apps, flags);
+        }
+    }
+
+    private void dumpCheckinLocked(Context context, PrintWriter pw, List<ApplicationInfo> apps,
+            int flags) {
         if (apps != null) {
             SparseArray<Pair<ArrayList<String>, MutableBoolean>> uids = new SparseArray<>();
             for (int i=0; i<apps.size(); i++) {
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index 0a7eb43..086b0e5 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -70,10 +70,7 @@
      * An interface describing the callback for bugreport progress and status.
      *
      * <p>Callers will receive {@link #onProgress} calls as the bugreport progresses, followed by a
-     * terminal call to either {@link #onFinished} or {@link #onError}. Note that
-     * {@link #onFinished(String)} will only be invoked when calling {@code startBugreport} with the
-     * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag set. Otherwise,
-     * {@link #onFinished()} will be invoked.
+     * terminal call to either {@link #onFinished} or {@link #onError}.
      *
      * <p>If an issue is encountered while starting the bugreport asynchronously, callers will
      * receive an {@link #onError} call without any {@link #onProgress} callbacks.
@@ -149,8 +146,7 @@
         /** Called when taking bugreport finishes successfully.
          *
          * <p>This callback will be invoked if the
-         * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag is not set. Otherwise, the
-         * {@link #onFinished(String)} callback will be invoked.
+         * {@link BugreportParams#BUGREPORT_FLAG_DEFER_CONSENT} flag is not set.
          */
         public void onFinished() {}
 
@@ -161,8 +157,10 @@
          * {@link #onFinished()} callback will be invoked.
          *
          * @param bugreportFile the absolute path of the generated bugreport file.
+         * @hide
 
          */
+        @SystemApi
         public void onFinished(@NonNull String bugreportFile) {}
 
         /**
@@ -279,7 +277,7 @@
      * <p>The bugreport artifacts will be copied over to the given file descriptor only if the user
      * consents to sharing with the calling app.
      *
-     * <p>{@link BugreportManager} takes ownership of {@code bugreportFd} and {@code screenshotFd}.
+     * <p>{@link BugreportManager} takes ownership of {@code bugreportFd}.
      *
      * <p>The caller may only request to retrieve a given bugreport once. Subsequent calls will fail
      * with error code {@link BugreportCallback#BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE}.
diff --git a/core/java/android/os/BundleMerger.java b/core/java/android/os/BundleMerger.java
index 51bd4ea..857aaf5 100644
--- a/core/java/android/os/BundleMerger.java
+++ b/core/java/android/os/BundleMerger.java
@@ -85,37 +85,43 @@
     /**
      * Merge strategy that numerically adds both conflicting values.
      */
-    public static final int STRATEGY_NUMBER_ADD = 5;
+    public static final int STRATEGY_NUMBER_ADD = 10;
 
     /**
      * Merge strategy that numerically increments the first conflicting value by
      * {@code 1} and ignores the last conflicting value.
      */
-    public static final int STRATEGY_NUMBER_INCREMENT_FIRST = 6;
+    public static final int STRATEGY_NUMBER_INCREMENT_FIRST = 20;
+
+    /**
+     * Merge strategy that numerically increments the first conflicting value by
+     * {@code 1} and also numerically adds both conflicting values.
+     */
+    public static final int STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD = 25;
 
     /**
      * Merge strategy that combines conflicting values using a boolean "and"
      * operation.
      */
-    public static final int STRATEGY_BOOLEAN_AND = 7;
+    public static final int STRATEGY_BOOLEAN_AND = 30;
 
     /**
      * Merge strategy that combines conflicting values using a boolean "or"
      * operation.
      */
-    public static final int STRATEGY_BOOLEAN_OR = 8;
+    public static final int STRATEGY_BOOLEAN_OR = 40;
 
     /**
      * Merge strategy that combines two conflicting array values by appending
      * the last array after the first array.
      */
-    public static final int STRATEGY_ARRAY_APPEND = 9;
+    public static final int STRATEGY_ARRAY_APPEND = 50;
 
     /**
      * Merge strategy that combines two conflicting {@link ArrayList} values by
      * appending the last {@link ArrayList} after the first {@link ArrayList}.
      */
-    public static final int STRATEGY_ARRAY_LIST_APPEND = 10;
+    public static final int STRATEGY_ARRAY_LIST_APPEND = 60;
 
     @IntDef(flag = false, prefix = { "STRATEGY_" }, value = {
             STRATEGY_REJECT,
@@ -125,6 +131,7 @@
             STRATEGY_COMPARABLE_MAX,
             STRATEGY_NUMBER_ADD,
             STRATEGY_NUMBER_INCREMENT_FIRST,
+            STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD,
             STRATEGY_BOOLEAN_AND,
             STRATEGY_BOOLEAN_OR,
             STRATEGY_ARRAY_APPEND,
@@ -282,6 +289,8 @@
                 return numberAdd(first, last);
             case STRATEGY_NUMBER_INCREMENT_FIRST:
                 return numberIncrementFirst(first, last);
+            case STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD:
+                return numberAdd(numberIncrementFirst(first, last), last);
             case STRATEGY_BOOLEAN_AND:
                 return booleanAnd(first, last);
             case STRATEGY_BOOLEAN_OR:
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index db5bc70..fb115b3 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -104,6 +104,10 @@
         return mAttrs;
     }
 
+    public IBinder getToken() {
+        return mToken;
+    }
+
     public VibrationAttributes getVibrationAttributes() {
         return new VibrationAttributes.Builder(mAttrs).build();
     }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index f1e3ab0..3b62881 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -48,6 +48,8 @@
     void wakeUp(long time, int reason, String details, String opPackageName);
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     void goToSleep(long time, int reason, int flags);
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
+    void goToSleepWithDisplayId(int displayId, long time, int reason, int flags);
     @UnsupportedAppUsage(maxTargetSdk = 28)
     void nap(long time);
     float getBrightnessConstraint(int constraint);
@@ -68,11 +70,29 @@
     boolean isBatteryDischargePredictionPersonalized();
     boolean isDeviceIdleMode();
     boolean isLightDeviceIdleMode();
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER })")
     boolean isLowPowerStandbySupported();
     boolean isLowPowerStandbyEnabled();
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER })")
     void setLowPowerStandbyEnabled(boolean enabled);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER })")
     void setLowPowerStandbyActiveDuringMaintenance(boolean activeDuringMaintenance);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER })")
     void forceLowPowerStandbyActive(boolean active);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER })")
+    void setLowPowerStandbyPolicy(in @nullable LowPowerStandbyPolicy policy);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER })")
+    LowPowerStandbyPolicy getLowPowerStandbyPolicy();
+    boolean isExemptFromLowPowerStandby();
+    boolean isReasonAllowedInLowPowerStandby(int reason);
+    boolean isFeatureAllowedInLowPowerStandby(String feature);
+
+    parcelable LowPowerStandbyPolicy {
+        String identifier;
+        List<String> exemptPackages;
+        int allowedReasons;
+        List<String> allowedFeatures;
+    }
 
     @UnsupportedAppUsage
     void reboot(boolean confirm, String reason, boolean wait);
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 810bd63..93d5082 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -45,6 +45,7 @@
 import android.system.OsConstants;
 import android.system.StructStat;
 import android.util.Log;
+import android.util.Slog;
 
 import dalvik.system.CloseGuard;
 import dalvik.system.VMRuntime;
@@ -329,6 +330,14 @@
     }
 
     private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException {
+        if ((mode & MODE_WRITE_ONLY) != 0 && (mode & MODE_APPEND) == 0
+                && (mode & MODE_TRUNCATE) == 0 && ((mode & MODE_READ_ONLY) == 0)
+                && file != null && file.exists()) {
+            Slog.wtfQuiet(TAG, "ParcelFileDescriptor.open is called with w without t or a or r, "
+                    + "which will have a different behavior beginning in Android Q."
+                    + "\nMode: " + mode + "\nFilename: " + file.getPath());
+        }
+
         final int flags = FileUtils.translateModePfdToPosix(mode) | ifAtLeastQ(O_CLOEXEC);
 
         int realMode = S_IRWXU | S_IRWXG;
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 90502af..2142c4c 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -35,6 +35,7 @@
 import android.service.dreams.Sandman;
 import android.sysprop.InitProperties;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
@@ -44,7 +45,10 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -1502,6 +1506,43 @@
     }
 
     /**
+     * Forces the {@link com.android.server.display.DisplayGroup} of the provided {@code displayId}
+     * to turn off.
+     *
+     * <p>If the {@link com.android.server.display.DisplayGroup} of the provided {@code displayId}
+     * is turned on it will be turned off. If all displays are off as a result of this action the
+     * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup} of
+     * the provided {@code displayId} is already off then nothing will happen.
+     *
+     * <p>Overrides all the wake locks that are held.
+     * This is what happens when the power key is pressed to turn off the screen.
+     *
+     * <p>Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+     *
+     * @param displayId The display ID to turn off. If {@code displayId} is
+     * {@link Display#INVALID_DISPLAY}, then all displays are turned off.
+     * @param time The time when the request to go to sleep was issued, in the
+     * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+     * order the go to sleep request with other power management functions.  It should be set
+     * to the timestamp of the input event that caused the request to go to sleep.
+     * @param reason The reason the device is going to sleep.
+     * @param flags Optional flags to apply when going to sleep.
+     *
+     * @see #userActivity
+     * @see #wakeUp
+     *
+     * @hide Requires signature permission.
+     */
+    @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+    public void goToSleep(int displayId, long time, @GoToSleepReason int reason, int flags) {
+        try {
+            mService.goToSleepWithDisplayId(displayId, time, reason, flags);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group}
      * to turn on.
      *
@@ -2344,6 +2385,93 @@
     }
 
     /**
+     * Sets the current Low Power Standby policy.
+     *
+     * When the policy changes {@link #ACTION_LOW_POWER_STANDBY_POLICY_CHANGED} is broadcast to
+     * registered receivers.
+     *
+     * @param policy The policy to set. If null, resets to the default policy.
+     * @see #getLowPowerStandbyPolicy
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
+            android.Manifest.permission.DEVICE_POWER
+    })
+    public void setLowPowerStandbyPolicy(@Nullable LowPowerStandbyPolicy policy) {
+        try {
+            mService.setLowPowerStandbyPolicy(LowPowerStandbyPolicy.toParcelable(policy));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the current Low Power Standby policy.
+     *
+     * When the policy changes {@link #ACTION_LOW_POWER_STANDBY_POLICY_CHANGED} is broadcast to
+     * registered receivers.
+     *
+     * @see #setLowPowerStandbyPolicy
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
+            android.Manifest.permission.DEVICE_POWER
+    })
+    public LowPowerStandbyPolicy getLowPowerStandbyPolicy() {
+        try {
+            return LowPowerStandbyPolicy.fromParcelable(mService.getLowPowerStandbyPolicy());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if the calling package is exempt from Low Power Standby restrictions or
+     * Low Power Standby is disabled (so Low Power Standby does not restrict apps),
+     * false otherwise.
+     */
+    public boolean isExemptFromLowPowerStandby() {
+        try {
+            return mService.isExemptFromLowPowerStandby();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if Low Power Standby is disabled (so Low Power Standby does not restrict apps),
+     * or apps may be automatically exempt from Low Power Standby restrictions for the given reason.
+     *
+     * The system may exempt apps from Low Power Standby restrictions when using allowed features.
+     * For example, if {@link #LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION} is allowed,
+     * then apps with active voice interaction sessions are exempt from restrictions.
+     */
+    public boolean isAllowedInLowPowerStandby(@LowPowerStandbyAllowedReason int reason) {
+        try {
+            return mService.isReasonAllowedInLowPowerStandby(reason);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if Low Power Standby is disabled (so Low Power Standby does not restrict apps),
+     * or apps are allowed to use a given feature during Low Power Standby.
+     */
+    public boolean isAllowedInLowPowerStandby(@NonNull String feature) {
+        try {
+            return mService.isFeatureAllowedInLowPowerStandby(feature);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Return whether the given application package name is on the device's power allowlist.
      * Apps can be placed on the allowlist through the settings UI invoked by
      * {@link android.provider.Settings#ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS}.
@@ -2840,6 +2968,176 @@
             "android.os.action.LOW_POWER_STANDBY_ENABLED_CHANGED";
 
     /**
+     * Intent that is broadcast when Low Power Standby is enabled or disabled.
+     * This broadcast is only sent to registered receivers.
+     *
+     * @see #getLowPowerStandbyPolicy
+     * @see #setLowPowerStandbyPolicy
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_LOW_POWER_STANDBY)
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_LOW_POWER_STANDBY_POLICY_CHANGED =
+            "android.os.action.LOW_POWER_STANDBY_POLICY_CHANGED";
+
+    /**
+     * Signals that wake-on-lan/wake-on-wlan is allowed in Low Power Standby.
+     *
+     * @see #isAllowedInLowPowerStandby(String)
+     */
+    public static final String LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN =
+            "com.android.lowpowerstandby.WAKE_ON_LAN";
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = { "LOW_POWER_STANDBY_ALLOWED_REASON_" }, flag = true, value = {
+            LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface LowPowerStandbyAllowedReason {
+    }
+
+    /**
+     * Exempts active Voice Interaction Sessions in Low Power Standby.
+     *
+     * @see #isAllowedInLowPowerStandby(int)
+     */
+    public static final int LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION = 1 << 0;
+
+    /** @hide */
+    public static String lowPowerStandbyAllowedReasonsToString(
+            @LowPowerStandbyAllowedReason int allowedReasons) {
+        ArrayList<String> allowedStrings = new ArrayList<>();
+        if ((allowedReasons & LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION) != 0) {
+            allowedStrings.add("ALLOWED_REASON_VOICE_INTERACTION");
+            allowedReasons &= ~LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION;
+        }
+        if (allowedReasons != 0) {
+            allowedStrings.add(String.valueOf(allowedReasons));
+        }
+        return String.join(",", allowedStrings);
+    }
+
+    /**
+     * Policy that defines the restrictions enforced by Low Power Standby.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class LowPowerStandbyPolicy {
+        /** Name of the policy, used for debugging & metrics */
+        @NonNull
+        private final String mIdentifier;
+
+        /** Packages that are exempt from Low Power Standby restrictions. */
+        @NonNull
+        private final Set<String> mExemptPackages;
+
+        /**
+         * Reasons that this policy allows apps to be automatically exempted
+         * from Low Power Standby restrictions for.
+         */
+        @LowPowerStandbyAllowedReason
+        private final int mAllowedReasons;
+
+        /** Features that are allowed to be used in Low Power Standby. */
+        @NonNull
+        private final Set<String> mAllowedFeatures;
+
+        public LowPowerStandbyPolicy(@NonNull String identifier,
+                @NonNull Set<String> exemptPackages,
+                @LowPowerStandbyAllowedReason int allowedReasons,
+                @NonNull Set<String> allowedFeatures) {
+            Objects.requireNonNull(identifier);
+            Objects.requireNonNull(exemptPackages);
+            Objects.requireNonNull(allowedFeatures);
+
+            mIdentifier = identifier;
+            mExemptPackages = Collections.unmodifiableSet(exemptPackages);
+            mAllowedReasons = allowedReasons;
+            mAllowedFeatures = Collections.unmodifiableSet(allowedFeatures);
+        }
+
+        @NonNull
+        public String getIdentifier() {
+            return mIdentifier;
+        }
+
+        @NonNull
+        public Set<String> getExemptPackages() {
+            return mExemptPackages;
+        }
+
+        @LowPowerStandbyAllowedReason
+        public int getAllowedReasons() {
+            return mAllowedReasons;
+        }
+
+        @NonNull
+        public Set<String> getAllowedFeatures() {
+            return mAllowedFeatures;
+        }
+
+        @Override
+        public String toString() {
+            return "Policy{"
+                    + "mIdentifier='" + mIdentifier + '\''
+                    + ", mExemptPackages=" + String.join(",", mExemptPackages)
+                    + ", mAllowedReasons=" + lowPowerStandbyAllowedReasonsToString(mAllowedReasons)
+                    + ", mAllowedFeatures=" + String.join(",", mAllowedFeatures)
+                    + '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof LowPowerStandbyPolicy)) return false;
+            LowPowerStandbyPolicy that = (LowPowerStandbyPolicy) o;
+            return mAllowedReasons == that.mAllowedReasons && Objects.equals(mIdentifier,
+                    that.mIdentifier) && Objects.equals(mExemptPackages, that.mExemptPackages)
+                    && Objects.equals(mAllowedFeatures, that.mAllowedFeatures);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mIdentifier, mExemptPackages, mAllowedReasons,
+                    mAllowedFeatures);
+        }
+
+        /** @hide */
+        public static IPowerManager.LowPowerStandbyPolicy toParcelable(
+                LowPowerStandbyPolicy policy) {
+            if (policy == null) {
+                return null;
+            }
+
+            IPowerManager.LowPowerStandbyPolicy parcelablePolicy =
+                    new IPowerManager.LowPowerStandbyPolicy();
+            parcelablePolicy.identifier = policy.mIdentifier;
+            parcelablePolicy.exemptPackages = new ArrayList<>(policy.mExemptPackages);
+            parcelablePolicy.allowedReasons = policy.mAllowedReasons;
+            parcelablePolicy.allowedFeatures = new ArrayList<>(policy.mAllowedFeatures);
+            return parcelablePolicy;
+        }
+
+        /** @hide */
+        public static LowPowerStandbyPolicy fromParcelable(
+                IPowerManager.LowPowerStandbyPolicy parcelablePolicy) {
+            if (parcelablePolicy == null) {
+                return null;
+            }
+
+            return new LowPowerStandbyPolicy(
+                    parcelablePolicy.identifier,
+                    new ArraySet<>(parcelablePolicy.exemptPackages),
+                    parcelablePolicy.allowedReasons,
+                    new ArraySet<>(parcelablePolicy.allowedFeatures));
+        }
+    }
+
+    /**
      * Constant for PreIdleTimeout normal mode (default mode, not short nor extend timeout) .
      * @hide
      */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 0efd264..1df45d1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1069,11 +1069,6 @@
      * Specifies that windows besides app windows should not be
      * created. This will block the creation of the following types of windows.
      * <li>{@link LayoutParams#TYPE_TOAST}</li>
-     * <li>{@link LayoutParams#TYPE_PHONE}</li>
-     * <li>{@link LayoutParams#TYPE_PRIORITY_PHONE}</li>
-     * <li>{@link LayoutParams#TYPE_SYSTEM_ALERT}</li>
-     * <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
-     * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
      * <li>{@link LayoutParams#TYPE_APPLICATION_OVERLAY}</li>
      *
      * <p>This can only be set by device owners and profile owners on the primary user.
diff --git a/core/java/android/os/storage/OWNERS b/core/java/android/os/storage/OWNERS
index c80c57c..e5b76f6 100644
--- a/core/java/android/os/storage/OWNERS
+++ b/core/java/android/os/storage/OWNERS
@@ -1,7 +1,9 @@
 # Bug component: 95221
 
+# Please assign new bugs to android-storage-triage@, not to individual people
+
 # Android Storage Team
-abkaur@google.com
+alukin@google.com
 corinac@google.com
 dipankarb@google.com
 krishang@google.com
diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java
index f5f1c37..2a4c01e1 100644
--- a/core/java/android/permission/PermissionUsageHelper.java
+++ b/core/java/android/permission/PermissionUsageHelper.java
@@ -398,7 +398,8 @@
             Context userContext = getUserContext(user);
             PackageInfo packageInfo = userContext.getPackageManager().getPackageInfo(
                     packageName,
-                    PackageManager.GET_PERMISSIONS | PackageManager.GET_ATTRIBUTIONS);
+                    PackageManager.PackageInfoFlags.of(
+                            PackageManager.GET_PERMISSIONS | PackageManager.GET_ATTRIBUTIONS_LONG));
             Context pkgContext = userContext.createPackageContext(packageInfo.packageName, 0);
             for (Attribution attribution : packageInfo.attributions) {
                 try {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4f96805..e0c022f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -599,7 +599,7 @@
 
     /**
      * Activity Action: Show settings to allow configuration of
-     * {@link Manifest.permission#RUN_LONG_JOBS} permission
+     * {@link Manifest.permission#RUN_USER_INITIATED_JOBS} permission
      *
      * Input: Optionally, the Intent's data URI can specify the application package name to
      * directly invoke the management GUI specific to the package name. For example
@@ -7000,6 +7000,58 @@
                 "bluetooth_le_broadcast_app_source_name";
 
         /**
+         * Ringtone routing value for hearing aid. It routes ringtone to hearing aid or device
+         * speaker.
+         * <ul>
+         *     <li> 0 = Default
+         *     <li> 1 = Route to hearing aid
+         *     <li> 2 = Route to device speaker
+         * </ul>
+         * @hide
+         */
+        public static final String HEARING_AID_RINGTONE_ROUTING =
+                "hearing_aid_ringtone_routing";
+
+        /**
+         * Phone call routing value for hearing aid. It routes phone call to hearing aid or
+         * device speaker.
+         * <ul>
+         *     <li> 0 = Default
+         *     <li> 1 = Route to hearing aid
+         *     <li> 2 = Route to device speaker
+         * </ul>
+         * @hide
+         */
+        public static final String HEARING_AID_CALL_ROUTING =
+                "hearing_aid_call_routing";
+
+        /**
+         * Media routing value for hearing aid. It routes media to hearing aid or device
+         * speaker.
+         * <ul>
+         *     <li> 0 = Default
+         *     <li> 1 = Route to hearing aid
+         *     <li> 2 = Route to device speaker
+         * </ul>
+         * @hide
+         */
+        public static final String HEARING_AID_MEDIA_ROUTING =
+                "hearing_aid_media_routing";
+
+        /**
+         * System sounds routing value for hearing aid. It routes system sounds to hearing aid
+         * or device speaker.
+         * <ul>
+         *     <li> 0 = Default
+         *     <li> 1 = Route to hearing aid
+         *     <li> 2 = Route to device speaker
+         * </ul>
+         * @hide
+         */
+        public static final String HEARING_AID_SYSTEM_SOUNDS_ROUTING =
+                "hearing_aid_system_sounds_routing";
+
+        /**
          * Setting to indicate that on device captions are enabled.
          *
          * @hide
@@ -7425,7 +7477,7 @@
          * @hide
          */
         @SuppressLint("NoSettingsProvider")
-        public static final String STYLUS_BUTTONS_DISABLED = "stylus_buttons_disabled";
+        public static final String STYLUS_BUTTONS_ENABLED = "stylus_buttons_enabled";
 
         /**
          * Host name and port for global http proxy. Uses ':' seperator for
@@ -10271,6 +10323,17 @@
                 "active_unlock_on_unlock_intent_when_biometric_enrolled";
 
         /**
+         * If active unlock triggers on unlock intents, then also request active unlock on
+         * these wake-up reasons. See PowerManager.WakeReason for value mappings.
+         * WakeReasons should be separated by a pipe. For example: "0|3" or "0". If this
+         * setting should be disabled, then this should be set to an empty string. A null value
+         * will use the system default value (WAKE_REASON_UNFOLD_DEVICE).
+         * @hide
+         */
+        public static final String ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS =
+                "active_unlock_wakeups_considered_unlock_intents";
+
+        /**
          * Whether the assist gesture should be enabled.
          *
          * @hide
@@ -11150,6 +11213,15 @@
         public static final int ACCESSIBILITY_MAGNIFICATION_MODE_ALL = 0x3;
 
         /**
+         * Whether the magnification always on feature is enabled. If true, the magnifier will not
+         * deactivate on Activity transitions; it will only zoom out to 100%.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED =
+                "accessibility_magnification_always_on_enabled";
+
+        /**
          * Whether the following typing focus feature for magnification is enabled.
          * @hide
          */
@@ -11157,6 +11229,13 @@
                 "accessibility_magnification_follow_typing_enabled";
 
         /**
+         * Whether the magnification joystick controller feature is enabled.
+         * @hide
+         */
+        public static final String ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED =
+                "accessibility_magnification_joystick_enabled";
+
+        /**
          * Controls magnification capability. Accessibility magnification is capable of at least one
          * of the magnification modes.
          *
@@ -11457,6 +11536,13 @@
                 "extra_automatic_power_save_mode";
 
         /**
+         * Whether lockscreen weather is enabled.
+         *
+         * @hide
+         */
+        public static final String LOCK_SCREEN_WEATHER_ENABLED = "lockscreen_weather_enabled";
+
+        /**
          * These entries are considered common between the personal and the managed profile,
          * since the managed profile doesn't get to change them.
          */
@@ -15901,6 +15987,36 @@
                 "user_preferred_resolution_width";
 
         /**
+         * The HDR output mode chosen by the user. This is one of:
+         * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_PASSTHROUGH},
+         * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_SYSTEM},
+         * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_FORCE}.
+         *
+         * @hide
+         */
+        @TestApi
+        @Readable
+        public static final String HDR_CONVERSION_MODE = "hdr_conversion_mode";
+
+        /**
+         * The output HDR type chosen by the user in case when {@link #HDR_CONVERSION_MODE} is
+         * {@link #HDR_CONVERSION_FORCE}. This is one of:
+         * {@link android.view.Display.HdrCapabilities#HDR_TYPE_INVALID},
+         * {@link android.view.Display.HdrCapabilities#HDR_TYPE_DOLBY_VISION},
+         * {@link android.view.Display.HdrCapabilities#HDR_TYPE_HDR10},
+         * {@link android.view.Display.HdrCapabilities#HDR_TYPE_HLG},
+         * {@link android.view.Display.HdrCapabilities#HDR_TYPE_HDR10_PLUS}
+         * <p>
+         * The value is {@link android.view.Display.HdrCapabilities#HDR_TYPE_INVALID} when user
+         * chooses SDR output type. </p>
+         *
+         * @hide
+         */
+        @TestApi
+        @Readable
+        public static final String HDR_FORCE_CONVERSION_TYPE = "hdr_force_conversion_type";
+
+        /**
          * The name of the device
          */
         @Readable
@@ -18386,6 +18502,91 @@
              * @hide
              */
             public static final String DYNAMIC_COLOR_THEME_ENABLED = "dynamic_color_theme_enabled";
+
+            /**
+             * Current state of accessibility vibration watch feature
+             * (0 = false, 1 = true)
+             *
+             * @hide
+             */
+            public static final String ACCESSIBILITY_VIBRATION_WATCH_ENABLED =
+                    "a11y_vibration_watch_enabled";
+
+            /**
+             * Stores current type of accessibility vibration
+             * (0 = {@link #ACCESSIBILITY_VIBRATION_WATCH_TYPE_DIGIT},
+             * 1 = {@link #ACCESSIBILITY_VIBRATION_WATCH_TYPE_TERSE)
+             *
+             * @hide
+             */
+            public static final String ACCESSIBILITY_VIBRATION_WATCH_TYPE =
+                    "a11y_vibration_watch_type";
+
+            /**
+             * Vibration watch type digit
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_TYPE}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_TYPE_DIGIT = 0;
+
+            /**
+             * Vibration watch type terse
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_TYPE}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_TYPE_TERSE = 1;
+
+            /**
+             * Stores current accessibility vibration watch speed
+             * (0 = {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED_VERY_SLOW},
+             * 1 = {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED_SLOW},
+             * 2 = {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED_MEDIUM},
+             * 3 = {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED_FAST},
+             * 4 = {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED_VERY_FAST})
+             */
+            public static final String ACCESSIBILITY_VIBRATION_WATCH_SPEED = "vibration_speed";
+
+            /**
+             * Vibration watch speed type very slow
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_SPEED_VERY_SLOW = 0;
+
+            /**
+             * Vibration watch speed type slow
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_SPEED_SLOW = 1;
+
+            /**
+             * Vibration watch speed type medium
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_SPEED_MEDIUM = 2;
+
+            /**
+             * Vibration watch speed type fast
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_SPEED_FAST = 3;
+
+            /**
+             * Vibration watch speed type very fast
+             * One of the possible states for {@link #ACCESSIBILITY_VIBRATION_WATCH_SPEED}.
+             *
+             * @hide
+             */
+            public static final int ACCESSIBILITY_VIBRATION_WATCH_SPEED_VERY_FAST = 4;
         }
     }
 
@@ -19311,6 +19512,18 @@
             "android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION";
 
     /**
+     * Activity Action: Show screen for controlling whether an app can send full screen intents.
+     * <p>
+     *     Input: the intent's data URI must specify the application package name for which you want
+     *     to manage full screen intents.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT =
+            "android.settings.MANAGE_APP_USE_FULL_SCREEN_INTENT";
+
+    /**
      * Activity Action: For system or preinstalled apps to show their {@link Activity} embedded
      * in Settings app on large screen devices.
      *
diff --git a/core/java/android/security/rkp/IGetKeyCallback.aidl b/core/java/android/security/rkp/IGetKeyCallback.aidl
index 85ceae62..a36d054 100644
--- a/core/java/android/security/rkp/IGetKeyCallback.aidl
+++ b/core/java/android/security/rkp/IGetKeyCallback.aidl
@@ -25,6 +25,36 @@
  * @hide
  */
 oneway interface IGetKeyCallback {
+    enum ErrorCode {
+        /**
+         * An unexpected error occurred and there's no standard way to describe it. See the
+         * corresponding error string for more information.
+         */
+        ERROR_UNKNOWN = 1,
+
+        /**
+         * Device will not receive remotely provisioned keys because it's running vulnerable
+         * code. The device needs to be updated to a fixed build to recover.
+         */
+        ERROR_REQUIRES_SECURITY_PATCH = 2,
+
+        /**
+         * Indicates that the attestation key pool has been exhausted, and the remote key
+         * provisioning server cannot currently be reached. Clients should wait for the
+         * device to have connectivity, then retry.
+         */
+        ERROR_PENDING_INTERNET_CONNECTIVITY = 3,
+
+        /**
+         * Indicates that this device will never be able to provision attestation keys using
+         * the remote provsisioning server. This may be due to multiple causes, such as the
+         * device is not registered with the remote provisioning backend or the device has
+         * been permanently revoked. Clients who receive this error should not attempt to
+         * retry key creation.
+         */
+        ERROR_PERMANENT = 5,
+    }
+
     /**
      * Called in response to {@link IRegistration.getKey}, indicating
      * a remotely-provisioned key is available.
@@ -42,8 +72,9 @@
     /**
      * Called when an error has occurred while trying to get a remotely provisioned key.
      *
-     * @param error A description of what failed, suitable for logging.
+     * @param error allows code to handle certain errors, if desired
+     * @param description human-readable explanation of what failed, suitable for logging.
      */
-    void onError(String error);
+    void onError(ErrorCode error, String description);
 }
 
diff --git a/core/java/android/service/assist/OWNERS b/core/java/android/service/assist/OWNERS
new file mode 100644
index 0000000..533b1f1
--- /dev/null
+++ b/core/java/android/service/assist/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 351486
+
+include /core/java/android/view/autofill/OWNERS
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/core/java/android/service/assist/classification/FieldClassification.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to core/java/android/service/assist/classification/FieldClassification.aidl
index 497c272..7d0c078 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/core/java/android/service/assist/classification/FieldClassification.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.service.assist.classification;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable FieldClassification;
diff --git a/core/java/android/service/assist/classification/FieldClassification.java b/core/java/android/service/assist/classification/FieldClassification.java
new file mode 100644
index 0000000..0ea8112
--- /dev/null
+++ b/core/java/android/service/assist/classification/FieldClassification.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.assist.classification;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArraySet;
+import android.view.autofill.AutofillId;
+
+
+import com.android.internal.util.DataClass;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Represents a classified field from the detection service.
+ */
+// TODO(b/266930067): Once @SystemApi is supported, use genSetters and genConstructor.
+@DataClass(
+        genToString = true,
+        genConstructor = false
+)
+public final class FieldClassification implements Parcelable {
+
+    /**
+     * Autofill id of the detected field
+     */
+    private final @NonNull AutofillId mAutofillId;
+
+    /**
+     * Detected fields types represented as autofill hints
+     *
+     * A particular field can be detected as multiple types. For eg: A sign-in field may take in a
+     * username, an email address or a phone number. In such cases, it should be detected as
+     * "username", "emailAddress" and "phoneNumber"
+     *
+     * The value of these hints are contained in androidx.autofill.HintConstants
+     */
+    private final @NonNull Set<String> mHints;
+
+
+    /**
+     * Group hints are the hints that may represent the group of related hints (including
+     * themselves). The value of these group hints are contained in androidx.autofill.HintConstants
+     *
+     * <p>
+     *
+     * "creditCardNumber" is the group hint for hints containing credit card related fields:
+     * "creditCardNumber", "creditCardExpirationDate", "creditCardExpirationDay",
+     * "creditCardExpirationMonth", "creditCardExpirationYear", "creditCardSecurityCode",
+     *
+     * <p>
+     *
+     * "postalAddress" is the group hint for hints all postal address related fields:
+     * "postalAddress", "streetAddress", "aptNumber", "dependentLocality", "extendedAddress",
+     * "postalCode", "extendedPostalCode", "addressLocality", "addressRegion", "addressCountry".
+     *
+     * <p>
+     *
+     * "phoneNumber" is the group hint for hints all phone number related fields: "phoneNumber",
+     * "phoneNumberDevice", "phoneNational", "phoneCountryCode".
+     *
+     * <p>
+     *
+     * "personName" is the group hint for hints all name related fields: "personName",
+     * "personFamilyName", "personGivenName", "personMiddleName", "personMiddleInitial",
+     * "personNamePrefix", "personNameSuffix" .
+     *
+     * <p>
+     *
+     * "birthDateFull" is the group hint for hints containing birthday related fields:
+     * "birthDateFull", "birthDateMonth", "birthDateYear",
+     *
+     * @hide
+     */
+    private final @NonNull Set<String> mGroupHints;
+
+    /**
+     * Autofill id of the detected field.
+     */
+    public @NonNull AutofillId getAutofillId() {
+        return mAutofillId;
+    }
+
+    /**
+     * Detected fields types represented as autofill hints.
+     *
+     * A particular field can be detected as multiple types. For eg: A sign-in field may take in a
+     * username, an email address or a phone number. In such cases, it should be detected as
+     * "username", "emailAddress" and "phoneNumber"
+     *
+     * The value of these hints are contained in androidx.autofill.HintConstants
+     */
+    public @NonNull Set<String> getHints() {
+        return mHints;
+    }
+
+    /**
+    * Group hints are the hints that may represent the group of related hints (including
+    * themselves). The value of these group hints are contained in androidx.autofill.HintConstants
+    *
+    * <p>
+    *
+    * "creditCardNumber" is the group hint for hints containing credit card related fields:
+    * "creditCardNumber", "creditCardExpirationDate", "creditCardExpirationDay",
+    * "creditCardExpirationMonth", "creditCardExpirationYear", "creditCardSecurityCode",
+    *
+    * <p>
+    *
+    * "postalAddress" is the group hint for hints all postal address related fields:
+    * "postalAddress", "streetAddress", "aptNumber", "dependentLocality", "extendedAddress",
+    * "postalCode", "extendedPostalCode", "addressLocality", "addressRegion", "addressCountry".
+    *
+    * <p>
+    *
+    * "phoneNumber" is the group hint for hints all phone number related fields: "phoneNumber",
+    * "phoneNumberDevice", "phoneNational", "phoneCountryCode".
+    *
+    * <p>
+    *
+    * "personName" is the group hint for hints all name related fields: "personName",
+    * "personFamilyName", "personGivenName", "personMiddleName", "personMiddleInitial",
+    * "personNamePrefix", "personNameSuffix" .
+    *
+    * <p>
+    *
+    * "birthDateFull" is the group hint for hints containing birthday related fields:
+    * "birthDateFull", "birthDateMonth", "birthDateYear",
+    *
+    * @hide
+    */
+    @SystemApi
+    public @NonNull Set<String> getGroupHints() {
+        return mGroupHints;
+    }
+
+    static Set<String> unparcelHints(Parcel in) {
+        List<String> hints = new java.util.ArrayList<>();
+        in.readStringList(hints);
+        return new ArraySet<>(hints);
+    }
+
+    void parcelHints(Parcel dest, int flags) {
+        dest.writeStringList(new ArrayList<>(mHints));
+    }
+
+    static Set<String> unparcelGroupHints(Parcel in) {
+        List<String> groupHints = new java.util.ArrayList<>();
+        in.readStringList(groupHints);
+        return new ArraySet<>(groupHints);
+    }
+
+    void parcelGroupHints(Parcel dest, int flags) {
+        dest.writeStringList(new ArrayList<>(mGroupHints));
+    }
+
+    /**
+     * Creates a new FieldClassification.
+     *
+     * @param autofillId
+     *   Autofill id of the detected field
+     * @param hints
+     *   Detected fields types represented as autofill hints.
+     *   A particular field can be detected as multiple types. For eg: A sign-in field may take in
+     *   a username, an email address or a phone number. In such cases, it should be detected as
+     *   "username", "emailAddress" and "phoneNumber"
+     */
+    public FieldClassification(
+            @NonNull AutofillId autofillId,
+            @NonNull Set<String> hints) {
+        this(autofillId, hints, new ArraySet<>());
+    }
+
+    /**
+    * Creates a new FieldClassification.
+    *
+    * @param autofillId Autofill id of the detected field
+    * @param hints Detected fields types represented as autofill hints A particular field can be
+    *     detected as multiple types. For eg: A sign-in field may take in a username, an email
+    *     address or a phone number. In such cases, it should be detected as "username",
+    *     "emailAddress" and "phoneNumber"
+    * @param groupHints Hints that may represent the group of related hints (including themselves).
+    *     The value of these group hints are contained in androidx.autofill.HintConstants.
+     *    See {@link #getGroupHints()} for more details
+    * @hide
+    */
+    @SystemApi
+    @DataClass.Generated.Member
+    public FieldClassification(
+            @NonNull AutofillId autofillId,
+            @NonNull Set<String> hints,
+            @NonNull Set<String> groupHints) {
+        this.mAutofillId = autofillId;
+//        com.android.internal.util.AnnotationValidations.validate(
+//                NonNull.class, null, mAutofillId);
+        this.mHints = hints;
+//        com.android.internal.util.AnnotationValidations.validate(
+//                NonNull.class, null, mHints);
+        this.mGroupHints = groupHints;
+//        com.android.internal.util.AnnotationValidations.validate(
+//                NonNull.class, null, mGroupHints);
+    }
+
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/assist/classification/FieldClassification.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "FieldClassification { " +
+                "autofillId = " + mAutofillId + ", " +
+                "hints = " + mHints + ", " +
+                "groupHints = " + mGroupHints +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeTypedObject(mAutofillId, flags);
+        parcelHints(dest, flags);
+        parcelGroupHints(dest, flags);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ FieldClassification(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        AutofillId autofillId = (AutofillId) in.readTypedObject(AutofillId.CREATOR);
+        Set<String> hints = unparcelHints(in);
+        Set<String> groupHints = unparcelGroupHints(in);
+
+        this.mAutofillId = autofillId;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAutofillId);
+        this.mHints = hints;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mHints);
+        this.mGroupHints = groupHints;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mGroupHints);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<FieldClassification> CREATOR
+            = new Parcelable.Creator<FieldClassification>() {
+        @Override
+        public FieldClassification[] newArray(int size) {
+            return new FieldClassification[size];
+        }
+
+        @Override
+        public FieldClassification createFromParcel(@NonNull Parcel in) {
+            return new FieldClassification(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1675320464097L,
+            codegenVersion = "1.0.23",
+            sourceFile = "frameworks/base/core/java/android/service/assist/classification/FieldClassification.java",
+            inputSignatures = "private final @android.annotation.NonNull android.view.autofill.AutofillId mAutofillId\nprivate final @android.annotation.NonNull java.util.Set<java.lang.String> mHints\nprivate final @android.annotation.NonNull java.util.Set<java.lang.String> mGroupHints\npublic @android.annotation.NonNull android.view.autofill.AutofillId getAutofillId()\npublic @android.annotation.NonNull java.util.Set<java.lang.String> getHints()\npublic @android.annotation.SystemApi @android.annotation.NonNull java.util.Set<java.lang.String> getGroupHints()\nstatic  java.util.Set<java.lang.String> unparcelHints(android.os.Parcel)\n  void parcelHints(android.os.Parcel,int)\nstatic  java.util.Set<java.lang.String> unparcelGroupHints(android.os.Parcel)\n  void parcelGroupHints(android.os.Parcel,int)\nclass FieldClassification extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genConstructor=false)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/packages/SystemUI/res/values-television/strings.xml b/core/java/android/service/assist/classification/FieldClassificationRequest.aidl
similarity index 60%
copy from packages/SystemUI/res/values-television/strings.xml
copy to core/java/android/service/assist/classification/FieldClassificationRequest.aidl
index 86106e6..740c5cb9 100644
--- a/packages/SystemUI/res/values-television/strings.xml
+++ b/core/java/android/service/assist/classification/FieldClassificationRequest.aidl
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
 /**
- * Copyright (c) 2022, The Android Open Source Project
+ * Copyright (c) 2023, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Learn more URL for the log access confirmation dialog. [DO NOT TRANSLATE]-->
-    <string name="log_access_confirmation_learn_more_url" translatable="false"></string>
-</resources>
\ No newline at end of file
+
+package android.service.assist.classification;
+
+parcelable FieldClassificationRequest;
\ No newline at end of file
diff --git a/core/java/android/service/assist/classification/FieldClassificationRequest.java b/core/java/android/service/assist/classification/FieldClassificationRequest.java
new file mode 100644
index 0000000..0afcca9
--- /dev/null
+++ b/core/java/android/service/assist/classification/FieldClassificationRequest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.assist.classification;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.assist.AssistStructure;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * Represents a request to detect fields on an activity.
+ * @hide
+ */
+@SystemApi
+@DataClass(
+        genToString = true
+)
+public final class FieldClassificationRequest implements Parcelable {
+    private final @NonNull AssistStructure mAssistStructure;
+
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/assist/classification/FieldClassificationRequest.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    @DataClass.Generated.Member
+    public FieldClassificationRequest(
+            @NonNull AssistStructure assistStructure) {
+        this.mAssistStructure = assistStructure;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAssistStructure);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public @NonNull AssistStructure getAssistStructure() {
+        return mAssistStructure;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "FieldClassificationRequest { " +
+                "assistStructure = " + mAssistStructure +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeTypedObject(mAssistStructure, flags);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ FieldClassificationRequest(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        AssistStructure assistStructure = (AssistStructure) in.readTypedObject(AssistStructure.CREATOR);
+
+        this.mAssistStructure = assistStructure;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mAssistStructure);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<FieldClassificationRequest> CREATOR
+            = new Parcelable.Creator<FieldClassificationRequest>() {
+        @Override
+        public FieldClassificationRequest[] newArray(int size) {
+            return new FieldClassificationRequest[size];
+        }
+
+        @Override
+        public FieldClassificationRequest createFromParcel(@NonNull Parcel in) {
+            return new FieldClassificationRequest(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1675320491692L,
+            codegenVersion = "1.0.23",
+            sourceFile = "frameworks/base/core/java/android/service/assist/classification/FieldClassificationRequest.java",
+            inputSignatures = "private final @android.annotation.NonNull android.app.assist.AssistStructure mAssistStructure\nclass FieldClassificationRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/core/java/android/service/assist/classification/FieldClassificationResponse.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to core/java/android/service/assist/classification/FieldClassificationResponse.aidl
index 497c272..1b0de85 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/core/java/android/service/assist/classification/FieldClassificationResponse.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.service.assist.classification;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable FieldClassificationResponse;
diff --git a/core/java/android/service/assist/classification/FieldClassificationResponse.java b/core/java/android/service/assist/classification/FieldClassificationResponse.java
new file mode 100644
index 0000000..faa9488
--- /dev/null
+++ b/core/java/android/service/assist/classification/FieldClassificationResponse.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.assist.classification;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArraySet;
+
+import com.android.internal.util.DataClass;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * Represents a response from detection service.
+ * @hide
+ */
+@SystemApi
+@DataClass(
+        genToString = true
+)
+public final class FieldClassificationResponse implements Parcelable {
+
+    /**
+     * List of classified fields
+     */
+    private final @NonNull Set<FieldClassification> mClassifications;
+
+    static Set<FieldClassification> unparcelClassifications(Parcel in) {
+        List<FieldClassification> detections = new java.util.ArrayList<>();
+        in.readParcelableList(
+                detections, FieldClassification.class.getClassLoader(), FieldClassification.class);
+        return new ArraySet<>(detections);
+    }
+
+    void parcelClassifications(Parcel dest, int flags) {
+        dest.writeParcelableList(new ArrayList<>(mClassifications), flags);
+    }
+
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/assist/classification/FieldClassificationResponse.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    /**
+     * Creates a new FieldClassificationResponse.
+     *
+     * @param classifications
+     *   List of classified fields
+     */
+    @DataClass.Generated.Member
+    public FieldClassificationResponse(
+            @NonNull Set<FieldClassification> classifications) {
+        this.mClassifications = classifications;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mClassifications);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * List of classified fields
+     */
+    @DataClass.Generated.Member
+    public @NonNull Set<FieldClassification> getClassifications() {
+        return mClassifications;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "FieldClassificationResponse { " +
+                "classifications = " + mClassifications +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        parcelClassifications(dest, flags);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ FieldClassificationResponse(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        Set<FieldClassification> classifications = unparcelClassifications(in);
+
+        this.mClassifications = classifications;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mClassifications);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<FieldClassificationResponse> CREATOR
+            = new Parcelable.Creator<FieldClassificationResponse>() {
+        @Override
+        public FieldClassificationResponse[] newArray(int size) {
+            return new FieldClassificationResponse[size];
+        }
+
+        @Override
+        public FieldClassificationResponse createFromParcel(@NonNull Parcel in) {
+            return new FieldClassificationResponse(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1675320458276L,
+            codegenVersion = "1.0.23",
+            sourceFile = "frameworks/base/core/java/android/service/assist/classification/FieldClassificationResponse.java",
+            inputSignatures = "private final @android.annotation.NonNull java.util.Set<android.service.assist.classification.FieldClassification> mClassifications\nstatic  java.util.Set<android.service.assist.classification.FieldClassification> unparcelClassifications(android.os.Parcel)\n  void parcelClassifications(android.os.Parcel,int)\nclass FieldClassificationResponse extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/service/assist/classification/FieldClassificationService.java b/core/java/android/service/assist/classification/FieldClassificationService.java
new file mode 100644
index 0000000..abffdbf
--- /dev/null
+++ b/core/java/android/service/assist/classification/FieldClassificationService.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.assist.classification;
+
+import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.BaseBundle;
+import android.os.Build;
+import android.os.CancellationSignal;
+import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.OutcomeReceiver;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A service using {@link android.app.assist.AssistStructure} to detect fields on the screen.
+ * Service may use classifiers to look at the un-stripped AssistStructure to make informed decision
+ * and classify the fields.
+ *
+ * Currently, it's used to detect the field types for the Autofill Framework to provide relevant
+ * autofill suggestions to the user.
+ *
+ *
+ * The methods are invoked on the binder threads.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class FieldClassificationService extends Service {
+
+    private static final String TAG = FieldClassificationService.class.getSimpleName();
+
+    static boolean sDebug = Build.IS_USER ? false : true;
+    static boolean sVerbose = false;
+
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     * To be supported, the service must also require the
+     * {@link android.Manifest.permission#BIND_FIELD_CLASSIFICATION_SERVICE} permission so
+     * that other applications can not abuse it.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.assist.classification.FieldClassificationService";
+
+    // Used for metrics / debug only
+    private ComponentName mServiceComponentName;
+
+    private final class FieldClassificationServiceImpl
+            extends IFieldClassificationService.Stub {
+
+        @Override
+        public void onConnected(boolean debug, boolean verbose) {
+            handleOnConnected(debug, verbose);
+        }
+
+        @Override
+        public void onDisconnected() {
+            handleOnDisconnected();
+        }
+
+        @Override
+        public void onFieldClassificationRequest(
+                FieldClassificationRequest request, IFieldClassificationCallback callback) {
+            handleOnClassificationRequest(request, callback);
+        }
+    };
+
+    @CallSuper
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        BaseBundle.setShouldDefuse(true);
+    }
+
+    /** @hide */
+    @Override
+    public final IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            mServiceComponentName = intent.getComponent();
+            return new FieldClassificationServiceImpl().asBinder();
+        }
+        Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
+        return null;
+    }
+
+    /**
+     * Called when the Android system connects to service.
+     *
+     * <p>You should generally do initialization here rather than in {@link #onCreate}.
+     */
+    public void onConnected() {
+    }
+
+    /**
+     * Requests the service to handle field classification request.
+     * @param cancellationSignal signal for observing cancellation requests. The system will use
+     *     this to notify you that the detection result is no longer needed and the service should
+     *     stop handling this detection request in order to save resources.
+     * @param outcomeReceiver object used to notify the result of the request. Service <b>must</b>
+     *     call {@link OutcomeReceiver<>#onResult(FieldClassificationResponse)}.
+     */
+    public abstract void onClassificationRequest(
+            @NonNull FieldClassificationRequest request,
+            @NonNull CancellationSignal cancellationSignal,
+            @NonNull OutcomeReceiver<FieldClassificationResponse, Exception> outcomeReceiver);
+
+    /**
+     * Called when the Android system disconnects from the service.
+     *
+     * <p> At this point this service may no longer be an active
+     * {@link FieldClassificationService}.
+     */
+    public void onDisconnected() {
+    }
+
+    private void handleOnConnected(boolean debug, boolean verbose) {
+        if (sDebug || debug) {
+            Log.d(TAG, "handleOnConnected(): debug=" + debug + ", verbose=" + verbose);
+        }
+        sDebug = debug;
+        sVerbose = verbose;
+        onConnected();
+    }
+
+    private void handleOnDisconnected() {
+        onDisconnected();
+    }
+
+    private void handleOnClassificationRequest(
+            FieldClassificationRequest request, @NonNull IFieldClassificationCallback callback) {
+
+        final ICancellationSignal transport = CancellationSignal.createTransport();
+        final CancellationSignal cancellationSignal = CancellationSignal.fromTransport(transport);
+        onClassificationRequest(
+                request,
+                cancellationSignal,
+                new OutcomeReceiver<FieldClassificationResponse, Exception>() {
+                    @Override
+                    public void onResult(FieldClassificationResponse result) {
+                        try {
+                            callback.onSuccess(result);
+                        } catch (RemoteException e) {
+                            e.rethrowFromSystemServer();
+                        }
+                    }
+                    @Override
+                    public void onError(Exception e) {
+                        try {
+                            callback.onFailure();
+                        } catch (RemoteException ex) {
+                            ex.rethrowFromSystemServer();
+                        }
+                    }
+                });
+    }
+}
+
diff --git a/core/java/android/service/assist/classification/IFieldClassificationCallback.aidl b/core/java/android/service/assist/classification/IFieldClassificationCallback.aidl
new file mode 100644
index 0000000..ca9e939
--- /dev/null
+++ b/core/java/android/service/assist/classification/IFieldClassificationCallback.aidl
@@ -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 android.service.assist.classification;
+
+import android.os.Bundle;
+import android.os.ICancellationSignal;
+
+import android.service.assist.classification.FieldClassificationResponse;
+
+import java.util.List;
+
+/**
+ * Interface to receive the result of an autofill request.
+ *
+ * @hide
+ */
+interface IFieldClassificationCallback {
+
+    void onCancellable(in ICancellationSignal cancellation);
+
+    void onSuccess(in FieldClassificationResponse response);
+
+    void onFailure();
+
+    boolean isCompleted();
+
+    void cancel();
+}
diff --git a/core/java/android/service/assist/classification/IFieldClassificationService.aidl b/core/java/android/service/assist/classification/IFieldClassificationService.aidl
new file mode 100644
index 0000000..a93688d
--- /dev/null
+++ b/core/java/android/service/assist/classification/IFieldClassificationService.aidl
@@ -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 android.service.assist.classification;
+
+import android.content.ComponentName;
+import android.os.IBinder;
+import android.service.assist.classification.IFieldClassificationCallback;
+import android.service.assist.classification.FieldClassificationRequest;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.view.inputmethod.InlineSuggestionsRequest;
+import java.util.List;
+/**
+ * Interface from the system to an Autofill classification service.
+ *
+ * @hide
+ */
+oneway interface IFieldClassificationService {
+    void onConnected(boolean debug, boolean verbose);
+    void onDisconnected();
+    void onFieldClassificationRequest(
+            in FieldClassificationRequest request, in IFieldClassificationCallback callback);
+}
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index e9f099a..d943bf9 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -18,6 +18,7 @@
 
 import static android.view.autofill.Helper.sDebug;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
@@ -33,6 +34,8 @@
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Objects;
 import java.util.regex.Pattern;
@@ -112,6 +115,55 @@
  * </ol>
  */
 public final class Dataset implements Parcelable {
+    /**
+     * This dataset is picked because of unknown reason.
+     * @hide
+     */
+    public static final int PICK_REASON_UNKNOWN = 0;
+    /**
+     * This dataset is picked because of autofill provider detection was chosen.
+     * @hide
+     */
+    public static final int PICK_REASON_AUTOFILL_PROVIDER_DETECTION = 1;
+    /**
+     * This dataset is picked because of PCC detection was chosen.
+     * @hide
+     */
+    public static final int PICK_REASON_PCC_DETECTION = 2;
+    /**
+     * This dataset is picked because of Framework detection was chosen.
+     * @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;
+
+    @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,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DatasetEligibleReason{}
+
+    private @DatasetEligibleReason int mEligibleReason;
 
     private final ArrayList<AutofillId> mFieldIds;
     private final ArrayList<AutofillValue> mFieldValues;
@@ -120,6 +172,8 @@
     private final ArrayList<InlinePresentation> mFieldInlinePresentations;
     private final ArrayList<InlinePresentation> mFieldInlineTooltipPresentations;
     private final ArrayList<DatasetFieldFilter> mFieldFilters;
+    private final ArrayList<String> mAutofillDatatypes;
+
     @Nullable private final ClipData mFieldContent;
     private final RemoteViews mPresentation;
     private final RemoteViews mDialogPresentation;
@@ -128,6 +182,67 @@
     private final IntentSender mAuthentication;
     @Nullable String mId;
 
+    /**
+     * Constructor to copy the dataset, but replaces the AutofillId with the given input.
+     * Useful to modify the field type, and provide autofillId.
+     * @hide
+     */
+    public Dataset(
+            ArrayList<AutofillId> fieldIds,
+            ArrayList<AutofillValue> fieldValues,
+            ArrayList<RemoteViews> fieldPresentations,
+            ArrayList<RemoteViews> fieldDialogPresentations,
+            ArrayList<InlinePresentation> fieldInlinePresentations,
+            ArrayList<InlinePresentation> fieldInlineTooltipPresentations,
+            ArrayList<DatasetFieldFilter> fieldFilters,
+            ArrayList<String> autofillDatatypes,
+            ClipData fieldContent,
+            RemoteViews presentation,
+            RemoteViews dialogPresentation,
+            @Nullable InlinePresentation inlinePresentation,
+            @Nullable  InlinePresentation inlineTooltipPresentation,
+            @Nullable String id,
+            IntentSender authentication) {
+        mFieldIds = fieldIds;
+        mFieldValues = fieldValues;
+        mFieldPresentations = fieldPresentations;
+        mFieldDialogPresentations = fieldDialogPresentations;
+        mFieldInlinePresentations = fieldInlinePresentations;
+        mFieldInlineTooltipPresentations = fieldInlineTooltipPresentations;
+        mAutofillDatatypes = autofillDatatypes;
+        mFieldFilters = fieldFilters;
+        mFieldContent = fieldContent;
+        mPresentation = presentation;
+        mDialogPresentation = dialogPresentation;
+        mInlinePresentation = inlinePresentation;
+        mInlineTooltipPresentation = inlineTooltipPresentation;
+        mAuthentication = authentication;
+        mId = id;
+    }
+
+    /**
+     * Constructor to copy the dataset, but replaces the AutofillId with the given input.
+     * Useful to modify the field type, and provide autofillId.
+     * @hide
+     */
+    public Dataset(Dataset dataset, ArrayList<AutofillId> ids) {
+        mFieldIds = ids;
+        mFieldValues = dataset.mFieldValues;
+        mFieldPresentations = dataset.mFieldPresentations;
+        mFieldDialogPresentations = dataset.mFieldDialogPresentations;
+        mFieldInlinePresentations = dataset.mFieldInlinePresentations;
+        mFieldInlineTooltipPresentations = dataset.mFieldInlineTooltipPresentations;
+        mFieldFilters = dataset.mFieldFilters;
+        mFieldContent = dataset.mFieldContent;
+        mPresentation = dataset.mPresentation;
+        mDialogPresentation = dataset.mDialogPresentation;
+        mInlinePresentation = dataset.mInlinePresentation;
+        mInlineTooltipPresentation = dataset.mInlineTooltipPresentation;
+        mAuthentication = dataset.mAuthentication;
+        mId = dataset.mId;
+        mAutofillDatatypes = dataset.mAutofillDatatypes;
+    }
+
     private Dataset(Builder builder) {
         mFieldIds = builder.mFieldIds;
         mFieldValues = builder.mFieldValues;
@@ -143,6 +258,14 @@
         mInlineTooltipPresentation = builder.mInlineTooltipPresentation;
         mAuthentication = builder.mAuthentication;
         mId = builder.mId;
+        mAutofillDatatypes = builder.mAutofillDatatypes;
+    }
+
+    /** @hide */
+    @TestApi
+    @SuppressLint({"ConcreteCollection", "NullableCollection"})
+    public @Nullable ArrayList<String> getAutofillDatatypes() {
+        return mAutofillDatatypes;
     }
 
     /** @hide */
@@ -282,6 +405,22 @@
     }
 
     /**
+     * Sets the reason as to why this dataset is eligible
+     * @hide
+     */
+    public void setEligibleReasonReason(@DatasetEligibleReason int eligibleReason) {
+        this.mEligibleReason = eligibleReason;
+    }
+
+    /**
+     * Get the reason as to why this dataset is eligible.
+     * @hide
+     */
+    public @DatasetEligibleReason int getEligibleReason() {
+        return mEligibleReason;
+    }
+
+    /**
      * A builder for {@link Dataset} objects. You must provide at least
      * one value for a field or set an authentication intent.
      */
@@ -293,6 +432,7 @@
         private ArrayList<InlinePresentation> mFieldInlinePresentations;
         private ArrayList<InlinePresentation> mFieldInlineTooltipPresentations;
         private ArrayList<DatasetFieldFilter> mFieldFilters;
+        private ArrayList<String> mAutofillDatatypes;
         @Nullable private ClipData mFieldContent;
         private RemoteViews mPresentation;
         private RemoteViews mDialogPresentation;
@@ -922,6 +1062,55 @@
         }
 
         /**
+         * Adds a field to this Dataset with a specific type and no
+         * AutofillId. This is used to send back Field information
+         * when Autofilling with platform detections is on.
+         * Platform detections are on when receiving a populated list from
+         * FillRequest#getHints().
+         *
+         * Populate every field/type known for this user for this app.
+         *
+         * For example, if getHints() contains "username" and "password",
+         * a new Dataset should be created that calls this method twice,
+         * one for the username, then another for the password (assuming
+         * the only one credential pair is found for the user). If a user
+         * has two credential pairs, then two Datasets should be created,
+         * and so on.
+         *
+         * Using this will remove any data populated with
+         * setField(@NonNull AutofillId id, @Nullable Field field).
+         *
+         * @param hint An autofill hint returned from {@link
+         *         FillRequest#getHints()}.
+         *
+         * @param field the fill information about the field.
+         *
+         * @throws IllegalStateException if {@link #build()} was already called
+         * or this builder also contains AutofillId information
+         *
+         * @return this builder.
+         */
+        public @NonNull Dataset.Builder setField(
+                @NonNull String hint, @NonNull Field field) {
+            throwIfDestroyed();
+
+            final DatasetFieldFilter filter = field.getDatasetFieldFilter();
+            final Presentations presentations = field.getPresentations();
+            if (presentations == null) {
+                setLifeTheUniverseAndEverything(hint, field.getValue(), null, null, null,
+                        filter, null);
+            } else {
+                setLifeTheUniverseAndEverything(hint, field.getValue(),
+                        presentations.getMenuPresentation(),
+                        presentations.getInlinePresentation(),
+                        presentations.getInlineTooltipPresentation(), filter,
+                        presentations.getDialogPresentation());
+            }
+
+            return this;
+        }
+
+        /**
          * Sets the value of a field with an <a href="#Filtering">explicit filter</a>, and using an
          * {@link InlinePresentation} to visualize it as an inline suggestion.
          *
@@ -958,6 +1147,32 @@
             return this;
         }
 
+        private void setLifeTheUniverseAndEverything(String datatype,
+                @Nullable AutofillValue value,
+                @Nullable RemoteViews presentation,
+                @Nullable InlinePresentation inlinePresentation,
+                @Nullable InlinePresentation tooltip,
+                @Nullable DatasetFieldFilter filter,
+                @Nullable RemoteViews dialogPresentation) {
+            if (mAutofillDatatypes == null) {
+                mFieldValues = new ArrayList<>();
+                mFieldPresentations = new ArrayList<>();
+                mFieldDialogPresentations = new ArrayList<>();
+                mFieldInlinePresentations = new ArrayList<>();
+                mFieldInlineTooltipPresentations = new ArrayList<>();
+                mFieldFilters = new ArrayList<>();
+                mAutofillDatatypes = new ArrayList<>();
+                mFieldIds = null;
+            }
+            mFieldValues.add(value);
+            mFieldPresentations.add(presentation);
+            mFieldDialogPresentations.add(dialogPresentation);
+            mFieldInlinePresentations.add(inlinePresentation);
+            mFieldInlineTooltipPresentations.add(tooltip);
+            mFieldFilters.add(filter);
+            mAutofillDatatypes.add(datatype);
+        }
+
         private void setLifeTheUniverseAndEverything(@NonNull AutofillId id,
                 @Nullable AutofillValue value, @Nullable RemoteViews presentation,
                 @Nullable InlinePresentation inlinePresentation,
@@ -984,6 +1199,7 @@
                 mFieldInlinePresentations = new ArrayList<>();
                 mFieldInlineTooltipPresentations = new ArrayList<>();
                 mFieldFilters = new ArrayList<>();
+                mAutofillDatatypes = null;
             }
             mFieldIds.add(id);
             mFieldValues.add(value);
@@ -1007,9 +1223,14 @@
         public @NonNull Dataset build() {
             throwIfDestroyed();
             mDestroyed = true;
-            if (mFieldIds == null) {
+            if (mFieldIds == null && mAutofillDatatypes == null) {
                 throw new IllegalStateException("at least one value must be set");
             }
+            if (mFieldIds != null && mAutofillDatatypes != null) {
+                if (mFieldIds.size() > 0 && mAutofillDatatypes.size() > 0) {
+                    throw new IllegalStateException("both field and datatype were populated");
+                }
+            }
             if (mFieldContent != null) {
                 if (mFieldIds.size() > 1) {
                     throw new IllegalStateException(
@@ -1051,9 +1272,11 @@
         parcel.writeTypedList(mFieldInlinePresentations, flags);
         parcel.writeTypedList(mFieldInlineTooltipPresentations, flags);
         parcel.writeTypedList(mFieldFilters, flags);
+        parcel.writeStringList(mAutofillDatatypes);
         parcel.writeParcelable(mFieldContent, flags);
         parcel.writeParcelable(mAuthentication, flags);
         parcel.writeString(mId);
+        parcel.writeInt(mEligibleReason);
     }
 
     public static final @NonNull Creator<Dataset> CREATOR = new Creator<Dataset>() {
@@ -1081,11 +1304,14 @@
                     parcel.createTypedArrayList(InlinePresentation.CREATOR);
             final ArrayList<DatasetFieldFilter> filters =
                     parcel.createTypedArrayList(DatasetFieldFilter.CREATOR);
+            final ArrayList<String> datatypes =
+                    parcel.createStringArrayList();
             final ClipData fieldContent = parcel.readParcelable(null,
                     android.content.ClipData.class);
             final IntentSender authentication = parcel.readParcelable(null,
                     android.content.IntentSender.class);
             final String datasetId = parcel.readString();
+            final int eligibleReason = parcel.readInt();
 
             // Always go through the builder to ensure the data ingested by
             // the system obeys the contract of the builder to avoid attacks
@@ -1114,23 +1340,43 @@
                 builder.setContent(ids.get(0), fieldContent);
             }
             final int inlinePresentationsSize = inlinePresentations.size();
-            for (int i = 0; i < ids.size(); i++) {
-                final AutofillId id = ids.get(i);
-                final AutofillValue value = values.get(i);
-                final RemoteViews fieldPresentation = presentations.get(i);
-                final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
-                final InlinePresentation fieldInlinePresentation =
-                        i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
-                final InlinePresentation fieldInlineTooltipPresentation =
-                        i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
-                final DatasetFieldFilter filter = filters.get(i);
-                builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation,
-                        fieldInlinePresentation, fieldInlineTooltipPresentation, filter,
-                        fieldDialogPresentation);
+
+            if (ids.size() == 0 && datatypes.size() > 0) {
+                for (int i = 0; i < ids.size(); i++) {
+                    final String datatype = datatypes.get(i);
+                    final AutofillValue value = values.get(i);
+                    final RemoteViews fieldPresentation = presentations.get(i);
+                    final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
+                    final InlinePresentation fieldInlinePresentation =
+                            i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
+                    final InlinePresentation fieldInlineTooltipPresentation =
+                            i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
+                    final DatasetFieldFilter filter = filters.get(i);
+                    builder.setLifeTheUniverseAndEverything(
+                            datatype, value, fieldPresentation, fieldInlinePresentation,
+                            fieldInlineTooltipPresentation, filter, fieldDialogPresentation);
+                }
+            } else {
+                for (int i = 0; i < ids.size(); i++) {
+                    final AutofillId id = ids.get(i);
+                    final AutofillValue value = values.get(i);
+                    final RemoteViews fieldPresentation = presentations.get(i);
+                    final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
+                    final InlinePresentation fieldInlinePresentation =
+                            i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
+                    final InlinePresentation fieldInlineTooltipPresentation =
+                            i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
+                    final DatasetFieldFilter filter = filters.get(i);
+                    builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation,
+                            fieldInlinePresentation, fieldInlineTooltipPresentation, filter,
+                            fieldDialogPresentation);
+                }
             }
             builder.setAuthentication(authentication);
             builder.setId(datasetId);
-            return builder.build();
+            Dataset dataset = builder.build();
+            dataset.mEligibleReason = eligibleReason;
+            return dataset;
         }
 
         @Override
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index 0f7c9b6..4a848dd 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -117,6 +117,12 @@
      */
     public static final @RequestFlags int FLAG_RESET_FILL_DIALOG_STATE = 0x100;
 
+    /**
+     * Indicate the fill request is made for PCC detection
+     * @hide
+     */
+    public static final @RequestFlags int FLAG_PCC_DETECTION = 0x200;
+
     /** @hide */
     public static final int INVALID_REQUEST_ID = Integer.MIN_VALUE;
 
@@ -135,6 +141,19 @@
     private final @NonNull List<FillContext> mFillContexts;
 
     /**
+     * Sends a list of datatypes for the Autofill Provider.
+     *
+     * If this is populated, Autofill Provider should return data
+     * for the autofill hints requested here,
+     * even though the Autofill Provider may not have detected these types.
+     * The hints would be part of HintConstants:
+     * https://developer.android.com/reference/androidx/autofill/HintConstants
+     *
+     * This is populated if the platform's field detection is enabled.
+     */
+    private final @NonNull List<String> mHints;
+
+    /**
      * Gets the latest client state bundle set by the service in a
      * {@link FillResponse.Builder#setClientState(Bundle) fill response}.
      *
@@ -190,6 +209,7 @@
 
     private void onConstructed() {
         Preconditions.checkCollectionElementsNotNull(mFillContexts, "contexts");
+        Preconditions.checkCollectionElementsNotNull(mHints, "hints");
     }
 
 
@@ -200,7 +220,7 @@
     // CHECKSTYLE:OFF Generated code
     //
     // To regenerate run:
-    // $ codegen $ANDROID_BUILD_TOP/./frameworks/base/core/java/android/service/autofill/FillRequest.java
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/autofill/FillRequest.java
     //
     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
     //   Settings > Editor > Code Style > Formatter Control
@@ -215,7 +235,8 @@
         FLAG_VIEW_NOT_FOCUSED,
         FLAG_SUPPORTS_FILL_DIALOG,
         FLAG_IME_SHOWING,
-        FLAG_RESET_FILL_DIALOG_STATE
+        FLAG_RESET_FILL_DIALOG_STATE,
+        FLAG_PCC_DETECTION
     })
     @Retention(RetentionPolicy.SOURCE)
     @DataClass.Generated.Member
@@ -245,6 +266,8 @@
                     return "FLAG_IME_SHOWING";
             case FLAG_RESET_FILL_DIALOG_STATE:
                     return "FLAG_RESET_FILL_DIALOG_STATE";
+            case FLAG_PCC_DETECTION:
+                    return "FLAG_PCC_DETECTION";
             default: return Integer.toHexString(value);
         }
     }
@@ -260,6 +283,11 @@
      *   <p><b>Note:</b> Starting on Android {@link android.os.Build.VERSION_CODES#Q}, it could also
      *   include contexts from requests whose {@link SaveInfo} had the
      *   {@link SaveInfo#FLAG_DELAY_SAVE} flag.
+     * @param hints
+     *   Autofill Provider should return data for the autofill hints requested here,
+     *   even though the Autofill Provider may not have detected these types.
+     *   The hints would be part of HintConstants:
+     *   https://developer.android.com/reference/androidx/autofill/HintConstants
      * @param clientState
      *   Gets the latest client state bundle set by the service in a
      *   {@link FillResponse.Builder#setClientState(Bundle) fill response}.
@@ -303,6 +331,7 @@
     public FillRequest(
             int id,
             @NonNull List<FillContext> fillContexts,
+            @NonNull List<String> hints,
             @Nullable Bundle clientState,
             @RequestFlags int flags,
             @Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
@@ -311,6 +340,9 @@
         this.mFillContexts = fillContexts;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mFillContexts);
+        this.mHints = hints;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mHints);
         this.mClientState = clientState;
         this.mFlags = flags;
 
@@ -322,7 +354,8 @@
                         | FLAG_VIEW_NOT_FOCUSED
                         | FLAG_SUPPORTS_FILL_DIALOG
                         | FLAG_IME_SHOWING
-                        | FLAG_RESET_FILL_DIALOG_STATE);
+                        | FLAG_RESET_FILL_DIALOG_STATE
+                        | FLAG_PCC_DETECTION);
         this.mInlineSuggestionsRequest = inlineSuggestionsRequest;
         this.mDelayedFillIntentSender = delayedFillIntentSender;
 
@@ -350,6 +383,17 @@
     }
 
     /**
+     * Autofill Provider should return data for the autofill hints requested here,
+     * even though the Autofill Provider may not have detected these types.
+     * The hints would be part of HintConstants:
+     * https://developer.android.com/reference/androidx/autofill/HintConstants
+     */
+    @DataClass.Generated.Member
+    public @NonNull List<String> getHints() {
+        return mHints;
+    }
+
+    /**
      * Gets the latest client state bundle set by the service in a
      * {@link FillResponse.Builder#setClientState(Bundle) fill response}.
      *
@@ -423,6 +467,7 @@
         return "FillRequest { " +
                 "id = " + mId + ", " +
                 "fillContexts = " + mFillContexts + ", " +
+                "hints = " + mHints + ", " +
                 "clientState = " + mClientState + ", " +
                 "flags = " + requestFlagsToString(mFlags) + ", " +
                 "inlineSuggestionsRequest = " + mInlineSuggestionsRequest + ", " +
@@ -437,12 +482,13 @@
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         byte flg = 0;
-        if (mClientState != null) flg |= 0x4;
-        if (mInlineSuggestionsRequest != null) flg |= 0x10;
-        if (mDelayedFillIntentSender != null) flg |= 0x20;
+        if (mClientState != null) flg |= 0x8;
+        if (mInlineSuggestionsRequest != null) flg |= 0x20;
+        if (mDelayedFillIntentSender != null) flg |= 0x40;
         dest.writeByte(flg);
         dest.writeInt(mId);
         dest.writeParcelableList(mFillContexts, flags);
+        dest.writeStringList(mHints);
         if (mClientState != null) dest.writeBundle(mClientState);
         dest.writeInt(mFlags);
         if (mInlineSuggestionsRequest != null) dest.writeTypedObject(mInlineSuggestionsRequest, flags);
@@ -463,16 +509,21 @@
         byte flg = in.readByte();
         int id = in.readInt();
         List<FillContext> fillContexts = new ArrayList<>();
-        in.readParcelableList(fillContexts, FillContext.class.getClassLoader(), android.service.autofill.FillContext.class);
-        Bundle clientState = (flg & 0x4) == 0 ? null : in.readBundle();
+        in.readParcelableList(fillContexts, FillContext.class.getClassLoader());
+        List<String> hints = new ArrayList<>();
+        in.readStringList(hints);
+        Bundle clientState = (flg & 0x8) == 0 ? null : in.readBundle();
         int flags = in.readInt();
-        InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x10) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR);
-        IntentSender delayedFillIntentSender = (flg & 0x20) == 0 ? null : (IntentSender) in.readTypedObject(IntentSender.CREATOR);
+        InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x20) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR);
+        IntentSender delayedFillIntentSender = (flg & 0x40) == 0 ? null : (IntentSender) in.readTypedObject(IntentSender.CREATOR);
 
         this.mId = id;
         this.mFillContexts = fillContexts;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mFillContexts);
+        this.mHints = hints;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mHints);
         this.mClientState = clientState;
         this.mFlags = flags;
 
@@ -484,7 +535,8 @@
                         | FLAG_VIEW_NOT_FOCUSED
                         | FLAG_SUPPORTS_FILL_DIALOG
                         | FLAG_IME_SHOWING
-                        | FLAG_RESET_FILL_DIALOG_STATE);
+                        | FLAG_RESET_FILL_DIALOG_STATE
+                        | FLAG_PCC_DETECTION);
         this.mInlineSuggestionsRequest = inlineSuggestionsRequest;
         this.mDelayedFillIntentSender = delayedFillIntentSender;
 
@@ -506,10 +558,10 @@
     };
 
     @DataClass.Generated(
-            time = 1663290803064L,
+            time = 1675711417112L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/service/autofill/FillRequest.java",
-            inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final  int INVALID_REQUEST_ID\nprivate final  int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate  void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
+            inputSignatures = "public static final @android.service.autofill.FillRequest.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PASSWORD_INPUT_TYPE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_VIEW_NOT_FOCUSED\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_SUPPORTS_FILL_DIALOG\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_IME_SHOWING\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_RESET_FILL_DIALOG_STATE\npublic static final @android.service.autofill.FillRequest.RequestFlags int FLAG_PCC_DETECTION\npublic static final  int INVALID_REQUEST_ID\nprivate final  int mId\nprivate final @android.annotation.NonNull java.util.List<android.service.autofill.FillContext> mFillContexts\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mHints\nprivate final @android.annotation.Nullable android.os.Bundle mClientState\nprivate final @android.service.autofill.FillRequest.RequestFlags int mFlags\nprivate final @android.annotation.Nullable android.view.inputmethod.InlineSuggestionsRequest mInlineSuggestionsRequest\nprivate final @android.annotation.Nullable android.content.IntentSender mDelayedFillIntentSender\nprivate  void onConstructed()\nclass FillRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstructor=true, genHiddenConstDefs=true)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 385b0aa..c962bf1 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -34,6 +34,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.service.assist.classification.FieldClassification;
 import android.view.autofill.AutofillId;
 import android.widget.RemoteViews;
 
@@ -45,6 +46,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Response for an {@link
@@ -113,6 +115,81 @@
     private final @StringRes int mServiceDisplayNameResourceId;
     private final boolean mShowFillDialogIcon;
     private final boolean mShowSaveDialogIcon;
+    private final @Nullable FieldClassification[] mDetectedFieldTypes;
+
+    /**
+    * Creates a shollow copy of the provided FillResponse.
+    *
+    * @hide
+    */
+    public static FillResponse shallowCopy(FillResponse r, List<Dataset> datasets) {
+        return new FillResponse(
+                (datasets != null) ? new ParceledListSlice<>(datasets) : null,
+                r.mSaveInfo,
+                r.mClientState,
+                r.mPresentation,
+                r.mInlinePresentation,
+                r.mInlineTooltipPresentation,
+                r.mDialogPresentation,
+                r.mDialogHeader,
+                r.mHeader,
+                r.mFooter,
+                r.mAuthentication,
+                r.mAuthenticationIds,
+                r.mIgnoredIds,
+                r.mFillDialogTriggerIds,
+                r.mDisableDuration,
+                r.mFieldClassificationIds,
+                r.mFlags,
+                r.mRequestId,
+                r.mUserData,
+                r.mCancelIds,
+                r.mSupportsInlineSuggestions,
+                r.mIconResourceId,
+                r.mServiceDisplayNameResourceId,
+                r.mShowFillDialogIcon,
+                r.mShowSaveDialogIcon,
+                r.mDetectedFieldTypes);
+    }
+
+    private FillResponse(ParceledListSlice<Dataset> datasets, SaveInfo saveInfo, Bundle clientState,
+            RemoteViews presentation, InlinePresentation inlinePresentation,
+            InlinePresentation inlineTooltipPresentation, RemoteViews dialogPresentation,
+            RemoteViews dialogHeader, RemoteViews header, RemoteViews footer,
+            IntentSender authentication, AutofillId[] authenticationIds, AutofillId[] ignoredIds,
+            AutofillId[] fillDialogTriggerIds, long disableDuration,
+            AutofillId[] fieldClassificationIds, int flags, int requestId, UserData userData,
+            int[] cancelIds, boolean supportsInlineSuggestions, int iconResourceId,
+            int serviceDisplayNameResourceId, boolean showFillDialogIcon,
+            boolean showSaveDialogIcon,
+            FieldClassification[] detectedFieldTypes) {
+        mDatasets = datasets;
+        mSaveInfo = saveInfo;
+        mClientState = clientState;
+        mPresentation = presentation;
+        mInlinePresentation = inlinePresentation;
+        mInlineTooltipPresentation = inlineTooltipPresentation;
+        mDialogPresentation = dialogPresentation;
+        mDialogHeader = dialogHeader;
+        mHeader = header;
+        mFooter = footer;
+        mAuthentication = authentication;
+        mAuthenticationIds = authenticationIds;
+        mIgnoredIds = ignoredIds;
+        mFillDialogTriggerIds = fillDialogTriggerIds;
+        mDisableDuration = disableDuration;
+        mFieldClassificationIds = fieldClassificationIds;
+        mFlags = flags;
+        mRequestId = requestId;
+        mUserData = userData;
+        mCancelIds = cancelIds;
+        mSupportsInlineSuggestions = supportsInlineSuggestions;
+        mIconResourceId = iconResourceId;
+        mServiceDisplayNameResourceId = serviceDisplayNameResourceId;
+        mShowFillDialogIcon = showFillDialogIcon;
+        mShowSaveDialogIcon = showSaveDialogIcon;
+        mDetectedFieldTypes = detectedFieldTypes;
+    }
 
     private FillResponse(@NonNull Builder builder) {
         mDatasets = (builder.mDatasets != null) ? new ParceledListSlice<>(builder.mDatasets) : null;
@@ -140,6 +217,14 @@
         mServiceDisplayNameResourceId = builder.mServiceDisplayNameResourceId;
         mShowFillDialogIcon = builder.mShowFillDialogIcon;
         mShowSaveDialogIcon = builder.mShowSaveDialogIcon;
+        mDetectedFieldTypes = builder.mDetectedFieldTypes;
+    }
+
+    /** @hide */
+    @TestApi
+    @NonNull
+    public Set<FieldClassification> getDetectedFieldClassifications() {
+        return Set.of(mDetectedFieldTypes);
     }
 
     /** @hide */
@@ -312,6 +397,28 @@
         private int mServiceDisplayNameResourceId;
         private boolean mShowFillDialogIcon = true;
         private boolean mShowSaveDialogIcon = true;
+        private FieldClassification[] mDetectedFieldTypes;
+
+        /**
+         * Adds a new {@link FieldClassification} to this response, to
+         * help the platform provide more accurate detection results.
+         *
+         * Call this when a field has been detected with a type.
+         *
+         * Altough similiarly named with {@link setFieldClassificationIds},
+         * it provides a different functionality - setFieldClassificationIds should
+         * be used when a field is only suspected to be Autofillable.
+         * This method should be used when a field is certainly Autofillable
+         * with a certain type.
+         */
+        @NonNull
+        public Builder setDetectedFieldClassifications(
+                @NonNull Set<FieldClassification> fieldInfos) {
+            throwIfDestroyed();
+            throwIfDisableAutofillCalled();
+            mDetectedFieldTypes = fieldInfos.toArray(new FieldClassification[0]);
+            return this;
+        }
 
         /**
          * Triggers a custom UI before autofilling the screen with any data set in this
@@ -641,6 +748,15 @@
         }
 
         /**
+         * @hide
+         */
+        @NonNull
+        public Builder setDatasets(ArrayList<Dataset> dataset) {
+            mDatasets = dataset;
+            return this;
+        }
+
+        /**
          * Sets the {@link SaveInfo} associated with this response.
          *
          * @return This builder.
@@ -1122,6 +1238,7 @@
         parcel.writeParcelableArray(mIgnoredIds, flags);
         parcel.writeLong(mDisableDuration);
         parcel.writeParcelableArray(mFieldClassificationIds, flags);
+        parcel.writeParcelableArray(mDetectedFieldTypes, flags);
         parcel.writeInt(mIconResourceId);
         parcel.writeInt(mServiceDisplayNameResourceId);
         parcel.writeBoolean(mShowFillDialogIcon);
@@ -1192,6 +1309,12 @@
                 builder.setFieldClassificationIds(fieldClassifactionIds);
             }
 
+            final FieldClassification[] detectedFields =
+                    parcel.readParcelableArray(null, FieldClassification.class);
+            if (detectedFields != null) {
+                builder.setDetectedFieldClassifications(Set.of(detectedFields));
+            }
+
             builder.setIconResourceId(parcel.readInt());
             builder.setServiceDisplayNameResourceId(parcel.readInt());
             builder.setShowFillDialogIcon(parcel.readBoolean());
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 5fe1d4f..828e466 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -308,7 +308,7 @@
      * username field, another for password).
      */
     // TODO(b/113281366): improve documentation: add example, document relationship with other
-    // flagss, etc...
+    // flags, etc...
     public static final int FLAG_DELAY_SAVE = 0x4;
 
     /** @hide */
@@ -777,17 +777,13 @@
         /**
          * Builds a new {@link SaveInfo} instance.
          *
-         * @throws IllegalStateException if no
-         * {@link #Builder(int, AutofillId[]) required ids},
+         * If no {@link #Builder(int, AutofillId[]) required ids},
          * or {@link #setOptionalIds(AutofillId[]) optional ids}, or {@link #FLAG_DELAY_SAVE}
-         * were set
+         * were set, Save Dialog will only be triggered if platform detection is enabled, which
+         * is indicated when {@link FillRequest.getHints()} is not empty.
          */
         public SaveInfo build() {
             throwIfDestroyed();
-            Preconditions.checkState(
-                    !ArrayUtils.isEmpty(mRequiredIds) || !ArrayUtils.isEmpty(mOptionalIds)
-                            || (mFlags & FLAG_DELAY_SAVE) != 0,
-                    "must have at least one required or optional id or FLAG_DELAYED_SAVE");
             mDestroyed = true;
             return new SaveInfo(this);
         }
diff --git a/core/java/android/service/credentials/BeginCreateCredentialRequest.java b/core/java/android/service/credentials/BeginCreateCredentialRequest.java
index 348bb2b..2eed998 100644
--- a/core/java/android/service/credentials/BeginCreateCredentialRequest.java
+++ b/core/java/android/service/credentials/BeginCreateCredentialRequest.java
@@ -17,6 +17,7 @@
 package android.service.credentials;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -24,8 +25,6 @@
 
 import com.android.internal.util.Preconditions;
 
-import java.util.Objects;
-
 /**
  * Request for beginning a create credential request.
  *
@@ -38,7 +37,7 @@
  */
 @SuppressLint("ParcelNotFinal")
 public class BeginCreateCredentialRequest implements Parcelable {
-    private final @NonNull CallingAppInfo mCallingAppInfo;
+    private final @Nullable CallingAppInfo mCallingAppInfo;
     private final @NonNull String mType;
     private final @NonNull Bundle mData;
 
@@ -49,13 +48,25 @@
      * null or empty.
      * @throws NullPointerException If {@code data} is null.
      */
-    public BeginCreateCredentialRequest(@NonNull CallingAppInfo callingAppInfo,
-            @NonNull String type, @NonNull Bundle data) {
-        mCallingAppInfo = Objects.requireNonNull(callingAppInfo,
-                "callingAppInfo must not be null");
+    public BeginCreateCredentialRequest(@NonNull String type, @NonNull Bundle data,
+            @Nullable CallingAppInfo callingAppInfo) {
         mType = Preconditions.checkStringNotEmpty(type,
                 "type must not be null or empty");
-        mData = Objects.requireNonNull(data, "data must not be null");
+        Bundle dataCopy = new Bundle();
+        dataCopy.putAll(data);
+        mData = dataCopy;
+        mCallingAppInfo = callingAppInfo;
+    }
+
+    /**
+     * Constructs a new instance without {@link CallingAppInfo}.
+     *
+     * @throws IllegalArgumentException If {{@code type} string is
+     * null or empty.
+     * @throws NullPointerException If {@code data} is null.
+     */
+    public BeginCreateCredentialRequest(@NonNull String type, @NonNull Bundle data) {
+        this(type, data, /*callingAppInfo=*/null);
     }
 
     private BeginCreateCredentialRequest(@NonNull Parcel in) {
@@ -90,7 +101,7 @@
     }
 
     /** Returns the info pertaining to the calling app. */
-    @NonNull
+    @Nullable
     public CallingAppInfo getCallingAppInfo() {
         return mCallingAppInfo;
     }
diff --git a/core/java/android/service/credentials/BeginCreateCredentialResponse.java b/core/java/android/service/credentials/BeginCreateCredentialResponse.java
index 8ca3a1a..f0f954d 100644
--- a/core/java/android/service/credentials/BeginCreateCredentialResponse.java
+++ b/core/java/android/service/credentials/BeginCreateCredentialResponse.java
@@ -34,6 +34,14 @@
     private final @NonNull List<CreateEntry> mCreateEntries;
     private final @Nullable CreateEntry mRemoteCreateEntry;
 
+    /**
+     * Creates an empty response instance, to be used when there are no {@link CreateEntry}
+     * to return.
+     */
+    public BeginCreateCredentialResponse() {
+        this(/*createEntries=*/new ArrayList<>(), /*remoteCreateEntry=*/null);
+    }
+
     private BeginCreateCredentialResponse(@NonNull Parcel in) {
         List<CreateEntry> createEntries = new ArrayList<>();
         in.readTypedList(createEntries, CreateEntry.CREATOR);
@@ -137,13 +145,8 @@
 
         /**
          * Builds a new instance of {@link BeginCreateCredentialResponse}.
-         *
-         * @throws NullPointerException If {@code createEntries} is null.
-         * @throws IllegalArgumentException If {@code createEntries} is empty.
          */
         public @NonNull BeginCreateCredentialResponse build() {
-            Preconditions.checkCollectionNotEmpty(mCreateEntries, "createEntries must "
-                    + "not be null, or empty");
             return new BeginCreateCredentialResponse(mCreateEntries, mRemoteCreateEntry);
         }
     }
diff --git a/core/java/android/service/credentials/BeginGetCredentialOption.java b/core/java/android/service/credentials/BeginGetCredentialOption.java
index 65d63c3..81b9f22 100644
--- a/core/java/android/service/credentials/BeginGetCredentialOption.java
+++ b/core/java/android/service/credentials/BeginGetCredentialOption.java
@@ -16,8 +16,6 @@
 
 package android.service.credentials;
 
-import static java.util.Objects.requireNonNull;
-
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.os.Bundle;
@@ -39,6 +37,13 @@
  */
 @SuppressLint("ParcelNotFinal")
 public class BeginGetCredentialOption implements Parcelable {
+    private static final String BUNDLE_ID_KEY =
+            "android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY";
+    /**
+     * A unique id associated with this request option.
+     */
+    @NonNull
+    private final String mId;
 
     /**
      * The requested credential type.
@@ -53,6 +58,14 @@
     private final Bundle mCandidateQueryData;
 
     /**
+     * Returns the unique id associated with this request. This is for internal use only.
+     */
+    @NonNull
+    public String getId() {
+        return mId;
+    }
+
+    /**
      * Returns the requested credential type.
      */
     @NonNull
@@ -80,6 +93,7 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeString8(mType);
         dest.writeBundle(mCandidateQueryData);
+        dest.writeString8(mId);
     }
 
     @Override
@@ -92,33 +106,43 @@
         return "GetCredentialOption {"
                 + "type=" + mType
                 + ", candidateQueryData=" + mCandidateQueryData
+                + ", id=" + mId
                 + "}";
     }
 
     /**
      * Constructs a {@link BeginGetCredentialOption}.
      *
-     * @param type the requested credential type
+     * @param id the unique id associated with this option
+     * @param type               the requested credential type
      * @param candidateQueryData the request candidateQueryData
-     *
      * @throws IllegalArgumentException If type is empty.
      */
     public BeginGetCredentialOption(
-            @NonNull String type,
+            @NonNull String id, @NonNull String type,
             @NonNull Bundle candidateQueryData) {
+        mId = id;
         mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
-        mCandidateQueryData = requireNonNull(
-                candidateQueryData, "candidateQueryData must not be null");
+        Bundle bundle = new Bundle();
+        bundle.putAll(candidateQueryData);
+        mCandidateQueryData = bundle;
+        addIdToBundle();
+    }
+
+    private void addIdToBundle() {
+        mCandidateQueryData.putString(BUNDLE_ID_KEY, mId);
     }
 
     private BeginGetCredentialOption(@NonNull Parcel in) {
         String type = in.readString8();
         Bundle candidateQueryData = in.readBundle();
+        String id = in.readString8();
 
         mType = type;
         AnnotationValidations.validate(NonNull.class, null, mType);
         mCandidateQueryData = candidateQueryData;
         AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
+        mId = id;
     }
 
     public static final @NonNull Creator<BeginGetCredentialOption> CREATOR =
diff --git a/core/java/android/service/credentials/BeginGetCredentialRequest.java b/core/java/android/service/credentials/BeginGetCredentialRequest.java
index e375cdd..48b2b05 100644
--- a/core/java/android/service/credentials/BeginGetCredentialRequest.java
+++ b/core/java/android/service/credentials/BeginGetCredentialRequest.java
@@ -17,9 +17,9 @@
 package android.service.credentials;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Intent;
-import android.credentials.GetCredentialOption;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -33,7 +33,7 @@
 /**
  * Query stage request for getting user's credentials from a given credential provider.
  *
- * <p>This request contains a list of {@link GetCredentialOption} that have parameters
+ * <p>This request contains a list of {@link BeginGetCredentialOption} that have parameters
  * to be used to query credentials, and return a list of {@link CredentialEntry} to be set
  * on the {@link BeginGetCredentialResponse}. This list is then shown to the user on a selector.
  *
@@ -44,7 +44,7 @@
  */
 public final class BeginGetCredentialRequest implements Parcelable {
     /** Info pertaining to the app requesting for credentials. */
-    @NonNull private final CallingAppInfo mCallingAppInfo;
+    @Nullable private final CallingAppInfo mCallingAppInfo;
 
     /**
      * List of credential options. Each {@link BeginGetCredentialOption} object holds parameters to
@@ -52,12 +52,12 @@
      *
      * This request does not reveal sensitive parameters. Complete list of parameters
      * is retrieved through the {@link PendingIntent} set on each {@link CredentialEntry}
-     * on {@link CredentialsResponseContent} set on {@link BeginGetCredentialResponse},
+     * on {@link BeginGetCredentialResponse} set on {@link BeginGetCredentialResponse},
      * when the user selects one of these entries.
      */
     @NonNull private final List<BeginGetCredentialOption> mBeginGetCredentialOptions;
 
-    private BeginGetCredentialRequest(@NonNull CallingAppInfo callingAppInfo,
+    private BeginGetCredentialRequest(@Nullable CallingAppInfo callingAppInfo,
             @NonNull List<BeginGetCredentialOption> getBeginCredentialOptions) {
         this.mCallingAppInfo = callingAppInfo;
         this.mBeginGetCredentialOptions = getBeginCredentialOptions;
@@ -99,7 +99,7 @@
     /**
      * Returns info pertaining to the app requesting credentials.
      */
-    public @NonNull CallingAppInfo getCallingAppInfo() {
+    public @Nullable CallingAppInfo getCallingAppInfo() {
         return mCallingAppInfo;
     }
 
@@ -115,17 +115,16 @@
      * Builder for {@link BeginGetCredentialRequest}.
      */
     public static final class Builder {
-        private CallingAppInfo mCallingAppInfo;
+        private CallingAppInfo mCallingAppInfo = null;
         private List<BeginGetCredentialOption> mBeginGetCredentialOptions = new ArrayList<>();
 
         /**
-         * Creates a new builder.
-         * @param callingAppInfo info pertaining to the app requesting credentials
-         *
-         * @throws IllegalArgumentException If {@code callingAppInfo} is null or empty.
+         * Sets information pertaining to the calling app.
+         * @param callingAppInfo the info object containing the package name, and app signatures
          */
-        public Builder(@NonNull CallingAppInfo callingAppInfo) {
-            mCallingAppInfo = Objects.requireNonNull(callingAppInfo);
+        public @NonNull Builder setCallingAppInfo(@Nullable CallingAppInfo callingAppInfo) {
+            mCallingAppInfo = callingAppInfo;
+            return this;
         }
 
         /**
@@ -166,7 +165,6 @@
          * {@code callingAppInfo} is null or empty.
          */
         public @NonNull BeginGetCredentialRequest build() {
-            Objects.requireNonNull(mCallingAppInfo, "callingAppInfo");
             Preconditions.checkCollectionNotEmpty(mBeginGetCredentialOptions,
                     "beginGetCredentialOptions");
             return new BeginGetCredentialRequest(mCallingAppInfo, mBeginGetCredentialOptions);
diff --git a/core/java/android/service/credentials/BeginGetCredentialResponse.java b/core/java/android/service/credentials/BeginGetCredentialResponse.java
index 85e8d85..3652742 100644
--- a/core/java/android/service/credentials/BeginGetCredentialResponse.java
+++ b/core/java/android/service/credentials/BeginGetCredentialResponse.java
@@ -21,6 +21,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -28,70 +32,55 @@
  * data to be shown on the account selector UI.
  */
 public final class BeginGetCredentialResponse implements Parcelable {
-    /** Content to be used for the UI. */
-    private final @Nullable CredentialsResponseContent mCredentialsResponseContent;
+    /** List of credential entries to be displayed on the UI. */
+    private final @NonNull List<CredentialEntry> mCredentialEntries;
+
+    /** List of authentication entries to be displayed on the UI. */
+    private final @NonNull List<Action> mAuthenticationEntries;
+
+    /** List of provider actions to be displayed on the UI. */
+    private final @NonNull List<Action> mActions;
+
+    /** Remote credential entry to get the response from a different device. */
+    private final @Nullable CredentialEntry mRemoteCredentialEntry;
 
     /**
-     * Authentication action that must be launched and completed before showing any content
-     * from the provider.
+     * Creates an empty response instance, to be used when there are no {@link CredentialEntry},
+     * or {@link Action} to return.
      */
-    private final @Nullable Action mAuthenticationAction;
-
-    /**
-     * Creates a {@link BeginGetCredentialResponse} instance with an authentication
-     * {@link Action} set. Providers must use this method when no content can be shown
-     * before authentication.
-     *
-     * <p> When the user selects this {@code authenticationAction}, the system invokes the
-     * corresponding {@code pendingIntent}. Once the authentication flow is complete,
-     * the {@link android.app.Activity} result should be set
-     * to {@link android.app.Activity#RESULT_OK} and the
-     * {@link CredentialProviderService#EXTRA_CREDENTIALS_RESPONSE_CONTENT} extra should be set
-     * with a fully populated {@link CredentialsResponseContent} object.
-     * the authentication action activity is launched, and the user is authenticated, providers
-     * should create another response with {@link CredentialsResponseContent} using
-     * {@code createWithDisplayContent}, and add that response to the result of the authentication
-     * activity.
-     *
-     * @throws NullPointerException If {@code authenticationAction} is null.
-     */
-    public static @NonNull BeginGetCredentialResponse createWithAuthentication(
-            @NonNull Action authenticationAction) {
-        Objects.requireNonNull(authenticationAction,
-                "authenticationAction must not be null");
-        return new BeginGetCredentialResponse(null, authenticationAction);
+    public BeginGetCredentialResponse() {
+        this(/*credentialEntries=*/new ArrayList<>(),
+                /*authenticationActions=*/new ArrayList<>(),
+                /*actions=*/new ArrayList<>(),
+                /*remoteCredentialEntry=*/null);
     }
 
-    /**
-     * Creates a {@link BeginGetCredentialRequest} instance with content to be shown on the UI.
-     * Providers must use this method when there is content to be shown without top level
-     * authentication required, including credential entries, action entries or a remote entry,
-     *
-     * @throws NullPointerException If {@code credentialsResponseContent} is null.
-     */
-    public static @NonNull BeginGetCredentialResponse createWithResponseContent(
-            @NonNull CredentialsResponseContent credentialsResponseContent) {
-        Objects.requireNonNull(credentialsResponseContent,
-                "credentialsResponseContent must not be null");
-        return new BeginGetCredentialResponse(credentialsResponseContent, null);
-    }
-
-    private BeginGetCredentialResponse(@Nullable CredentialsResponseContent
-            credentialsResponseContent,
-            @Nullable Action authenticationAction) {
-        mCredentialsResponseContent = credentialsResponseContent;
-        mAuthenticationAction = authenticationAction;
+    private BeginGetCredentialResponse(@NonNull List<CredentialEntry> credentialEntries,
+            @NonNull List<Action> authenticationEntries, @NonNull List<Action> actions,
+            @Nullable CredentialEntry remoteCredentialEntry) {
+        mCredentialEntries = new ArrayList<>(credentialEntries);
+        mAuthenticationEntries = new ArrayList<>(authenticationEntries);
+        mActions = new ArrayList<>(actions);
+        mRemoteCredentialEntry = remoteCredentialEntry;
     }
 
     private BeginGetCredentialResponse(@NonNull Parcel in) {
-        mCredentialsResponseContent = in.readTypedObject(CredentialsResponseContent.CREATOR);
-        mAuthenticationAction = in.readTypedObject(Action.CREATOR);
+        List<CredentialEntry> credentialEntries = new ArrayList<>();
+        in.readTypedList(credentialEntries, CredentialEntry.CREATOR);
+        mCredentialEntries = credentialEntries;
+        List<Action> authenticationEntries = new ArrayList<>();
+        in.readTypedList(authenticationEntries, Action.CREATOR);
+        mAuthenticationEntries = authenticationEntries;
+        List<Action> actions = new ArrayList<>();
+        in.readTypedList(actions, Action.CREATOR);
+        mActions = actions;
+        mRemoteCredentialEntry = in.readTypedObject(CredentialEntry.CREATOR);
     }
 
     public static final @NonNull Creator<BeginGetCredentialResponse> CREATOR =
             new Creator<BeginGetCredentialResponse>() {
                 @Override
-                public BeginGetCredentialResponse createFromParcel(Parcel in) {
+                public BeginGetCredentialResponse createFromParcel(@NonNull Parcel in) {
                     return new BeginGetCredentialResponse(in);
                 }
 
@@ -108,23 +97,167 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeTypedObject(mCredentialsResponseContent, flags);
-        dest.writeTypedObject(mAuthenticationAction, flags);
+        dest.writeTypedList(mCredentialEntries, flags);
+        dest.writeTypedList(mAuthenticationEntries, flags);
+        dest.writeTypedList(mActions, flags);
+        dest.writeTypedObject(mRemoteCredentialEntry, flags);
     }
 
     /**
-     * If this response represents a top level authentication action, returns the authentication
-     * action to be invoked before any other content can be shown to the user.
+     * Returns the list of credential entries to be displayed on the UI.
      */
-    public @Nullable Action getAuthenticationAction() {
-        return mAuthenticationAction;
+    public @NonNull List<CredentialEntry> getCredentialEntries() {
+        return mCredentialEntries;
     }
 
     /**
-     * Returns the actual content to be displayed on the selector, if this response does not
-     * require any top level authentication.
+     * Returns the list of authentication entries to be displayed on the UI.
      */
-    public @Nullable CredentialsResponseContent getCredentialsResponseContent() {
-        return mCredentialsResponseContent;
+    public @NonNull List<Action> getAuthenticationActions() {
+        return mAuthenticationEntries;
+    }
+
+    /**
+     * Returns the list of actions to be displayed on the UI.
+     */
+    public @NonNull List<Action> getActions() {
+        return mActions;
+    }
+
+    /**
+     * Returns the remote credential entry to be displayed on the UI.
+     */
+    public @Nullable CredentialEntry getRemoteCredentialEntry() {
+        return mRemoteCredentialEntry;
+    }
+
+    /**
+     * Builds an instance of {@link BeginGetCredentialResponse}.
+     */
+    public static final class Builder {
+        private List<CredentialEntry> mCredentialEntries = new ArrayList<>();
+
+        private List<Action> mAuthenticationEntries = new ArrayList<>();
+        private List<Action> mActions = new ArrayList<>();
+        private CredentialEntry mRemoteCredentialEntry;
+
+        /**
+         * Sets a remote credential entry to be shown on the UI. Provider must set this if they
+         * wish to get the credential from a different device.
+         *
+         * <p> When constructing the {@link CredentialEntry} object, the {@code pendingIntent}
+         * must be set such that it leads to an activity that can provide UI to fulfill the request
+         * on a remote device. When user selects this {@code remoteCredentialEntry}, the system will
+         * invoke the {@code pendingIntent} set on the {@link CredentialEntry}.
+         *
+         * <p> Once the remote credential flow is complete, the {@link android.app.Activity}
+         * result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
+         * {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE} key should be populated
+         * with a {@link android.credentials.Credential} object.
+         */
+        public @NonNull Builder setRemoteCredentialEntry(@Nullable CredentialEntry
+                remoteCredentialEntry) {
+            mRemoteCredentialEntry = remoteCredentialEntry;
+            return this;
+        }
+
+        /**
+         * Adds a {@link CredentialEntry} to the list of entries to be displayed on
+         * the UI.
+         *
+         * @throws NullPointerException If the {@code credentialEntry} is null.
+         */
+        public @NonNull Builder addCredentialEntry(@NonNull CredentialEntry credentialEntry) {
+            mCredentialEntries.add(Objects.requireNonNull(credentialEntry));
+            return this;
+        }
+
+        /**
+         * Add an authentication entry to be shown on the UI. Providers must set this entry if
+         * the corresponding account is locked and no underlying credentials can be returned.
+         *
+         * <p> When the user selects this {@code authenticationAction}, the system invokes the
+         * corresponding {@code pendingIntent}.
+         * Once the authentication action activity is launched, and the user is authenticated,
+         * providers should create another response with {@link BeginGetCredentialResponse} using
+         * this time adding the unlocked credentials in the form of {@link CredentialEntry}'s.
+         *
+         * <p>The new response object must be set on the authentication activity's
+         * result. The result code should be set to {@link android.app.Activity#RESULT_OK} and
+         * the {@link CredentialProviderService#EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE} extra
+         * should be set with the new fully populated {@link BeginGetCredentialResponse} object.
+         *
+         * @throws NullPointerException If {@code authenticationAction} is null.
+         */
+        public @NonNull Builder addAuthenticationAction(@NonNull Action authenticationAction) {
+            mAuthenticationEntries.add(Objects.requireNonNull(authenticationAction));
+            return this;
+        }
+
+        /**
+         * Adds an {@link Action} to the list of actions to be displayed on
+         * the UI.
+         *
+         * <p> An {@code action} must be used for independent user actions,
+         * such as opening the app, intenting directly into a certain app activity etc. The
+         * {@code pendingIntent} set with the {@code action} must invoke the corresponding
+         * activity.
+         *
+         * @throws NullPointerException If {@code action} is null.
+         */
+        public @NonNull Builder addAction(@NonNull Action action) {
+            mActions.add(Objects.requireNonNull(action, "action must not be null"));
+            return this;
+        }
+
+        /**
+         * Sets the list of actions to be displayed on the UI.
+         *
+         * @throws NullPointerException If {@code actions} is null, or any of its elements
+         *                              is null.
+         */
+        public @NonNull Builder setActions(@NonNull List<Action> actions) {
+            mActions = Preconditions.checkCollectionElementsNotNull(actions,
+                    "actions");
+            return this;
+        }
+
+        /**
+         * Sets the list of credential entries to be displayed on the
+         * account selector UI.
+         *
+         * @throws NullPointerException If {@code credentialEntries} is null, or any of its
+         *                              elements is null.
+         */
+        public @NonNull Builder setCredentialEntries(
+                @NonNull List<CredentialEntry> credentialEntries) {
+            mCredentialEntries = Preconditions.checkCollectionElementsNotNull(
+                    credentialEntries,
+                    "credentialEntries");
+            return this;
+        }
+
+        /**
+         * Sets the list of authentication entries to be displayed on the
+         * account selector UI.
+         *
+         * @throws NullPointerException If {@code authenticationEntries} is null, or any of its
+         *                              elements is null.
+         */
+        public @NonNull Builder setAuthenticationActions(
+                @NonNull List<Action> authenticationActions) {
+            mAuthenticationEntries = Preconditions.checkCollectionElementsNotNull(
+                    authenticationActions,
+                    "authenticationActions");
+            return this;
+        }
+
+        /**
+         * Builds a {@link BeginGetCredentialResponse} instance.
+         */
+        public @NonNull BeginGetCredentialResponse build() {
+            return new BeginGetCredentialResponse(mCredentialEntries, mAuthenticationEntries,
+                    mActions, mRemoteCredentialEntry);
+        }
     }
 }
diff --git a/core/java/android/service/credentials/CredentialEntry.java b/core/java/android/service/credentials/CredentialEntry.java
index b037268..b6c13c4 100644
--- a/core/java/android/service/credentials/CredentialEntry.java
+++ b/core/java/android/service/credentials/CredentialEntry.java
@@ -16,7 +16,10 @@
 
 package android.service.credentials;
 
+import static java.util.Objects.requireNonNull;
+
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.PendingIntent;
 import android.app.slice.Slice;
@@ -29,9 +32,11 @@
  * user.
  *
  * <p>If user selects this entry, the corresponding {@link PendingIntent},
- * set on the {@code slice} as a {@link androidx.slice.core.SliceAction} will be
- * invoked to launch activities that require some user engagement before getting
- * the credential corresponding to this entry, e.g. authentication, confirmation etc.
+ * set on the {@code slice} will be invoked to launch activities that require some user engagement
+ * before getting the credential corresponding to this entry, e.g. authentication,
+ * confirmation etc. The extras associated with the resulting {@link android.app.Activity} will
+ * also contain the complete credential request containing all required parameters. This request
+ * can be retrieved against {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_REQUEST}.
  *
  * Once the activity fulfills the required user engagement, the {@link android.app.Activity}
  * result should be set to {@link android.app.Activity#RESULT_OK}, and the
@@ -42,24 +47,69 @@
  * object passed into the constructor. Any other field will not be parceled through. If the
  * derived class has custom parceling implementation, this class will not be able to unpack
  * the parcel without having access to that implementation.
+ *
+ * <p>While creating this entry, providers must set a {@code requestId} to be retrieved
+ * from {@link BeginGetCredentialOption#getId()}, to determine for which request this entry is
+ * being presented to the user. This will ensure that when user selects the entry, the correct
+ * complete request is added to the {@link PendingIntent} mentioned above.
  */
 @SuppressLint("ParcelNotFinal")
 public class CredentialEntry implements Parcelable {
+    /** The request option that corresponds to this entry. **/
+    private final @Nullable BeginGetCredentialOption mBeginGetCredentialOption;
+
     /** The type of the credential entry to be shown on the UI. */
     private final @NonNull String mType;
 
+
     /** The object containing display content to be shown along with this credential entry
      * on the UI. */
     private final @NonNull Slice mSlice;
 
+    /**
+     * Creates an entry that is associated with a {@link BeginGetCredentialOption} request.
+     * Providers must use this constructor when they extend from {@link CredentialProviderService}
+     * to respond to query phase {@link CredentialProviderService#onBeginGetCredential}
+     * credential retrieval requests.
+     *
+     * @param beginGetCredentialOption the request option for which this credential entry is
+     *                                 being constructed This helps maintain an association,
+     *                                 such that when the user selects this entry, providers
+     *                                 can receive the conmplete corresponding request.
+     * @param slice the slice containing the metadata to be shown on the UI. Must be
+     *              constructed through the androidx.credentials jetpack library.
+     */
+    public CredentialEntry(@NonNull BeginGetCredentialOption beginGetCredentialOption,
+            @NonNull Slice slice) {
+        mBeginGetCredentialOption = requireNonNull(beginGetCredentialOption,
+                "beginGetCredentialOption must not be null");
+        mType = requireNonNull(mBeginGetCredentialOption.getType(),
+                "type must not be null");
+        mSlice = requireNonNull(slice, "slice must not be null");
+    }
+
+    /**
+     * Creates an entry that is independent of an incoming {@link BeginGetCredentialOption}
+     * request. Providers must use this constructor for constructing entries to be registered
+     * with the framework outside of the span of an API call.
+     *
+     * @param type the type of the credential
+     * @param slice the slice containing the metadata to be shown on the UI. Must be
+     *              constructed through the androidx.credentials jetpack library.
+     *
+     * @hide
+     */
+    // TODO: Unhide this constructor when the registry APIs are stable
     public CredentialEntry(@NonNull String type, @NonNull Slice slice) {
-        mType = type;
-        mSlice = slice;
+        mBeginGetCredentialOption = null;
+        mType = requireNonNull(type, "type must not be null");
+        mSlice = requireNonNull(slice, "slice must not be null");
     }
 
     private CredentialEntry(@NonNull Parcel in) {
         mType = in.readString8();
         mSlice = in.readTypedObject(Slice.CREATOR);
+        mBeginGetCredentialOption = in.readTypedObject(BeginGetCredentialOption.CREATOR);
     }
 
     @NonNull
@@ -85,6 +135,15 @@
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeString8(mType);
         dest.writeTypedObject(mSlice, flags);
+        dest.writeTypedObject(mBeginGetCredentialOption, flags);
+    }
+
+    /**
+     * Returns the request option for which this credential entry has been constructed.
+     */
+    @NonNull
+    public BeginGetCredentialOption getBeginGetCredentialOption() {
+        return mBeginGetCredentialOption;
     }
 
     /**
diff --git a/core/java/android/service/credentials/CredentialProviderInfo.java b/core/java/android/service/credentials/CredentialProviderInfo.java
index 6a10a6a..ce8bd0c 100644
--- a/core/java/android/service/credentials/CredentialProviderInfo.java
+++ b/core/java/android/service/credentials/CredentialProviderInfo.java
@@ -175,7 +175,8 @@
                         serviceInfo.packageName,
                         PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY));
                 if (appInfo != null
-                        && context.checkPermission(Manifest.permission.SYSTEM_CREDENTIAL_PROVIDER,
+                        && context.checkPermission(
+                                Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE,
                         /*pId=*/-1, appInfo.uid) == PackageManager.PERMISSION_GRANTED) {
                     services.add(new CredentialProviderInfo(context, serviceInfo,
                             /*isSystemProvider=*/true));
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index ee386c3..dabf08e 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -90,14 +90,15 @@
     /**
      * Intent extra: The result of an authentication flow, to be set on finish of the
      * {@link android.app.Activity} invoked through the {@link android.app.PendingIntent} set on
-     * a {@link BeginGetCredentialResponse}. This result should contain the actual content,
+     * an authentication {@link Action}, as part of the original
+     * {@link BeginGetCredentialResponse}. This result should contain the actual content,
      * including credential entries and action entries, to be shown on the selector.
      *
      * <p>
-     * Type: {@link CredentialsResponseContent}
+     * Type: {@link BeginGetCredentialResponse}
      */
-    public static final String EXTRA_CREDENTIALS_RESPONSE_CONTENT =
-            "android.service.credentials.extra.CREDENTIALS_RESPONSE_CONTENT";
+    public static final String EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE =
+            "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_RESPONSE";
 
     /**
      * Intent extra: The failure exception set at the final stage of a get flow.
@@ -133,7 +134,7 @@
      * <p>When a provider app receives a {@link BeginGetCredentialRequest} through the
      * {@link CredentialProviderService#onBeginGetCredential} call, it can construct the
      * {@link BeginGetCredentialResponse} with either an authentication {@link Action} (if the app
-     * is locked), or a {@link CredentialsResponseContent} (if the app is unlocked). In the former
+     * is locked), or a {@link BeginGetCredentialResponse} (if the app is unlocked). In the former
      * case, i.e. the app is locked, user will be shown the authentication action. When selected,
      * the underlying {@link PendingIntent} will be invoked which will lead the user to provider's
      * unlock activity. This pending intent will also contain the original
@@ -141,7 +142,7 @@
      * flow is complete.
      *
      * <p>After the app is unlocked, the {@link BeginGetCredentialResponse} must be constructed
-     * using a {@link CredentialsResponseContent}, which must be set on an {@link Intent} as an
+     * using a {@link BeginGetCredentialResponse}, which must be set on an {@link Intent} as an
      * intent extra against CredentialProviderService#EXTRA_CREDENTIALS_RESPONSE_CONTENT}.
      * This intent should then be set as a result through {@link android.app.Activity#setResult}
      * before finishing the activity.
@@ -308,7 +309,7 @@
      *
      * <p>This API denotes a query stage request for getting user's credentials from a given
      * credential provider. The request contains a list of
-     * {@link android.credentials.GetCredentialOption} that have parameters to be used for
+     * {@link BeginGetCredentialOption} that have parameters to be used for
      * populating candidate credentials, as a list of {@link CredentialEntry} to be set
      * on the {@link BeginGetCredentialResponse}. This list is then shown to the user on a
      * selector.
diff --git a/core/java/android/service/credentials/CredentialsResponseContent.java b/core/java/android/service/credentials/CredentialsResponseContent.java
deleted file mode 100644
index ce6972d..0000000
--- a/core/java/android/service/credentials/CredentialsResponseContent.java
+++ /dev/null
@@ -1,206 +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 android.service.credentials;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.Preconditions;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * The content to be displayed on the account selector UI, including credential entries,
- * actions etc. Returned as part of {@link BeginGetCredentialResponse}
- */
-public final class CredentialsResponseContent implements Parcelable {
-    /** List of credential entries to be displayed on the UI. */
-    private final @NonNull List<CredentialEntry> mCredentialEntries;
-
-    /** List of provider actions to be displayed on the UI. */
-    private final @NonNull List<Action> mActions;
-
-    /** Remote credential entry to get the response from a different device. */
-    private final @Nullable CredentialEntry mRemoteCredentialEntry;
-
-    private CredentialsResponseContent(@NonNull List<CredentialEntry> credentialEntries,
-            @NonNull List<Action> actions,
-            @Nullable CredentialEntry remoteCredentialEntry) {
-        mCredentialEntries = credentialEntries;
-        mActions = actions;
-        mRemoteCredentialEntry = remoteCredentialEntry;
-    }
-
-    private CredentialsResponseContent(@NonNull Parcel in) {
-        List<CredentialEntry> credentialEntries = new ArrayList<>();
-        in.readTypedList(credentialEntries, CredentialEntry.CREATOR);
-        mCredentialEntries = credentialEntries;
-        List<Action> actions = new ArrayList<>();
-        in.readTypedList(actions, Action.CREATOR);
-        mActions = actions;
-        mRemoteCredentialEntry = in.readTypedObject(CredentialEntry.CREATOR);
-    }
-
-    public static final @NonNull Creator<CredentialsResponseContent> CREATOR =
-            new Creator<CredentialsResponseContent>() {
-                @Override
-                public CredentialsResponseContent createFromParcel(@NonNull Parcel in) {
-                    return new CredentialsResponseContent(in);
-                }
-
-                @Override
-                public CredentialsResponseContent[] newArray(int size) {
-                    return new CredentialsResponseContent[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeTypedList(mCredentialEntries, flags);
-        dest.writeTypedList(mActions, flags);
-        dest.writeTypedObject(mRemoteCredentialEntry, flags);
-    }
-
-    /**
-     * Returns the list of credential entries to be displayed on the UI.
-     */
-    public @NonNull List<CredentialEntry> getCredentialEntries() {
-        return mCredentialEntries;
-    }
-
-    /**
-     * Returns the list of actions to be displayed on the UI.
-     */
-    public @NonNull List<Action> getActions() {
-        return mActions;
-    }
-
-    /**
-     * Returns the remote credential entry to be displayed on the UI.
-     */
-    public @Nullable CredentialEntry getRemoteCredentialEntry() {
-        return mRemoteCredentialEntry;
-    }
-
-    /**
-     * Builds an instance of {@link CredentialsResponseContent}.
-     */
-    public static final class Builder {
-        private List<CredentialEntry> mCredentialEntries = new ArrayList<>();
-        private List<Action> mActions = new ArrayList<>();
-        private CredentialEntry mRemoteCredentialEntry;
-
-        /**
-         * Sets a remote credential entry to be shown on the UI. Provider must set this if they
-         * wish to get the credential from a different device.
-         *
-         * <p> When constructing the {@link CredentialEntry} object, the {@code pendingIntent}
-         * must be set such that it leads to an activity that can provide UI to fulfill the request
-         * on a remote device. When user selects this {@code remoteCredentialEntry}, the system will
-         * invoke the {@code pendingIntent} set on the {@link CredentialEntry}.
-         *
-         * <p> Once the remote credential flow is complete, the {@link android.app.Activity}
-         * result should be set to {@link android.app.Activity#RESULT_OK} and an extra with the
-         * {@link CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE} key should be populated
-         * with a {@link android.credentials.Credential} object.
-         */
-        public @NonNull Builder setRemoteCredentialEntry(@Nullable CredentialEntry
-                remoteCredentialEntry) {
-            mRemoteCredentialEntry = remoteCredentialEntry;
-            return this;
-        }
-
-        /**
-         * Adds a {@link CredentialEntry} to the list of entries to be displayed on
-         * the UI.
-         *
-         * @throws NullPointerException If the {@code credentialEntry} is null.
-         */
-        public @NonNull Builder addCredentialEntry(@NonNull CredentialEntry credentialEntry) {
-            mCredentialEntries.add(Objects.requireNonNull(credentialEntry));
-            return this;
-        }
-
-        /**
-         * Adds an {@link Action} to the list of actions to be displayed on
-         * the UI.
-         *
-         * <p> An {@code action} must be used for independent user actions,
-         * such as opening the app, intenting directly into a certain app activity etc. The
-         * {@code pendingIntent} set with the {@code action} must invoke the corresponding
-         * activity.
-         *
-         * @throws NullPointerException If {@code action} is null.
-         */
-        public @NonNull Builder addAction(@NonNull Action action) {
-            mActions.add(Objects.requireNonNull(action, "action must not be null"));
-            return this;
-        }
-
-        /**
-         * Sets the list of actions to be displayed on the UI.
-         *
-         * @throws NullPointerException If {@code actions} is null, or any of its elements
-         * is null.
-         */
-        public @NonNull Builder setActions(@NonNull List<Action> actions) {
-            mActions = Preconditions.checkCollectionElementsNotNull(actions,
-                    "actions");
-            return this;
-        }
-
-        /**
-         * Sets the list of credential entries to be displayed on the
-         * account selector UI.
-         *
-         * @throws NullPointerException If {@code credentialEntries} is null, or any of its
-         * elements is null.
-         */
-        public @NonNull Builder setCredentialEntries(
-                @NonNull List<CredentialEntry> credentialEntries) {
-            mCredentialEntries = Preconditions.checkCollectionElementsNotNull(
-                    credentialEntries,
-                    "credentialEntries");
-            return this;
-        }
-
-        /**
-         * Builds a {@link CredentialsResponseContent} instance.
-         *
-         * @throws IllegalStateException if {@code credentialEntries}, {@code actions}
-         * and {@code remoteCredentialEntry} are all null or empty.
-         */
-        public @NonNull CredentialsResponseContent build() {
-            if (mCredentialEntries != null && mCredentialEntries.isEmpty()
-                    && mActions != null && mActions.isEmpty() && mRemoteCredentialEntry == null) {
-                throw new IllegalStateException("credentialEntries and actions must not both "
-                        + "be empty");
-            }
-            return new CredentialsResponseContent(mCredentialEntries, mActions,
-                    mRemoteCredentialEntry);
-        }
-    }
-}
diff --git a/core/java/android/service/credentials/GetCredentialRequest.java b/core/java/android/service/credentials/GetCredentialRequest.java
index 4b946f0..7cdccc6 100644
--- a/core/java/android/service/credentials/GetCredentialRequest.java
+++ b/core/java/android/service/credentials/GetCredentialRequest.java
@@ -17,7 +17,7 @@
 package android.service.credentials;
 
 import android.annotation.NonNull;
-import android.credentials.GetCredentialOption;
+import android.credentials.CredentialOption;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -32,28 +32,30 @@
  */
 public final class GetCredentialRequest implements Parcelable {
     /** Calling package of the app requesting for credentials. */
-    private final @NonNull CallingAppInfo mCallingAppInfo;
+    @NonNull
+    private final CallingAppInfo mCallingAppInfo;
 
     /**
      * Holds parameters to be used for retrieving a specific type of credential.
      */
-    private final @NonNull GetCredentialOption mGetCredentialOption;
+    @NonNull
+    private final CredentialOption mCredentialOption;
 
     public GetCredentialRequest(@NonNull CallingAppInfo callingAppInfo,
-            @NonNull GetCredentialOption getCredentialOption) {
+            @NonNull CredentialOption credentialOption) {
         this.mCallingAppInfo = callingAppInfo;
-        this.mGetCredentialOption = getCredentialOption;
+        this.mCredentialOption = credentialOption;
     }
 
     private GetCredentialRequest(@NonNull Parcel in) {
         mCallingAppInfo = in.readTypedObject(CallingAppInfo.CREATOR);
         AnnotationValidations.validate(NonNull.class, null, mCallingAppInfo);
-        mGetCredentialOption = in.readTypedObject(GetCredentialOption.CREATOR);
-        AnnotationValidations.validate(NonNull.class, null, mGetCredentialOption);
+        mCredentialOption = in.readTypedObject(CredentialOption.CREATOR);
+        AnnotationValidations.validate(NonNull.class, null, mCredentialOption);
     }
 
-    public static final @NonNull Creator<GetCredentialRequest> CREATOR =
-            new Creator<GetCredentialRequest>() {
+    @NonNull public static final  Creator<GetCredentialRequest> CREATOR =
+            new Creator<>() {
                 @Override
                 public GetCredentialRequest createFromParcel(Parcel in) {
                     return new GetCredentialRequest(in);
@@ -73,20 +75,22 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeTypedObject(mCallingAppInfo, flags);
-        dest.writeTypedObject(mGetCredentialOption, flags);
+        dest.writeTypedObject(mCredentialOption, flags);
     }
 
     /**
      * Returns info pertaining to the app requesting credentials.
      */
-    public @NonNull CallingAppInfo getCallingAppInfo() {
+    @NonNull
+    public CallingAppInfo getCallingAppInfo() {
         return mCallingAppInfo;
     }
 
     /**
      * Returns the parameters needed to return a given type of credential.
      */
-    public @NonNull GetCredentialOption getGetCredentialOption() {
-        return mGetCredentialOption;
+    @NonNull
+    public CredentialOption getCredentialOption() {
+        return mCredentialOption;
     }
 }
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 6a4710f..d79ea89 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -234,6 +234,7 @@
     private boolean mCanDoze;
     private boolean mDozing;
     private boolean mWindowless;
+    private boolean mOverlayFinishing;
     private int mDozeScreenState = Display.STATE_UNKNOWN;
     private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
 
@@ -1051,6 +1052,7 @@
         // We must unbind from any overlay connection if we are unbound before finishing.
         if (mOverlayConnection != null) {
             mOverlayConnection.unbind();
+            mOverlayConnection = null;
         }
 
         return super.onUnbind(intent);
@@ -1067,7 +1069,9 @@
         // If there is an active overlay connection, signal that the dream is ending before
         // continuing. Note that the overlay cannot rely on the unbound state, since another dream
         // might have bound to it in the meantime.
-        if (mOverlayConnection != null) {
+        if (mOverlayConnection != null && !mOverlayFinishing) {
+            // Set mOverlayFinish to true to only allow this consumer to be added once.
+            mOverlayFinishing = true;
             mOverlayConnection.addConsumer(overlay -> {
                 try {
                     overlay.endDream();
@@ -1300,9 +1304,10 @@
      * Must run on mHandler.
      *
      * @param dreamToken Token for this dream service.
-     * @param started A callback that will be invoked once onDreamingStarted has completed.
+     * @param started    A callback that will be invoked once onDreamingStarted has completed.
      */
-    private void attach(IBinder dreamToken, boolean canDoze, IRemoteCallback started) {
+    private void attach(IBinder dreamToken, boolean canDoze, boolean isPreviewMode,
+            IRemoteCallback started) {
         if (mDreamToken != null) {
             Slog.e(mTag, "attach() called when dream with token=" + mDreamToken
                     + " already attached");
@@ -1350,7 +1355,8 @@
             i.putExtra(DreamActivity.EXTRA_CALLBACK, new DreamActivityCallbacks(mDreamToken));
             final ServiceInfo serviceInfo = fetchServiceInfo(this,
                     new ComponentName(this, getClass()));
-            i.putExtra(DreamActivity.EXTRA_DREAM_TITLE, fetchDreamLabel(this, serviceInfo));
+            i.putExtra(DreamActivity.EXTRA_DREAM_TITLE,
+                    fetchDreamLabel(this, serviceInfo, isPreviewMode));
 
             try {
                 if (!ActivityTaskManager.getService().startDreamActivity(i)) {
@@ -1466,10 +1472,18 @@
 
     @Nullable
     private static CharSequence fetchDreamLabel(Context context,
-            @Nullable ServiceInfo serviceInfo) {
-        if (serviceInfo == null) return null;
+            @Nullable ServiceInfo serviceInfo,
+            boolean isPreviewMode) {
+        if (serviceInfo == null) {
+            return null;
+        }
         final PackageManager pm = context.getPackageManager();
-        return serviceInfo.loadLabel(pm);
+        final CharSequence dreamLabel = serviceInfo.loadLabel(pm);
+        if (!isPreviewMode || dreamLabel == null) {
+            return dreamLabel;
+        }
+        // When in preview mode, return a special label indicating the dream is in preview.
+        return context.getResources().getString(R.string.dream_preview_title, dreamLabel);
     }
 
     @Nullable
@@ -1525,8 +1539,9 @@
     final class DreamServiceWrapper extends IDreamService.Stub {
         @Override
         public void attach(final IBinder dreamToken, final boolean canDoze,
-                IRemoteCallback started) {
-            mHandler.post(() -> DreamService.this.attach(dreamToken, canDoze, started));
+                final boolean isPreviewMode, IRemoteCallback started) {
+            mHandler.post(
+                    () -> DreamService.this.attach(dreamToken, canDoze, isPreviewMode, started));
         }
 
         @Override
diff --git a/core/java/android/service/dreams/IDreamService.aidl b/core/java/android/service/dreams/IDreamService.aidl
index ce04354..8b5d875 100644
--- a/core/java/android/service/dreams/IDreamService.aidl
+++ b/core/java/android/service/dreams/IDreamService.aidl
@@ -22,7 +22,7 @@
  * @hide
  */
 oneway interface IDreamService {
-    void attach(IBinder windowToken, boolean canDoze, IRemoteCallback started);
+    void attach(IBinder windowToken, boolean canDoze, boolean isPreviewMode, IRemoteCallback started);
     void detach();
     void wakeUp();
 }
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index df185ee..3807685 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -52,7 +52,7 @@
     /** @hide */
     @StringDef (prefix = { "KEY_" }, value = {
             KEY_CONTEXTUAL_ACTIONS, KEY_GROUP_KEY, KEY_IMPORTANCE, KEY_PEOPLE, KEY_SNOOZE_CRITERIA,
-            KEY_TEXT_REPLIES, KEY_USER_SENTIMENT, KEY_IMPORTANCE_PROPOSAL
+            KEY_TEXT_REPLIES, KEY_USER_SENTIMENT, KEY_IMPORTANCE_PROPOSAL, KEY_SENSITIVE_CONTENT
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Keys {}
@@ -134,6 +134,13 @@
     public static final String KEY_IMPORTANCE_PROPOSAL = "key_importance_proposal";
 
     /**
+     * Data type: boolean, when true it suggests that the content text of this notification is
+     * sensitive. A notification listener can use this information to redact notifications on locked
+     * devices.
+     */
+    public static final String KEY_SENSITIVE_CONTENT = "key_sensitive_content";
+
+    /**
      * Data type: float, a ranking score from 0 (lowest) to 1 (highest).
      * Used to rank notifications inside that fall under the same classification (i.e. alerting,
      * silenced).
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 11e51ad..4bc0d22 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1732,10 +1732,13 @@
         private boolean mIsBubble;
         // Notification assistant importance suggestion
         private int mProposedImportance;
+        // Sensitive info detected by the notification assistant
+        private boolean mSensitiveContent;
 
         private static final int PARCEL_VERSION = 2;
 
-        public Ranking() { }
+        public Ranking() {
+        }
 
         // You can parcel it, but it's not Parcelable
         /** @hide */
@@ -1770,6 +1773,7 @@
             out.writeInt(mRankingAdjustment);
             out.writeBoolean(mIsBubble);
             out.writeInt(mProposedImportance);
+            out.writeBoolean(mSensitiveContent);
         }
 
         /** @hide */
@@ -1809,6 +1813,7 @@
             mRankingAdjustment = in.readInt();
             mIsBubble = in.readBoolean();
             mProposedImportance = in.readInt();
+            mSensitiveContent = in.readBoolean();
         }
 
 
@@ -1918,6 +1923,17 @@
         }
 
         /**
+         * Returns true if the notification text is sensitive (e.g. containing an OTP).
+         *
+         * @return whether the notification contains sensitive content
+         * @hide
+         */
+        @SystemApi
+        public boolean hasSensitiveContent() {
+            return mSensitiveContent;
+        }
+
+        /**
          * If the system has overridden the group key, then this will be non-null, and this
          * key should be used to bundle notifications.
          */
@@ -2081,7 +2097,8 @@
                 boolean noisy, ArrayList<Notification.Action> smartActions,
                 ArrayList<CharSequence> smartReplies, boolean canBubble,
                 boolean isTextChanged, boolean isConversation, ShortcutInfo shortcutInfo,
-                int rankingAdjustment, boolean isBubble, int proposedImportance) {
+                int rankingAdjustment, boolean isBubble, int proposedImportance,
+                boolean sensitiveContent) {
             mKey = key;
             mRank = rank;
             mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -2108,6 +2125,7 @@
             mRankingAdjustment = rankingAdjustment;
             mIsBubble = isBubble;
             mProposedImportance = proposedImportance;
+            mSensitiveContent = sensitiveContent;
         }
 
         /**
@@ -2149,7 +2167,8 @@
                     other.mShortcutInfo,
                     other.mRankingAdjustment,
                     other.mIsBubble,
-                    other.mProposedImportance);
+                    other.mProposedImportance,
+                    other.mSensitiveContent);
         }
 
         /**
@@ -2209,7 +2228,8 @@
                     (other.mShortcutInfo == null ? 0 : other.mShortcutInfo.getId()))
                     && Objects.equals(mRankingAdjustment, other.mRankingAdjustment)
                     && Objects.equals(mIsBubble, other.mIsBubble)
-                    && Objects.equals(mProposedImportance, other.mProposedImportance);
+                    && Objects.equals(mProposedImportance, other.mProposedImportance)
+                    && Objects.equals(mSensitiveContent, other.mSensitiveContent);
         }
     }
 
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index e2c84dc..bb56939 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -298,6 +298,16 @@
     }
 
     /**
+     * @hide
+     *
+     * Convenience method to check the notification's flags for
+     * {@link Notification#FLAG_NO_DISMISS}.
+     */
+    public boolean isNonDismissable() {
+        return (notification.flags & Notification.FLAG_NO_DISMISS) != 0;
+    }
+
+    /**
      * Convenience method to check the notification's flags for
      * either {@link Notification#FLAG_ONGOING_EVENT} or
      * {@link Notification#FLAG_NO_CLEAR}.
diff --git a/core/java/android/service/quickaccesswallet/WalletCard.java b/core/java/android/service/quickaccesswallet/WalletCard.java
index 950f9b5..e52adcc 100644
--- a/core/java/android/service/quickaccesswallet/WalletCard.java
+++ b/core/java/android/service/quickaccesswallet/WalletCard.java
@@ -36,7 +36,7 @@
  * card, library card, transit pass, etc. Cards are identified by a String identifier and contain a
  * card type, card image, card image content description, and a {@link PendingIntent} to be used if
  * the user clicks on the card. Cards may be displayed with an icon and label, though these are
- * optional. Valuable cards will also have a second image that will be displayed when the card is
+ * optional. Non-payment cards will also have a second image that will be displayed when the card is
  * tapped.
  */
 
@@ -54,10 +54,10 @@
     public static final int CARD_TYPE_PAYMENT = 1;
 
     /**
-     * Valuable cards refer to any cards that are not used for cash-equivalent payment.
-     * This includes event tickets, flights, offers, loyalty cards, gift cards and transit tickets.
+     * Non-payment cards refer to any cards that are not used for cash-equivalent payment, including
+     * event tickets, flights, offers, loyalty cards, gift cards and transit tickets.
      */
-    public static final int CARD_TYPE_VALUABLE = 2;
+    public static final int CARD_TYPE_NON_PAYMENT = 2;
 
     private final String mCardId;
     private final int mCardType;
@@ -66,7 +66,7 @@
     private final PendingIntent mPendingIntent;
     private final Icon mCardIcon;
     private final CharSequence mCardLabel;
-    private final Icon mValuableCardSecondaryImage;
+    private final Icon mNonPaymentCardSecondaryImage;
 
     private WalletCard(Builder builder) {
         this.mCardId = builder.mCardId;
@@ -76,7 +76,7 @@
         this.mPendingIntent = builder.mPendingIntent;
         this.mCardIcon = builder.mCardIcon;
         this.mCardLabel = builder.mCardLabel;
-        this.mValuableCardSecondaryImage = builder.mValuableCardSecondaryImage;
+        this.mNonPaymentCardSecondaryImage = builder.mNonPaymentCardSecondaryImage;
     }
 
     /**
@@ -86,7 +86,7 @@
     @IntDef(prefix = {"CARD_TYPE_"}, value = {
             CARD_TYPE_UNKNOWN,
             CARD_TYPE_PAYMENT,
-            CARD_TYPE_VALUABLE
+            CARD_TYPE_NON_PAYMENT
     })
     public @interface CardType {
     }
@@ -105,7 +105,7 @@
         PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, dest);
         writeIconIfNonNull(mCardIcon, dest, flags);
         TextUtils.writeToParcel(mCardLabel, dest, flags);
-        writeIconIfNonNull(mValuableCardSecondaryImage, dest, flags);
+        writeIconIfNonNull(mNonPaymentCardSecondaryImage, dest, flags);
 
     }
 
@@ -128,14 +128,14 @@
         PendingIntent pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(source);
         Icon cardIcon = source.readByte() == 0 ? null : Icon.CREATOR.createFromParcel(source);
         CharSequence cardLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-        Icon valuableCardSecondaryImage = source.readByte() == 0 ? null :
+        Icon nonPaymentCardSecondaryImage = source.readByte() == 0 ? null :
                 Icon.CREATOR.createFromParcel(source);
         Builder builder = new Builder(cardId, cardType, cardImage, contentDesc, pendingIntent)
                 .setCardIcon(cardIcon)
                 .setCardLabel(cardLabel);
 
-        return cardType == CARD_TYPE_VALUABLE
-                ? builder.setValuableCardSecondaryImage(valuableCardSecondaryImage).build() :
+        return cardType == CARD_TYPE_NON_PAYMENT
+                ? builder.setNonPaymentCardSecondaryImage(nonPaymentCardSecondaryImage).build() :
                  builder.build();
     }
 
@@ -225,12 +225,12 @@
     }
 
     /**
-    * Visual representation of the card when it is tapped. Includes a barcode to scan the card in
-     * addition to the information in the primary image.
-    */
+     * Visual representation of the card when it is tapped. May include additional information
+     *  unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT.
+     */
     @Nullable
-    public Icon getValuableCardSecondaryImage() {
-        return mValuableCardSecondaryImage;
+    public Icon getNonPaymentCardSecondaryImage() {
+        return mNonPaymentCardSecondaryImage;
     }
 
     /**
@@ -246,7 +246,7 @@
         private PendingIntent mPendingIntent;
         private Icon mCardIcon;
         private CharSequence mCardLabel;
-        private Icon mValuableCardSecondaryImage;
+        private Icon mNonPaymentCardSecondaryImage;
 
         /**
          * @param cardId             The card id must be non-null and unique within the list of
@@ -254,7 +254,7 @@
          *                           </b> this card ID should <b>not</b> contain PII (Personally
          *                           Identifiable Information, such as username or email address).
          * @param cardType           Integer representing the card type. The card type must be
-         *                           non-null. If not provided, it defaults to unknown.
+         *                           non-null.
          * @param cardImage          The visual representation of the card. If the card image Icon
          *                           is a bitmap, it should have a width of {@link
          *                           GetWalletCardsRequest#getCardWidthPx()} and a height of {@link
@@ -289,8 +289,8 @@
         }
 
         /**
-         * Called when a card type is not provided. Calls {@link
-         * Builder#Builder(String, int, Icon, CharSequence, PendingIntent)} with default card type
+         * Called when a card type is not provided, in which case it defaults to CARD_TYPE_UNKNOWN.
+         * Calls {@link Builder#Builder(String, int, Icon, CharSequence, PendingIntent)}
          */
         public Builder(@NonNull String cardId,
                 @NonNull Icon cardImage,
@@ -332,14 +332,15 @@
         }
 
         /**
-         * Visual representation of the card when it is tapped. Includes a barcode to scan the card
-         * in addition to the information in the primary image.
+         * Visual representation of the card when it is tapped. May include additional information
+         *  unique to the card, such as a barcode or number. Only valid for CARD_TYPE_NON_PAYMENT.
          */
         @NonNull
-        public Builder setValuableCardSecondaryImage(@Nullable Icon valuableCardSecondaryImage) {
-            Preconditions.checkState(mCardType == CARD_TYPE_VALUABLE,
-                    "This field can only be set on valuable cards");
-            mValuableCardSecondaryImage = valuableCardSecondaryImage;
+        public Builder
+                setNonPaymentCardSecondaryImage(@Nullable Icon nonPaymentCardSecondaryImage) {
+            Preconditions.checkState(mCardType == CARD_TYPE_NON_PAYMENT,
+                    "This field can only be set on non-payment cards");
+            mNonPaymentCardSecondaryImage = nonPaymentCardSecondaryImage;
             return this;
         }
 
diff --git a/core/java/android/service/remotelockscreenvalidation/IRemoteLockscreenValidationCallback.aidl b/core/java/android/service/remotelockscreenvalidation/IRemoteLockscreenValidationCallback.aidl
new file mode 100644
index 0000000..fa4a75c
--- /dev/null
+++ b/core/java/android/service/remotelockscreenvalidation/IRemoteLockscreenValidationCallback.aidl
@@ -0,0 +1,12 @@
+package android.service.remotelockscreenvalidation;
+
+import android.app.RemoteLockscreenValidationResult;
+
+/**
+* Callback interface for remote device lockscreen validation
+* @hide
+*/
+interface IRemoteLockscreenValidationCallback {
+    oneway void onSuccess(in RemoteLockscreenValidationResult result);
+    oneway void onFailure(in String message);
+}
diff --git a/core/java/android/service/remotelockscreenvalidation/IRemoteLockscreenValidationService.aidl b/core/java/android/service/remotelockscreenvalidation/IRemoteLockscreenValidationService.aidl
new file mode 100644
index 0000000..530e5ce
--- /dev/null
+++ b/core/java/android/service/remotelockscreenvalidation/IRemoteLockscreenValidationService.aidl
@@ -0,0 +1,12 @@
+package android.service.remotelockscreenvalidation;
+
+import android.app.RemoteLockscreenValidationResult;
+import android.service.remotelockscreenvalidation.IRemoteLockscreenValidationCallback;
+
+/**
+* Interface used by the System to validate remote device lockscreen.
+* {@hide}
+*/
+interface IRemoteLockscreenValidationService {
+    void validateLockscreenGuess(in byte[] guess, in IRemoteLockscreenValidationCallback callback);
+}
diff --git a/core/java/android/service/remotelockscreenvalidation/OWNERS b/core/java/android/service/remotelockscreenvalidation/OWNERS
new file mode 100644
index 0000000..cfa0585
--- /dev/null
+++ b/core/java/android/service/remotelockscreenvalidation/OWNERS
@@ -0,0 +1,2 @@
+include /services/core/java/com/android/server/locksettings/recoverablekeystore/OWNERS
+brnlee@google.com
\ No newline at end of file
diff --git a/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationClient.java b/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationClient.java
new file mode 100644
index 0000000..e06b0cd
--- /dev/null
+++ b/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationClient.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.remotelockscreenvalidation;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Client for {@link RemoteLockscreenValidationService}
+ * @hide
+ */
+public interface RemoteLockscreenValidationClient {
+
+    /**
+     * Create a client for the {@link RemoteLockscreenValidationService} specified by the
+     * {@link ComponentName}
+     * @hide
+     */
+    @NonNull
+    static RemoteLockscreenValidationClient create(@NonNull Context context,
+            @NonNull ComponentName serviceComponent) {
+        return new RemoteLockscreenValidationClientImpl(
+                context,
+                /* bgExecutor= */ null,
+                serviceComponent);
+    }
+
+    /**
+     * Create a client for the {@link RemoteLockscreenValidationService} specified by the
+     * {@link ComponentName}
+     * @param context Context.
+     * @param bgExecutor A background {@link Executor} for service registration.
+     * @hide
+     */
+    @NonNull
+    static RemoteLockscreenValidationClient create(@NonNull Context context,
+            @Nullable Executor bgExecutor, @NonNull ComponentName serviceComponent) {
+        return new RemoteLockscreenValidationClientImpl(context, bgExecutor, serviceComponent);
+    }
+
+    /**
+     * Returns whether the {@link RemoteLockscreenValidationService} defined by the
+     * {@code ComponentName} provided in the constructor is available.
+     *
+     * <p>Calling API methods like {@link #validateLockscreenGuess} will fail if unavailable.
+     */
+    boolean isServiceAvailable();
+
+    /**
+     * Unbinds from the {@link RemoteLockscreenValidationService}
+     */
+    void disconnect();
+
+    /**
+     * Validates the lockscreen guess.
+     *
+     * @param guess lockscreen guess
+     * @param callback object used to relay the response of the guess validation
+     */
+    void validateLockscreenGuess(byte[] guess, IRemoteLockscreenValidationCallback callback);
+}
diff --git a/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationClientImpl.java b/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationClientImpl.java
new file mode 100644
index 0000000..140ef39
--- /dev/null
+++ b/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationClientImpl.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.remotelockscreenvalidation;
+
+import static android.service.remotelockscreenvalidation.RemoteLockscreenValidationService.SERVICE_INTERFACE;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Queue;
+import java.util.concurrent.Executor;
+
+/**
+ * Implements {@link RemoteLockscreenValidationClient}.
+ *
+ * @hide
+ */
+public class RemoteLockscreenValidationClientImpl implements RemoteLockscreenValidationClient,
+        ServiceConnection {
+
+    private static final String TAG = RemoteLockscreenValidationClientImpl.class.getSimpleName();
+    private final Handler mHandler;
+    private final Context mContext;
+    private final Queue<Call> mRequestQueue;
+    private final Executor mLifecycleExecutor;
+    private final boolean mIsServiceAvailable;
+    private boolean mIsConnected;
+
+    @Nullable
+    private IRemoteLockscreenValidationService mService;
+
+    @Nullable
+    private ServiceInfo mServiceInfo;
+
+    RemoteLockscreenValidationClientImpl(
+            @NonNull Context context,
+            @Nullable Executor bgExecutor,
+            @NonNull ComponentName serviceComponent) {
+        mContext = context.getApplicationContext();
+        mIsServiceAvailable = isServiceAvailable(mContext, serviceComponent);
+        mHandler = new Handler(Looper.getMainLooper());
+        mLifecycleExecutor = (bgExecutor == null) ? Runnable::run : bgExecutor;
+        mRequestQueue = new ArrayDeque<>();
+    }
+
+    @Override
+    public boolean isServiceAvailable() {
+        return mIsServiceAvailable;
+    }
+
+    @Override
+    public void validateLockscreenGuess(
+            byte[] guess, IRemoteLockscreenValidationCallback callback) {
+        try {
+            if (!isServiceAvailable()) {
+                callback.onFailure("Service is not available");
+                return;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error while failing for service unavailable", e);
+        }
+
+        executeApiCall(new Call() {
+            @Override
+            public void exec(IRemoteLockscreenValidationService service) throws RemoteException {
+                service.validateLockscreenGuess(guess, callback);
+            }
+
+            @Override
+            void onError(String msg) {
+                try {
+                    callback.onFailure(msg);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error while failing validateLockscreenGuess", e);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void disconnect() {
+        mHandler.post(this::disconnectInternal);
+    }
+
+    private void disconnectInternal() {
+        if (!mIsConnected) {
+            Log.w(TAG, "already disconnected");
+            return;
+        }
+        mIsConnected = false;
+        mLifecycleExecutor.execute(() -> mContext.unbindService(/* conn= */ this));
+        mService = null;
+        mRequestQueue.clear();
+    }
+
+    private void connect() {
+        mHandler.post(this::connectInternal);
+    }
+
+    private void connectInternal() {
+        if (mServiceInfo == null) {
+            Log.w(TAG, "RemoteLockscreenValidation service unavailable");
+            return;
+        }
+        if (mIsConnected) {
+            return;
+        }
+        mIsConnected = true;
+        Intent intent = new Intent(SERVICE_INTERFACE);
+        intent.setComponent(mServiceInfo.getComponentName());
+        int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY;
+        mLifecycleExecutor.execute(() -> mContext.bindService(intent, this, flags));
+    }
+
+    private void onConnectedInternal(IRemoteLockscreenValidationService service) {
+        if (!mIsConnected) {
+            Log.w(TAG, "onConnectInternal but connection closed");
+            mService = null;
+            return;
+        }
+        mService = service;
+        for (Call call : new ArrayList<>(mRequestQueue)) {
+            performApiCallInternal(call, mService);
+            mRequestQueue.remove(call);
+        }
+    }
+
+    private boolean isServiceAvailable(
+            @NonNull Context context,
+            @NonNull ComponentName serviceComponent) {
+        mServiceInfo = getServiceInfo(context, serviceComponent);
+        if (mServiceInfo == null) {
+            return false;
+        }
+
+        if (!Manifest.permission.BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE.equals(
+                mServiceInfo.permission)) {
+            Log.w(TAG, TextUtils.formatSimple("%s/%s does not require permission %s",
+                    mServiceInfo.packageName, mServiceInfo.name,
+                    Manifest.permission.BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE));
+            return false;
+        }
+        return true;
+    }
+
+    private ServiceInfo getServiceInfo(
+            @NonNull Context context, @NonNull ComponentName serviceComponent) {
+        try {
+            return context.getPackageManager().getServiceInfo(serviceComponent,
+                    PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA));
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, TextUtils.formatSimple("Cannot resolve service %s",
+                    serviceComponent.getClass().getName()));
+            return null;
+        }
+    }
+
+    private void executeApiCall(Call call) {
+        mHandler.post(() -> executeInternal(call));
+    }
+
+    private void executeInternal(RemoteLockscreenValidationClientImpl.Call call) {
+        if (mIsConnected && mService != null) {
+            performApiCallInternal(call, mService);
+        } else {
+            mRequestQueue.add(call);
+            connect();
+        }
+    }
+
+    private void performApiCallInternal(
+            RemoteLockscreenValidationClientImpl.Call apiCaller,
+            IRemoteLockscreenValidationService service) {
+        if (service == null) {
+            apiCaller.onError("Service is null");
+            return;
+        }
+        try {
+            apiCaller.exec(service);
+        } catch (RemoteException e) {
+            Log.w(TAG, "executeInternal error", e);
+            apiCaller.onError(e.getMessage());
+            disconnect();
+        }
+    }
+
+    @Override // ServiceConnection
+    public void onServiceConnected(ComponentName name, IBinder binder) {
+        IRemoteLockscreenValidationService service =
+                IRemoteLockscreenValidationService.Stub.asInterface(binder);
+        mHandler.post(() -> onConnectedInternal(service));
+    }
+
+    @Override // ServiceConnection
+    public void onServiceDisconnected(ComponentName name) {
+        // Do not disconnect, as we may later be re-connected
+    }
+
+    @Override // ServiceConnection
+    public void onBindingDied(ComponentName name) {
+        // This is a recoverable error but the client will need to reconnect.
+        disconnect();
+    }
+
+    @Override // ServiceConnection
+    public void onNullBinding(ComponentName name) {
+        disconnect();
+    }
+
+    private abstract static class Call {
+        abstract void exec(IRemoteLockscreenValidationService service)
+                throws RemoteException;
+        abstract void onError(String msg);
+    }
+}
diff --git a/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationService.java b/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationService.java
new file mode 100644
index 0000000..9b588034
--- /dev/null
+++ b/core/java/android/service/remotelockscreenvalidation/RemoteLockscreenValidationService.java
@@ -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 android.service.remotelockscreenvalidation;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.RemoteLockscreenValidationResult;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.OutcomeReceiver;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Provides an interface to validate a remote device's lockscreen
+ * @hide
+ */
+@SystemApi
+public abstract class RemoteLockscreenValidationService extends Service {
+
+    /**
+     * The {@link Intent} that must be declared as handled by the service. To be supported, the
+     * service must also require the
+     * {@link android.Manifest.permission#BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE}
+     * permission so that other applications can not abuse it.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.remotelockscreenvalidation.RemoteLockscreenValidationService";
+    private static final String TAG = RemoteLockscreenValidationService.class.getSimpleName();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final IRemoteLockscreenValidationService mInterface =
+            new IRemoteLockscreenValidationService.Stub() {
+                @Override
+                public void validateLockscreenGuess(
+                        byte[] guess, IRemoteLockscreenValidationCallback callback) {
+                    mHandler.sendMessage(obtainMessage(
+                            RemoteLockscreenValidationService::onValidateLockscreenGuess,
+                            RemoteLockscreenValidationService.this, guess,
+                            new OutcomeReceiver<RemoteLockscreenValidationResult,
+                                    Exception>() {
+                                @Override
+                                public void onResult(RemoteLockscreenValidationResult result) {
+                                    try {
+                                        callback.onSuccess(result);
+                                    } catch (RemoteException e) {
+                                        e.rethrowFromSystemServer();
+                                    }
+                                }
+                                @Override
+                                public void onError(Exception e) {
+                                    try {
+                                        callback.onFailure(e.getMessage());
+                                    } catch (RemoteException ex) {
+                                        ex.rethrowFromSystemServer();
+                                    }
+                                }
+                            }
+                    ));
+                }
+            };
+
+    @Override
+    @Nullable
+    public final IBinder onBind(@NonNull Intent intent) {
+        if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+            Log.w(TAG, "Wrong action");
+            return null;
+        }
+        return mInterface.asBinder();
+    }
+
+    /**
+     * Validates the lockscreen guess.
+     *
+     * <p>Implementation should send guess to remote device and perform lockscreen validation
+     * using {@link android.app.KeyguardManager#validateRemoteLockScreen}.
+     *
+     * @param guess lockscreen guess
+     * @param callback object used to relay the response of the guess validation
+     */
+    public abstract void onValidateLockscreenGuess(@NonNull byte[] guess,
+            @NonNull OutcomeReceiver<RemoteLockscreenValidationResult, Exception> callback);
+}
diff --git a/core/java/android/service/search/ISearchUiService.aidl b/core/java/android/service/search/ISearchUiService.aidl
index aae66ca..bc6d421 100644
--- a/core/java/android/service/search/ISearchUiService.aidl
+++ b/core/java/android/service/search/ISearchUiService.aidl
@@ -37,5 +37,11 @@
 
     void onNotifyEvent(in SearchSessionId sessionId, in Query input, in SearchTargetEvent event);
 
+    void onRegisterEmptyQueryResultUpdateCallback (in SearchSessionId sessionId, in ISearchCallback callback);
+
+    void onRequestEmptyQueryResultUpdate(in SearchSessionId sessionId);
+
+    void onUnregisterEmptyQueryResultUpdateCallback(in SearchSessionId sessionId, in ISearchCallback callback);
+
     void onDestroy(in SearchSessionId sessionId);
 }
diff --git a/core/java/android/service/search/SearchUiService.java b/core/java/android/service/search/SearchUiService.java
index 02d41ef..55a96fa 100644
--- a/core/java/android/service/search/SearchUiService.java
+++ b/core/java/android/service/search/SearchUiService.java
@@ -20,6 +20,7 @@
 import android.annotation.CallSuper;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.app.search.ISearchCallback;
@@ -35,8 +36,10 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.service.search.ISearchUiService.Stub;
+import android.util.ArrayMap;
 import android.util.Slog;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Consumer;
 
@@ -66,6 +69,9 @@
     public static final String SERVICE_INTERFACE =
             "android.service.search.SearchUiService";
 
+    private final ArrayMap<SearchSessionId, ArrayList<CallbackWrapper>>
+            mSessionEmptyQueryResultCallbacks = new ArrayMap<>();
+
     private Handler mHandler;
 
     private final android.service.search.ISearchUiService mInterface = new Stub() {
@@ -87,7 +93,7 @@
             mHandler.sendMessage(
                     obtainMessage(SearchUiService::onQuery,
                             SearchUiService.this, sessionId, input,
-                            new CallbackWrapper(callback)));
+                            new CallbackWrapper(callback, null)));
         }
 
         @Override
@@ -98,6 +104,28 @@
         }
 
         @Override
+        public void onRegisterEmptyQueryResultUpdateCallback(SearchSessionId sessionId,
+                ISearchCallback callback) {
+            mHandler.sendMessage(
+                    obtainMessage(SearchUiService::doRegisterEmptyQueryResultUpdateCallback,
+                            SearchUiService.this, sessionId, callback));
+        }
+
+        @Override
+        public void onRequestEmptyQueryResultUpdate(SearchSessionId sessionId) {
+            mHandler.sendMessage(obtainMessage(SearchUiService::doRequestEmptyQueryResultUpdate,
+                    SearchUiService.this, sessionId));
+        }
+
+        @Override
+        public void onUnregisterEmptyQueryResultUpdateCallback(SearchSessionId sessionId,
+                ISearchCallback callback) {
+            mHandler.sendMessage(
+                    obtainMessage(SearchUiService::doUnregisterEmptyQueryResultUpdateCallback,
+                            SearchUiService.this, sessionId, callback));
+        }
+
+        @Override
         public void onDestroy(SearchSessionId sessionId) {
             mHandler.sendMessage(
                     obtainMessage(SearchUiService::doDestroy,
@@ -126,21 +154,23 @@
     /**
      * Creates a new search session.
      *
+     * @removed
      * @deprecated this is method will be removed as soon as
      * {@link #onSearchSessionCreated(SearchContext, SearchSessionId)}
      * is adopted by the service.
-     *
-     * @removed
      */
     @Deprecated
     public void onCreateSearchSession(@NonNull SearchContext context,
-            @NonNull SearchSessionId sessionId) {}
+            @NonNull SearchSessionId sessionId) {
+    }
 
     /**
      * A new search session is created.
      */
     public void onSearchSessionCreated(@NonNull SearchContext context,
-            @NonNull SearchSessionId sessionId) {}
+            @NonNull SearchSessionId sessionId) {
+        mSessionEmptyQueryResultCallbacks.put(sessionId, new ArrayList<>());
+    }
 
     /**
      * Called by the client to request search results using a query string.
@@ -161,6 +191,98 @@
             @NonNull Query query,
             @NonNull SearchTargetEvent event);
 
+    private void doRegisterEmptyQueryResultUpdateCallback(@NonNull SearchSessionId sessionId,
+            @NonNull ISearchCallback callback) {
+        final ArrayList<CallbackWrapper> callbacks = mSessionEmptyQueryResultCallbacks.get(
+                sessionId);
+        if (callbacks == null) {
+            Slog.e(TAG, "Failed to register for updates for unknown session: " + sessionId);
+            return;
+        }
+
+        final CallbackWrapper wrapper = findCallbackWrapper(callbacks, callback);
+        if (wrapper == null) {
+            callbacks.add(new CallbackWrapper(callback,
+                    callbackWrapper ->
+                            mHandler.post(() ->
+                                    removeCallbackWrapper(callbacks, callbackWrapper))));
+            if (callbacks.size() == 1) {
+                onStartUpdateEmptyQueryResult();
+            }
+        }
+    }
+
+    /**
+     * Called when the first empty query result callback is registered. Service provider may make
+     * their own decision whether to generate data if no callback is registered to optimize for
+     * system health.
+     */
+    @MainThread
+    public void onStartUpdateEmptyQueryResult() {}
+
+    private void doRequestEmptyQueryResultUpdate(@NonNull SearchSessionId sessionId) {
+        // Just an optimization, if there are no callbacks, then don't bother notifying the service
+        final ArrayList<CallbackWrapper> callbacks = mSessionEmptyQueryResultCallbacks.get(
+                sessionId);
+        if (callbacks != null && !callbacks.isEmpty()) {
+            onRequestEmptyQueryResultUpdate(sessionId);
+        }
+    }
+
+    /**
+     * Called by a client to request empty query search target result for zero state. This method
+     * is only called if there are one or more empty query result update callbacks registered.
+     *
+     * @see #updateEmptyQueryResult(SearchSessionId, List)
+     */
+    @MainThread
+    public void onRequestEmptyQueryResultUpdate(@NonNull SearchSessionId sessionId) {}
+
+    private void doUnregisterEmptyQueryResultUpdateCallback(@NonNull SearchSessionId sessionId,
+            @NonNull ISearchCallback callback) {
+        final ArrayList<CallbackWrapper> callbacks = mSessionEmptyQueryResultCallbacks.get(
+                sessionId);
+        if (callbacks == null) {
+            Slog.e(TAG, "Failed to unregister for updates for unknown session: " + sessionId);
+            return;
+        }
+
+        final CallbackWrapper wrapper = findCallbackWrapper(callbacks, callback);
+        removeCallbackWrapper(callbacks, wrapper);
+    }
+
+    /**
+     * Finds the callback wrapper for the given callback.
+     */
+    private CallbackWrapper findCallbackWrapper(ArrayList<CallbackWrapper> callbacks,
+            ISearchCallback callback) {
+        for (int i = callbacks.size() - 1; i >= 0; i--) {
+            if (callbacks.get(i).isCallback(callback)) {
+                return callbacks.get(i);
+            }
+        }
+        return null;
+    }
+
+    private void removeCallbackWrapper(@Nullable ArrayList<CallbackWrapper> callbacks,
+            @Nullable CallbackWrapper wrapper) {
+        if (callbacks == null || wrapper == null) {
+            return;
+        }
+        callbacks.remove(wrapper);
+        wrapper.destroy();
+        if (callbacks.isEmpty()) {
+            onStopUpdateEmptyQueryResult();
+        }
+    }
+
+    /**
+     * Called when there are no longer any empty query result callbacks registered. Service
+     * provider can choose to stop generating data to optimize for system health.
+     */
+    @MainThread
+    public void onStopUpdateEmptyQueryResult() {}
+
     private void doDestroy(@NonNull SearchSessionId sessionId) {
         super.onDestroy();
         onDestroy(sessionId);
@@ -172,14 +294,49 @@
     @MainThread
     public abstract void onDestroy(@NonNull SearchSessionId sessionId);
 
-    private static final class CallbackWrapper implements Consumer<List<SearchTarget>> {
+    /**
+     * Used by the service provider to send back results the client app. The can be called
+     * in response to {@link #onRequestEmptyQueryResultUpdate(SearchSessionId)} or proactively as
+     * a result of changes in zero state data.
+     */
+    public final void updateEmptyQueryResult(@NonNull SearchSessionId sessionId,
+            @NonNull List<SearchTarget> targets) {
+        List<CallbackWrapper> callbacks = mSessionEmptyQueryResultCallbacks.get(sessionId);
+        if (callbacks != null) {
+            for (CallbackWrapper callback : callbacks) {
+                callback.accept(targets);
+            }
+        }
+    }
+
+    private static final class CallbackWrapper implements Consumer<List<SearchTarget>>,
+            IBinder.DeathRecipient {
 
         private ISearchCallback mCallback;
+        private final Consumer<CallbackWrapper> mOnBinderDied;
 
-        CallbackWrapper(ISearchCallback callback) {
+        CallbackWrapper(ISearchCallback callback,
+                @Nullable Consumer<CallbackWrapper> onBinderDied) {
             mCallback = callback;
+            mOnBinderDied = onBinderDied;
+            if (mOnBinderDied != null) {
+                try {
+                    mCallback.asBinder().linkToDeath(this, 0);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Failed to link to death:" + e);
+                }
+            }
         }
 
+        public boolean isCallback(@NonNull ISearchCallback callback) {
+            if (mCallback == null) {
+                Slog.e(TAG, "Callback is null, likely the binder has died.");
+                return false;
+            }
+            return mCallback.asBinder().equals(callback.asBinder());
+        }
+
+
         @Override
         public void accept(List<SearchTarget> searchTargets) {
             try {
@@ -193,5 +350,20 @@
                 Slog.e(TAG, "Error sending result:" + e);
             }
         }
+
+        public void destroy() {
+            if (mCallback != null && mOnBinderDied != null) {
+                mCallback.asBinder().unlinkToDeath(this, 0);
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            destroy();
+            mCallback = null;
+            if (mOnBinderDied != null) {
+                mOnBinderDied.accept(this);
+            }
+        }
     }
 }
diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS
index 59a0c2e..ec44100 100644
--- a/core/java/android/service/voice/OWNERS
+++ b/core/java/android/service/voice/OWNERS
@@ -1,3 +1,7 @@
 # Bug component: 533220
 
 include /core/java/android/app/assist/OWNERS
+
+# The owner here should not be assist owner
+liangyuchen@google.com
+tuanng@google.com
diff --git a/core/java/android/service/voice/VoiceInteractionManagerInternal.java b/core/java/android/service/voice/VoiceInteractionManagerInternal.java
index c47fdd3..270f848 100644
--- a/core/java/android/service/voice/VoiceInteractionManagerInternal.java
+++ b/core/java/android/service/voice/VoiceInteractionManagerInternal.java
@@ -39,7 +39,7 @@
      * @param options A Bundle of private arguments to the current voice interaction service
      */
     public abstract void startLocalVoiceInteraction(@NonNull IBinder callingActivity,
-            @Nullable String attributionTag, @NonNull Bundle options);
+            @Nullable String attributionTag, @Nullable Bundle options);
 
     /**
      * Returns whether the currently selected voice interaction service supports local voice
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index ca4716b..064c0ad 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -766,11 +766,13 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("VOICE INTERACTION");
         synchronized (mLock) {
-            pw.println("  Sandboxed Detector(s)");
+            pw.println("  Sandboxed Detector(s):");
             if (mActiveDetectors.size() == 0) {
-                pw.println("    NULL");
+                pw.println("    No detector.");
             } else {
                 mActiveDetectors.forEach(detector -> {
+                    pw.print("  Using sandboxed detection service=");
+                    pw.println(detector.isUsingSandboxedDetectionService());
                     detector.dump("    ", pw);
                     pw.println();
                 });
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 0d51395..5778518 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1781,11 +1781,13 @@
      * Intent.EXTRA_TIME ("android.intent.extra.TIME") indicating timing
      * in milliseconds of the KeyEvent that triggered Assistant and
      * Intent.EXTRA_ASSIST_INPUT_DEVICE_ID (android.intent.extra.ASSIST_INPUT_DEVICE_ID)
-     *  referring to the device that sent the request.
+     *  referring to the device that sent the request. Starting from Android 14, the system will
+     * add {@link VoiceInteractionService#KEY_SHOW_SESSION_ID}, the Bundle is not null. But the
+     * application should handle null case before Android 14.
      * @param showFlags The show flags originally provided to
      * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
      */
-    public void onShow(Bundle args, int showFlags) {
+    public void onShow(@Nullable Bundle args, int showFlags) {
     }
 
     /**
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 44afb89..23513fad 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1242,7 +1242,7 @@
                             null /* ignoringVisibilityState */, config.isScreenRound(),
                             false /* alwaysConsumeSystemBars */, mLayout.softInputMode,
                             mLayout.flags, SYSTEM_UI_FLAG_VISIBLE, mLayout.type,
-                            config.windowConfiguration.getWindowingMode(), null /* typeSideMap */);
+                            config.windowConfiguration.getWindowingMode(), null /* idSideMap */);
 
                     if (!fixedSize) {
                         final Rect padding = mIWallpaperEngine.mDisplayPadding;
diff --git a/core/java/android/tracing/OWNERS b/core/java/android/tracing/OWNERS
index 7d1b48b..079d4c5 100644
--- a/core/java/android/tracing/OWNERS
+++ b/core/java/android/tracing/OWNERS
@@ -1,2 +1,3 @@
 carmenjackson@google.com
+kevinjeon@google.com
 include platform/external/perfetto:/OWNERS
diff --git a/core/java/android/transparency/BinaryTransparencyManager.java b/core/java/android/transparency/BinaryTransparencyManager.java
index d77bbcc..c18adfc 100644
--- a/core/java/android/transparency/BinaryTransparencyManager.java
+++ b/core/java/android/transparency/BinaryTransparencyManager.java
@@ -67,24 +67,6 @@
     }
 
     /**
-     * Gets binary measurements of all installed APEXs, each packed in a Bundle.
-     * @return A List of {@link android.os.Bundle}s with the following keys:
-     *         {@link com.android.server.BinaryTransparencyService#BUNDLE_PACKAGE_INFO}
-     *         {@link com.android.server.BinaryTransparencyService#BUNDLE_CONTENT_DIGEST_ALGORITHM}
-     *         {@link com.android.server.BinaryTransparencyService#BUNDLE_CONTENT_DIGEST}
-     */
-    // TODO(b/259422958): Fix static constants referenced here - should be defined here
-    @NonNull
-    public List getApexInfo() {
-        try {
-            Slog.d(TAG, "Calling backend's getApexInfo()");
-            return mService.getApexInfo();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Collects the APEX information on the device.
      *
      * @param includeTestOnly Whether to include test only data in the returned ApexInfo.
@@ -116,4 +98,21 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Collects the silent installed MBA information on the device.
+     *
+     * @return A List containing the MBA info of silent installed.
+     * @hide
+     */
+    @NonNull
+    public List<IBinaryTransparencyService.AppInfo> collectAllSilentInstalledMbaInfo(
+            Bundle packagesToSkip) {
+        try {
+            Slog.d(TAG, "Calling backend's collectAllSilentInstalledMbaInfo()");
+            return mService.collectAllSilentInstalledMbaInfo(packagesToSkip);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index b98deba..c02dd6a 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -76,6 +76,16 @@
     public static final String SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME =
             "settings_app_allow_dark_theme_activation_at_bedtime";
 
+    /**
+     * Flag to decouple bluetooth LE Audio Broadcast from Unicast
+     * If the flag is true, the broadcast feature will be enabled when the phone
+     * is connected to the BLE device.
+     * If the flag is false, it is not necessary to connect the BLE device.
+     * @hide
+     */
+    public static final String SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST =
+            "settings_need_connected_ble_device_for_broadcast";
+
     /** @hide */
     public static final String SETTINGS_AUTO_TEXT_WRAPPING = "settings_auto_text_wrapping";
 
@@ -173,6 +183,14 @@
     public static final String SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API =
             "settings_enable_lockscreen_transfer_api";
 
+    /**
+     * Flag to enable remote device credential validation
+     * @hide
+     */
+    public static final String SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION =
+            "settings_remote_device_credential_validation";
+
+
     private static final Map<String, String> DEFAULT_FLAGS;
 
     static {
@@ -199,6 +217,7 @@
         DEFAULT_FLAGS.put(SETTINGS_VOLUME_PANEL_IN_SYSTEMUI, "false");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
+        DEFAULT_FLAGS.put(SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, "true");
         DEFAULT_FLAGS.put(SETTINGS_AUTO_TEXT_WRAPPING, "false");
         DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_UI, "false");
         DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_SHORTCUT, "false");
@@ -207,14 +226,15 @@
         DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_TRACKPAD_GESTURE, "false");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA, "true");
         DEFAULT_FLAGS.put(SETTINGS_ADB_METRICS_WRITER, "false");
-        DEFAULT_FLAGS.put(SETTINGS_SHOW_STYLUS_PREFERENCES, "false");
+        DEFAULT_FLAGS.put(SETTINGS_SHOW_STYLUS_PREFERENCES, "true");
         DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_ENROLLMENT, "false");
         DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_HEARING_AID_PAGE, "false");
         DEFAULT_FLAGS.put(SETTINGS_PREFER_ACCESSIBILITY_MENU_IN_SYSTEM, "false");
         DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
         DEFAULT_FLAGS.put(SETTINGS_FLASH_ALERTS, "false");
-        DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "false");
+        DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "true");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "false");
+        DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "false");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/util/RotationUtils.java b/core/java/android/util/RotationUtils.java
index 3e7c67e..f20767b 100644
--- a/core/java/android/util/RotationUtils.java
+++ b/core/java/android/util/RotationUtils.java
@@ -27,6 +27,7 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.view.Surface;
 import android.view.Surface.Rotation;
 import android.view.SurfaceControl;
 
@@ -245,4 +246,23 @@
                 throw new IllegalArgumentException("Unknown rotation: " + rotation);
         }
     }
+
+    /**
+     * Reverses the rotation direction around the Z axis. Note that this method assumes all
+     * rotations are relative to {@link Surface.ROTATION_0}.
+     *
+     * @param rotation the original rotation.
+     * @return the new rotation that should be applied.
+     */
+    @Surface.Rotation
+    public static int reverseRotationDirectionAroundZAxis(@Surface.Rotation int rotation) {
+        // Flipping 270 and 90 has the same effect as changing the direction which rotation is
+        // applied.
+        if (rotation == Surface.ROTATION_90) {
+            rotation = Surface.ROTATION_270;
+        } else if (rotation == Surface.ROTATION_270) {
+            rotation = Surface.ROTATION_90;
+        }
+        return rotation;
+    }
 }
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 91febcd..3dc79cf 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -270,10 +270,14 @@
     private static final int CALLBACK_LAST = CALLBACK_COMMIT;
 
     private Choreographer(Looper looper, int vsyncSource) {
+        this(looper, vsyncSource, /* layerHandle */ 0L);
+    }
+
+    private Choreographer(Looper looper, int vsyncSource, long layerHandle) {
         mLooper = looper;
         mHandler = new FrameHandler(looper);
         mDisplayEventReceiver = USE_VSYNC
-                ? new FrameDisplayEventReceiver(looper, vsyncSource)
+                ? new FrameDisplayEventReceiver(looper, vsyncSource, layerHandle)
                 : null;
         mLastFrameTimeNanos = Long.MIN_VALUE;
 
@@ -313,6 +317,26 @@
     }
 
     /**
+     * Gets the choreographer associated with the SurfaceControl.
+     *
+     * @param layerHandle to which the choreographer will be attached.
+     * @param looper      the choreographer is attached on this looper.
+     *
+     * @return The choreographer for the looper which is attached
+     * to the sourced SurfaceControl::mNativeHandle.
+     * @throws IllegalStateException if the looper sourced is null.
+     * @hide
+     */
+    @NonNull
+    static Choreographer getInstanceForSurfaceControl(long layerHandle,
+            @NonNull Looper looper) {
+        if (looper == null) {
+            throw new IllegalStateException("The current thread must have a looper!");
+        }
+        return new Choreographer(looper, VSYNC_SOURCE_APP, layerHandle);
+    }
+
+    /**
      * @return The Choreographer of the main thread, if it exists, or {@code null} otherwise.
      * @hide
      */
@@ -334,6 +358,15 @@
     }
 
     /**
+     * Dispose the DisplayEventReceiver on the Choreographer.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    void invalidate() {
+        dispose();
+    }
+
+    /**
      * The amount of time, in milliseconds, between each frame of the animation.
      * <p>
      * This is a requested time that the animation will attempt to honor, but the actual delay
@@ -1166,8 +1199,8 @@
         private int mFrame;
         private VsyncEventData mLastVsyncEventData = new VsyncEventData();
 
-        public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
-            super(looper, vsyncSource, 0);
+        FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) {
+            super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle);
         }
 
         // TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 39ea2fd..6b1499f 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -2508,5 +2508,24 @@
                     + ", mMaxAverageLuminance=" + mMaxAverageLuminance
                     + ", mMinLuminance=" + mMinLuminance + '}';
         }
+
+        /**
+         * @hide
+         */
+        @NonNull
+        public static String hdrTypeToString(int hdrType) {
+            switch (hdrType) {
+                case HDR_TYPE_DOLBY_VISION:
+                    return "HDR_TYPE_DOLBY_VISION";
+                case HDR_TYPE_HDR10:
+                    return "HDR_TYPE_HDR10";
+                case HDR_TYPE_HLG:
+                    return "HDR_TYPE_HLG";
+                case HDR_TYPE_HDR10_PLUS:
+                    return "HDR_TYPE_HDR10_PLUS";
+                default:
+                    return "HDR_TYPE_INVALID";
+            }
+        }
     }
 }
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index ce7606a0..edce001 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -27,6 +27,8 @@
 
 import dalvik.annotation.optimization.FastNative;
 
+import libcore.util.NativeAllocationRegistry;
+
 import java.lang.ref.WeakReference;
 
 /**
@@ -80,12 +82,18 @@
     private MessageQueue mMessageQueue;
 
     private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
-            MessageQueue messageQueue, int vsyncSource, int eventRegistration);
-    private static native void nativeDispose(long receiverPtr);
+            MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle);
+    private static native long nativeGetDisplayEventReceiverFinalizer();
     @FastNative
     private static native void nativeScheduleVsync(long receiverPtr);
     private static native VsyncEventData nativeGetLatestVsyncEventData(long receiverPtr);
 
+    private static final NativeAllocationRegistry sNativeAllocationRegistry =
+            NativeAllocationRegistry.createMalloced(
+                    DisplayEventReceiver.class.getClassLoader(),
+                    nativeGetDisplayEventReceiverFinalizer());
+    private Runnable mFreeNativeResources;
+
     /**
      * Creates a display event receiver.
      *
@@ -93,7 +101,11 @@
      */
     @UnsupportedAppUsage
     public DisplayEventReceiver(Looper looper) {
-        this(looper, VSYNC_SOURCE_APP, 0);
+        this(looper, VSYNC_SOURCE_APP, /* eventRegistration */ 0, /* layerHandle */ 0L);
+    }
+
+    public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) {
+        this(looper, vsyncSource, eventRegistration, /* layerHandle */ 0L);
     }
 
     /**
@@ -103,36 +115,27 @@
      * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values.
      * @param eventRegistration Which events to dispatch. Must be a bitfield consist of the
      * EVENT_REGISTRATION_*_FLAG values.
+     * @param layerHandle Layer to which the current instance is attached to
      */
-    public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) {
+    public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration,
+            long layerHandle) {
         if (looper == null) {
             throw new IllegalArgumentException("looper must not be null");
         }
 
         mMessageQueue = looper.getQueue();
         mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
-                vsyncSource, eventRegistration);
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            dispose(true);
-        } finally {
-            super.finalize();
-        }
+                vsyncSource, eventRegistration, layerHandle);
+        mFreeNativeResources = sNativeAllocationRegistry.registerNativeAllocation(this,
+                mReceiverPtr);
     }
 
     /**
      * Disposes the receiver.
      */
     public void dispose() {
-        dispose(false);
-    }
-
-    private void dispose(boolean finalized) {
         if (mReceiverPtr != 0) {
-            nativeDispose(mReceiverPtr);
+            mFreeNativeResources.run();
             mReceiverPtr = 0;
         }
         mMessageQueue = null;
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index e26c7be..3a02c48 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -337,6 +337,9 @@
     @Nullable
     public DisplayShape displayShape;
 
+    @Nullable
+    public SurfaceControl.RefreshRateRange layoutLimitedRefreshRate;
+
     public static final @android.annotation.NonNull Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
         @Override
         public DisplayInfo createFromParcel(Parcel source) {
@@ -411,7 +414,8 @@
                 && brightnessDefault == other.brightnessDefault
                 && Objects.equals(roundedCorners, other.roundedCorners)
                 && installOrientation == other.installOrientation
-                && Objects.equals(displayShape, other.displayShape);
+                && Objects.equals(displayShape, other.displayShape)
+                && Objects.equals(layoutLimitedRefreshRate, other.layoutLimitedRefreshRate);
     }
 
     @Override
@@ -466,6 +470,7 @@
         roundedCorners = other.roundedCorners;
         installOrientation = other.installOrientation;
         displayShape = other.displayShape;
+        layoutLimitedRefreshRate = other.layoutLimitedRefreshRate;
     }
 
     public void readFromParcel(Parcel source) {
@@ -526,6 +531,7 @@
         }
         installOrientation = source.readInt();
         displayShape = source.readTypedObject(DisplayShape.CREATOR);
+        layoutLimitedRefreshRate = source.readTypedObject(SurfaceControl.RefreshRateRange.CREATOR);
     }
 
     @Override
@@ -584,6 +590,7 @@
         }
         dest.writeInt(installOrientation);
         dest.writeTypedObject(displayShape, flags);
+        dest.writeTypedObject(layoutLimitedRefreshRate, flags);
     }
 
     @Override
@@ -758,7 +765,7 @@
         sb.append(name);
         sb.append("\", displayId ");
         sb.append(displayId);
-        sb.append("\", displayGroupId ");
+        sb.append(", displayGroupId ");
         sb.append(displayGroupId);
         sb.append(flagsToString(flags));
         sb.append(", real ");
@@ -843,6 +850,8 @@
         sb.append(brightnessDefault);
         sb.append(", installOrientation ");
         sb.append(Surface.rotationToString(installOrientation));
+        sb.append(", layoutLimitedRefreshRate ");
+        sb.append(layoutLimitedRefreshRate);
         sb.append("}");
         return sb.toString();
     }
diff --git a/core/java/android/view/DisplayShape.java b/core/java/android/view/DisplayShape.java
index 43bd773..26722bc 100644
--- a/core/java/android/view/DisplayShape.java
+++ b/core/java/android/view/DisplayShape.java
@@ -218,7 +218,7 @@
     @Override
     public String toString() {
         return "DisplayShape{"
-                + " spec=" + mDisplayShapeSpec
+                + " spec=" + mDisplayShapeSpec.hashCode()
                 + " displayWidth=" + mDisplayWidth
                 + " displayHeight=" + mDisplayHeight
                 + " physicalPixelDisplaySizeRatio=" + mPhysicalPixelDisplaySizeRatio
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index e89be47..4a3b8ac 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -123,7 +123,7 @@
 
         // TODO: ResultReceiver for IME.
         // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag.
-        ImeTracker.get().onProgress(statsToken,
+        ImeTracker.forLogging().onProgress(statsToken,
                 ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_REQUEST_SHOW);
 
         if (getControl() == null) {
@@ -133,7 +133,8 @@
         // If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
         // this code here means that we now got control, so we can start the animation immediately.
         // If client window is trying to control IME and IME is already visible, it is immediate.
-        if (fromIme || (mState.getSource(getId()).isVisible() && getControl() != null)) {
+        if (fromIme
+                || (mState.isSourceOrDefaultVisible(getId(), getType()) && getControl() != null)) {
             return ShowResult.SHOW_IMMEDIATELY;
         }
 
@@ -164,12 +165,13 @@
         //  - we do already have one, but we have control and use the passed in token
         //      for the insets animation already.
         if (statsToken == null || getControl() != null) {
-            statsToken = ImeTracker.get().onRequestHide(null /* component */, Process.myUid(),
+            statsToken = ImeTracker.forLogging().onRequestHide(null /* component */,
+                    Process.myUid(),
                     ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
                     SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
         }
 
-        ImeTracker.get().onProgress(statsToken,
+        ImeTracker.forLogging().onProgress(statsToken,
                 ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_NOTIFY_HIDDEN);
 
         getImm().notifyImeHidden(mController.getHost().getWindowToken(), statsToken);
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 309a94a..75f1666 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -33,12 +33,12 @@
 import static android.view.InsetsController.DEBUG;
 import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN;
 import static android.view.InsetsController.LayoutInsetsDuringAnimation;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsState.ISIDE_BOTTOM;
 import static android.view.InsetsState.ISIDE_FLOATING;
 import static android.view.InsetsState.ISIDE_LEFT;
 import static android.view.InsetsState.ISIDE_RIGHT;
 import static android.view.InsetsState.ISIDE_TOP;
-import static android.view.InsetsState.ITYPE_IME;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;
@@ -132,19 +132,19 @@
         mController = controller;
         mInitialInsetsState = new InsetsState(state, true /* copySources */);
         if (frame != null) {
-            final SparseIntArray typeSideMap = new SparseIntArray();
-            mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */);
+            final SparseIntArray idSideMap = new SparseIntArray();
+            mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* idSideMap */);
             mHiddenInsets = calculateInsets(mInitialInsetsState, frame, controls, false /* shown */,
-                    null /* typeSideMap */);
+                    null /* idSideMap */);
             mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
-                    typeSideMap);
+                    idSideMap);
             mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsType(WindowInsets.Type.ime());
             if (mHasZeroInsetsIme) {
                 // IME has shownInsets of ZERO, and can't map to a side by default.
                 // Map zero insets IME to bottom, making it a special case of bottom insets.
-                typeSideMap.put(ITYPE_IME, ISIDE_BOTTOM);
+                idSideMap.put(ID_IME, ISIDE_BOTTOM);
             }
-            buildSideControlsMap(typeSideMap, mSideControlsMap, controls);
+            buildSideControlsMap(idSideMap, mSideControlsMap, controls);
         } else {
             // Passing a null frame indicates the caller wants to play the insets animation anyway,
             // no matter the source provides insets to the frame or not.
@@ -399,27 +399,27 @@
     }
 
     private Insets getInsetsFromState(InsetsState state, Rect frame,
-            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
+            @Nullable @InternalInsetsSide SparseIntArray idSideMap) {
         return state.calculateInsets(frame, null /* ignoringVisibilityState */,
                 false /* isScreenRound */, false /* alwaysConsumeSystemBars */,
                 LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/,
                 0 /* legacyWindowFlags */, 0 /* legacySystemUiFlags */, TYPE_APPLICATION,
-                WINDOWING_MODE_UNDEFINED, typeSideMap).getInsets(mTypes);
+                WINDOWING_MODE_UNDEFINED, idSideMap).getInsets(mTypes);
     }
 
     /** Computes the insets relative to the given frame. */
     private Insets calculateInsets(InsetsState state, Rect frame,
             SparseArray<InsetsSourceControl> controls, boolean shown,
-            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
+            @Nullable @InternalInsetsSide SparseIntArray idSideMap) {
         for (int i = controls.size() - 1; i >= 0; i--) {
             final InsetsSourceControl control  = controls.valueAt(i);
             if (control == null) {
                 // control may be null if it got revoked.
                 continue;
             }
-            state.getSource(control.getId()).setVisible(shown);
+            state.setSourceVisible(control.getId(), shown);
         }
-        return getInsetsFromState(state, frame, typeSideMap);
+        return getInsetsFromState(state, frame, idSideMap);
     }
 
     /** Computes the insets from the insets hints of controls. */
@@ -435,7 +435,8 @@
                 // control may be null if it got revoked.
                 continue;
             }
-            if (state == null || state.getSource(control.getId()).isVisible()) {
+            if (state == null
+                    || state.isSourceOrDefaultVisible(control.getId(), control.getType())) {
                 insets = Insets.max(insets, control.getInsetsHint());
             }
         }
@@ -465,20 +466,23 @@
         // TODO: Implement behavior when inset spans over multiple types
         for (int i = controls.size() - 1; i >= 0; i--) {
             final InsetsSourceControl control = controls.valueAt(i);
-            final InsetsSource source = mInitialInsetsState.getSource(control.getId());
+            final InsetsSource source = mInitialInsetsState.peekSource(control.getId());
             final SurfaceControl leash = control.getLeash();
 
             mTmpMatrix.setTranslate(control.getSurfacePosition().x, control.getSurfacePosition().y);
-            mTmpFrame.set(source.getFrame());
+            if (source != null) {
+                mTmpFrame.set(source.getFrame());
+            }
             addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
 
             final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM
                     ? (mAnimationType == ANIMATION_TYPE_SHOW || !mFinished)
                     : inset != 0;
 
-            if (outState != null) {
-                outState.getSource(source.getId()).setVisible(visible);
-                outState.getSource(source.getId()).setFrame(mTmpFrame);
+            if (outState != null && source != null) {
+                outState.getOrCreateSource(source.getId(), source.getType())
+                        .setVisible(visible)
+                        .setFrame(mTmpFrame);
             }
 
             // If the system is controlling the insets source, the leash can be null.
@@ -517,12 +521,12 @@
         }
     }
 
-    private static void buildSideControlsMap(SparseIntArray typeSideMap,
+    private static void buildSideControlsMap(SparseIntArray idSideMap,
             SparseSetArray<InsetsSourceControl> sideControlsMap,
             SparseArray<InsetsSourceControl> controls) {
-        for (int i = typeSideMap.size() - 1; i >= 0; i--) {
-            final int type = typeSideMap.keyAt(i);
-            final int side = typeSideMap.valueAt(i);
+        for (int i = idSideMap.size() - 1; i >= 0; i--) {
+            final int type = idSideMap.keyAt(i);
+            final int side = idSideMap.valueAt(i);
             final InsetsSourceControl control = controls.get(type);
             if (control == null) {
                 // If the types that we are controlling are less than the types that the system has,
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8e8e28a..d8bff1c 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -19,13 +19,14 @@
 import static android.os.Trace.TRACE_TAG_VIEW;
 import static android.view.InsetsControllerProto.CONTROL;
 import static android.view.InsetsControllerProto.STATE;
-import static android.view.InsetsState.ITYPE_CAPTION_BAR;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
 import static android.view.WindowInsets.Type.FIRST;
 import static android.view.WindowInsets.Type.LAST;
 import static android.view.WindowInsets.Type.all;
+import static android.view.WindowInsets.Type.captionBar;
 import static android.view.WindowInsets.Type.ime;
+import static android.view.inputmethod.ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL;
 
 import android.animation.AnimationHandler;
 import android.animation.Animator;
@@ -35,6 +36,8 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.content.Context;
 import android.content.res.CompatibilityInfo;
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -44,13 +47,12 @@
 import android.os.Process;
 import android.os.Trace;
 import android.text.TextUtils;
-import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.InsetsSourceConsumer.ShowResult;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl.Transaction;
 import android.view.WindowInsets.Type;
 import android.view.WindowInsets.Type.InsetsType;
@@ -60,6 +62,7 @@
 import android.view.animation.LinearInterpolator;
 import android.view.animation.PathInterpolator;
 import android.view.inputmethod.ImeTracker;
+import android.view.inputmethod.ImeTracker.InputMethodJankContext;
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -186,6 +189,14 @@
         @Nullable
         String getRootViewTitle();
 
+        /**
+         * @return the context related to the rootView.
+         */
+        @Nullable
+        default Context getRootViewContext() {
+            return null;
+        }
+
         /** @see ViewRootImpl#dipToPx */
         int dipToPx(int dips);
 
@@ -249,6 +260,9 @@
     /** The amount IME will move up/down when animating in floating mode. */
     private static final int FLOATING_IME_BOTTOM_INSET_DP = -80;
 
+    private static final int ID_CAPTION_BAR =
+            InsetsSource.createId(null /* owner */, 0 /* index */, captionBar());
+
     static final boolean DEBUG = false;
     static final boolean WARN = false;
 
@@ -306,7 +320,7 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(value = {ANIMATION_TYPE_NONE, ANIMATION_TYPE_SHOW, ANIMATION_TYPE_HIDE,
             ANIMATION_TYPE_USER, ANIMATION_TYPE_RESIZE})
-    @interface AnimationType {
+    public @interface AnimationType {
     }
 
     /**
@@ -321,6 +335,25 @@
     /** Logging listener. */
     private WindowInsetsAnimationControlListener mLoggingListener;
 
+    /** Context for {@link android.view.inputmethod.ImeTracker.ImeJankTracker} to monitor jank. */
+    private final InputMethodJankContext mJankContext = new InputMethodJankContext() {
+        @Override
+        public Context getDisplayContext() {
+            return mHost != null ? mHost.getRootViewContext() : null;
+        }
+
+        @Override
+        public SurfaceControl getTargetSurfaceControl() {
+            final InsetsSourceControl imeSourceControl = getImeSourceConsumer().getControl();
+            return imeSourceControl != null ? imeSourceControl.getLeash() : null;
+        }
+
+        @Override
+        public String getHostPackageName() {
+            return mHost != null ? mHost.getRootViewContext().getPackageName() : null;
+        }
+    };
+
     /**
      * The default implementation of listener, to be used by InsetsController and InsetsPolicy to
      * animate insets.
@@ -338,6 +371,7 @@
         private final boolean mDisable;
         private final int mFloatingImeBottomInset;
         private final WindowInsetsAnimationControlListener mLoggingListener;
+        private final InputMethodJankContext mInputMethodJankContext;
 
         private final ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
                 new ThreadLocal<AnimationHandler>() {
@@ -351,7 +385,8 @@
 
         public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
                 @InsetsType int requestedTypes, @Behavior int behavior, boolean disable,
-                int floatingImeBottomInset, WindowInsetsAnimationControlListener loggingListener) {
+                int floatingImeBottomInset, WindowInsetsAnimationControlListener loggingListener,
+                @Nullable InputMethodJankContext jankContext) {
             mShow = show;
             mHasAnimationCallbacks = hasAnimationCallbacks;
             mRequestedTypes = requestedTypes;
@@ -360,6 +395,7 @@
             mDisable = disable;
             mFloatingImeBottomInset = floatingImeBottomInset;
             mLoggingListener = loggingListener;
+            mInputMethodJankContext = jankContext;
         }
 
         @Override
@@ -406,10 +442,26 @@
                         + insetsFraction);
             });
             mAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    if (mInputMethodJankContext == null) return;
+                    ImeTracker.forJank().onRequestAnimation(
+                            mInputMethodJankContext,
+                            mShow ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
+                            !mHasAnimationCallbacks);
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    if (mInputMethodJankContext == null) return;
+                    ImeTracker.forJank().onCancelAnimation();
+                }
 
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     onAnimationFinish();
+                    if (mInputMethodJankContext == null) return;
+                    ImeTracker.forJank().onFinishAnimation();
                 }
             });
             if (!mHasAnimationCallbacks) {
@@ -621,6 +673,79 @@
     private final Runnable mInvokeControllableInsetsChangedListeners =
             this::invokeControllableInsetsChangedListeners;
 
+    private final InsetsState.OnTraverseCallbacks mRemoveGoneSources =
+            new InsetsState.OnTraverseCallbacks() {
+
+                private final IntArray mPendingRemoveIndexes = new IntArray();
+
+                @Override
+                public void onIdNotFoundInState2(int index1, InsetsSource source1) {
+                    if (!CAPTION_ON_SHELL && source1.getType() == captionBar()) {
+                        return;
+                    }
+
+                    // Don't change the indexes of the sources while traversing. Remove it later.
+                    mPendingRemoveIndexes.add(index1);
+
+                    // Remove the consumer as well except the IME one. IME consumer should always
+                    // be there since we need to communicate with InputMethodManager no matter we
+                    // have the source or not.
+                    if (source1.getType() != ime()) {
+                        mSourceConsumers.remove(source1.getId());
+                    }
+                }
+
+                @Override
+                public void onFinish(InsetsState state1, InsetsState state2) {
+                    for (int i = mPendingRemoveIndexes.size() - 1; i >= 0; i--) {
+                        state1.removeSourceAt(mPendingRemoveIndexes.get(i));
+                    }
+                    mPendingRemoveIndexes.clear();
+                }
+            };
+
+    private final InsetsState.OnTraverseCallbacks mStartResizingAnimationIfNeeded =
+            new InsetsState.OnTraverseCallbacks() {
+
+                private @InsetsType int mTypes;
+                private InsetsState mToState;
+
+                @Override
+                public void onStart(InsetsState state1, InsetsState state2) {
+                    mTypes = 0;
+                    mToState = null;
+                }
+
+                @Override
+                public void onIdMatch(InsetsSource source1, InsetsSource source2) {
+                    final @InsetsType int type = source1.getType();
+                    if ((type & Type.systemBars()) == 0
+                            || !source1.isVisible() || !source2.isVisible()
+                            || source1.getFrame().equals(source2.getFrame())
+                            || !(Rect.intersects(mFrame, source1.getFrame())
+                                    || Rect.intersects(mFrame, source2.getFrame()))) {
+                        return;
+                    }
+                    mTypes |= type;
+                    if (mToState == null) {
+                        mToState = new InsetsState();
+                    }
+                    mToState.addSource(new InsetsSource(source2));
+                }
+
+                @Override
+                public void onFinish(InsetsState state1, InsetsState state2) {
+                    if (mTypes == 0) {
+                        return;
+                    }
+                    cancelExistingControllers(mTypes);
+                    final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
+                            mFrame, state1, mToState, RESIZE_INTERPOLATOR,
+                            ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
+                    mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType()));
+                }
+            };
+
     public InsetsController(Host host) {
         this(host, (controller, source) -> {
             if (source.getType() == ime()) {
@@ -671,7 +796,7 @@
             WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/,
                     mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(),
                     mLastLegacySoftInputMode, mLastLegacyWindowFlags, mLastLegacySystemUiFlags,
-                    mWindowType, mLastWindowingMode, null /* typeSideMap */);
+                    mWindowType, mLastWindowingMode, null /* idSideMap */);
             mHost.dispatchWindowInsetsAnimationProgress(insets,
                     Collections.unmodifiableList(runningAnimations));
             if (DEBUG) {
@@ -687,7 +812,7 @@
         };
 
         // Make mImeSourceConsumer always non-null.
-        mImeSourceConsumer = getSourceConsumer(new InsetsSource(ITYPE_IME, ime()));
+        mImeSourceConsumer = getSourceConsumer(new InsetsSource(ID_IME, ime()));
     }
 
     @VisibleForTesting
@@ -739,29 +864,21 @@
                 true /* excludeInvisibleIme */)) {
             if (DEBUG) Log.d(TAG, "onStateChanged, notifyInsetsChanged");
             mHost.notifyInsetsChanged();
-            startResizingAnimationIfNeeded(lastState);
+            if (lastState.getDisplayFrame().equals(mState.getDisplayFrame())) {
+                InsetsState.traverse(lastState, mState, mStartResizingAnimationIfNeeded);
+            }
         }
         return true;
     }
 
     private void updateState(InsetsState newState) {
         mState.set(newState, 0 /* types */);
-        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
-            final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
-            final InsetsSource source = newState.peekSource(consumer.getId());
-            if (source == null && consumer != mImeSourceConsumer) {
-                // IME source consumer should always be there since we need to communicate with
-                // InputMethodManager no matter we have the source or not.
-                mSourceConsumers.removeAt(i);
-            }
-        }
         @InsetsType int existingTypes = 0;
         @InsetsType int visibleTypes = 0;
         @InsetsType int disabledUserAnimationTypes = 0;
         @InsetsType int[] cancelledUserAnimationTypes = {0};
-        for (int i = 0; i < InsetsState.SIZE; i++) {
-            InsetsSource source = newState.peekSource(i);
-            if (source == null) continue;
+        for (int i = 0, size = newState.sourceSize(); i < size; i++) {
+            final InsetsSource source = newState.sourceAt(i);
             @InsetsType int type = source.getType();
             @AnimationType int animationType = getAnimationType(type);
             if (!source.isUserControllable()) {
@@ -789,15 +906,7 @@
             }
             mVisibleTypes = visibleTypes;
         }
-        for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
-            // Only update the server side insets here.
-            if (!CAPTION_ON_SHELL && type == ITYPE_CAPTION_BAR) continue;
-            InsetsSource source = mState.peekSource(type);
-            if (source == null) continue;
-            if (newState.peekSource(type) == null) {
-                mState.removeSource(type);
-            }
-        }
+        InsetsState.traverse(mState, newState, mRemoveGoneSources);
 
         updateDisabledUserAnimationTypes(disabledUserAnimationTypes);
 
@@ -825,55 +934,20 @@
         if (CAPTION_ON_SHELL) {
             return false;
         }
-        if (mState.peekSource(ITYPE_CAPTION_BAR) == null
-                && mCaptionInsetsHeight == 0) {
+        final InsetsSource source = mState.peekSource(ID_CAPTION_BAR);
+        if (source == null && mCaptionInsetsHeight == 0) {
             return false;
         }
-        if (mState.peekSource(ITYPE_CAPTION_BAR) != null
-                && mCaptionInsetsHeight
-                == mState.peekSource(ITYPE_CAPTION_BAR).getFrame().height()) {
+        if (source != null && mCaptionInsetsHeight == source.getFrame().height()) {
             return false;
         }
 
         return true;
     }
 
-    private void startResizingAnimationIfNeeded(InsetsState fromState) {
-        if (!fromState.getDisplayFrame().equals(mState.getDisplayFrame())) {
-            return;
-        }
-        @InsetsType int types = 0;
-        InsetsState toState = null;
-        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(Type.systemBars());
-        for (int i = internalTypes.size() - 1; i >= 0; i--) {
-            final @InternalInsetsType int type = internalTypes.valueAt(i);
-            final InsetsSource fromSource = fromState.peekSource(type);
-            final InsetsSource toSource = mState.peekSource(type);
-            if (fromSource != null && toSource != null
-                    && fromSource.isVisible() && toSource.isVisible()
-                    && !fromSource.getFrame().equals(toSource.getFrame())
-                    && (Rect.intersects(mFrame, fromSource.getFrame())
-                            || Rect.intersects(mFrame, toSource.getFrame()))) {
-                types |= toSource.getType();
-                if (toState == null) {
-                    toState = new InsetsState();
-                }
-                toState.addSource(new InsetsSource(toSource));
-            }
-        }
-        if (types == 0) {
-            return;
-        }
-        cancelExistingControllers(types);
-        final InsetsAnimationControlRunner runner = new InsetsResizeAnimationRunner(
-                mFrame, fromState, toState, RESIZE_INTERPOLATOR, ANIMATION_DURATION_RESIZE, types,
-                this);
-        mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType()));
-    }
-
     /**
      * @see InsetsState#calculateInsets(Rect, InsetsState, boolean, boolean, int, int, int, int,
-     *      int, SparseIntArray)
+     *      int, android.util.SparseIntArray)
      */
     @VisibleForTesting
     public WindowInsets calculateInsets(boolean isScreenRound, boolean alwaysConsumeSystemBars,
@@ -886,7 +960,7 @@
         mLastLegacySystemUiFlags = legacySystemUiFlags;
         mLastInsets = mState.calculateInsets(mFrame, null /* ignoringVisibilityState*/,
                 isScreenRound, alwaysConsumeSystemBars, legacySoftInputMode, legacyWindowFlags,
-                legacySystemUiFlags, windowType, windowingMode, null /* typeSideMap */);
+                legacySystemUiFlags, windowType, windowingMode, null /* idSideMap */);
         return mLastInsets;
     }
 
@@ -981,7 +1055,7 @@
     public void show(@InsetsType int types) {
         ImeTracker.Token statsToken = null;
         if ((types & ime()) != 0) {
-            statsToken = ImeTracker.get().onRequestShow(null /* component */,
+            statsToken = ImeTracker.forLogging().onRequestShow(null /* component */,
                     Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
                     SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API);
         }
@@ -1006,6 +1080,9 @@
         }
         // Handle pending request ready in case there was one set.
         if (fromIme && mPendingImeControlRequest != null) {
+            if ((types & Type.ime()) != 0) {
+                ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication);
+            }
             handlePendingControlRequest(statsToken);
             return;
         }
@@ -1028,7 +1105,7 @@
                         "show ignored for type: %d animType: %d requestedVisible: %s",
                         type, animationType, requestedVisible));
                 if (isImeAnimation) {
-                    ImeTracker.get().onCancelled(statsToken,
+                    ImeTracker.forLogging().onCancelled(statsToken,
                             ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
                 }
                 continue;
@@ -1036,16 +1113,21 @@
             if (fromIme && animationType == ANIMATION_TYPE_USER) {
                 // App is already controlling the IME, don't cancel it.
                 if (isImeAnimation) {
-                    ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
+                    ImeTracker.forLogging().onFailed(
+                            statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
                 }
                 continue;
             }
             if (isImeAnimation) {
-                ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
+                ImeTracker.forLogging().onProgress(
+                        statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
             }
             typesReady |= type;
         }
         if (DEBUG) Log.d(TAG, "show typesReady: " + typesReady);
+        if (fromIme && (typesReady & Type.ime()) != 0) {
+            ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication);
+        }
         applyAnimation(typesReady, true /* show */, fromIme, statsToken);
     }
 
@@ -1074,7 +1156,7 @@
     public void hide(@InsetsType int types) {
         ImeTracker.Token statsToken = null;
         if ((types & ime()) != 0) {
-            statsToken = ImeTracker.get().onRequestHide(null /* component */,
+            statsToken = ImeTracker.forLogging().onRequestHide(null /* component */,
                     Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
                     SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
         }
@@ -1123,13 +1205,14 @@
                 // no-op: already hidden or animating out (because window visibility is
                 // applied before starting animation).
                 if (isImeAnimation) {
-                    ImeTracker.get().onCancelled(statsToken,
+                    ImeTracker.forLogging().onCancelled(statsToken,
                             ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
                 }
                 continue;
             }
             if (isImeAnimation) {
-                ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
+                ImeTracker.forLogging().onProgress(
+                        statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
             }
             typesReady |= type;
         }
@@ -1201,8 +1284,19 @@
             @AnimationType int animationType,
             @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
             boolean useInsetsAnimationThread, @Nullable ImeTracker.Token statsToken) {
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION);
         if ((types & mTypesBeingCancelled) != 0) {
+            final boolean monitoredAnimation =
+                    animationType == ANIMATION_TYPE_SHOW || animationType == ANIMATION_TYPE_HIDE;
+            if (monitoredAnimation && (types & Type.ime()) != 0) {
+                if (animationType == ANIMATION_TYPE_SHOW) {
+                    ImeTracker.forLatency().onShowCancelled(statsToken,
+                            PHASE_CLIENT_ANIMATION_CANCEL, ActivityThread::currentApplication);
+                } else {
+                    ImeTracker.forLatency().onHideCancelled(statsToken,
+                            PHASE_CLIENT_ANIMATION_CANCEL, ActivityThread::currentApplication);
+                }
+            }
             throw new IllegalStateException("Cannot start a new insets animation of "
                     + Type.toString(types)
                     + " while an existing " + Type.toString(mTypesBeingCancelled)
@@ -1214,10 +1308,11 @@
             types &= ~mDisabledUserAnimationInsetsTypes;
 
             if ((disabledTypes & ime()) != 0) {
-                ImeTracker.get().onFailed(statsToken,
+                ImeTracker.forLogging().onFailed(statsToken,
                         ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);
 
-                if (fromIme && !mState.getSource(mImeSourceConsumer.getId()).isVisible()) {
+                if (fromIme
+                        && !mState.isSourceOrDefaultVisible(mImeSourceConsumer.getId(), ime())) {
                     // We've requested IMM to show IME, but the IME is not controllable. We need to
                     // cancel the request.
                     setRequestedVisibleTypes(0 /* visibleTypes */, ime());
@@ -1235,7 +1330,8 @@
             Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
             return;
         }
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);
+        ImeTracker.forLogging().onProgress(statsToken,
+                ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);
         if (DEBUG) Log.d(TAG, "controlAnimation types: " + types);
         mLastStartedAnimTypes |= types;
 
@@ -1302,8 +1398,11 @@
         if ((typesReady & WindowInsets.Type.ime()) != 0) {
             ImeTracing.getInstance().triggerClientDump("InsetsAnimationControlImpl",
                     mHost.getInputMethodManager(), null /* icProto */);
+            if (animationType == ANIMATION_TYPE_HIDE) {
+                ImeTracker.forLatency().onHidden(statsToken, ActivityThread::currentApplication);
+            }
         }
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
         mRunningAnimations.add(new RunningAnimation(runner, animationType));
         if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
                 + useInsetsAnimationThread);
@@ -1343,7 +1442,8 @@
     private Pair<Integer, Boolean> collectSourceControls(boolean fromIme, @InsetsType int types,
             SparseArray<InsetsSourceControl> controls, @AnimationType int animationType,
             @Nullable ImeTracker.Token statsToken) {
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_COLLECT_SOURCE_CONTROLS);
+        ImeTracker.forLogging().onProgress(statsToken,
+                ImeTracker.PHASE_CLIENT_COLLECT_SOURCE_CONTROLS);
 
         int typesReady = 0;
         boolean imeReady = true;
@@ -1446,13 +1546,13 @@
         }
         final ImeTracker.Token statsToken = runner.getStatsToken();
         if (shown) {
-            ImeTracker.get().onProgress(statsToken,
+            ImeTracker.forLogging().onProgress(statsToken,
                     ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_SHOW);
-            ImeTracker.get().onShown(statsToken);
+            ImeTracker.forLogging().onShown(statsToken);
         } else {
-            ImeTracker.get().onProgress(statsToken,
+            ImeTracker.forLogging().onProgress(statsToken,
                     ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_HIDE);
-            ImeTracker.get().onHidden(statsToken);
+            ImeTracker.forLogging().onHidden(statsToken);
         }
         reportRequestedVisibleTypes();
     }
@@ -1478,13 +1578,13 @@
 
     private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) {
         if (invokeCallback) {
-            ImeTracker.get().onCancelled(control.getStatsToken(),
-                    ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL);
+            ImeTracker.forLogging().onCancelled(control.getStatsToken(),
+                    PHASE_CLIENT_ANIMATION_CANCEL);
             control.cancel();
         } else {
             // Succeeds if invokeCallback is false (i.e. when called from notifyFinished).
-            ImeTracker.get().onProgress(control.getStatsToken(),
-                    ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL);
+            ImeTracker.forLogging().onProgress(control.getStatsToken(),
+                    PHASE_CLIENT_ANIMATION_CANCEL);
         }
         if (DEBUG) {
             Log.d(TAG, TextUtils.formatSimple(
@@ -1649,7 +1749,7 @@
         final InternalAnimationControlListener listener = new InternalAnimationControlListener(
                 show, hasAnimationCallbacks, types, mHost.getSystemBarsBehavior(),
                 skipAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP),
-                mLoggingListener);
+                mLoggingListener, mJankContext);
 
         // We are about to playing the default animation (show/hide). Passing a null frame indicates
         // the controlled types should be animated regardless of the frame.
@@ -1757,10 +1857,10 @@
         if (mCaptionInsetsHeight != height) {
             mCaptionInsetsHeight = height;
             if (mCaptionInsetsHeight != 0) {
-                mState.getSource(ITYPE_CAPTION_BAR).setFrame(mFrame.left, mFrame.top,
-                        mFrame.right, mFrame.top + mCaptionInsetsHeight);
+                mState.getOrCreateSource(ID_CAPTION_BAR, captionBar()).setFrame(
+                        mFrame.left, mFrame.top, mFrame.right, mFrame.top + mCaptionInsetsHeight);
             } else {
-                mState.removeSource(ITYPE_CAPTION_BAR);
+                mState.removeSource(ID_CAPTION_BAR);
             }
             mHost.notifyInsetsChanged();
         }
diff --git a/core/java/android/view/InsetsResizeAnimationRunner.java b/core/java/android/view/InsetsResizeAnimationRunner.java
index cf64eedf..bffaeea 100644
--- a/core/java/android/view/InsetsResizeAnimationRunner.java
+++ b/core/java/android/view/InsetsResizeAnimationRunner.java
@@ -33,7 +33,6 @@
 import android.graphics.Rect;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsAnimation.Bounds;
 import android.view.animation.Interpolator;
@@ -142,24 +141,23 @@
             return false;
         }
         final float fraction = mAnimation.getInterpolatedFraction();
-        for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
-            final InsetsSource fromSource = mFromState.peekSource(type);
-            final InsetsSource toSource = mToState.peekSource(type);
-            if (fromSource == null || toSource == null) {
-                continue;
+        InsetsState.traverse(mFromState, mToState, new InsetsState.OnTraverseCallbacks() {
+            @Override
+            public void onIdMatch(InsetsSource fromSource, InsetsSource toSource) {
+                final Rect fromFrame = fromSource.getFrame();
+                final Rect toFrame = toSource.getFrame();
+                final Rect frame = new Rect(
+                        (int) (fromFrame.left + fraction * (toFrame.left - fromFrame.left)),
+                        (int) (fromFrame.top + fraction * (toFrame.top - fromFrame.top)),
+                        (int) (fromFrame.right + fraction * (toFrame.right - fromFrame.right)),
+                        (int) (fromFrame.bottom + fraction * (toFrame.bottom - fromFrame.bottom)));
+                final InsetsSource source =
+                        new InsetsSource(fromSource.getId(), fromSource.getType());
+                source.setFrame(frame);
+                source.setVisible(toSource.isVisible());
+                outState.addSource(source);
             }
-            final Rect fromFrame = fromSource.getFrame();
-            final Rect toFrame = toSource.getFrame();
-            final Rect frame = new Rect(
-                    (int) (fromFrame.left + fraction * (toFrame.left - fromFrame.left)),
-                    (int) (fromFrame.top + fraction * (toFrame.top - fromFrame.top)),
-                    (int) (fromFrame.right + fraction * (toFrame.right - fromFrame.right)),
-                    (int) (fromFrame.bottom + fraction * (toFrame.bottom - fromFrame.bottom)));
-            final InsetsSource source = new InsetsSource(type, fromSource.getType());
-            source.setFrame(frame);
-            source.setVisible(toSource.isVisible());
-            outState.addSource(source);
-        }
+        });
         if (mFinished) {
             mController.notifyFinished(this, true /* shown */);
         }
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index f6b063d..17ab83c 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -21,7 +21,9 @@
 import static android.view.InsetsSourceProto.VISIBLE;
 import static android.view.InsetsSourceProto.VISIBLE_FRAME;
 import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
+import static android.view.WindowInsets.Type.ime;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Insets;
@@ -40,6 +42,9 @@
  */
 public class InsetsSource implements Parcelable {
 
+    /** The insets source ID of IME */
+    public static final int ID_IME = createId(null, 0, ime());
+
     /**
      * An unique integer to identify this source across processes.
      */
@@ -83,20 +88,24 @@
         mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
     }
 
-    public void setFrame(int left, int top, int right, int bottom) {
+    public InsetsSource setFrame(int left, int top, int right, int bottom) {
         mFrame.set(left, top, right, bottom);
+        return this;
     }
 
-    public void setFrame(Rect frame) {
+    public InsetsSource setFrame(Rect frame) {
         mFrame.set(frame);
+        return this;
     }
 
-    public void setVisibleFrame(@Nullable Rect visibleFrame) {
+    public InsetsSource setVisibleFrame(@Nullable Rect visibleFrame) {
         mVisibleFrame = visibleFrame != null ? new Rect(visibleFrame) : null;
+        return this;
     }
 
-    public void setVisible(boolean visible) {
+    public InsetsSource setVisible(boolean visible) {
         mVisible = visible;
+        return this;
     }
 
     public int getId() {
@@ -128,8 +137,9 @@
         return mInsetsRoundedCornerFrame;
     }
 
-    public void setInsetsRoundedCornerFrame(boolean insetsRoundedCornerFrame) {
+    public InsetsSource setInsetsRoundedCornerFrame(boolean insetsRoundedCornerFrame) {
         mInsetsRoundedCornerFrame = insetsRoundedCornerFrame;
+        return this;
     }
 
     /**
@@ -223,6 +233,29 @@
     }
 
     /**
+     * Creates an identifier of an {@link InsetsSource}.
+     *
+     * @param owner An object owned by the owner. Only the owner can modify its own sources.
+     * @param index An owner may have multiple sources with the same type. For example, the system
+     *              server might have multiple display cutout sources. This is used to identify
+     *              which one is which. The value must be in a range of [0, 2047].
+     * @param type The {@link WindowInsets.Type.InsetsType type} of the source.
+     * @return a unique integer as the identifier.
+     */
+    public static int createId(Object owner, @IntRange(from = 0, to = 2047) int index,
+            @InsetsType int type) {
+        if (index < 0 || index >= 2048) {
+            throw new IllegalArgumentException();
+        }
+        // owner takes top 16 bits;
+        // index takes 11 bits since the 6th bit;
+        // type takes bottom 5 bits.
+        return (((owner != null ? owner.hashCode() : 1) % (1 << 16)) << 16)
+                + (index << 5)
+                + WindowInsets.Type.indexOf(type);
+    }
+
+    /**
      * Export the state of {@link InsetsSource} into a protocol buffer output stream.
      *
      * @param proto   Stream to write the state to
@@ -241,7 +274,7 @@
 
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
-        pw.print("InsetsSource id="); pw.print(mId);
+        pw.print("InsetsSource id="); pw.print(Integer.toHexString(mId));
         pw.print(" type="); pw.print(WindowInsets.Type.toString(mType));
         pw.print(" frame="); pw.print(mFrame.toShortString());
         if (mVisibleFrame != null) {
@@ -258,7 +291,7 @@
     }
 
     /**
-     * @param excludeInvisibleImeFrames If {@link InsetsState#ITYPE_IME} frames should be ignored
+     * @param excludeInvisibleImeFrames If {@link WindowInsets.Type#ime()} frames should be ignored
      *                                  when IME is not visible.
      */
     public boolean equals(@Nullable Object o, boolean excludeInvisibleImeFrames) {
@@ -316,8 +349,7 @@
 
     @Override
     public String toString() {
-        return "InsetsSource: {"
-                + "mId=" + mId
+        return "InsetsSource: {" + Integer.toHexString(mId)
                 + " mType=" + WindowInsets.Type.toString(mType)
                 + " mFrame=" + mFrame.toShortString()
                 + " mVisible=" + mVisible
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index c849cb5..7ea93f5 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -205,8 +205,7 @@
 
     @Override
     public String toString() {
-        return "InsetsSourceControl: {"
-                + "mId=" + mId
+        return "InsetsSourceControl: {" + Integer.toHexString(mId)
                 + " mType=" + WindowInsets.Type.toString(mType)
                 + (mInitiallyVisible ? " initiallyVisible" : "")
                 + " mSurfacePosition=" + mSurfacePosition
@@ -217,7 +216,7 @@
 
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
-        pw.print("InsetsSourceControl mId="); pw.print(mId);
+        pw.print("InsetsSourceControl mId="); pw.print(Integer.toHexString(mId));
         pw.print(" mType="); pw.print(WindowInsets.Type.toString(mType));
         pw.print(" mLeash="); pw.print(mLeash);
         pw.print(" mInitiallyVisible="); pw.print(mInitiallyVisible);
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 054d177..ba7d823 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -20,6 +20,7 @@
 import static android.view.InsetsStateProto.DISPLAY_FRAME;
 import static android.view.InsetsStateProto.SOURCES;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+import static android.view.WindowInsets.Type.captionBar;
 import static android.view.WindowInsets.Type.displayCutout;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.indexOf;
@@ -42,6 +43,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArraySet;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.WindowInsets.Type;
@@ -53,7 +55,6 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
 import java.util.Objects;
 import java.util.StringJoiner;
 
@@ -85,11 +86,6 @@
             ITYPE_TOP_TAPPABLE_ELEMENT,
             ITYPE_RIGHT_TAPPABLE_ELEMENT,
             ITYPE_BOTTOM_TAPPABLE_ELEMENT,
-            ITYPE_LEFT_DISPLAY_CUTOUT,
-            ITYPE_TOP_DISPLAY_CUTOUT,
-            ITYPE_RIGHT_DISPLAY_CUTOUT,
-            ITYPE_BOTTOM_DISPLAY_CUTOUT,
-            ITYPE_IME,
             ITYPE_CLIMATE_BAR,
             ITYPE_EXTRA_NAVIGATION_BAR,
             ITYPE_LEFT_GENERIC_OVERLAY,
@@ -99,15 +95,7 @@
     })
     public @interface InternalInsetsType {}
 
-    /**
-     * Special value to be used to by methods returning an {@link InternalInsetsType} to indicate
-     * that the objects/parameters aren't associated with an {@link InternalInsetsType}
-     */
-    public static final int ITYPE_INVALID = -1;
-
-    static final int FIRST_TYPE = 0;
-
-    public static final int ITYPE_STATUS_BAR = FIRST_TYPE;
+    public static final int ITYPE_STATUS_BAR = 0;
     public static final int ITYPE_NAVIGATION_BAR = 1;
     public static final int ITYPE_CAPTION_BAR = 2;
 
@@ -121,19 +109,11 @@
     public static final int ITYPE_LEFT_MANDATORY_GESTURES = 9;
     public static final int ITYPE_RIGHT_MANDATORY_GESTURES = 10;
 
-    public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 11;
-    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 12;
-    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 13;
-    public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 14;
-
     public static final int ITYPE_LEFT_TAPPABLE_ELEMENT = 15;
     public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 16;
     public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 17;
     public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 18;
 
-    /** Input method window. */
-    public static final int ITYPE_IME = 19;
-
     /** Additional system decorations inset type. */
     public static final int ITYPE_CLIMATE_BAR = 20;
     public static final int ITYPE_EXTRA_NAVIGATION_BAR = 21;
@@ -144,16 +124,8 @@
     public static final int ITYPE_RIGHT_GENERIC_OVERLAY = 24;
     public static final int ITYPE_BOTTOM_GENERIC_OVERLAY = 25;
 
-    static final int LAST_TYPE = ITYPE_BOTTOM_GENERIC_OVERLAY;
-    public static final int SIZE = LAST_TYPE + 1;
-
-    // Derived types
-
-    /** A shelf is the same as the navigation bar. */
-    public static final int ITYPE_SHELF = ITYPE_NAVIGATION_BAR;
-
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "IINSETS_SIDE", value = {
+    @IntDef(prefix = "ISIDE", value = {
             ISIDE_LEFT,
             ISIDE_TOP,
             ISIDE_RIGHT,
@@ -169,7 +141,7 @@
     static final int ISIDE_FLOATING = 4;
     static final int ISIDE_UNKNOWN = 5;
 
-    private final InsetsSource[] mSources = new InsetsSource[SIZE];
+    private final SparseArray<InsetsSource> mSources;
 
     /**
      * The frame of the display these sources are relative to.
@@ -201,13 +173,15 @@
     private DisplayShape mDisplayShape = DisplayShape.NONE;
 
     public InsetsState() {
+        mSources = new SparseArray<>();
     }
 
     public InsetsState(InsetsState copy) {
-        set(copy);
+        this(copy, false /* copySources */);
     }
 
     public InsetsState(InsetsState copy, boolean copySources) {
+        mSources = new SparseArray<>(copy.mSources.size());
         set(copy, copySources);
     }
 
@@ -224,36 +198,29 @@
             boolean isScreenRound, boolean alwaysConsumeSystemBars,
             int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags,
             int windowType, @WindowConfiguration.WindowingMode int windowingMode,
-            @Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
+            @Nullable @InternalInsetsSide SparseIntArray idSideMap) {
         Insets[] typeInsetsMap = new Insets[Type.SIZE];
         Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
         boolean[] typeVisibilityMap = new boolean[Type.SIZE];
         final Rect relativeFrame = new Rect(frame);
         final Rect relativeFrameMax = new Rect(frame);
-        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
-            InsetsSource source = mSources[type];
-            if (source == null) {
-                int index = indexOf(toPublicType(type));
-                if (typeInsetsMap[index] == null) {
-                    typeInsetsMap[index] = Insets.NONE;
-                }
-                continue;
-            }
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
 
             processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
-                    typeSideMap, typeVisibilityMap);
+                    idSideMap, typeVisibilityMap);
 
             // IME won't be reported in max insets as the size depends on the EditorInfo of the IME
             // target.
             if (source.getType() != WindowInsets.Type.ime()) {
                 InsetsSource ignoringVisibilitySource = ignoringVisibilityState != null
-                        ? ignoringVisibilityState.getSource(type)
+                        ? ignoringVisibilityState.peekSource(source.getId())
                         : source;
                 if (ignoringVisibilitySource == null) {
                     continue;
                 }
                 processSource(ignoringVisibilitySource, relativeFrameMax,
-                        true /* ignoreVisibility */, typeMaxInsetsMap, null /* typeSideMap */,
+                        true /* ignoreVisibility */, typeMaxInsetsMap, null /* idSideMap */,
                         null /* typeVisibilityMap */);
             }
         }
@@ -306,8 +273,9 @@
         // If mRoundedCornerFrame is set, we should calculate the new RoundedCorners based on this
         // frame.
         final Rect roundedCornerFrame = new Rect(mRoundedCornerFrame);
-        for (InsetsSource source : mSources) {
-            if (source != null && source.getInsetsRoundedCornerFrame()) {
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
+            if (source.getInsetsRoundedCornerFrame()) {
                 final Insets insets = source.calculateInsets(roundedCornerFrame, false);
                 roundedCornerFrame.inset(insets);
             }
@@ -351,13 +319,9 @@
 
     public Insets calculateInsets(Rect frame, @InsetsType int types, boolean ignoreVisibility) {
         Insets insets = Insets.NONE;
-        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
-            InsetsSource source = mSources[type];
-            if (source == null) {
-                continue;
-            }
-            int publicType = InsetsState.toPublicType(type);
-            if ((publicType & types) == 0) {
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
+            if ((source.getType() & types) == 0) {
                 continue;
             }
             insets = Insets.max(source.calculateInsets(frame, ignoreVisibility), insets);
@@ -368,13 +332,9 @@
     public Insets calculateInsets(Rect frame, @InsetsType int types,
             @InsetsType int requestedVisibleTypes) {
         Insets insets = Insets.NONE;
-        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
-            InsetsSource source = mSources[type];
-            if (source == null) {
-                continue;
-            }
-            int publicType = InsetsState.toPublicType(type);
-            if ((publicType & types & requestedVisibleTypes) == 0) {
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
+            if ((source.getType() & types & requestedVisibleTypes) == 0) {
                 continue;
             }
             insets = Insets.max(source.calculateInsets(frame, true), insets);
@@ -392,13 +352,9 @@
                 ? systemBars() | ime()
                 : systemBars();
         Insets insets = Insets.NONE;
-        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
-            InsetsSource source = mSources[type];
-            if (source == null) {
-                continue;
-            }
-            final int publicType = InsetsState.toPublicType(type);
-            if ((publicType & visibleInsetsTypes) == 0) {
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
+            if ((source.getType() & visibleInsetsTypes) == 0) {
                 continue;
             }
             insets = Insets.max(source.calculateVisibleInsets(frame), insets);
@@ -416,13 +372,10 @@
     @InsetsType
     public int calculateUncontrollableInsetsFromFrame(Rect frame) {
         int blocked = 0;
-        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
-            InsetsSource source = mSources[type];
-            if (source == null) {
-                continue;
-            }
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
             if (!canControlSource(frame, source)) {
-                blocked |= toPublicType(type);
+                blocked |= source.getType();
             }
         }
         return blocked;
@@ -438,12 +391,12 @@
     }
 
     private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
-            Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray typeSideMap,
+            Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray idSideMap,
             @Nullable boolean[] typeVisibilityMap) {
         Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
 
         final int type = source.getType();
-        processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+        processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                 insets, type);
 
         if (type == Type.MANDATORY_SYSTEM_GESTURES) {
@@ -452,24 +405,24 @@
             //       Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the
             //       ability to set systemGestureInsets() independently from
             //       mandatorySystemGestureInsets() in the Builder.
-            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                     insets, Type.SYSTEM_GESTURES);
         }
         if (type == Type.CAPTION_BAR) {
             // Caption should also be gesture and tappable elements. This should not be needed when
             // the caption is added from the shell, as the shell can add other types at the same
             // time.
-            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                     insets, Type.SYSTEM_GESTURES);
-            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                     insets, Type.MANDATORY_SYSTEM_GESTURES);
-            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                     insets, Type.TAPPABLE_ELEMENT);
         }
     }
 
     private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
-            @InternalInsetsSide @Nullable SparseIntArray typeSideMap,
+            @InternalInsetsSide @Nullable SparseIntArray idSideMap,
             @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
         int index = indexOf(type);
         Insets existing = typeInsetsMap[index];
@@ -483,10 +436,10 @@
             typeVisibilityMap[index] = source.isVisible();
         }
 
-        if (typeSideMap != null) {
+        if (idSideMap != null) {
             @InternalInsetsSide int insetSide = getInsetSide(insets);
             if (insetSide != ISIDE_UNKNOWN) {
-                typeSideMap.put(source.getId(), insetSide);
+                idSideMap.put(source.getId(), insetSide);
             }
         }
     }
@@ -514,31 +467,60 @@
         return ISIDE_UNKNOWN;
     }
 
-    public InsetsSource getSource(@InternalInsetsType int type) {
-        InsetsSource source = mSources[type];
+    /**
+     * Gets the source mapped from the ID, or creates one if no such mapping has been made.
+     */
+    public InsetsSource getOrCreateSource(int id, int type) {
+        InsetsSource source = mSources.get(id);
         if (source != null) {
             return source;
         }
-        source = new InsetsSource(type, toPublicType(type));
-        mSources[type] = source;
+        source = new InsetsSource(id, type);
+        mSources.put(id, source);
         return source;
     }
 
-    public @Nullable InsetsSource peekSource(@InternalInsetsType int type) {
-        return mSources[type];
+    /**
+     * Gets the source mapped from the ID, or <code>null</code> if no such mapping has been made.
+     */
+    public @Nullable InsetsSource peekSource(int id) {
+        return mSources.get(id);
     }
 
     /**
-     * Returns the source visibility or the default visibility if the source doesn't exist. This is
-     * useful if when treating this object as a request.
+     * Given an index in the range <code>0...sourceSize()-1</code>, returns the source ID from the
+     * <code>index</code>th ID-source mapping that this state stores.
+     */
+    public int sourceIdAt(int index) {
+        return mSources.keyAt(index);
+    }
+
+    /**
+     * Given an index in the range <code>0...sourceSize()-1</code>, returns the source from the
+     * <code>index</code>th ID-source mapping that this state stores.
+     */
+    public InsetsSource sourceAt(int index) {
+        return mSources.valueAt(index);
+    }
+
+    /**
+     * Returns the amount of the sources.
+     */
+    public int sourceSize() {
+        return mSources.size();
+    }
+
+    /**
+     * Returns if the source is visible or the type is default visible and the source doesn't exist.
      *
-     * @param type The {@link InternalInsetsType} to query.
+     * @param id The ID of the source.
+     * @param type The {@link InsetsType} to see if it is default visible.
      * @return {@code true} if the source is visible or the type is default visible and the source
      *         doesn't exist.
      */
-    public boolean getSourceOrDefaultVisibility(@InternalInsetsType int type) {
-        final InsetsSource source = mSources[type];
-        return source != null ? source.isVisible() : getDefaultVisibility(type);
+    public boolean isSourceOrDefaultVisible(int id, @InsetsType int type) {
+        final InsetsSource source = mSources.get(id);
+        return source != null ? source.isVisible() : (type & Type.defaultVisible()) != 0;
     }
 
     public void setDisplayFrame(Rect frame) {
@@ -612,28 +594,31 @@
     }
 
     /**
-     * Modifies the state of this class to exclude a certain type to make it ready for dispatching
-     * to the client.
+     * Removes the source which has the ID from this state, if there was any.
      *
-     * @param type The {@link InternalInsetsType} of the source to remove
-     * @return {@code true} if this InsetsState was modified; {@code false} otherwise.
+     * @param id The ID of the source to remove.
      */
-    public boolean removeSource(@InternalInsetsType int type) {
-        if (mSources[type] == null) {
-            return false;
-        }
-        mSources[type] = null;
-        return true;
+    public void removeSource(int id) {
+        mSources.delete(id);
+    }
+
+    /**
+     * Removes the source at the specified index.
+     *
+     * @param index The index of the source to remove.
+     */
+    public void removeSourceAt(int index) {
+        mSources.removeAt(index);
     }
 
     /**
      * A shortcut for setting the visibility of the source.
      *
-     * @param type The {@link InternalInsetsType} of the source to set the visibility
+     * @param id The ID of the source to set the visibility
      * @param visible {@code true} for visible
      */
-    public void setSourceVisible(@InternalInsetsType int type, boolean visible) {
-        InsetsSource source = mSources[type];
+    public void setSourceVisible(int id, boolean visible) {
+        final InsetsSource source = mSources.get(id);
         if (source != null) {
             source.setVisible(visible);
         }
@@ -651,14 +636,12 @@
         mRoundedCornerFrame.scale(scale);
         mPrivacyIndicatorBounds = mPrivacyIndicatorBounds.scale(scale);
         mDisplayShape = mDisplayShape.setScale(scale);
-        for (int i = 0; i < SIZE; i++) {
-            final InsetsSource source = mSources[i];
-            if (source != null) {
-                source.getFrame().scale(scale);
-                final Rect visibleFrame = source.getVisibleFrame();
-                if (visibleFrame != null) {
-                    visibleFrame.scale(scale);
-                }
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
+            source.getFrame().scale(scale);
+            final Rect visibleFrame = source.getVisibleFrame();
+            if (visibleFrame != null) {
+                visibleFrame.scale(scale);
             }
         }
     }
@@ -674,15 +657,12 @@
         mRoundedCornerFrame.set(other.mRoundedCornerFrame);
         mPrivacyIndicatorBounds = other.getPrivacyIndicatorBounds();
         mDisplayShape = other.getDisplayShape();
-        if (copySources) {
-            for (int i = 0; i < SIZE; i++) {
-                InsetsSource source = other.mSources[i];
-                mSources[i] = source != null ? new InsetsSource(source) : null;
-            }
-        } else {
-            for (int i = 0; i < SIZE; i++) {
-                mSources[i] = other.mSources[i];
-            }
+        mSources.clear();
+        for (int i = 0, size = other.mSources.size(); i < size; i++) {
+            final InsetsSource otherSource = other.mSources.valueAt(i);
+            mSources.append(otherSource.getId(), copySources
+                    ? new InsetsSource(otherSource)
+                    : otherSource);
         }
     }
 
@@ -700,15 +680,25 @@
         mRoundedCornerFrame.set(other.mRoundedCornerFrame);
         mPrivacyIndicatorBounds = other.getPrivacyIndicatorBounds();
         mDisplayShape = other.getDisplayShape();
-        final ArraySet<Integer> t = toInternalType(types);
-        for (int i = t.size() - 1; i >= 0; i--) {
-            final int type = t.valueAt(i);
-            mSources[type] = other.mSources[type];
+        if (types == 0) {
+            return;
+        }
+        for (int i = mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mSources.valueAt(i);
+            if ((source.getType() & types) != 0) {
+                mSources.removeAt(i);
+            }
+        }
+        for (int i = other.mSources.size() - 1; i >= 0; i--) {
+            final InsetsSource otherSource = other.mSources.valueAt(i);
+            if ((otherSource.getType() & types) != 0) {
+                mSources.put(otherSource.getId(), otherSource);
+            }
         }
     }
 
     public void addSource(InsetsSource source) {
-        mSources[source.getId()] = source;
+        mSources.put(source.getId(), source);
     }
 
     public static boolean clearsCompatInsets(int windowType, int windowFlags, int windowingMode) {
@@ -748,15 +738,6 @@
             result.add(ITYPE_RIGHT_MANDATORY_GESTURES);
             result.add(ITYPE_BOTTOM_MANDATORY_GESTURES);
         }
-        if ((types & Type.DISPLAY_CUTOUT) != 0) {
-            result.add(ITYPE_LEFT_DISPLAY_CUTOUT);
-            result.add(ITYPE_TOP_DISPLAY_CUTOUT);
-            result.add(ITYPE_RIGHT_DISPLAY_CUTOUT);
-            result.add(ITYPE_BOTTOM_DISPLAY_CUTOUT);
-        }
-        if ((types & Type.IME) != 0) {
-            result.add(ITYPE_IME);
-        }
         return result;
     }
 
@@ -780,8 +761,6 @@
                 return Type.SYSTEM_OVERLAYS;
             case ITYPE_CAPTION_BAR:
                 return Type.CAPTION_BAR;
-            case ITYPE_IME:
-                return Type.IME;
             case ITYPE_TOP_MANDATORY_GESTURES:
             case ITYPE_BOTTOM_MANDATORY_GESTURES:
             case ITYPE_LEFT_MANDATORY_GESTURES:
@@ -797,33 +776,11 @@
             case ITYPE_RIGHT_TAPPABLE_ELEMENT:
             case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
                 return Type.TAPPABLE_ELEMENT;
-            case ITYPE_LEFT_DISPLAY_CUTOUT:
-            case ITYPE_TOP_DISPLAY_CUTOUT:
-            case ITYPE_RIGHT_DISPLAY_CUTOUT:
-            case ITYPE_BOTTOM_DISPLAY_CUTOUT:
-                return Type.DISPLAY_CUTOUT;
             default:
                 throw new IllegalArgumentException("Unknown type: " + type);
         }
     }
 
-    public static boolean getDefaultVisibility(@InternalInsetsType int type) {
-        return type != ITYPE_IME;
-    }
-
-    public static boolean containsType(@InternalInsetsType int[] types,
-            @InternalInsetsType int type) {
-        if (types == null) {
-            return false;
-        }
-        for (int t : types) {
-            if (t == type) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public void dump(String prefix, PrintWriter pw) {
         final String newPrefix = prefix + "  ";
         pw.println(prefix + "InsetsState");
@@ -833,16 +790,14 @@
         pw.println(newPrefix + "mRoundedCornerFrame=" + mRoundedCornerFrame);
         pw.println(newPrefix + "mPrivacyIndicatorBounds=" + mPrivacyIndicatorBounds);
         pw.println(newPrefix + "mDisplayShape=" + mDisplayShape);
-        for (int i = 0; i < SIZE; i++) {
-            InsetsSource source = mSources[i];
-            if (source == null) continue;
-            source.dump(newPrefix + "  ", pw);
+        for (int i = 0, size = mSources.size(); i < size; i++) {
+            mSources.valueAt(i).dump(newPrefix + "  ", pw);
         }
     }
 
     void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
-        InsetsSource source = mSources[ITYPE_IME];
+        final InsetsSource source = mSources.get(InsetsSource.ID_IME);
         if (source != null) {
             source.dumpDebug(proto, SOURCES);
         }
@@ -883,16 +838,6 @@
                 return "ITYPE_RIGHT_TAPPABLE_ELEMENT";
             case ITYPE_BOTTOM_TAPPABLE_ELEMENT:
                 return "ITYPE_BOTTOM_TAPPABLE_ELEMENT";
-            case ITYPE_LEFT_DISPLAY_CUTOUT:
-                return "ITYPE_LEFT_DISPLAY_CUTOUT";
-            case ITYPE_TOP_DISPLAY_CUTOUT:
-                return "ITYPE_TOP_DISPLAY_CUTOUT";
-            case ITYPE_RIGHT_DISPLAY_CUTOUT:
-                return "ITYPE_RIGHT_DISPLAY_CUTOUT";
-            case ITYPE_BOTTOM_DISPLAY_CUTOUT:
-                return "ITYPE_BOTTOM_DISPLAY_CUTOUT";
-            case ITYPE_IME:
-                return "ITYPE_IME";
             case ITYPE_CLIMATE_BAR:
                 return "ITYPE_CLIMATE_BAR";
             case ITYPE_EXTRA_NAVIGATION_BAR:
@@ -921,8 +866,8 @@
      * excluded.
      * @param excludingCaptionInsets {@code true} if we want to compare two InsetsState objects but
      *                                           ignore the caption insets source value.
-     * @param excludeInvisibleImeFrames If {@link #ITYPE_IME} frames should be ignored when IME is
-     *                                  not visible.
+     * @param excludeInvisibleImeFrames If {@link WindowInsets.Type#ime()} frames should be ignored
+     *                                  when IME is not visible.
      * @return {@code true} if the two InsetsState objects are equal, {@code false} otherwise.
      */
     @VisibleForTesting
@@ -941,38 +886,56 @@
                 || !mDisplayShape.equals(state.mDisplayShape)) {
             return false;
         }
-        for (int i = 0; i < SIZE; i++) {
-            if (excludingCaptionInsets) {
-                if (i == ITYPE_CAPTION_BAR) continue;
+
+        final SparseArray<InsetsSource> thisSources = mSources;
+        final SparseArray<InsetsSource> thatSources = state.mSources;
+        if (!excludingCaptionInsets && !excludeInvisibleImeFrames) {
+            return thisSources.contentEquals(thatSources);
+        } else {
+            final int thisSize = thisSources.size();
+            final int thatSize = thatSources.size();
+            int thisIndex = 0;
+            int thatIndex = 0;
+            while (thisIndex < thisSize && thatIndex < thatSize) {
+                // Seek to the next non-excluding source of ours.
+                InsetsSource thisSource = thisSources.valueAt(thisIndex);
+                while (thisSource != null
+                        && (excludingCaptionInsets && thisSource.getType() == captionBar()
+                                || excludeInvisibleImeFrames && thisSource.getType() == ime()
+                                        && !thisSource.isVisible())) {
+                    thisIndex++;
+                    thisSource = thisIndex < thisSize ? thisSources.valueAt(thisIndex) : null;
+                }
+
+                // Seek to the next non-excluding source of theirs.
+                InsetsSource thatSource = thatSources.valueAt(thatIndex);
+                while (thatSource != null
+                        && (excludingCaptionInsets && thatSource.getType() == captionBar()
+                                || excludeInvisibleImeFrames && thatSource.getType() == ime()
+                                        && !thatSource.isVisible())) {
+                    thatIndex++;
+                    thatSource = thatIndex < thatSize ? thatSources.valueAt(thatIndex) : null;
+                }
+
+                if (!Objects.equals(thisSource, thatSource)) {
+                    return false;
+                }
+
+                thisIndex++;
+                thatIndex++;
             }
-            InsetsSource source = mSources[i];
-            InsetsSource otherSource = state.mSources[i];
-            if (source == null && otherSource == null) {
-                continue;
-            }
-            if (excludeInvisibleImeFrames && i == ITYPE_IME
-                    && ((source == null && !otherSource.isVisible())
-                            || (otherSource == null && !source.isVisible()))) {
-                continue;
-            }
-            if (source == null || otherSource == null) {
-                return false;
-            }
-            if (!otherSource.equals(source, excludeInvisibleImeFrames)) {
-                return false;
-            }
+            return thisIndex >= thisSize && thatIndex >= thatSize;
         }
-        return true;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mDisplayFrame, mDisplayCutout, Arrays.hashCode(mSources),
+        return Objects.hash(mDisplayFrame, mDisplayCutout, mSources.contentHashCode(),
                 mRoundedCorners, mPrivacyIndicatorBounds, mRoundedCornerFrame, mDisplayShape);
     }
 
     public InsetsState(Parcel in) {
-        readFromParcel(in);
+        mSources = readFromParcel(in);
     }
 
     @Override
@@ -984,14 +947,18 @@
     public void writeToParcel(Parcel dest, int flags) {
         mDisplayFrame.writeToParcel(dest, flags);
         mDisplayCutout.writeToParcel(dest, flags);
-        dest.writeTypedArray(mSources, 0 /* parcelableFlags */);
         dest.writeTypedObject(mRoundedCorners, flags);
         mRoundedCornerFrame.writeToParcel(dest, flags);
         dest.writeTypedObject(mPrivacyIndicatorBounds, flags);
         dest.writeTypedObject(mDisplayShape, flags);
+        final int size = mSources.size();
+        dest.writeInt(size);
+        for (int i = 0; i < size; i++) {
+            dest.writeTypedObject(mSources.valueAt(i), flags);
+        }
     }
 
-    public static final @NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {
+    public static final @NonNull Creator<InsetsState> CREATOR = new Creator<>() {
 
         public InsetsState createFromParcel(Parcel in) {
             return new InsetsState(in);
@@ -1002,24 +969,34 @@
         }
     };
 
-    public void readFromParcel(Parcel in) {
+    public SparseArray<InsetsSource> readFromParcel(Parcel in) {
         mDisplayFrame.readFromParcel(in);
         mDisplayCutout.readFromParcel(in);
-        in.readTypedArray(mSources, InsetsSource.CREATOR);
         mRoundedCorners = in.readTypedObject(RoundedCorners.CREATOR);
         mRoundedCornerFrame.readFromParcel(in);
         mPrivacyIndicatorBounds = in.readTypedObject(PrivacyIndicatorBounds.CREATOR);
         mDisplayShape = in.readTypedObject(DisplayShape.CREATOR);
+        final int size = in.readInt();
+        final SparseArray<InsetsSource> sources;
+        if (mSources == null) {
+            // We are constructing this InsetsState.
+            sources = new SparseArray<>(size);
+        } else {
+            sources = mSources;
+            sources.clear();
+        }
+        for (int i = 0; i < size; i++) {
+            final InsetsSource source = in.readTypedObject(InsetsSource.CREATOR);
+            sources.append(source.getId(), source);
+        }
+        return sources;
     }
 
     @Override
     public String toString() {
-        StringJoiner joiner = new StringJoiner(", ");
-        for (int i = 0; i < SIZE; i++) {
-            InsetsSource source = mSources[i];
-            if (source != null) {
-                joiner.add(source.toString());
-            }
+        final StringJoiner joiner = new StringJoiner(", ");
+        for (int i = 0, size = mSources.size(); i < size; i++) {
+            joiner.add(mSources.valueAt(i).toString());
         }
         return "InsetsState: {"
                 + "mDisplayFrame=" + mDisplayFrame
@@ -1031,5 +1008,112 @@
                 + ", mSources= { " + joiner
                 + " }";
     }
+
+    /**
+     * Traverses sources in two {@link InsetsState}s and calls back when events defined in
+     * {@link OnTraverseCallbacks} happen. This is optimized for {@link SparseArray} that we avoid
+     * triggering the binary search while getting the key or the value.
+     *
+     * This can be used to copy attributes of sources from one InsetsState to the other one, or to
+     * remove sources existing in one InsetsState but not in the other one.
+     *
+     * @param state1 The first {@link InsetsState} to be traversed.
+     * @param state2 The second {@link InsetsState} to be traversed.
+     * @param cb The {@link OnTraverseCallbacks} to call back to the caller.
+     */
+    public static void traverse(InsetsState state1, InsetsState state2, OnTraverseCallbacks cb) {
+        cb.onStart(state1, state2);
+        final int size1 = state1.sourceSize();
+        final int size2 = state2.sourceSize();
+        int index1 = 0;
+        int index2 = 0;
+        while (index1 < size1 && index2 < size2) {
+            int id1 = state1.sourceIdAt(index1);
+            int id2 = state2.sourceIdAt(index2);
+            while (id1 != id2) {
+                if (id1 < id2) {
+                    cb.onIdNotFoundInState2(index1, state1.sourceAt(index1));
+                    index1++;
+                    if (index1 < size1) {
+                        id1 = state1.sourceIdAt(index1);
+                    } else {
+                        break;
+                    }
+                } else {
+                    cb.onIdNotFoundInState1(index2, state2.sourceAt(index2));
+                    index2++;
+                    if (index2 < size2) {
+                        id2 = state2.sourceIdAt(index2);
+                    } else {
+                        break;
+                    }
+                }
+            }
+            if (index1 >= size1 || index2 >= size2) {
+                break;
+            }
+            final InsetsSource source1 = state1.sourceAt(index1);
+            final InsetsSource source2 = state2.sourceAt(index2);
+            cb.onIdMatch(source1, source2);
+            index1++;
+            index2++;
+        }
+        while (index2 < size2) {
+            cb.onIdNotFoundInState1(index2, state2.sourceAt(index2));
+            index2++;
+        }
+        while (index1 < size1) {
+            cb.onIdNotFoundInState2(index1, state1.sourceAt(index1));
+            index1++;
+        }
+        cb.onFinish(state1, state2);
+    }
+
+    /**
+     * Used with {@link #traverse(InsetsState, InsetsState, OnTraverseCallbacks)} to call back when
+     * certain events happen.
+     */
+    public interface OnTraverseCallbacks {
+
+        /**
+         * Called at the beginning of the traverse.
+         *
+         * @param state1 same as the state1 supplied to {@link #traverse}
+         * @param state2 same as the state2 supplied to {@link #traverse}
+         */
+        default void onStart(InsetsState state1, InsetsState state2) { }
+
+        /**
+         * Called when finding two IDs from two InsetsStates are the same.
+         *
+         * @param source1 the source in state1.
+         * @param source2 the source in state2.
+         */
+        default void onIdMatch(InsetsSource source1, InsetsSource source2) { }
+
+        /**
+         * Called when finding an ID in state2 but not in state1.
+         *
+         * @param index2 the index of the ID in state2.
+         * @param source2 the source which has the ID in state2.
+         */
+        default void onIdNotFoundInState1(int index2, InsetsSource source2) { }
+
+        /**
+         * Called when finding an ID in state1 but not in state2.
+         *
+         * @param index1 the index of the ID in state1.
+         * @param source1 the source which has the ID in state1.
+         */
+        default void onIdNotFoundInState2(int index1, InsetsSource source1) { }
+
+        /**
+         * Called at the end of the traverse.
+         *
+         * @param state1 same as the state1 supplied to {@link #traverse}
+         * @param state2 same as the state2 supplied to {@link #traverse}
+         */
+        default void onFinish(InsetsState state1, InsetsState state2) { }
+    }
 }
 
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 54e1a53..8e09411 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -64,6 +64,7 @@
 import android.opengl.EGLSync;
 import android.os.Build;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -172,6 +173,7 @@
             boolean isTrustedOverlay);
     private static native void nativeSetDropInputMode(
             long transactionObj, long nativeObject, int flags);
+    private static native void nativeSurfaceFlushJankData(long nativeSurfaceObject);
     private static native boolean nativeClearContentFrameStats(long nativeObject);
     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
     private static native boolean nativeClearAnimationFrameStats();
@@ -463,6 +465,10 @@
     public long mNativeObject;
     private long mNativeHandle;
 
+    private final Object mChoreographerLock = new Object();
+    @GuardedBy("mChoreographerLock")
+    private Choreographer mChoreographer;
+
     // TODO: Move width/height to native and fix locking through out.
     private final Object mLock = new Object();
     @GuardedBy("mLock")
@@ -474,6 +480,14 @@
 
     private WeakReference<View> mLocalOwnerView;
 
+    // A throwable with the stack filled when this SurfaceControl is released (only if
+    // sDebugUsageAfterRelease) is enabled
+    private Throwable mReleaseStack = null;
+
+    // Triggers the stack to be saved when any SurfaceControl in this process is released, which can
+    // be dumped as additional context
+    private static volatile boolean sDebugUsageAfterRelease = false;
+
     static GlobalTransactionWrapper sGlobalTransaction;
     static long sTransactionNestCount = 0;
 
@@ -746,6 +760,11 @@
         }
         mNativeObject = nativeObject;
         mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
+        if (sDebugUsageAfterRelease && mNativeObject == 0) {
+            mReleaseStack = new Throwable("Assigned invalid nativeObject");
+        } else {
+            mReleaseStack = null;
+        }
     }
 
     /**
@@ -1241,6 +1260,9 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        if (sDebugUsageAfterRelease) {
+            checkNotReleased();
+        }
         dest.writeString8(mName);
         dest.writeInt(mWidth);
         dest.writeInt(mHeight);
@@ -1257,6 +1279,18 @@
     }
 
     /**
+     * Enables additional debug logs to track usage-after-release of all SurfaceControls in this
+     * process.
+     * @hide
+     */
+    public static void setDebugUsageAfterRelease(boolean debug) {
+        if (!Build.isDebuggable()) {
+            return;
+        }
+        sDebugUsageAfterRelease = debug;
+    }
+
+    /**
      * Checks whether two {@link SurfaceControl} objects represent the same surface.
      *
      * @param other The other object to check
@@ -1269,6 +1303,59 @@
     }
 
     /**
+     * Returns the associated {@link Choreographer} instance with the
+     * current instance of the SurfaceControl.
+     * Must be called from a thread that already has a {@link android.os.Looper}
+     * associated with it.
+     * If there is no {@link Choreographer} associated with the SurfaceControl then a new instance
+     * of the {@link Choreographer} is created.
+     *
+     * @hide
+     */
+    @TestApi
+    public @NonNull Choreographer getChoreographer() {
+        return getChoreographer(Looper.myLooper());
+    }
+
+    /**
+     * Returns the associated {@link Choreographer} instance with the
+     * current instance of the SurfaceControl.
+     * If there is no {@link Choreographer} associated with the SurfaceControl then a new instance
+     * of the {@link Choreographer} is created.
+     *
+     * @param looper the choreographer is attached on this looper
+     *
+     * @hide
+     */
+    @TestApi
+    public @NonNull Choreographer getChoreographer(@NonNull Looper looper) {
+        checkNotReleased();
+        synchronized (mChoreographerLock) {
+            if (mChoreographer != null) {
+                return mChoreographer;
+            }
+
+            mChoreographer = Choreographer.getInstanceForSurfaceControl(mNativeHandle, looper);
+            return mChoreographer;
+        }
+    }
+
+    /**
+     * Returns true if {@link Choreographer} is present otherwise false.
+     * To check the validity use {@link #isValid} on the SurfaceControl, a valid SurfaceControl with
+     * choreographer will have the valid Choreographer.
+     *
+     * @hide
+     */
+    @TestApi
+    @UnsupportedAppUsage
+    public boolean hasChoreographer() {
+        synchronized (mChoreographerLock) {
+            return mChoreographer != null;
+        }
+    }
+
+    /**
      * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
      * android.view.SurfaceControlProto}.
      *
@@ -1324,7 +1411,16 @@
             mFreeNativeResources.run();
             mNativeObject = 0;
             mNativeHandle = 0;
+            if (sDebugUsageAfterRelease) {
+                mReleaseStack = new Throwable("Released");
+            }
             mCloseGuard.close();
+            synchronized (mChoreographerLock) {
+                if (mChoreographer != null) {
+                    mChoreographer.invalidate();
+                    mChoreographer = null;
+                }
+            }
         }
     }
 
@@ -1339,8 +1435,15 @@
     }
 
     private void checkNotReleased() {
-        if (mNativeObject == 0) throw new NullPointerException(
-                "Invalid " + this + ", mNativeObject is null. Have you called release() already?");
+        if (mNativeObject == 0) {
+            if (mReleaseStack != null) {
+                throw new IllegalStateException("Invalid usage after release of " + this,
+                        mReleaseStack);
+            } else {
+                throw new NullPointerException("mNativeObject of " + this
+                        + " is null. Have you called release() already?");
+            }
+        }
     }
 
     /**
@@ -1692,7 +1795,7 @@
      * Information about the min and max refresh rate DM would like to set the display to.
      * @hide
      */
-    public static final class RefreshRateRange {
+    public static final class RefreshRateRange implements Parcelable {
         public static final String TAG = "RefreshRateRange";
 
         // The tolerance within which we consider something approximately equals.
@@ -1761,6 +1864,35 @@
             this.min = other.min;
             this.max = other.max;
         }
+
+        /**
+         * Writes the RefreshRateRange to parce
+         *
+         * @param dest parcel to write the transaction to
+         */
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
+            dest.writeFloat(min);
+            dest.writeFloat(max);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final @NonNull Creator<RefreshRateRange> CREATOR =
+                new Creator<RefreshRateRange>() {
+                    @Override
+                    public RefreshRateRange createFromParcel(Parcel in) {
+                        return new RefreshRateRange(in.readFloat(), in.readFloat());
+                    }
+
+                    @Override
+                    public RefreshRateRange[] newArray(int size) {
+                        return new RefreshRateRange[size];
+                    }
+                };
     }
 
     /**
@@ -2411,10 +2543,10 @@
      * {@link Transaction#setTrustedPresentationCallback(SurfaceControl,
      * TrustedPresentationThresholds, Executor, Consumer)}
      */
-    public static class TrustedPresentationThresholds {
-        private float mMinAlpha;
-        private float mMinFractionRendered;
-        private int mStabilityRequirementMs;
+    public static final class TrustedPresentationThresholds {
+        private final float mMinAlpha;
+        private final float mMinFractionRendered;
+        private final int mStabilityRequirementMs;
 
         /**
          * Creates a TrustedPresentationThresholds that's used when calling
@@ -2645,7 +2777,7 @@
          */
         @NonNull
         public Transaction setFrameRateSelectionPriority(@NonNull SurfaceControl sc, int priority) {
-            sc.checkNotReleased();
+            checkPreconditions(sc);
             nativeSetFrameRateSelectionPriority(mNativeObject, sc.mNativeObject, priority);
             return this;
         }
@@ -3754,6 +3886,15 @@
         }
 
         /**
+         * Sends a flush jank data transaction for the given surface.
+         * @hide
+         */
+        public static void sendSurfaceFlushJankData(SurfaceControl sc) {
+            sc.checkNotReleased();
+            nativeSurfaceFlushJankData(sc.mNativeObject);
+        }
+
+        /**
          * @hide
          */
         public void sanitize() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 06dab15..cecfc8a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8919,8 +8919,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    @TestApi
-    public void getBoundsOnScreen(@NonNull Rect outRect, boolean clipToParent) {
+    public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
         if (mAttachInfo == null) {
             return;
         }
@@ -8928,7 +8927,6 @@
         getBoundsToScreenInternal(position, clipToParent);
         outRect.set(Math.round(position.left), Math.round(position.top),
                 Math.round(position.right), Math.round(position.bottom));
-        mAttachInfo.mViewRootImpl.applyViewBoundsSandboxingIfNeeded(outRect);
     }
 
     /**
@@ -14121,7 +14119,7 @@
         // working solution.
         View source = this;
         while (true) {
-            if (source.includeForAccessibility()) {
+            if (source.includeForAccessibility(false)) {
                 source.sendAccessibilityEvent(eventType);
                 return;
             }
@@ -14475,11 +14473,12 @@
             // importance, since we'll need to check it later to make sure.
             final boolean maySkipNotify = oldMode == IMPORTANT_FOR_ACCESSIBILITY_AUTO
                     || mode == IMPORTANT_FOR_ACCESSIBILITY_AUTO;
-            final boolean oldIncludeForAccessibility = maySkipNotify && includeForAccessibility();
+            final boolean oldIncludeForAccessibility =
+                    maySkipNotify && includeForAccessibility(false);
             mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
             mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
                     & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
-            if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility()) {
+            if (!maySkipNotify || oldIncludeForAccessibility != includeForAccessibility(false)) {
                 notifySubtreeAccessibilityStateChangedIfNeeded();
             } else {
                 notifyViewAccessibilityStateChangedIfNeeded(
@@ -14611,28 +14610,53 @@
     }
 
     /**
-     * Whether to regard this view for accessibility. A view is regarded for
-     * accessibility if it is important for accessibility or the querying
-     * accessibility service has explicitly requested that view not
-     * important for accessibility are regarded.
-     *
-     * @return Whether to regard the view for accessibility.
-     *
+     * @see #includeForAccessibility(boolean)
      * @hide
      */
     @UnsupportedAppUsage
     public boolean includeForAccessibility() {
-        if (mAttachInfo != null) {
+        return includeForAccessibility(true);
+    }
+
+    /**
+     * Whether to regard this view for accessibility.
+     *
+     * <p>
+     * If this decision is used for generating the accessibility node tree then this returns false
+     * for {@link #isAccessibilityDataPrivate()} views queried by non-accessibility tools.
+     * </p>
+     * <p>
+     * Otherwise, a view is regarded for accessibility if:
+     * <li>the view returns true for {@link #isImportantForAccessibility()}, or</li>
+     * <li>the querying accessibility service has explicitly requested that views not important for
+     * accessibility are regarded by setting
+     * {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS}</li>
+     * </p>
+     *
+     * @param forNodeTree True if the result of this function will be used for generating a node
+     *                    tree, otherwise false (like when sending {@link AccessibilityEvent}s).
+     * @return Whether to regard the view for accessibility.
+     * @hide
+     */
+    public boolean includeForAccessibility(boolean forNodeTree) {
+        if (mAttachInfo == null) {
+            return false;
+        }
+
+        if (forNodeTree) {
+            // The AccessibilityDataPrivate property should not effect whether this View is
+            // included for consideration when sending AccessibilityEvents. Events copy their
+            // source View's AccessibilityDataPrivate value, and then filtering is done when
+            // AccessibilityManagerService propagates events to each recipient AccessibilityService.
             if (!AccessibilityManager.getInstance(mContext).isRequestFromAccessibilityTool()
                     && isAccessibilityDataPrivate()) {
                 return false;
             }
-
-            return (mAttachInfo.mAccessibilityFetchFlags
-                    & AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
-                    || isImportantForAccessibility();
         }
-        return false;
+
+        return (mAttachInfo.mAccessibilityFetchFlags
+                & AccessibilityNodeInfo.FLAG_SERVICE_REQUESTS_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
+                || isImportantForAccessibility();
     }
 
     /**
@@ -15966,8 +15990,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    @TestApi
-    public void getWindowDisplayFrame(@NonNull Rect outRect) {
+    public void getWindowDisplayFrame(Rect outRect) {
         if (mAttachInfo != null) {
             mAttachInfo.mViewRootImpl.getDisplayFrame(outRect);
             return;
@@ -17144,6 +17167,9 @@
      * This is similar to {@link View#requestUnbufferedDispatch(MotionEvent)}, but does not
      * automatically terminate, and allows the specification of arbitrary input source classes.
      *
+     * <p>Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, this method will fail
+     * when this View is not attached to a window.
+     *
      * @param source The combined input source class to request unbuffered dispatch for. All
      *               events coming from these source classes will not be buffered. Set to
      *               {@link InputDevice#SOURCE_CLASS_NONE} in order to return to default behaviour.
@@ -17181,7 +17207,8 @@
     void setFlags(int flags, int mask) {
         final boolean accessibilityEnabled =
                 AccessibilityManager.getInstance(mContext).isEnabled();
-        final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
+        final boolean oldIncludeForAccessibility =
+                accessibilityEnabled && includeForAccessibility(false);
 
         int old = mViewFlags;
         mViewFlags = (mViewFlags & ~mask) | (flags & mask);
@@ -17407,7 +17434,7 @@
             if ((changed & FOCUSABLE) != 0 || (changed & VISIBILITY_MASK) != 0
                     || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
                     || (changed & CONTEXT_CLICKABLE) != 0) {
-                if (oldIncludeForAccessibility != includeForAccessibility()) {
+                if (oldIncludeForAccessibility != includeForAccessibility(false)) {
                     notifySubtreeAccessibilityStateChangedIfNeeded();
                 } else {
                     notifyViewAccessibilityStateChangedIfNeeded(
@@ -26176,11 +26203,7 @@
         getLocationInWindow(outLocation);
 
         final AttachInfo info = mAttachInfo;
-
-        // Need to offset the outLocation with the window bounds, but only if "Sandboxing View
-        // Bounds APIs" is disabled. If this override is enabled, it sandboxes {@link outLocation}
-        // within activity bounds.
-        if (info != null && !info.mViewRootImpl.isViewBoundsSandboxingEnabled()) {
+        if (info != null) {
             outLocation[0] += info.mWindowLeft;
             outLocation[1] += info.mWindowTop;
         }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0e4ac01..73d4471 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3532,7 +3532,7 @@
     @Override
     public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
         boolean handled = false;
-        if (includeForAccessibility()) {
+        if (includeForAccessibility(false)) {
             handled = super.dispatchPopulateAccessibilityEventInternal(event);
             if (handled) {
                 return handled;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cb316e2..d0f095c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -16,14 +16,13 @@
 
 package android.view;
 
-import static android.content.pm.ActivityInfo.OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS;
 import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
 import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
 import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.InputDevice.SOURCE_CLASS_NONE;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.View.PFLAG_DRAW_ANIMATION;
 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
 import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
@@ -80,7 +79,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
@@ -100,7 +98,6 @@
 import android.app.ICompatCameraControlCallback;
 import android.app.ResourcesManager;
 import android.app.WindowConfiguration;
-import android.app.compat.CompatChanges;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -294,7 +291,7 @@
      * @hide
      */
     public static final boolean CAPTION_ON_SHELL =
-            SystemProperties.getBoolean("persist.wm.debug.caption_on_shell", false);
+            SystemProperties.getBoolean("persist.wm.debug.caption_on_shell", true);
 
     /**
      * Whether the client should compute the window frame on its own.
@@ -772,7 +769,12 @@
     private long mFpsPrevTime = -1;
     private int mFpsNumFrames;
 
-    private int mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED;
+    /**
+     * The resolved pointer icon type requested by this window.
+     * A null value indicates the resolved pointer icon has not yet been calculated.
+     */
+    @Nullable
+    private Integer mPointerIconType = null;
     private PointerIcon mCustomPointerIcon = null;
 
     /**
@@ -892,15 +894,6 @@
 
     private boolean mRelayoutRequested;
 
-    /**
-     * Whether sandboxing of {@link android.view.View#getBoundsOnScreen},
-     * {@link android.view.View#getLocationOnScreen},
-     * {@link android.view.View#getWindowDisplayFrame} and
-     * {@link android.view.View#getWindowVisibleDisplayFrame}
-     * within Activity bounds is enabled for the current application.
-     */
-    private final boolean mViewBoundsSandboxingEnabled;
-
     private int mLastTransformHint = Integer.MIN_VALUE;
 
     private AccessibilityWindowAttributes mAccessibilityWindowAttributes;
@@ -992,8 +985,6 @@
                 mViewConfiguration,
                 mContext.getSystemService(InputMethodManager.class));
 
-        mViewBoundsSandboxingEnabled = getViewBoundsSandboxingEnabled();
-
         String processorOverrideName = context.getResources().getString(
                                     R.string.config_inputEventCompatProcessorOverrideClassName);
         if (processorOverrideName.isEmpty()) {
@@ -1411,6 +1402,8 @@
                                 listener, listener.data, mHandler, true /*waitForPresentTime*/);
                         mAttachInfo.mThreadedRenderer.addObserver(mHardwareRendererObserver);
                     }
+                    // Update unbuffered request when set the root view.
+                    mUnbufferedInputSource = mView.mUnbufferedInputSource;
                 }
 
                 view.assignParent(this);
@@ -5824,7 +5817,7 @@
                 }
                 case MSG_SHOW_INSETS: {
                     final ImeTracker.Token statsToken = (ImeTracker.Token) msg.obj;
-                    ImeTracker.get().onProgress(statsToken,
+                    ImeTracker.forLogging().onProgress(statsToken,
                             ImeTracker.PHASE_CLIENT_HANDLE_SHOW_INSETS);
                     if (mView == null) {
                         Log.e(TAG,
@@ -5837,7 +5830,7 @@
                 }
                 case MSG_HIDE_INSETS: {
                     final ImeTracker.Token statsToken = (ImeTracker.Token) msg.obj;
-                    ImeTracker.get().onProgress(statsToken,
+                    ImeTracker.forLogging().onProgress(statsToken,
                             ImeTracker.PHASE_CLIENT_HANDLE_HIDE_INSETS);
                     mInsetsController.hide(msg.arg1, msg.arg2 == 1, statsToken);
                     break;
@@ -6905,13 +6898,13 @@
                         || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) {
                     // Other apps or the window manager may change the icon type outside of
                     // this app, therefore the icon type has to be reset on enter/exit event.
-                    mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED;
+                    mPointerIconType = null;
                 }
 
                 if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) {
                     if (!updatePointerIcon(event) &&
                             event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) {
-                        mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED;
+                        mPointerIconType = null;
                     }
                 }
             }
@@ -6950,7 +6943,7 @@
     }
 
     private void resetPointerIcon(MotionEvent event) {
-        mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED;
+        mPointerIconType = null;
         updatePointerIcon(event);
     }
 
@@ -6980,9 +6973,9 @@
         }
 
         final int pointerType = (pointerIcon != null) ?
-                pointerIcon.getType() : PointerIcon.TYPE_DEFAULT;
+                pointerIcon.getType() : PointerIcon.TYPE_NOT_SPECIFIED;
 
-        if (mPointerIconType != pointerType) {
+        if (mPointerIconType == null || mPointerIconType != pointerType) {
             mPointerIconType = pointerType;
             mCustomPointerIcon = null;
             if (mPointerIconType != PointerIcon.TYPE_CUSTOM) {
@@ -8570,9 +8563,6 @@
      */
     void getDisplayFrame(Rect outFrame) {
         outFrame.set(mTmpFrames.displayFrame);
-        // Apply sandboxing here (in getter) due to possible layout updates on the client after
-        // {@link #mTmpFrames.displayFrame} is received from the server.
-        applyViewBoundsSandboxingIfNeeded(outFrame);
     }
 
     /**
@@ -8589,60 +8579,6 @@
         outFrame.top += insets.top;
         outFrame.right -= insets.right;
         outFrame.bottom -= insets.bottom;
-        // Apply sandboxing here (in getter) due to possible layout updates on the client after
-        // {@link #mTmpFrames.displayFrame} is received from the server.
-        applyViewBoundsSandboxingIfNeeded(outFrame);
-    }
-
-    /**
-     * Offset outRect to make it sandboxed within Window's bounds.
-     *
-     * <p>This is used by {@link android.view.View#getBoundsOnScreen},
-     * {@link android.view.ViewRootImpl#getDisplayFrame} and
-     * {@link android.view.ViewRootImpl#getWindowVisibleDisplayFrame}, which are invoked by
-     * {@link android.view.View#getWindowDisplayFrame} and
-     * {@link android.view.View#getWindowVisibleDisplayFrame}, as well as
-     * {@link android.view.ViewDebug#captureLayers} for debugging.
-     */
-    void applyViewBoundsSandboxingIfNeeded(final Rect inOutRect) {
-        if (isViewBoundsSandboxingEnabled()) {
-            inOutRect.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
-        }
-    }
-
-    /**
-     * Whether the sanboxing of the {@link android.view.View} APIs is enabled.
-     *
-     * <p>This is called by {@link #applyViewBoundsSandboxingIfNeeded} and
-     * {@link android.view.View#getLocationOnScreen} to check if there is a need to add
-     * {@link android.view.View.AttachInfo.mWindowLeft} and
-     * {@link android.view.View.AttachInfo.mWindowTop} offsets.
-     */
-    boolean isViewBoundsSandboxingEnabled() {
-        return mViewBoundsSandboxingEnabled;
-    }
-
-    private boolean getViewBoundsSandboxingEnabled() {
-        if (!CompatChanges.isChangeEnabled(OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS)) {
-            // OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS change-id is disabled.
-            return false;
-        }
-
-        // OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS is enabled by the device manufacturer.
-        try {
-            final List<PackageManager.Property> properties = mContext.getPackageManager()
-                    .queryApplicationProperty(PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS);
-
-            final boolean isOptedOut = !properties.isEmpty() && !properties.get(0).getBoolean();
-            if (isOptedOut) {
-                // PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS is disabled by the app devs.
-                return false;
-            }
-        } catch (RuntimeException e) {
-            // remote exception.
-        }
-
-        return true;
     }
 
     /**
@@ -8839,6 +8775,8 @@
 
         mInsetsController.dump(prefix, writer);
 
+        mOnBackInvokedDispatcher.dump(prefix, writer);
+
         writer.println(prefix + "View Hierarchy:");
         dumpViewHierarchy(innerPrefix, writer, mView);
     }
@@ -9040,7 +8978,7 @@
         if (mTranslator != null) {
             mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
         }
-        if (insetsState.getSourceOrDefaultVisibility(ITYPE_IME)) {
+        if (insetsState.isSourceOrDefaultVisible(ID_IME, Type.ime())) {
             ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchResized",
                     getInsetsController().getHost().getInputMethodManager(), null /* icProto */);
         }
@@ -9072,7 +9010,7 @@
             mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
             mTranslator.translateSourceControlsInScreenToAppWindow(activeControls);
         }
-        if (insetsState != null && insetsState.getSourceOrDefaultVisibility(ITYPE_IME)) {
+        if (insetsState != null && insetsState.isSourceOrDefaultVisible(ID_IME, Type.ime())) {
             ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchInsetsControlChanged",
                     getInsetsController().getHost().getInputMethodManager(), null /* icProto */);
         }
@@ -10471,10 +10409,10 @@
                         null /* icProto */);
             }
             if (viewAncestor != null) {
-                ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
+                ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
                 viewAncestor.showInsets(types, fromIme, statsToken);
             } else {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
             }
         }
 
@@ -10488,10 +10426,10 @@
                         null /* icProto */);
             }
             if (viewAncestor != null) {
-                ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
+                ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
                 viewAncestor.hideInsets(types, fromIme, statsToken);
             } else {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
             }
         }
 
@@ -11511,33 +11449,25 @@
         });
     }
 
-    private class VRISurfaceSyncGroup extends SurfaceSyncGroup {
-        VRISurfaceSyncGroup(String name) {
-            super(name);
-        }
-
-        @Override
-        public void onSyncReady() {
-            Runnable runnable = () -> {
-                mNumPausedForSync--;
-                if (!mIsInTraversal && mNumPausedForSync == 0) {
-                    scheduleTraversals();
-                }
-            };
-
-            if (Thread.currentThread() == mThread) {
-                runnable.run();
-            } else {
-                mHandler.post(runnable);
-            }
-        }
-    }
-
     @Override
     public SurfaceSyncGroup getOrCreateSurfaceSyncGroup() {
         boolean newSyncGroup = false;
         if (mActiveSurfaceSyncGroup == null) {
-            mActiveSurfaceSyncGroup = new VRISurfaceSyncGroup(mTag);
+            mActiveSurfaceSyncGroup = new SurfaceSyncGroup(mTag);
+            mActiveSurfaceSyncGroup.setAddedToSyncListener(() -> {
+                Runnable runnable = () -> {
+                    mNumPausedForSync--;
+                    if (!mIsInTraversal && mNumPausedForSync == 0) {
+                        scheduleTraversals();
+                    }
+                };
+
+                if (Thread.currentThread() == mThread) {
+                    runnable.run();
+                } else {
+                    mHandler.post(runnable);
+                }
+            });
             updateSyncInProgressCount(mActiveSurfaceSyncGroup);
             newSyncGroup = true;
         }
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index c59d83e..a2708ee 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -21,6 +21,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 
 import android.annotation.NonNull;
+import android.content.Context;
 import android.content.res.CompatibilityInfo;
 import android.os.Handler;
 import android.os.IBinder;
@@ -246,6 +247,11 @@
     }
 
     @Override
+    public Context getRootViewContext() {
+        return mViewRoot != null ? mViewRoot.mContext : null;
+    }
+
+    @Override
     public int dipToPx(int dips) {
         if (mViewRoot != null) {
             return mViewRoot.dipToPx(dips);
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 7077804..3b8298e 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -16,10 +16,10 @@
 
 package android.view;
 
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.systemBars;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
@@ -89,7 +89,7 @@
         if (attachedWindowFrame == null) {
             outParentFrame.set(outDisplayFrame);
             if ((pfl & PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME) != 0) {
-                final InsetsSource source = state.peekSource(ITYPE_IME);
+                final InsetsSource source = state.peekSource(ID_IME);
                 if (source != null) {
                     outParentFrame.inset(source.calculateInsets(
                             outParentFrame, false /* ignoreVisibility */));
@@ -109,14 +109,6 @@
             // Ensure that windows with a non-ALWAYS display cutout mode are laid out in
             // the cutout safe zone.
             final Rect displayFrame = state.getDisplayFrame();
-            final InsetsSource statusBarSource = state.peekSource(ITYPE_STATUS_BAR);
-            if (statusBarSource != null && displayCutoutSafe.top > displayFrame.top) {
-                // Make sure that the zone we're avoiding for the cutout is at least as tall as the
-                // status bar; otherwise fullscreen apps will end up cutting halfway into the status
-                // bar.
-                displayCutoutSafeExceptMaybeBars.top =
-                        Math.max(statusBarSource.getFrame().bottom, displayCutoutSafe.top);
-            }
             if (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) {
                 if (displayFrame.width() < displayFrame.height()) {
                     displayCutoutSafeExceptMaybeBars.top = MIN_Y;
@@ -131,7 +123,7 @@
                     && (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
                     || cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)) {
                 final Insets systemBarsInsets = state.calculateInsets(
-                        displayFrame, WindowInsets.Type.systemBars(), requestedVisibleTypes);
+                        displayFrame, systemBars(), requestedVisibleTypes);
                 if (systemBarsInsets.left > 0) {
                     displayCutoutSafeExceptMaybeBars.left = MIN_X;
                 }
@@ -145,12 +137,11 @@
                     displayCutoutSafeExceptMaybeBars.bottom = MAX_Y;
                 }
             }
-            if (type == TYPE_INPUT_METHOD) {
-                final InsetsSource navSource = state.peekSource(ITYPE_NAVIGATION_BAR);
-                if (navSource != null && navSource.calculateInsets(displayFrame, true).bottom > 0) {
-                    // The IME can always extend under the bottom cutout if the navbar is there.
-                    displayCutoutSafeExceptMaybeBars.bottom = MAX_Y;
-                }
+            if (type == TYPE_INPUT_METHOD
+                    && displayCutoutSafeExceptMaybeBars.bottom != MAX_Y
+                    && state.calculateInsets(displayFrame, navigationBars(), true).bottom > 0) {
+                // The IME can always extend under the bottom cutout if the navbar is there.
+                displayCutoutSafeExceptMaybeBars.bottom = MAX_Y;
             }
             final boolean attachedInParent = attachedWindowFrame != null && !layoutInScreen;
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 3d3f4f6..0f68cd0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -855,42 +855,6 @@
 
     /**
      * Application level {@link android.content.pm.PackageManager.Property PackageManager
-     * .Property} for an app to inform the system that it needs to be opted-out from the
-     * compatibility treatment that sandboxes {@link android.view.View} API.
-     *
-     * <p>The treatment can be enabled by device manufacturers for applications which misuse
-     * {@link android.view.View} APIs by expecting that
-     * {@link android.view.View#getLocationOnScreen},
-     * {@link android.view.View#getBoundsOnScreen},
-     * {@link android.view.View#getWindowVisibleDisplayFrame},
-     * {@link android.view.View#getWindowDisplayFrame}
-     * return coordinates as if an activity is positioned in the top-left corner of the screen, with
-     * left coordinate equal to 0. This may not be the case for applications in multi-window and in
-     * letterbox modes.
-     *
-     * <p>Setting this property to {@code false} informs the system that the application must be
-     * opted-out from the "Sandbox {@link android.view.View} API to Activity bounds" 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_SANDBOXING_VIEW_BOUNDS_APIS"
-     *     android:value="false"/&gt;
-     * &lt;/application&gt;
-     * </pre>
-     *
-     * @hide
-     */
-    // TODO(b/263984287): Make this public API.
-    String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS =
-            "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS";
-
-    /**
-     * Application level {@link android.content.pm.PackageManager.Property PackageManager
      * .Property} for an app to inform the system that the application can be opted-in or opted-out
      * from the compatibility treatment that enables sending a fake focus event for unfocused
      * resumed split screen activities. This is needed because some game engines wait to get
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 3ce419e..d405c0b 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -186,6 +186,18 @@
      */
     public static final int ACCESSIBILITY_SHORTCUT_KEY = 1;
 
+    /** @hide */
+    public static final int FLASH_REASON_CALL = 1;
+
+    /** @hide */
+    public static final int FLASH_REASON_ALARM = 2;
+
+    /** @hide */
+    public static final int FLASH_REASON_NOTIFICATION = 3;
+
+    /** @hide */
+    public static final int FLASH_REASON_PREVIEW = 4;
+
     /**
      * Annotations for the shortcut type.
      * @hide
@@ -210,6 +222,19 @@
     public @interface ContentFlag {}
 
     /**
+     * Annotations for reason of Flash notification.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "FLASH_REASON_" }, value = {
+            FLASH_REASON_CALL,
+            FLASH_REASON_ALARM,
+            FLASH_REASON_NOTIFICATION,
+            FLASH_REASON_PREVIEW
+    })
+    public @interface FlashNotificationReason {}
+
+    /**
      * Use this flag to indicate the content of a UI that times out contains icons.
      *
      * @see #getRecommendedTimeoutMillis(int, int)
@@ -230,17 +255,6 @@
      */
     public static final int FLAG_CONTENT_CONTROLS = 4;
 
-
-    /**
-     * {@link ComponentName} for the Accessibility Menu {@link AccessibilityService} as provided
-     * inside the system build, used for automatic migration to this version of the service.
-     * @hide
-     */
-    public static final ComponentName ACCESSIBILITY_MENU_IN_SYSTEM =
-            new ComponentName("com.android.systemui.accessibility.accessibilitymenu",
-                    "com.android.systemui.accessibility.accessibilitymenu"
-                            + ".AccessibilityMenuService");
-
     @UnsupportedAppUsage
     static final Object sInstanceSync = new Object();
 
@@ -317,6 +331,13 @@
     private SparseArray<List<AccessibilityRequestPreparer>> mRequestPreparerLists;
 
     /**
+     * Binder for flash notification.
+     *
+     * @see #startFlashNotificationSequence(Context, int)
+     */
+    private final Binder mBinder = new Binder();
+
+    /**
      * Listener for the system accessibility state. To listen for changes to the
      * accessibility state on the device, implement this interface and register
      * it with the system by calling {@link #addAccessibilityStateChangeListener}.
@@ -2096,6 +2117,95 @@
         }
     }
 
+    /**
+     * Start sequence (infinite) type of flash notification. Use
+     * {@code Context.getOpPackageName()} as the identifier of this flash notification.
+     * The notification can be cancelled later by calling {@link #stopFlashNotificationSequence}
+     * with same {@code Context.getOpPackageName()}.
+     * If the binder associated with this {@link AccessibilityManager} instance dies then the
+     * sequence will stop automatically. It is strongly recommended to call
+     * {@link #stopFlashNotificationSequence} within a reasonable amount of time after calling
+     * this method.
+     *
+     * @param context The context in which this manager operates.
+     * @param reason The triggering reason of flash notification.
+     * @return {@code true} if flash notification works properly.
+     * @hide
+     */
+    public boolean startFlashNotificationSequence(@NonNull Context context,
+            @FlashNotificationReason int reason) {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return false;
+            }
+        }
+
+        try {
+            return service.startFlashNotificationSequence(context.getOpPackageName(),
+                    reason, mBinder);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while start flash notification sequence", re);
+            return false;
+        }
+    }
+
+    /**
+     * Stop sequence (infinite) type of flash notification. The flash notification with
+     * {@code Context.getOpPackageName()} as identifier will be stopped if exist.
+     * It is strongly recommended to call this method within a reasonable amount of time after
+     * calling {@link #startFlashNotificationSequence} method.
+     *
+     * @param context The context in which this manager operates.
+     * @return {@code true} if flash notification stops properly.
+     * @hide
+     */
+    public boolean stopFlashNotificationSequence(@NonNull Context context) {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return false;
+            }
+        }
+
+        try {
+            return service.stopFlashNotificationSequence(context.getOpPackageName());
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while stop flash notification sequence", re);
+            return false;
+        }
+    }
+
+    /**
+     * Start event (finite) type of flash notification.
+     *
+     * @param context The context in which this manager operates.
+     * @param reason The triggering reason of flash notification.
+     * @param reasonPkg The package that trigger the flash notification.
+     * @return {@code true} if flash notification works properly.
+     * @hide
+     */
+    public boolean startFlashNotificationEvent(@NonNull Context context,
+            @FlashNotificationReason int reason, @Nullable String reasonPkg) {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return false;
+            }
+        }
+
+        try {
+            return service.startFlashNotificationEvent(context.getOpPackageName(),
+                    reason, reasonPkg);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while start flash notification event", re);
+            return false;
+        }
+    }
+
     private IAccessibilityManager getServiceLocked() {
         if (mService == null) {
             tryConnectToServiceLocked(null);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 5629e0f..d88cdf1 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1817,13 +1817,12 @@
      * </p>
      *
      * @see AccessibilityEvent#getContentChangeTypes for all content change types.
-     * @param minDurationBetweenContentChanges the minimum duration between content change events.
+     * @param duration the minimum duration between content change events.
      *                                         Negative duration would be treated as zero.
      */
-    public void setMinDurationBetweenContentChanges(
-            @NonNull Duration minDurationBetweenContentChanges) {
+    public void setMinDurationBetweenContentChanges(@NonNull Duration duration) {
         enforceNotSealed();
-        mMinDurationBetweenContentChanges = minDurationBetweenContentChanges.toMillis();
+        mMinDurationBetweenContentChanges = duration.toMillis();
     }
 
     /**
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index c2d899a..098e97c 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -120,4 +120,8 @@
     void injectInputEventToInputFilter(in InputEvent event);
 
     float getUiContrast();
+
+    boolean startFlashNotificationSequence(String opPkg, int reason, IBinder token);
+    boolean stopFlashNotificationSequence(String opPkg);
+    boolean startFlashNotificationEvent(String opPkg, int reason, String reasonPkg);
 }
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index cba399f..6d78e60 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -145,19 +145,13 @@
      * <p>For example, a list with only 1 package would be, {@code Package1:;}. A list with one
      * denied activity {@code Activity1} under {@code Package1} and a full denied package
      * {@code Package2} would be {@code Package1:Activity1;Package2:;}
-     *
-     * @hide
      */
-    @TestApi
     public static final String DEVICE_CONFIG_PACKAGE_DENYLIST_FOR_UNIMPORTANT_VIEW =
             "package_deny_list_for_unimportant_view";
 
     /**
      * Whether the heuristics check for view is enabled
-     *
-     * @hide
      */
-    @TestApi
     public static final String DEVICE_CONFIG_TRIGGER_FILL_REQUEST_ON_UNIMPORTANT_VIEW =
             "trigger_fill_request_on_unimportant_view";
 
@@ -169,15 +163,46 @@
      *
      * <p> For example, a imeAction list could be "2,3,4", corresponding to ime_action definition
      * in {@link android.view.inputmethod.EditorInfo.java}</p>
-     *
-     * @hide
      */
-    @TestApi
     @SuppressLint("IntentName")
     public static final String DEVICE_CONFIG_NON_AUTOFILLABLE_IME_ACTION_IDS =
             "non_autofillable_ime_action_ids";
     // END AUTOFILL FOR ALL APPS FLAGS //
 
+
+    // START AUTOFILL PCC CLASSIFICATION FLAGS
+
+    /**
+     * Sets the fill dialog feature enabled or not.
+     */
+    public static final String DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED =
+            "pcc_classification_enabled";
+
+    /**
+     * Give preference to autofill provider's detection.
+     * @hide
+     */
+    public static final String DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC = "prefer_provider_over_pcc";
+
+    /**
+     * Indicates the Autofill Hints that would be requested by the service from the Autofill
+     * Provider.
+     */
+    public static final String DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS =
+            "pcc_classification_hints";
+
+    /**
+     * Use data from secondary source if primary not present .
+     * For eg: if we prefer PCC over provider, and PCC detection didn't classify a field, however,
+     * autofill provider did, this flag would decide whether we use that result, and show some
+     * presentation for that particular field.
+     * @hide
+     */
+    public static final String DEVICE_CONFIG_PCC_USE_FALLBACK = "pcc_use_fallback";
+
+    // END AUTOFILL PCC CLASSIFICATION FLAGS
+
+
     /**
      * Sets a value of delay time to show up the inline tooltip view.
      *
@@ -191,6 +216,7 @@
     private static final boolean DEFAULT_HAS_FILL_DIALOG_UI_FEATURE = false;
     private static final String DEFAULT_FILL_DIALOG_ENABLED_HINTS = "";
 
+
     // CREDENTIAL MANAGER DEFAULTS
     // Credential manager is enabled by default so as to allow testing by app developers
     private static final boolean DEFAULT_CREDENTIAL_MANAGER_ENABLED = true;
@@ -199,6 +225,14 @@
     private static final boolean DEFAULT_CREDENTIAL_MANAGER_SUPPRESS_SAVE_DIALOG = false;
     // END CREDENTIAL MANAGER DEFAULTS
 
+
+    // AUTOFILL PCC CLASSIFICATION FLAGS DEFAULTS
+    // Default for whether the pcc classification is enabled for autofill.
+    /** @hide */
+    public static final boolean DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED = false;
+    // END AUTOFILL PCC CLASSIFICATION FLAGS DEFAULTS
+
+
     private AutofillFeatureFlags() {};
 
     /**
@@ -302,4 +336,23 @@
             DeviceConfig.NAMESPACE_AUTOFILL,
             DEVICE_CONFIG_PACKAGE_DENYLIST_FOR_UNIMPORTANT_VIEW, "");
     }
+
+
+    // START AUTOFILL PCC CLASSIFICATION FUNCTIONS
+
+    /**
+     * Whether Autofill PCC Detection is enabled.
+     *
+     * @hide
+     */
+    public static boolean isAutofillPccClassificationEnabled() {
+        // TODO(b/266379948): Add condition for checking whether device has PCC first
+
+        return DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_AUTOFILL,
+                DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED,
+                DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED);
+    }
+
+    // END AUTOFILL PCC CLASSIFICATION FUNCTIONS
 }
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b5764c5..bdc7333 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -19,6 +19,7 @@
 import static android.service.autofill.FillRequest.FLAG_IME_SHOWING;
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
+import static android.service.autofill.FillRequest.FLAG_PCC_DETECTION;
 import static android.service.autofill.FillRequest.FLAG_RESET_FILL_DIALOG_STATE;
 import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
 import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
@@ -1312,6 +1313,22 @@
             return;
         }
 
+        // Start session with PCC flag to get assist structure and send field classification request
+        // to PCC classification service.
+        if (AutofillFeatureFlags.isAutofillPccClassificationEnabled()) {
+            synchronized (mLock) {
+                final boolean clientAdded = tryAddServiceClientIfNeededLocked();
+                if (clientAdded){
+                    startSessionLocked(/* id= */ AutofillId.NO_AUTOFILL_ID,
+                        /* bounds= */ null, /* value= */ null, /* flags= */ FLAG_PCC_DETECTION);
+                } else {
+                    if (sVerbose) {
+                        Log.v(TAG, "not starting session: no service client");
+                    }
+                }
+            }
+        }
+
         if (mIsFillDialogEnabled
                 || ArrayUtils.containsAny(autofillHints, mFillDialogEnabledHints)) {
             if (sDebug) {
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 2134d81..ee86fc14 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -15,6 +15,7 @@
  */
 package android.view.contentcapture;
 
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
 import static android.view.contentcapture.ContentCaptureHelper.sDebug;
 import static android.view.contentcapture.ContentCaptureHelper.sVerbose;
 import static android.view.contentcapture.ContentCaptureManager.NO_SESSION_ID;
@@ -23,6 +24,9 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.graphics.Insets;
 import android.util.DebugUtils;
 import android.util.Log;
@@ -41,6 +45,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.security.SecureRandom;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -171,6 +176,10 @@
     /** @hide */
     public static final int FLUSH_REASON_SESSION_CONNECTED = 7;
 
+    @ChangeId
+    @EnabledSince(targetSdkVersion = UPSIDE_DOWN_CAKE)
+    static final long NOTIFY_NODES_DISAPPEAR_NOW_SENDS_TREE_EVENTS = 258825825L;
+
     /** @hide */
     @IntDef(prefix = { "FLUSH_REASON_" }, value = {
             FLUSH_REASON_FULL,
@@ -229,7 +238,7 @@
         mId = id;
     }
 
-    // Used by ChildCOntentCaptureSession
+    // Used by ChildContentCaptureSession
     ContentCaptureSession(@NonNull ContentCaptureContext initialContext) {
         this();
         mClientContext = Objects.requireNonNull(initialContext);
@@ -362,6 +371,9 @@
      * automatically by the Android System for views that return {@code true} on
      * {@link View#onProvideContentCaptureStructure(ViewStructure, int)}.
      *
+     * <p>Consider use {@link #notifyViewsAppeared} which has a better performance when notifying
+     * a list of nodes has appeared.
+     *
      * @param node node that has been added.
      */
     public final void notifyViewAppeared(@NonNull ViewStructure node) {
@@ -383,6 +395,9 @@
      * <p>Typically called "manually" by views that handle their own virtual view hierarchy, or
      * automatically by the Android System for standard views.
      *
+     * <p>Consider use {@link #notifyViewsDisappeared} which has a better performance when notifying
+     * a list of nodes has disappeared.
+     *
      * @param id id of the node that has been removed.
      */
     public final void notifyViewDisappeared(@NonNull AutofillId id) {
@@ -395,11 +410,42 @@
     abstract void internalNotifyViewDisappeared(@NonNull AutofillId id);
 
     /**
+     * Notifies the Content Capture Service that a list of nodes has appeared in the view structure.
+     *
+     * <p>Typically called manually by views that handle their own virtual view hierarchy.
+     *
+     * @param appearedNodes nodes that have appeared. Each element represents a view node that has
+     * been added to the view structure. The order of the elements is important, which should be
+     * preserved as the attached order of when the node is attached to the virtual view hierarchy.
+     */
+    public final void notifyViewsAppeared(@NonNull List<ViewStructure> appearedNodes) {
+        Preconditions.checkCollectionElementsNotNull(appearedNodes, "appearedNodes");
+        if (!isContentCaptureEnabled()) return;
+
+        for (int i = 0; i < appearedNodes.size(); i++) {
+            ViewStructure v = appearedNodes.get(i);
+            if (!(v instanceof ViewNode.ViewStructureImpl)) {
+                throw new IllegalArgumentException("Invalid class: " + v.getClass());
+            }
+        }
+
+        internalNotifyViewTreeEvent(/* started= */ true);
+        for (int i = 0; i < appearedNodes.size(); i++) {
+            ViewStructure v = appearedNodes.get(i);
+            internalNotifyViewAppeared((ViewStructureImpl) v);
+        }
+        internalNotifyViewTreeEvent(/* started= */ false);
+    }
+
+    /**
      * Notifies the Content Capture Service that many nodes has been removed from a virtual view
      * structure.
      *
      * <p>Should only be called by views that handle their own virtual view hierarchy.
      *
+     * <p>After UPSIDE_DOWN_CAKE, this method wraps the virtual children with a pair of view tree
+     * appearing and view tree appeared events.
+     *
      * @param hostId id of the non-virtual view hosting the virtual view hierarchy (it can be
      * obtained by calling {@link ViewStructure#getAutofillId()}).
      * @param virtualIds ids of the virtual children.
@@ -413,11 +459,17 @@
         Preconditions.checkArgument(!ArrayUtils.isEmpty(virtualIds), "virtual ids cannot be empty");
         if (!isContentCaptureEnabled()) return;
 
+        if (CompatChanges.isChangeEnabled(NOTIFY_NODES_DISAPPEAR_NOW_SENDS_TREE_EVENTS)) {
+            internalNotifyViewTreeEvent(/* started= */ true);
+        }
         // TODO(b/123036895): use a internalNotifyViewsDisappeared that optimizes how the event is
         // parcelized
         for (long id : virtualIds) {
             internalNotifyViewDisappeared(new AutofillId(hostId, id, mId));
         }
+        if (CompatChanges.isChangeEnabled(NOTIFY_NODES_DISAPPEAR_NOW_SENDS_TREE_EVENTS)) {
+            internalNotifyViewTreeEvent(/* started= */ false);
+        }
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index 3b6ec80..e5a99ff 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -16,24 +16,36 @@
 
 package android.view.inputmethod;
 
+import static com.android.internal.inputmethod.InputMethodDebug.softInputDisplayReasonToString;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_ANIMATION;
+import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_HIDDEN;
+import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_SHOWN;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityThread;
+import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemProperties;
 import android.util.Log;
+import android.view.InsetsController.AnimationType;
+import android.view.SurfaceControl;
 
 import com.android.internal.inputmethod.InputMethodDebug;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.jank.InteractionJankMonitor.Configuration;
+import com.android.internal.util.LatencyTracker;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Field;
 import java.util.Arrays;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 import java.util.stream.Collectors;
@@ -385,15 +397,35 @@
     void onHidden(@Nullable Token token);
 
     /**
-     * Get the singleton instance of this class.
+     * Get the singleton request tracker instance.
      *
-     * @return the singleton instance of this class
+     * @return the singleton request tracker instance
      */
     @NonNull
-    static ImeTracker get() {
+    static ImeTracker forLogging() {
         return LOGGER;
     }
 
+    /**
+     * Get the singleton jank tracker instance.
+     *
+     * @return the singleton jank tracker instance
+     */
+    @NonNull
+    static ImeJankTracker forJank() {
+        return JANK_TRACKER;
+    }
+
+    /**
+     * Get the singleton latency tracker instance.
+     *
+     * @return the singleton latency tracker instance
+     */
+    @NonNull
+    static ImeLatencyTracker forLatency() {
+        return LATENCY_TRACKER;
+    }
+
     /** The singleton IME tracker instance. */
     @NonNull
     ImeTracker LOGGER = new ImeTracker() {
@@ -489,6 +521,12 @@
         }
     };
 
+    /** The singleton IME tracker instance for instrumenting jank metrics. */
+    ImeJankTracker JANK_TRACKER = new ImeJankTracker();
+
+    /** The singleton IME tracker instance for instrumenting latency metrics. */
+    ImeLatencyTracker LATENCY_TRACKER = new ImeLatencyTracker();
+
     /** A token that tracks the progress of an IME request. */
     class Token implements Parcelable {
 
@@ -592,4 +630,162 @@
             }
         }
     }
+
+    /**
+     * Context related to {@link InteractionJankMonitor}.
+     */
+    interface InputMethodJankContext {
+        /**
+         * @return a context associated with a display
+         */
+        Context getDisplayContext();
+
+        /**
+         * @return a SurfaceControl that is going to be monitored
+         */
+        SurfaceControl getTargetSurfaceControl();
+
+        /**
+         * @return the package name of the host
+         */
+        String getHostPackageName();
+    }
+
+    /**
+     * Context related to {@link LatencyTracker}.
+     */
+    interface InputMethodLatencyContext {
+        /**
+         * @return a context associated with current application
+         */
+        Context getAppContext();
+    }
+
+    /**
+     * A tracker instance which is in charge of communicating with {@link InteractionJankMonitor}.
+     * This class disallows instantiating from outside, use {@link #forJank()} to get the singleton.
+     */
+    final class ImeJankTracker {
+
+        /**
+         * This class disallows instantiating from outside.
+         */
+        private ImeJankTracker() {
+        }
+
+        /**
+         * Called when the animation, which is going to be monitored, starts.
+         *
+         * @param jankContext context which is needed by {@link InteractionJankMonitor}
+         * @param animType {@link AnimationType}
+         * @param useSeparatedThread {@code true} if the animation is handled by the app,
+         *                           {@code false} if the animation will be scheduled on the
+         *                           {@link android.view.InsetsAnimationThread}
+         */
+        public void onRequestAnimation(@NonNull InputMethodJankContext jankContext,
+                @AnimationType int animType, boolean useSeparatedThread) {
+            if (jankContext.getDisplayContext() == null
+                    || jankContext.getTargetSurfaceControl() == null) {
+                return;
+            }
+            final Configuration.Builder builder = Configuration.Builder.withSurface(
+                            CUJ_IME_INSETS_ANIMATION,
+                            jankContext.getDisplayContext(),
+                            jankContext.getTargetSurfaceControl())
+                    .setTag(String.format(Locale.US, "%d@%d@%s", animType,
+                            useSeparatedThread ? 0 : 1, jankContext.getHostPackageName()));
+            InteractionJankMonitor.getInstance().begin(builder);
+        }
+
+        /**
+         * Called when the animation, which is going to be monitored, cancels.
+         */
+        public void onCancelAnimation() {
+            InteractionJankMonitor.getInstance().cancel(CUJ_IME_INSETS_ANIMATION);
+        }
+
+        /**
+         * Called when the animation, which is going to be monitored, ends.
+         */
+        public void onFinishAnimation() {
+            InteractionJankMonitor.getInstance().end(CUJ_IME_INSETS_ANIMATION);
+        }
+    }
+
+    /**
+     * A tracker instance which is in charge of communicating with {@link LatencyTracker}.
+     * This class disallows instantiating from outside, use {@link #forLatency()}
+     * to get the singleton.
+     */
+    final class ImeLatencyTracker {
+
+        /**
+         * This class disallows instantiating from outside.
+         */
+        private ImeLatencyTracker() {
+        }
+
+        private boolean shouldMonitorLatency(@SoftInputShowHideReason int reason) {
+            return reason == SoftInputShowHideReason.SHOW_SOFT_INPUT
+                    || reason == SoftInputShowHideReason.HIDE_SOFT_INPUT
+                    || reason == SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API
+                    || reason == SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API
+                    || reason == SoftInputShowHideReason.SHOW_SOFT_INPUT_FROM_IME
+                    || reason == SoftInputShowHideReason.HIDE_SOFT_INPUT_FROM_IME;
+        }
+
+        public void onRequestShow(@Nullable Token token, @Origin int origin,
+                @SoftInputShowHideReason int reason,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            if (!shouldMonitorLatency(reason)) return;
+            LatencyTracker.getInstance(latencyContext.getAppContext())
+                    .onActionStart(
+                            ACTION_REQUEST_IME_SHOWN,
+                            softInputDisplayReasonToString(reason));
+        }
+
+        public void onRequestHide(@Nullable Token token, @Origin int origin,
+                @SoftInputShowHideReason int reason,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            if (!shouldMonitorLatency(reason)) return;
+            LatencyTracker.getInstance(latencyContext.getAppContext())
+                    .onActionStart(
+                            ACTION_REQUEST_IME_HIDDEN,
+                            softInputDisplayReasonToString(reason));
+        }
+
+        public void onShowFailed(@Nullable Token token, @Phase int phase,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            onShowCancelled(token, phase, latencyContext);
+        }
+
+        public void onHideFailed(@Nullable Token token, @Phase int phase,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            onHideCancelled(token, phase, latencyContext);
+        }
+
+        public void onShowCancelled(@Nullable Token token, @Phase int phase,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            LatencyTracker.getInstance(latencyContext.getAppContext())
+                    .onActionCancel(ACTION_REQUEST_IME_SHOWN);
+        }
+
+        public void onHideCancelled(@Nullable Token token, @Phase int phase,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            LatencyTracker.getInstance(latencyContext.getAppContext())
+                    .onActionCancel(ACTION_REQUEST_IME_HIDDEN);
+        }
+
+        public void onShown(@Nullable Token token,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            LatencyTracker.getInstance(latencyContext.getAppContext())
+                    .onActionEnd(ACTION_REQUEST_IME_SHOWN);
+        }
+
+        public void onHidden(@Nullable Token token,
+                @NonNull InputMethodLatencyContext latencyContext) {
+            LatencyTracker.getInstance(latencyContext.getAppContext())
+                    .onActionEnd(ACTION_REQUEST_IME_HIDDEN);
+        }
+    }
 }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 99bd02d..642182b 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2045,10 +2045,11 @@
     private boolean showSoftInput(View view, @Nullable ImeTracker.Token statsToken, int flags,
             ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
         if (statsToken == null) {
-            statsToken = ImeTracker.get().onRequestShow(null /* component */,
+            statsToken = ImeTracker.forLogging().onRequestShow(null /* component */,
                     Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT, reason);
         }
-
+        ImeTracker.forLatency().onRequestShow(statsToken, ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
+                reason, ActivityThread::currentApplication);
         ImeTracing.getInstance().triggerClientDump("InputMethodManager#showSoftInput", this,
                 null /* icProto */);
         // Re-dispatch if there is a context mismatch.
@@ -2060,12 +2061,15 @@
         checkFocus();
         synchronized (mH) {
             if (!hasServedByInputMethodLocked(view)) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLatency().onShowFailed(
+                        statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED,
+                        ActivityThread::currentApplication);
                 Log.w(TAG, "Ignoring showSoftInput() as view=" + view + " is not served.");
                 return false;
             }
 
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
             // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread.
             // TODO(b/229426865): call WindowInsetsController#show instead.
@@ -2095,20 +2099,20 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768499)
     public void showSoftInputUnchecked(int flags, ResultReceiver resultReceiver) {
         synchronized (mH) {
-            final ImeTracker.Token statsToken = ImeTracker.get().onRequestShow(null /* component */,
-                    Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
+            final ImeTracker.Token statsToken = ImeTracker.forLogging().onRequestShow(
+                    null /* component */, Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
                     SoftInputShowHideReason.SHOW_SOFT_INPUT);
 
             Log.w(TAG, "showSoftInputUnchecked() is a hidden method, which will be"
                     + " removed soon. If you are using androidx.appcompat.widget.SearchView,"
                     + " please update to version 26.0 or newer version.");
             if (mCurRootView == null || mCurRootView.getView() == null) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
                 Log.w(TAG, "No current root view, ignoring showSoftInputUnchecked()");
                 return;
             }
 
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
             // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread.
             // TODO(b/229426865): call WindowInsetsController#show instead.
@@ -2186,20 +2190,24 @@
 
     private boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
             ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
-        final ImeTracker.Token statsToken = ImeTracker.get().onRequestHide(null /* component */,
-                Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT, reason);
-
+        final ImeTracker.Token statsToken = ImeTracker.forLogging().onRequestHide(
+                null /* component */, Process.myUid(),
+                ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT, reason);
+        ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+                reason, ActivityThread::currentApplication);
         ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
                 this, null /* icProto */);
         checkFocus();
         synchronized (mH) {
             final View servedView = getServedViewLocked();
             if (servedView == null || servedView.getWindowToken() != windowToken) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLatency().onHideFailed(statsToken,
+                        ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
                 return false;
             }
 
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
             return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken, statsToken,
                     flags, resultReceiver, reason);
@@ -2835,18 +2843,22 @@
 
     @UnsupportedAppUsage
     void closeCurrentInput() {
-        final ImeTracker.Token statsToken = ImeTracker.get().onRequestHide(null /* component */,
-                Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+        final ImeTracker.Token statsToken = ImeTracker.forLogging().onRequestHide(
+                null /* component */, Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
                 SoftInputShowHideReason.HIDE_SOFT_INPUT);
+        ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+                SoftInputShowHideReason.HIDE_SOFT_INPUT, ActivityThread::currentApplication);
 
         synchronized (mH) {
             if (mCurRootView == null || mCurRootView.getView() == null) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLatency().onHideFailed(statsToken,
+                        ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
                 Log.w(TAG, "No current root view, ignoring closeCurrentInput()");
                 return;
             }
 
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
             IInputMethodManagerGlobalInvoker.hideSoftInput(
                     mClient,
@@ -2905,11 +2917,13 @@
         synchronized (mH) {
             final View servedView = getServedViewLocked();
             if (servedView == null || servedView.getWindowToken() != windowToken) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
+                ImeTracker.forLogging().onFailed(statsToken,
+                        ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
                 return false;
             }
 
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
+            ImeTracker.forLogging().onProgress(statsToken,
+                    ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
 
             showSoftInput(servedView, statsToken, 0 /* flags */, null /* resultReceiver */,
                     SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API);
@@ -2927,21 +2941,25 @@
      */
     public void notifyImeHidden(IBinder windowToken, @Nullable ImeTracker.Token statsToken) {
         if (statsToken == null) {
-            statsToken = ImeTracker.get().onRequestHide(null /* component */,
+            statsToken = ImeTracker.forLogging().onRequestHide(null /* component */,
                     Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
                     SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
         }
-
+        ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+                SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API,
+                ActivityThread::currentApplication);
         ImeTracing.getInstance().triggerClientDump("InputMethodManager#notifyImeHidden", this,
                 null /* icProto */);
         synchronized (mH) {
             if (!isImeSessionAvailableLocked() || mCurRootView == null
                     || mCurRootView.getWindowToken() != windowToken) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+                ImeTracker.forLatency().onHideFailed(statsToken,
+                        ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
                 return;
             }
 
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
 
             IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken, statsToken,
                     0 /* flags */, null /* resultReceiver */,
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 7142597..e87cd12 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -124,13 +124,11 @@
 import android.view.animation.LinearInterpolator;
 import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.CursorAnchorInfo;
-import android.view.inputmethod.EditorBoundsInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.TextAppearanceInfo;
 import android.view.textclassifier.TextClassification;
 import android.view.textclassifier.TextClassificationManager;
 import android.widget.AdapterView.OnItemClickListener;
@@ -4669,7 +4667,7 @@
      * {@link InputMethodManager#isWatchingCursor(View)} returns false.
      */
     private final class CursorAnchorInfoNotifier implements TextViewPositionListener {
-        final CursorAnchorInfo.Builder mSelectionInfoBuilder = new CursorAnchorInfo.Builder();
+        final CursorAnchorInfo.Builder mCursorAnchorInfoBuilder = new CursorAnchorInfo.Builder();
         final Matrix mViewToScreenMatrix = new Matrix();
 
         @Override
@@ -4689,165 +4687,21 @@
             // Skip if the IME has not requested the cursor/anchor position.
             final int knownCursorAnchorInfoModes =
                     InputConnection.CURSOR_UPDATE_IMMEDIATE | InputConnection.CURSOR_UPDATE_MONITOR;
-            if ((mInputMethodState.mUpdateCursorAnchorInfoMode & knownCursorAnchorInfoModes) == 0) {
+            if ((ims.mUpdateCursorAnchorInfoMode & knownCursorAnchorInfoModes) == 0) {
                 return;
             }
-            Layout layout = mTextView.getLayout();
-            if (layout == null) {
-                return;
+
+            final CursorAnchorInfo cursorAnchorInfo =
+                    mTextView.getCursorAnchorInfo(ims.mUpdateCursorAnchorInfoFilter,
+                            mCursorAnchorInfoBuilder, mViewToScreenMatrix);
+
+            if (cursorAnchorInfo != null) {
+                imm.updateCursorAnchorInfo(mTextView, cursorAnchorInfo);
+
+                // Drop the immediate flag if any.
+                mInputMethodState.mUpdateCursorAnchorInfoMode &=
+                        ~InputConnection.CURSOR_UPDATE_IMMEDIATE;
             }
-            final int filter = mInputMethodState.mUpdateCursorAnchorInfoFilter;
-            boolean includeEditorBounds =
-                    (filter & InputConnection.CURSOR_UPDATE_FILTER_EDITOR_BOUNDS) != 0;
-            boolean includeCharacterBounds =
-                    (filter & InputConnection.CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS) != 0;
-            boolean includeInsertionMarker =
-                    (filter & InputConnection.CURSOR_UPDATE_FILTER_INSERTION_MARKER) != 0;
-            boolean includeVisibleLineBounds =
-                    (filter & InputConnection.CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS) != 0;
-            boolean includeTextAppearance =
-                    (filter & InputConnection.CURSOR_UPDATE_FILTER_TEXT_APPEARANCE) != 0;
-            boolean includeAll =
-                    (!includeEditorBounds && !includeCharacterBounds && !includeInsertionMarker
-                    && !includeVisibleLineBounds && !includeTextAppearance);
-
-            includeEditorBounds |= includeAll;
-            includeCharacterBounds |= includeAll;
-            includeInsertionMarker |= includeAll;
-            includeVisibleLineBounds |= includeAll;
-            includeTextAppearance |= includeAll;
-
-            final CursorAnchorInfo.Builder builder = mSelectionInfoBuilder;
-            builder.reset();
-
-            final int selectionStart = mTextView.getSelectionStart();
-            builder.setSelectionRange(selectionStart, mTextView.getSelectionEnd());
-
-            // Construct transformation matrix from view local coordinates to screen coordinates.
-            mViewToScreenMatrix.reset();
-            mTextView.transformMatrixToGlobal(mViewToScreenMatrix);
-            builder.setMatrix(mViewToScreenMatrix);
-
-            if (includeEditorBounds) {
-                final RectF editorBounds = new RectF();
-                editorBounds.set(0 /* left */, 0 /* top */,
-                        mTextView.getWidth(), mTextView.getHeight());
-                final RectF handwritingBounds = new RectF(
-                        -mTextView.getHandwritingBoundsOffsetLeft(),
-                        -mTextView.getHandwritingBoundsOffsetTop(),
-                        mTextView.getWidth() + mTextView.getHandwritingBoundsOffsetRight(),
-                        mTextView.getHeight() + mTextView.getHandwritingBoundsOffsetBottom());
-                EditorBoundsInfo.Builder boundsBuilder = new EditorBoundsInfo.Builder();
-                EditorBoundsInfo editorBoundsInfo = boundsBuilder.setEditorBounds(editorBounds)
-                        .setHandwritingBounds(handwritingBounds).build();
-                builder.setEditorBoundsInfo(editorBoundsInfo);
-            }
-
-            if (includeCharacterBounds || includeInsertionMarker || includeVisibleLineBounds) {
-                final float viewportToContentHorizontalOffset =
-                        mTextView.viewportToContentHorizontalOffset();
-                final float viewportToContentVerticalOffset =
-                        mTextView.viewportToContentVerticalOffset();
-                final boolean isTextTransformed = (mTextView.getTransformationMethod() != null
-                        && mTextView.getTransformed() instanceof OffsetMapping);
-                if (includeCharacterBounds && !isTextTransformed) {
-                    final CharSequence text = mTextView.getText();
-                    if (text instanceof Spannable) {
-                        final Spannable sp = (Spannable) text;
-                        int composingTextStart = EditableInputConnection.getComposingSpanStart(sp);
-                        int composingTextEnd = EditableInputConnection.getComposingSpanEnd(sp);
-                        if (composingTextEnd < composingTextStart) {
-                            final int temp = composingTextEnd;
-                            composingTextEnd = composingTextStart;
-                            composingTextStart = temp;
-                        }
-                        final boolean hasComposingText =
-                                (0 <= composingTextStart) && (composingTextStart
-                                        < composingTextEnd);
-                        if (hasComposingText) {
-                            final CharSequence composingText = text.subSequence(composingTextStart,
-                                    composingTextEnd);
-                            builder.setComposingText(composingTextStart, composingText);
-                            mTextView.populateCharacterBounds(builder, composingTextStart,
-                                    composingTextEnd, viewportToContentHorizontalOffset,
-                                    viewportToContentVerticalOffset);
-                        }
-                    }
-                }
-
-                if (includeInsertionMarker) {
-                    // Treat selectionStart as the insertion point.
-                    if (0 <= selectionStart) {
-                        final int offsetTransformed = mTextView.originalToTransformed(
-                                selectionStart, OffsetMapping.MAP_STRATEGY_CURSOR);
-                        final int line = layout.getLineForOffset(offsetTransformed);
-                        final float insertionMarkerX =
-                                layout.getPrimaryHorizontal(offsetTransformed)
-                                        + viewportToContentHorizontalOffset;
-                        final float insertionMarkerTop = layout.getLineTop(line)
-                                + viewportToContentVerticalOffset;
-                        final float insertionMarkerBaseline = layout.getLineBaseline(line)
-                                + viewportToContentVerticalOffset;
-                        final float insertionMarkerBottom =
-                                layout.getLineBottom(line, /* includeLineSpacing= */ false)
-                                        + viewportToContentVerticalOffset;
-                        final boolean isTopVisible = mTextView
-                                .isPositionVisible(insertionMarkerX, insertionMarkerTop);
-                        final boolean isBottomVisible = mTextView
-                                .isPositionVisible(insertionMarkerX, insertionMarkerBottom);
-                        int insertionMarkerFlags = 0;
-                        if (isTopVisible || isBottomVisible) {
-                            insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
-                        }
-                        if (!isTopVisible || !isBottomVisible) {
-                            insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
-                        }
-                        if (layout.isRtlCharAt(offsetTransformed)) {
-                            insertionMarkerFlags |= CursorAnchorInfo.FLAG_IS_RTL;
-                        }
-                        builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
-                                insertionMarkerBaseline, insertionMarkerBottom,
-                                insertionMarkerFlags);
-                    }
-                }
-
-                if (includeVisibleLineBounds) {
-                    final Rect visibleRect = new Rect();
-                    if (mTextView.getContentVisibleRect(visibleRect)) {
-                        // Subtract the viewportToContentVerticalOffset to convert the view
-                        // coordinates to layout coordinates.
-                        final float visibleTop =
-                                visibleRect.top - viewportToContentVerticalOffset;
-                        final float visibleBottom =
-                                visibleRect.bottom - viewportToContentVerticalOffset;
-                        final int firstLine =
-                                layout.getLineForVertical((int) Math.floor(visibleTop));
-                        final int lastLine =
-                                layout.getLineForVertical((int) Math.ceil(visibleBottom));
-
-                        for (int line = firstLine; line <= lastLine; ++line) {
-                            final float left = layout.getLineLeft(line)
-                                    + viewportToContentHorizontalOffset;
-                            final float top = layout.getLineTop(line)
-                                    + viewportToContentVerticalOffset;
-                            final float right = layout.getLineRight(line)
-                                    + viewportToContentHorizontalOffset;
-                            final float bottom = layout.getLineBottom(line, false)
-                                    + viewportToContentVerticalOffset;
-                            builder.addVisibleLineBounds(left, top, right, bottom);
-                        }
-                    }
-                }
-            }
-
-            if (includeTextAppearance) {
-                builder.setTextAppearanceInfo(TextAppearanceInfo.createFromTextView(mTextView));
-            }
-            imm.updateCursorAnchorInfo(mTextView, builder.build());
-
-            // Drop the immediate flag if any.
-            mInputMethodState.mUpdateCursorAnchorInfoMode &=
-                    ~InputConnection.CURSOR_UPDATE_IMMEDIATE;
         }
     }
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index be58893..56bdea3 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -196,6 +196,7 @@
 import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.DeleteGesture;
 import android.view.inputmethod.DeleteRangeGesture;
+import android.view.inputmethod.EditorBoundsInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
@@ -209,6 +210,7 @@
 import android.view.inputmethod.RemoveSpaceGesture;
 import android.view.inputmethod.SelectGesture;
 import android.view.inputmethod.SelectRangeGesture;
+import android.view.inputmethod.TextAppearanceInfo;
 import android.view.inputmethod.TextBoundsInfo;
 import android.view.inspector.InspectableProperty;
 import android.view.inspector.InspectableProperty.EnumEntry;
@@ -6505,7 +6507,7 @@
     }
 
     boolean hasGesturePreviewHighlight() {
-        return mGesturePreviewHighlightStart > 0;
+        return mGesturePreviewHighlightStart >= 0;
     }
 
     /**
@@ -9957,8 +9959,8 @@
                 range = adjustHandwritingDeleteGestureRange(range);
             }
 
-            getEditableText().delete(range[0], range[1]);
             Selection.setSelection(getEditableText(), range[0]);
+            getEditableText().delete(range[0], range[1]);
         }
         return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS;
     }
@@ -10162,8 +10164,8 @@
             endOffset += Character.charCount(codePointAtEnd);
         }
         if (startOffset < endOffset) {
-            getEditableText().delete(startOffset, endOffset);
             Selection.setSelection(getEditableText(), startOffset);
+            getEditableText().delete(startOffset, endOffset);
             return InputConnection.HANDWRITING_GESTURE_RESULT_SUCCESS;
         } else {
             // No whitespace found, so insert a space.
@@ -10229,8 +10231,7 @@
             // The point is not within lineMargin of a line.
             return -1;
         }
-        if (point.x < mLayout.getLineLeft(line) - lineMargin
-                || point.x > mLayout.getLineRight(line) + lineMargin) {
+        if (point.x < -lineMargin || point.x > mLayout.getWidth() + lineMargin) {
             // The point is not within lineMargin of a line.
             return -1;
         }
@@ -13659,7 +13660,7 @@
      * @return true if at least part of the text content is visible; false if the text content is
      * completely clipped or translated out of the visible area.
      */
-    boolean getContentVisibleRect(Rect rect) {
+    private boolean getContentVisibleRect(Rect rect) {
         if (!getLocalVisibleRect(rect)) {
             return false;
         }
@@ -13745,6 +13746,176 @@
     }
 
     /**
+     * Compute {@link CursorAnchorInfo} from this {@link TextView}.
+     *
+     * @param filter the {@link CursorAnchorInfo} update filter which specified the needed
+     *               information from IME.
+     * @param cursorAnchorInfoBuilder a cached {@link CursorAnchorInfo.Builder} object used to build
+     *                                the result {@link CursorAnchorInfo}.
+     * @param viewToScreenMatrix a cached {@link Matrix} object used to compute the view to screen
+     *                           matrix.
+     * @return the result {@link CursorAnchorInfo} to be passed to IME.
+     * @hide
+     */
+    @VisibleForTesting
+    @Nullable
+    public CursorAnchorInfo getCursorAnchorInfo(@InputConnection.CursorUpdateFilter int filter,
+            @NonNull CursorAnchorInfo.Builder cursorAnchorInfoBuilder,
+            @NonNull Matrix viewToScreenMatrix) {
+        Layout layout = getLayout();
+        if (layout == null) {
+            return null;
+        }
+        boolean includeEditorBounds =
+                (filter & InputConnection.CURSOR_UPDATE_FILTER_EDITOR_BOUNDS) != 0;
+        boolean includeCharacterBounds =
+                (filter & InputConnection.CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS) != 0;
+        boolean includeInsertionMarker =
+                (filter & InputConnection.CURSOR_UPDATE_FILTER_INSERTION_MARKER) != 0;
+        boolean includeVisibleLineBounds =
+                (filter & InputConnection.CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS) != 0;
+        boolean includeTextAppearance =
+                (filter & InputConnection.CURSOR_UPDATE_FILTER_TEXT_APPEARANCE) != 0;
+        boolean includeAll =
+                (!includeEditorBounds && !includeCharacterBounds && !includeInsertionMarker
+                        && !includeVisibleLineBounds && !includeTextAppearance);
+
+        includeEditorBounds |= includeAll;
+        includeCharacterBounds |= includeAll;
+        includeInsertionMarker |= includeAll;
+        includeVisibleLineBounds |= includeAll;
+        includeTextAppearance |= includeAll;
+
+        final CursorAnchorInfo.Builder builder = cursorAnchorInfoBuilder;
+        builder.reset();
+
+        final int selectionStart = getSelectionStart();
+        builder.setSelectionRange(selectionStart, getSelectionEnd());
+
+        // Construct transformation matrix from view local coordinates to screen coordinates.
+        viewToScreenMatrix.reset();
+        transformMatrixToGlobal(viewToScreenMatrix);
+        builder.setMatrix(viewToScreenMatrix);
+
+        if (includeEditorBounds) {
+            final RectF editorBounds = new RectF();
+            editorBounds.set(0 /* left */, 0 /* top */,
+                    getWidth(), getHeight());
+            final RectF handwritingBounds = new RectF(
+                    -getHandwritingBoundsOffsetLeft(),
+                    -getHandwritingBoundsOffsetTop(),
+                    getWidth() + getHandwritingBoundsOffsetRight(),
+                    getHeight() + getHandwritingBoundsOffsetBottom());
+            EditorBoundsInfo.Builder boundsBuilder = new EditorBoundsInfo.Builder();
+            EditorBoundsInfo editorBoundsInfo = boundsBuilder.setEditorBounds(editorBounds)
+                    .setHandwritingBounds(handwritingBounds).build();
+            builder.setEditorBoundsInfo(editorBoundsInfo);
+        }
+
+        if (includeCharacterBounds || includeInsertionMarker || includeVisibleLineBounds) {
+            final float viewportToContentHorizontalOffset =
+                    viewportToContentHorizontalOffset();
+            final float viewportToContentVerticalOffset =
+                    viewportToContentVerticalOffset();
+            final boolean isTextTransformed = (getTransformationMethod() != null
+                    && getTransformed() instanceof OffsetMapping);
+            if (includeCharacterBounds && !isTextTransformed) {
+                final CharSequence text = getText();
+                if (text instanceof Spannable) {
+                    final Spannable sp = (Spannable) text;
+                    int composingTextStart = EditableInputConnection.getComposingSpanStart(sp);
+                    int composingTextEnd = EditableInputConnection.getComposingSpanEnd(sp);
+                    if (composingTextEnd < composingTextStart) {
+                        final int temp = composingTextEnd;
+                        composingTextEnd = composingTextStart;
+                        composingTextStart = temp;
+                    }
+                    final boolean hasComposingText =
+                            (0 <= composingTextStart) && (composingTextStart
+                                    < composingTextEnd);
+                    if (hasComposingText) {
+                        final CharSequence composingText = text.subSequence(composingTextStart,
+                                composingTextEnd);
+                        builder.setComposingText(composingTextStart, composingText);
+                        populateCharacterBounds(builder, composingTextStart,
+                                composingTextEnd, viewportToContentHorizontalOffset,
+                                viewportToContentVerticalOffset);
+                    }
+                }
+            }
+
+            if (includeInsertionMarker) {
+                // Treat selectionStart as the insertion point.
+                if (0 <= selectionStart) {
+                    final int offsetTransformed = originalToTransformed(
+                            selectionStart, OffsetMapping.MAP_STRATEGY_CURSOR);
+                    final int line = layout.getLineForOffset(offsetTransformed);
+                    final float insertionMarkerX =
+                            layout.getPrimaryHorizontal(offsetTransformed)
+                                    + viewportToContentHorizontalOffset;
+                    final float insertionMarkerTop = layout.getLineTop(line)
+                            + viewportToContentVerticalOffset;
+                    final float insertionMarkerBaseline = layout.getLineBaseline(line)
+                            + viewportToContentVerticalOffset;
+                    final float insertionMarkerBottom =
+                            layout.getLineBottom(line, /* includeLineSpacing= */ false)
+                                    + viewportToContentVerticalOffset;
+                    final boolean isTopVisible =
+                            isPositionVisible(insertionMarkerX, insertionMarkerTop);
+                    final boolean isBottomVisible =
+                            isPositionVisible(insertionMarkerX, insertionMarkerBottom);
+                    int insertionMarkerFlags = 0;
+                    if (isTopVisible || isBottomVisible) {
+                        insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+                    }
+                    if (!isTopVisible || !isBottomVisible) {
+                        insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+                    }
+                    if (layout.isRtlCharAt(offsetTransformed)) {
+                        insertionMarkerFlags |= CursorAnchorInfo.FLAG_IS_RTL;
+                    }
+                    builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
+                            insertionMarkerBaseline, insertionMarkerBottom,
+                            insertionMarkerFlags);
+                }
+            }
+
+            if (includeVisibleLineBounds) {
+                final Rect visibleRect = new Rect();
+                if (getContentVisibleRect(visibleRect)) {
+                    // Subtract the viewportToContentVerticalOffset to convert the view
+                    // coordinates to layout coordinates.
+                    final float visibleTop =
+                            visibleRect.top - viewportToContentVerticalOffset;
+                    final float visibleBottom =
+                            visibleRect.bottom - viewportToContentVerticalOffset;
+                    final int firstLine =
+                            layout.getLineForVertical((int) Math.floor(visibleTop));
+                    final int lastLine =
+                            layout.getLineForVertical((int) Math.ceil(visibleBottom));
+
+                    for (int line = firstLine; line <= lastLine; ++line) {
+                        final float left = layout.getLineLeft(line)
+                                + viewportToContentHorizontalOffset;
+                        final float top = layout.getLineTop(line)
+                                + viewportToContentVerticalOffset;
+                        final float right = layout.getLineRight(line)
+                                + viewportToContentHorizontalOffset;
+                        final float bottom = layout.getLineBottom(line, false)
+                                + viewportToContentVerticalOffset;
+                        builder.addVisibleLineBounds(left, top, right, bottom);
+                    }
+                }
+            }
+        }
+
+        if (includeTextAppearance) {
+            builder.setTextAppearanceInfo(TextAppearanceInfo.createFromTextView(this));
+        }
+        return builder.build();
+    }
+
+    /**
      * Creates the {@link TextBoundsInfo} for the text lines that intersects with the {@code rectF}.
      * @hide
      */
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java
index 535dc4e..c270053 100644
--- a/core/java/android/window/DisplayWindowPolicyController.java
+++ b/core/java/android/window/DisplayWindowPolicyController.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -137,7 +138,7 @@
     /**
      * This is called when the top activity of the display is changed.
      */
-    public void onTopActivityChanged(ComponentName topActivity, int uid) {}
+    public void onTopActivityChanged(ComponentName topActivity, int uid, @UserIdInt int userId) {}
 
     /**
      * This is called when the apps that contains running activities on the display has changed.
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index a0bd7f7..9ef6880 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -82,8 +82,13 @@
             @NonNull OnBackInvokedCallback callback) {
         final Bundle bundle = new Bundle();
         // Always invoke back for ime without checking the window focus.
+        // We use strong reference in the binder wrapper to avoid accidentally GC the callback.
+        // This is necessary because the callback is sent to and registered from
+        // the app process, which may treat the IME callback as weakly referenced. This will not
+        // cause a memory leak because the app side already clears the reference correctly.
         final IOnBackInvokedCallback iCallback =
-                new WindowOnBackInvokedDispatcher.OnBackInvokedCallbackWrapper(callback);
+                new WindowOnBackInvokedDispatcher.OnBackInvokedCallbackWrapper(
+                        callback, false /* useWeakRef */);
         bundle.putBinder(RESULT_KEY_CALLBACK, iCallback.asBinder());
         bundle.putInt(RESULT_KEY_PRIORITY, priority);
         bundle.putInt(RESULT_KEY_ID, callback.hashCode());
@@ -211,6 +216,12 @@
         IOnBackInvokedCallback getIOnBackInvokedCallback() {
             return mIOnBackInvokedCallback;
         }
+
+        @Override
+        public String toString() {
+            return "ImeCallback=ImeOnBackInvokedCallback@" + mId
+                    + " Callback=" + mIOnBackInvokedCallback;
+        }
     }
 
     /**
diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
index 09d8b0f..56c05b2 100644
--- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
@@ -180,16 +180,7 @@
                 return;
             }
             clearCallbacksOnDispatcher();
-            if (actualDispatcher instanceof ProxyOnBackInvokedDispatcher) {
-                // We don't want to nest ProxyDispatchers, so if we are given on, we unwrap its
-                // actual dispatcher.
-                // This can happen when an Activity is recreated but the Window is preserved (e.g.
-                // when going from split-screen back to single screen)
-                mActualDispatcher =
-                        ((ProxyOnBackInvokedDispatcher) actualDispatcher).mActualDispatcher;
-            } else {
-                mActualDispatcher = actualDispatcher;
-            }
+            mActualDispatcher = actualDispatcher;
             transferCallbacksToDispatcher();
         }
     }
diff --git a/core/java/android/window/SurfaceSyncGroup.java b/core/java/android/window/SurfaceSyncGroup.java
index 2e55041..78de954 100644
--- a/core/java/android/window/SurfaceSyncGroup.java
+++ b/core/java/android/window/SurfaceSyncGroup.java
@@ -53,7 +53,7 @@
  * see the <a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/window/SurfaceSyncGroup.md">SurfaceSyncGroup documentation</a>
  * </p>
  */
-public class SurfaceSyncGroup {
+public final class SurfaceSyncGroup {
     private static final String TAG = "SurfaceSyncGroup";
     private static final boolean DEBUG = false;
 
@@ -101,6 +101,9 @@
      */
     public final ISurfaceSyncGroup mISurfaceSyncGroup = new ISurfaceSyncGroupImpl();
 
+    @GuardedBy("mLock")
+    private Runnable mAddedToSyncListener;
+
     /**
      * Token to identify this SurfaceSyncGroup. This is used to register the SurfaceSyncGroup in
      * WindowManager. This token is also sent to other processes' SurfaceSyncGroup that want to be
@@ -447,12 +450,15 @@
     }
 
     /**
-     * Invoked when the SurfaceSyncGroup has been added to another SurfaceSyncGroup and is ready
-     * to proceed.
+     * Add a Runnable to be invoked when the SurfaceSyncGroup has been added to another
+     * SurfaceSyncGroup. This is useful to know when it's safe to proceed rendering.
      *
      * @hide
      */
-    public void onSyncReady() {
+    public void setAddedToSyncListener(Runnable addedToSyncListener) {
+        synchronized (mLock) {
+            mAddedToSyncListener = addedToSyncListener;
+        }
     }
 
     private boolean addSyncToWm(IBinder token, boolean parentSyncGroupMerge,
@@ -525,12 +531,15 @@
         if (DEBUG) {
             Log.d(TAG, "setTransactionCallbackFromParent " + mName);
         }
-        boolean finished = false;
+
         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
             Trace.traceBegin(Trace.TRACE_TAG_VIEW,
                     "setTransactionCallbackFromParent " + mName + " callback="
                             + transactionReadyCallback.hashCode());
         }
+
+        boolean finished = false;
+        Runnable addedToSyncListener = null;
         synchronized (mLock) {
             if (mFinished) {
                 finished = true;
@@ -577,6 +586,7 @@
                         Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                     }
                 };
+                addedToSyncListener = mAddedToSyncListener;
             }
         }
 
@@ -587,8 +597,8 @@
                 transactionReadyCallback.onTransactionReady(null);
             } catch (RemoteException e) {
             }
-        } else {
-            onSyncReady();
+        } else if (addedToSyncListener != null) {
+            addedToSyncListener.run();
         }
         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java
index 12ad914..c8f6327 100644
--- a/core/java/android/window/TaskFragmentAnimationParams.java
+++ b/core/java/android/window/TaskFragmentAnimationParams.java
@@ -33,6 +33,13 @@
     public static final TaskFragmentAnimationParams DEFAULT =
             new TaskFragmentAnimationParams.Builder().build();
 
+    /**
+     * The default value for animation background color, which means to use the theme window
+     * background color.
+     */
+    @ColorInt
+    public static final int DEFAULT_ANIMATION_BACKGROUND_COLOR = 0;
+
     @ColorInt
     private final int mAnimationBackgroundColor;
 
@@ -104,12 +111,13 @@
     public static final class Builder {
 
         @ColorInt
-        private int mAnimationBackgroundColor = 0;
+        private int mAnimationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
 
         /**
          * Sets the {@link ColorInt} to use for the background during the animation with this
          * TaskFragment if the animation requires a background. The default value is
-         * {@code 0}, which is to use the theme window background.
+         * {@link #DEFAULT_ANIMATION_BACKGROUND_COLOR}, which is to use the theme window background
+         * color.
          *
          * @param color a packed color int, {@code AARRGGBB}, for the animation background color.
          * @return this {@link Builder}.
diff --git a/core/java/android/window/TaskFragmentInfo.java b/core/java/android/window/TaskFragmentInfo.java
index dc60edd..a881a05 100644
--- a/core/java/android/window/TaskFragmentInfo.java
+++ b/core/java/android/window/TaskFragmentInfo.java
@@ -23,7 +23,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
-import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -89,9 +88,9 @@
     private final boolean mIsClearedForReorderActivityToFront;
 
     /**
-     * The maximum {@link ActivityInfo.WindowLayout#minWidth} and
-     * {@link ActivityInfo.WindowLayout#minHeight} aggregated from the TaskFragment's child
-     * activities.
+     * The maximum {@link android.content.pm.ActivityInfo.WindowLayout#minWidth} and
+     * {@link android.content.pm.ActivityInfo.WindowLayout#minHeight} aggregated from the
+     * TaskFragment's child activities.
      */
     @NonNull
     private final Point mMinimumDimensions = new Point();
@@ -179,7 +178,7 @@
 
     /**
      * Returns the minimum width this TaskFragment can be resized to.
-     * Client side must not {@link WindowContainerTransaction#setBounds(WindowContainerToken, Rect)}
+     * Client side must not {@link WindowContainerTransaction#setRelativeBounds}
      * that {@link Rect#width()} is shorter than the reported value.
      * @hide pending unhide
      */
@@ -189,7 +188,7 @@
 
     /**
      * Returns the minimum width this TaskFragment can be resized to.
-     * Client side must not {@link WindowContainerTransaction#setBounds(WindowContainerToken, Rect)}
+     * Client side must not {@link WindowContainerTransaction#setRelativeBounds}
      * that {@link Rect#height()} is shorter than the reported value.
      * @hide pending unhide
      */
diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java
index 0d6a58b..413f0cc 100644
--- a/core/java/android/window/TaskFragmentOperation.java
+++ b/core/java/android/window/TaskFragmentOperation.java
@@ -38,8 +38,8 @@
 public final class TaskFragmentOperation implements Parcelable {
 
     /**
-     * Type for tracking other {@link WindowContainerTransaction} to TaskFragment that is not set
-     * through {@link TaskFragmentOperation}, such as {@link WindowContainerTransaction#setBounds}.
+     * Type for tracking other unknown TaskFragment operation that is not set through
+     * {@link TaskFragmentOperation}, such as invalid request.
      */
     public static final int OP_TYPE_UNKNOWN = -1;
 
@@ -70,6 +70,9 @@
     /** Sets the {@link TaskFragmentAnimationParams} for the given TaskFragment. */
     public static final int OP_TYPE_SET_ANIMATION_PARAMS = 8;
 
+    /** Sets the relative bounds with {@link WindowContainerTransaction#setRelativeBounds}. */
+    public static final int OP_TYPE_SET_RELATIVE_BOUNDS = 9;
+
     @IntDef(prefix = { "OP_TYPE_" }, value = {
             OP_TYPE_UNKNOWN,
             OP_TYPE_CREATE_TASK_FRAGMENT,
@@ -80,7 +83,8 @@
             OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS,
             OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT,
             OP_TYPE_SET_COMPANION_TASK_FRAGMENT,
-            OP_TYPE_SET_ANIMATION_PARAMS
+            OP_TYPE_SET_ANIMATION_PARAMS,
+            OP_TYPE_SET_RELATIVE_BOUNDS
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface OperationType {}
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index a2fa162..a3209f6 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -308,7 +308,6 @@
     /**
      * Resizes a container by providing a bounds in its parent coordinate.
      * This is only used by {@link TaskFragmentOrganizer}.
-     * @hide
      */
     @NonNull
     public WindowContainerTransaction setRelativeBounds(
diff --git a/core/java/android/window/WindowMetricsController.java b/core/java/android/window/WindowMetricsController.java
index c497c94..3478b0f 100644
--- a/core/java/android/window/WindowMetricsController.java
+++ b/core/java/android/window/WindowMetricsController.java
@@ -127,7 +127,7 @@
                     isScreenRound, alwaysConsumeSystemBars, SOFT_INPUT_ADJUST_NOTHING,
                     0 /* flags */, SYSTEM_UI_FLAG_VISIBLE,
                     WindowManager.LayoutParams.INVALID_WINDOW_TYPE, windowingMode,
-                    null /* typeSideMap */);
+                    null /* idSideMap */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 7a5510c..a8c2b2f 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -29,6 +29,7 @@
 import android.view.IWindow;
 import android.view.IWindowSession;
 
+import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -232,11 +233,55 @@
         return Checker.isOnBackInvokedCallbackEnabled(mChecker.getContext());
     }
 
+    /**
+     * Dump information about this WindowOnBackInvokedDispatcher
+     * @param prefix the prefix that will be prepended to each line of the produced output
+     * @param writer the writer that will receive the resulting text
+     */
+    public void dump(String prefix, PrintWriter writer) {
+        String innerPrefix = prefix + "    ";
+        writer.println(prefix + "WindowOnBackDispatcher:");
+        if (mAllCallbacks.isEmpty()) {
+            writer.println(prefix + "<None>");
+            return;
+        }
+
+        writer.println(innerPrefix + "Top Callback: " + getTopCallback());
+        writer.println(innerPrefix + "Callbacks: ");
+        mAllCallbacks.forEach((callback, priority) -> {
+            writer.println(innerPrefix + "  Callback: " + callback + " Priority=" + priority);
+        });
+    }
+
     static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
-        private final WeakReference<OnBackInvokedCallback> mCallback;
+        static class CallbackRef {
+            final WeakReference<OnBackInvokedCallback> mWeakRef;
+            final OnBackInvokedCallback mStrongRef;
+            CallbackRef(@NonNull OnBackInvokedCallback callback, boolean useWeakRef) {
+                if (useWeakRef) {
+                    mWeakRef = new WeakReference<>(callback);
+                    mStrongRef = null;
+                } else {
+                    mStrongRef = callback;
+                    mWeakRef = null;
+                }
+            }
+
+            OnBackInvokedCallback get() {
+                if (mStrongRef != null) {
+                    return mStrongRef;
+                }
+                return mWeakRef.get();
+            }
+        }
+        final CallbackRef mCallbackRef;
 
         OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
-            mCallback = new WeakReference<>(callback);
+            mCallbackRef = new CallbackRef(callback, true /* useWeakRef */);
+        }
+
+        OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback, boolean useWeakRef) {
+            mCallbackRef = new CallbackRef(callback, useWeakRef);
         }
 
         @Override
@@ -279,8 +324,9 @@
         public void onBackInvoked() throws RemoteException {
             Handler.getMain().post(() -> {
                 mProgressAnimator.reset();
-                final OnBackInvokedCallback callback = mCallback.get();
+                final OnBackInvokedCallback callback = mCallbackRef.get();
                 if (callback == null) {
+                    Log.d(TAG, "Trying to call onBackInvoked() on a null callback reference.");
                     return;
                 }
                 callback.onBackInvoked();
@@ -289,7 +335,7 @@
 
         @Nullable
         private OnBackAnimationCallback getBackAnimationCallback() {
-            OnBackInvokedCallback callback = mCallback.get();
+            OnBackInvokedCallback callback = mCallbackRef.get();
             return callback instanceof OnBackAnimationCallback ? (OnBackAnimationCallback) callback
                     : null;
         }
diff --git a/core/java/com/android/internal/accessibility/common/MagnificationConstants.java b/core/java/com/android/internal/accessibility/common/MagnificationConstants.java
new file mode 100644
index 0000000..94c230b
--- /dev/null
+++ b/core/java/com/android/internal/accessibility/common/MagnificationConstants.java
@@ -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.internal.accessibility.common;
+
+/**
+ * Collection of common constants for accessibility shortcut.
+ */
+public final class MagnificationConstants {
+    private MagnificationConstants() {}
+
+    /**
+     * The min value for the magnification persisted scale. We assume if the scale is lower than
+     * the min value, there will be no obvious magnification effect.
+     */
+    public static final float PERSISTED_SCALE_MIN_VALUE = 1.3f;
+}
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
index 6a976ef..3a8f427 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
@@ -19,11 +19,16 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
 
+import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.Build;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -33,6 +38,8 @@
 import android.util.ArraySet;
 import android.view.accessibility.AccessibilityManager;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import libcore.util.EmptyArray;
 
 import java.lang.annotation.Retention;
@@ -40,6 +47,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 /**
@@ -66,6 +74,19 @@
     /** Specifies some parcelable spans has been changed. */
     public static final int PARCELABLE_SPAN = 2;
 
+    @VisibleForTesting
+    public static final String MENU_SERVICE_RELATIVE_CLASS_NAME = ".AccessibilityMenuService";
+
+    /**
+     * {@link ComponentName} for the Accessibility Menu {@link AccessibilityService} as provided
+     * inside the system build, used for automatic migration to this version of the service.
+     * @hide
+     */
+    public static final ComponentName ACCESSIBILITY_MENU_IN_SYSTEM =
+            new ComponentName("com.android.systemui.accessibility.accessibilitymenu",
+                    "com.android.systemui.accessibility.accessibilitymenu"
+                            + MENU_SERVICE_RELATIVE_CLASS_NAME);
+
     /**
      * Returns the set of enabled accessibility services for userId. If there are no
      * services, it returns the unmodifiable {@link Collections#emptySet()}.
@@ -244,4 +265,54 @@
         }
         return true;
     }
+
+    /**
+     * Finds the {@link ComponentName} of the AccessibilityMenu accessibility service that the
+     * device should be migrated off. Devices using this service should be migrated to
+     * {@link #ACCESSIBILITY_MENU_IN_SYSTEM}.
+     *
+     * <p>
+     * Requirements:
+     * <li>There are exactly two installed accessibility service components with class name
+     * {@link #MENU_SERVICE_RELATIVE_CLASS_NAME}.</li>
+     * <li>Exactly one of these components is equal to {@link #ACCESSIBILITY_MENU_IN_SYSTEM}.</li>
+     * </p>
+     *
+     * @return The {@link ComponentName} of the service that is not {@link
+     * #ACCESSIBILITY_MENU_IN_SYSTEM},
+     * or <code>null</code> if the above requirements are not met.
+     */
+    @Nullable
+    public static ComponentName getAccessibilityMenuComponentToMigrate(
+            PackageManager packageManager, int userId) {
+        final Set<ComponentName> menuComponentNames = findA11yMenuComponentNames(packageManager,
+                userId);
+        Optional<ComponentName> menuOutsideSystem = menuComponentNames.stream().filter(
+                name -> !name.equals(ACCESSIBILITY_MENU_IN_SYSTEM)).findFirst();
+        final boolean shouldMigrateToMenuInSystem = menuComponentNames.size() == 2
+                && menuComponentNames.contains(ACCESSIBILITY_MENU_IN_SYSTEM)
+                && menuOutsideSystem.isPresent();
+        return shouldMigrateToMenuInSystem ? menuOutsideSystem.get() : null;
+    }
+
+    /**
+     * Returns all {@link ComponentName}s whose class name ends in {@link
+     * #MENU_SERVICE_RELATIVE_CLASS_NAME}.
+     **/
+    private static Set<ComponentName> findA11yMenuComponentNames(
+            PackageManager packageManager, int userId) {
+        Set<ComponentName> result = new ArraySet<>();
+        final PackageManager.ResolveInfoFlags flags = PackageManager.ResolveInfoFlags.of(
+                PackageManager.MATCH_DISABLED_COMPONENTS
+                        | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+        for (ResolveInfo resolveInfo : packageManager.queryIntentServicesAsUser(
+                new Intent(AccessibilityService.SERVICE_INTERFACE), flags, userId)) {
+            final ComponentName componentName = resolveInfo.serviceInfo.getComponentName();
+            if (componentName.getClassName().endsWith(MENU_SERVICE_RELATIVE_CLASS_NAME)) {
+                result.add(componentName);
+            }
+        }
+        return result;
+    }
 }
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index fc5cb4b..d4ff794 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -81,7 +81,7 @@
      *             IVoiceInteractionSessionShowCallback, IBinder)} instead
      */
     @Deprecated
-    public boolean showSessionForActiveService(@NonNull Bundle args, int sourceFlags,
+    public boolean showSessionForActiveService(@Nullable Bundle args, int sourceFlags,
             @Nullable IVoiceInteractionSessionShowCallback showCallback,
             @Nullable IBinder activityToken) {
         return showSessionForActiveServiceInternal(args, sourceFlags, /* attributionTag */ null,
@@ -99,7 +99,7 @@
      * @param showCallback optional callback to be notified when the session was shown
      * @param activityToken optional token of activity that needs to be on top
      */
-    public boolean showSessionForActiveService(@NonNull Bundle args, int sourceFlags,
+    public boolean showSessionForActiveService(@Nullable Bundle args, int sourceFlags,
             @Nullable String attributionTag,
             @Nullable IVoiceInteractionSessionShowCallback showCallback,
             @Nullable IBinder activityToken) {
@@ -107,7 +107,7 @@
                 activityToken);
     }
 
-    private boolean showSessionForActiveServiceInternal(@NonNull Bundle args, int sourceFlags,
+    private boolean showSessionForActiveServiceInternal(@Nullable Bundle args, int sourceFlags,
             @Nullable String attributionTag,
             @Nullable IVoiceInteractionSessionShowCallback showCallback,
             @Nullable IBinder activityToken) {
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index 681bc7a..1eecb41 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -202,12 +202,12 @@
                     ri.nonLocalizedLabel = li.getNonLocalizedLabel();
                     ri.icon = li.getIconResource();
                     ri.iconResourceId = ri.icon;
-                    ri.userHandle = mInitialIntentsUserSpace;
                 }
                 if (userManager.isManagedProfile()) {
                     ri.noResourceId = true;
                     ri.icon = 0;
                 }
+                ri.userHandle = mInitialIntentsUserSpace;
                 mCallerTargets.add(new DisplayResolveInfo(ii, ri, ii, makePresentationGetter(ri)));
                 if (mCallerTargets.size() == MAX_SUGGESTED_APP_TARGETS) break;
             }
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index 3619c7b..685bd9a 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -277,8 +277,7 @@
             inflater.inflate(R.menu.language_selection_list, menu);
 
             final MenuItem searchMenuItem = menu.findItem(R.id.locale_search_menu);
-            if (mLocalePickerCollector.hasSpecificPackageName()
-                    && mOnActionExpandListener != null) {
+            if (mOnActionExpandListener != null) {
                 searchMenuItem.setOnActionExpandListener(mOnActionExpandListener);
             }
 
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index bcff907..b0a4b54 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -141,8 +141,9 @@
         @UnsupportedAppUsage
         public String getFullNameNative() {
             if (mFullNameNative == null) {
+                Locale locale = mLocale.stripExtensions();
                 mFullNameNative =
-                        LocaleHelper.getDisplayName(mLocale, mLocale, true /* sentence case */);
+                        LocaleHelper.getDisplayName(locale, locale, true /* sentence case */);
             }
             return mFullNameNative;
         }
@@ -563,6 +564,22 @@
         String id = locale.toLanguageTag();
         LocaleInfo result;
         if (!sLocaleCache.containsKey(id)) {
+            // Locale preferences can modify the language tag to current system languages, so we
+            // need to check the input locale without extra u extension except numbering system.
+            Locale filteredLocale = new Locale.Builder()
+                    .setLocale(locale.stripExtensions())
+                    .setUnicodeLocaleKeyword("nu", locale.getUnicodeLocaleType("nu"))
+                    .build();
+            if (sLocaleCache.containsKey(filteredLocale.toLanguageTag())) {
+                result = new LocaleInfo(locale);
+                LocaleInfo localeInfo = sLocaleCache.get(filteredLocale.toLanguageTag());
+                // This locale is included in supported locales, so follow the settings
+                // of supported locales.
+                result.mIsPseudo = localeInfo.mIsPseudo;
+                result.mIsTranslated = localeInfo.mIsTranslated;
+                result.mSuggestionFlags = localeInfo.mSuggestionFlags;
+                return result;
+            }
             result = new LocaleInfo(locale);
             sLocaleCache.put(id, result);
         } else {
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 69660ae..0d02683 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -6,6 +6,8 @@
 per-file *EmptyStateProvider.java = file:/packages/SystemUI/OWNERS
 per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
 per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
+per-file *SoundTrigger* = file:/media/java/android/media/soundtrigger/OWNERS
+
 
 # Voice Interaction
 per-file *Assist* = file:/core/java/android/service/voice/OWNERS
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 0ea60a7..18c8eb4 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -447,13 +447,13 @@
                         ri.nonLocalizedLabel = li.getNonLocalizedLabel();
                         ri.icon = li.getIconResource();
                         ri.iconResourceId = ri.icon;
-                        ri.userHandle = mInitialIntentsUserSpace;
                     }
                     if (userManager.isManagedProfile()) {
                         ri.noResourceId = true;
                         ri.icon = 0;
                     }
 
+                    ri.userHandle = mInitialIntentsUserSpace;
                     addResolveInfo(new DisplayResolveInfo(ii, ri,
                             ri.loadLabel(mPm), null, ii, makePresentationGetter(ri)));
                 }
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index b9373be..1084c71 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -562,6 +562,13 @@
             "task_manager_show_user_visible_jobs";
 
     /**
+     * (boolean) Whether the task manager should tell JobScheduler it's about to ask for an
+     * app stop.
+     */
+    public static final String TASK_MANAGER_INFORM_JOB_SCHEDULER_OF_PENDING_APP_STOP =
+            "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";
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
new file mode 100644
index 0000000..586b309
--- /dev/null
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -0,0 +1,188 @@
+/**
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.config.sysui;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Provides a central definition of debug SystemUI's SystemProperties flags, and their defaults.
+ *
+ * The main feature of this class is that it encodes a system-wide default for each flag which can
+ *  be updated by engineers with a single-line CL.
+ *
+ * NOTE: Because flag values returned by this class are not cached, it is important that developers
+ *  understand the intricacies of changing values and how that applies to their own code.
+ *  Generally, the best practice is to set the property, and then restart the device so that any
+ *  processes with stale state can be updated.  However, if your code has no state derived from the
+ *  flag value and queries it any time behavior is relevant, then it may be safe to change the flag
+ *  and not immediately reboot.
+ *
+ * To enable flags in debuggable builds, use the following commands:
+ *
+ * $ adb shell setprop persist.sysui.whatever_the_flag true
+ * $ adb reboot
+ *
+ * @hide
+ */
+public class SystemUiSystemPropertiesFlags {
+
+    /** The teamfood flag allows multiple features to be opted into at once. */
+    public static final Flag TEAMFOOD = devFlag("persist.sysui.teamfood");
+
+    /**
+     * Flags related to notification features
+     */
+    public static final class NotificationFlags {
+
+        /**
+         * FOR DEVELOPMENT / TESTING ONLY!!!
+         * Forcibly demote *ALL* FSI notifications as if no apps have the app op permission.
+         * NOTE: enabling this implies SHOW_STICKY_HUN_FOR_DENIED_FSI in SystemUI
+         */
+        public static final Flag FSI_FORCE_DEMOTE =
+                devFlag("persist.sysui.notification.fsi_force_demote");
+
+        /** Gating the feature which shows FSI-denied notifications as Sticky HUNs */
+        public static final Flag SHOW_STICKY_HUN_FOR_DENIED_FSI =
+                devFlag("persist.sysui.notification.show_sticky_hun_for_denied_fsi");
+
+        /** Gating the ability for users to dismiss ongoing event notifications */
+        public static final Flag ALLOW_DISMISS_ONGOING =
+                releasedFlag("persist.sysui.notification.ongoing_dismissal");
+
+        /** Gating the redaction of OTP notifications on the lockscreen */
+        public static final Flag OTP_REDACTION =
+                devFlag("persist.sysui.notification.otp_redaction");
+
+    }
+
+    //// == End of flags.  Everything below this line is the implementation. == ////
+
+    /** The interface used for resolving SystemUI SystemProperties Flags to booleans. */
+    public interface FlagResolver {
+        /** Is the flag enabled? */
+        boolean isEnabled(Flag flag);
+    }
+
+    /** The primary, immutable resolver returned by getResolver() */
+    private static final FlagResolver
+            MAIN_RESOLVER =
+            Build.IS_DEBUGGABLE ? new DebugResolver() : new ProdResolver();
+
+    /**
+     * On debuggable builds, this can be set to override the resolver returned by getResolver().
+     * This can be useful to override flags when testing components that do not allow injecting the
+     * SystemUiPropertiesFlags resolver they use.
+     * Always set this to null when tests tear down.
+     */
+    @VisibleForTesting
+    public static FlagResolver TEST_RESOLVER = null;
+
+    /** Get the resolver for this device configuration. */
+    public static FlagResolver getResolver() {
+        if (Build.IS_DEBUGGABLE && TEST_RESOLVER != null) {
+            Log.i("SystemUiSystemPropertiesFlags", "Returning debug resolver " + TEST_RESOLVER);
+            return TEST_RESOLVER;
+        }
+        return MAIN_RESOLVER;
+    }
+
+    /**
+     * Creates a flag that is enabled by default in debuggable builds.
+     * It can be enabled by setting this flag's SystemProperty to 1.
+     *
+     * This flag is ALWAYS disabled in release builds.
+     */
+    @VisibleForTesting
+    public static Flag devFlag(String name) {
+        return new Flag(name, false, null);
+    }
+
+    /**
+     * Creates a flag that is disabled by default in debuggable builds.
+     * It can be enabled or force-disabled by setting this flag's SystemProperty to 1 or 0.
+     * If this flag's SystemProperty is not set, the flag can be enabled by setting the
+     * TEAMFOOD flag's SystemProperty to 1.
+     *
+     * This flag is ALWAYS disabled in release builds.
+     */
+    @VisibleForTesting
+    public static Flag teamfoodFlag(String name) {
+        return new Flag(name, false, TEAMFOOD);
+    }
+
+    /**
+     * Creates a flag that is enabled by default in debuggable builds.
+     * It can be enabled by setting this flag's SystemProperty to 0.
+     *
+     * This flag is ALWAYS enabled in release builds.
+     */
+    @VisibleForTesting
+    public static Flag releasedFlag(String name) {
+        return new Flag(name, true, null);
+    }
+
+    /** Represents a developer-switchable gate for a feature. */
+    public static final class Flag {
+        public final String mSysPropKey;
+        public final boolean mDefaultValue;
+        @Nullable
+        public final Flag mDebugDefault;
+
+        /** constructs a new flag.  only visible for testing the class */
+        @VisibleForTesting
+        public Flag(@NonNull String sysPropKey, boolean defaultValue, @Nullable Flag debugDefault) {
+            mSysPropKey = sysPropKey;
+            mDefaultValue = defaultValue;
+            mDebugDefault = debugDefault;
+        }
+    }
+
+    /** Implementation of the interface used in release builds. */
+    @VisibleForTesting
+    public static final class ProdResolver implements
+            FlagResolver {
+        @Override
+        public boolean isEnabled(Flag flag) {
+            return flag.mDefaultValue;
+        }
+    }
+
+    /** Implementation of the interface used in debuggable builds. */
+    @VisibleForTesting
+    public static class DebugResolver implements FlagResolver {
+        @Override
+        public final boolean isEnabled(Flag flag) {
+            if (flag.mDebugDefault == null) {
+                return getBoolean(flag.mSysPropKey, flag.mDefaultValue);
+            }
+            return getBoolean(flag.mSysPropKey, isEnabled(flag.mDebugDefault));
+        }
+
+        /** Look up the value; overridable for tests to avoid needing to set SystemProperties */
+        @VisibleForTesting
+        public boolean getBoolean(String key, boolean defaultValue) {
+            return SystemProperties.getBoolean(key, defaultValue);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/expresslog/Histogram.java b/core/java/com/android/internal/expresslog/Histogram.java
new file mode 100644
index 0000000..db70cac
--- /dev/null
+++ b/core/java/com/android/internal/expresslog/Histogram.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.expresslog;
+
+import android.annotation.NonNull;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+/** Histogram encapsulates StatsD write API calls */
+public final class Histogram {
+
+    private final long mMetricIdHash;
+    private final BinOptions mBinOptions;
+
+    public Histogram(@NonNull String metricId, @NonNull BinOptions binOptions) {
+        mMetricIdHash = Utils.hashString(metricId);
+        mBinOptions = binOptions;
+    }
+
+    /**
+     * Logs increment sample count for automatically calculated bin
+     *
+     * @hide
+     */
+    public void logSample(float sample) {
+        final int binIndex = mBinOptions.getBinForSample(sample);
+        FrameworkStatsLog.write(FrameworkStatsLog.EXPRESS_HISTOGRAM_SAMPLE_REPORTED, mMetricIdHash,
+                /*count*/ 1, binIndex);
+    }
+
+    /** Used by Histogram to map data sample to corresponding bin */
+    public interface BinOptions {
+        /**
+         * Returns bins count to be used by a histogram
+         *
+         * @return bins count used to initialize Options, including overflow & underflow bins
+         * @hide
+         */
+        int getBinsCount();
+
+        /**
+         * @return zero based index
+         * Calculates bin index for the input sample value
+         * index == 0 stands for underflow
+         * index == getBinsCount() - 1 stands for overflow
+         * @hide
+         */
+        int getBinForSample(float sample);
+    }
+
+    /** Used by Histogram to map data sample to corresponding bin for uniform bins */
+    public static final class UniformOptions implements BinOptions {
+
+        private final int mBinCount;
+        private final float mMinValue;
+        private final float mExclusiveMaxValue;
+        private final float mBinSize;
+
+        public UniformOptions(int binCount, float minValue, float exclusiveMaxValue) {
+            if (binCount < 1) {
+                throw new IllegalArgumentException("Bin count should be positive number");
+            }
+
+            if (exclusiveMaxValue <= minValue) {
+                throw new IllegalArgumentException("Bins range invalid (maxValue < minValue)");
+            }
+
+            mMinValue = minValue;
+            mExclusiveMaxValue = exclusiveMaxValue;
+            mBinSize = (mExclusiveMaxValue - minValue) / binCount;
+
+            // Implicitly add 2 for the extra undeflow & overflow bins
+            mBinCount = binCount + 2;
+        }
+
+        @Override
+        public int getBinsCount() {
+            return mBinCount;
+        }
+
+        @Override
+        public int getBinForSample(float sample) {
+            if (sample < mMinValue) {
+                // goes to underflow
+                return 0;
+            } else if (sample >= mExclusiveMaxValue) {
+                // goes to overflow
+                return mBinCount - 1;
+            }
+            return (int) ((sample - mMinValue) / mBinSize + 1);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/expresslog/TEST_MAPPING b/core/java/com/android/internal/expresslog/TEST_MAPPING
new file mode 100644
index 0000000..c9b0cf8
--- /dev/null
+++ b/core/java/com/android/internal/expresslog/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "ExpressLogTests",
+      "options": [
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/jank/EventLogTags.logtags b/core/java/com/android/internal/jank/EventLogTags.logtags
index 6139bce..7af5d8f 100644
--- a/core/java/com/android/internal/jank/EventLogTags.logtags
+++ b/core/java/com/android/internal/jank/EventLogTags.logtags
@@ -3,8 +3,8 @@
 option java_package com.android.internal.jank;
 
 # Marks a request to start tracing a CUJ. Doesn't mean the request was executed.
-37001 jank_cuj_events_begin_request (CUJ Type|1|5)
+37001 jank_cuj_events_begin_request (CUJ Type|1|5),(Elapsed Time Ns|2|3),(Uptime Ns|2|3)
 # Marks a request to end tracing a CUJ. Doesn't mean the request was executed.
-37002 jank_cuj_events_end_request (CUJ Type|1|5)
+37002 jank_cuj_events_end_request (CUJ Type|1|5),(Elapsed Time Ns|2|3),(Uptime Time Ns|2|3)
 # Marks a request to cancel tracing a CUJ. Doesn't mean the request was executed.
-37003 jank_cuj_events_cancel_request (CUJ Type|1|5)
+37003 jank_cuj_events_cancel_request (CUJ Type|1|5),(Elapsed Time Ns|2|3),(Uptime Time Ns|2|3)
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index e4195d2..3226669 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -68,6 +68,9 @@
 
     private static final int MAX_LENGTH_EVENT_DESC = 20;
 
+    private static final int MAX_FLUSH_ATTEMPTS = 3;
+    private static final int FLUSH_DELAY_MILLISECOND = 60;
+
     static final int REASON_END_UNKNOWN = -1;
     static final int REASON_END_NORMAL = 0;
     static final int REASON_END_SURFACE_DESTROYED = 1;
@@ -358,11 +361,35 @@
             // will remove it when all the frame metrics in this duration are called back.
             // See onFrameMetricsAvailable for the logic of removing the observer.
             // Waiting at most 10 seconds for all callbacks to finish.
-            mWaitForFinishTimedOut = () -> {
-                Log.e(TAG, "force finish cuj because of time out:" + mSession.getName());
-                finish();
+            mWaitForFinishTimedOut = new Runnable() {
+                private int mFlushAttempts = 0;
+
+                @Override
+                public void run() {
+                    if (mWaitForFinishTimedOut == null || mMetricsFinalized) {
+                        return;
+                    }
+
+                    // Send a flush jank data transaction.
+                    if (mSurfaceControl != null && mSurfaceControl.isValid()) {
+                        SurfaceControl.Transaction.sendSurfaceFlushJankData(mSurfaceControl);
+                    }
+
+                    long delay;
+                    if (mFlushAttempts < MAX_FLUSH_ATTEMPTS) {
+                        delay = FLUSH_DELAY_MILLISECOND;
+                        mFlushAttempts++;
+                    } else {
+                        mWaitForFinishTimedOut = () -> {
+                            Log.e(TAG, "force finish cuj, time out: " + mSession.getName());
+                            finish();
+                        };
+                        delay = TimeUnit.SECONDS.toMillis(10);
+                    }
+                    getHandler().postDelayed(mWaitForFinishTimedOut, delay);
+                }
             };
-            getHandler().postDelayed(mWaitForFinishTimedOut, TimeUnit.SECONDS.toMillis(10));
+            getHandler().postDelayed(mWaitForFinishTimedOut, FLUSH_DELAY_MILLISECOND);
             notifyCujEvent(ACTION_SESSION_END);
             return true;
         }
@@ -537,11 +564,12 @@
 
     @UiThread
     private void finish() {
+        if (mMetricsFinalized || mCancelled) return;
+        mMetricsFinalized = true;
+
         getHandler().removeCallbacks(mWaitForFinishTimedOut);
         mWaitForFinishTimedOut = null;
-        if (mMetricsFinalized || mCancelled) return;
         markEvent("FT#finish#" + mJankInfos.size());
-        mMetricsFinalized = true;
 
         // The tracing has been ended, remove the observer, see if need to trigger perfetto.
         removeObservers();
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index d9e9a5f..62f1599 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -16,11 +16,15 @@
 
 package com.android.internal.jank;
 
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
 import static com.android.internal.jank.FrameTracker.REASON_CANCEL_NORMAL;
 import static com.android.internal.jank.FrameTracker.REASON_CANCEL_TIMEOUT;
 import static com.android.internal.jank.FrameTracker.REASON_END_NORMAL;
 import static com.android.internal.jank.FrameTracker.REASON_END_UNKNOWN;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP;
@@ -89,17 +93,20 @@
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL;
 import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
 
+import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.UiThread;
 import android.annotation.WorkerThread;
+import android.app.ActivityThread;
 import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.HandlerThread;
+import android.os.SystemClock;
 import android.provider.DeviceConfig;
-import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
@@ -232,6 +239,7 @@
     public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66;
     public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67;
     public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68;
+    public static final int CUJ_IME_INSETS_ANIMATION = 69;
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -309,6 +317,7 @@
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE,
             UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION,
     };
 
     private static class InstanceHolder {
@@ -401,7 +410,8 @@
             CUJ_RECENTS_SCROLLING,
             CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS,
             CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE,
-            CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME
+            CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+            CUJ_IME_INSETS_ANIMATION,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {
@@ -422,29 +432,37 @@
      * @param worker the worker thread for the callbacks
      */
     @VisibleForTesting
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
     public InteractionJankMonitor(@NonNull HandlerThread worker) {
-        // Check permission early.
-        Settings.Config.enforceReadPermission(
-            DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR);
-
         mRunningTrackers = new SparseArray<>();
         mTimeoutActions = new SparseArray<>();
         mWorker = worker;
         mWorker.start();
-        mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
         mDisplayResolutionTracker = new DisplayResolutionTracker(worker.getThreadHandler());
-
-        // Post initialization to the background in case we're running on the main
-        // thread.
-        mWorker.getThreadHandler().post(
-                () -> mPropertiesChangedListener.onPropertiesChanged(
-                        DeviceConfig.getProperties(
-                                DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR)));
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
-                new HandlerExecutor(mWorker.getThreadHandler()),
-                mPropertiesChangedListener);
+        mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
         mEnabled = DEFAULT_ENABLED;
+
+        final Context context = ActivityThread.currentApplication();
+        if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) == PERMISSION_GRANTED) {
+            // Post initialization to the background in case we're running on the main thread.
+            mWorker.getThreadHandler().post(
+                    () -> mPropertiesChangedListener.onPropertiesChanged(
+                            DeviceConfig.getProperties(
+                                    DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR)));
+            DeviceConfig.addOnPropertiesChangedListener(
+                    DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
+                    new HandlerExecutor(mWorker.getThreadHandler()),
+                    mPropertiesChangedListener);
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "Initialized the InteractionJankMonitor."
+                        + " (No READ_DEVICE_CONFIG permission to change configs)"
+                        + " enabled=" + mEnabled + ", interval=" + mSamplingInterval
+                        + ", missedFrameThreshold=" + mTraceThresholdMissedFrames
+                        + ", frameTimeThreshold=" + mTraceThresholdFrameTimeMillis
+                        + ", package=" + context.getPackageName());
+            }
+        }
     }
 
     /**
@@ -556,7 +574,8 @@
     public boolean begin(@NonNull Configuration.Builder builder) {
         try {
             final Configuration config = builder.build();
-            EventLogTags.writeJankCujEventsBeginRequest(config.mCujType);
+            EventLogTags.writeJankCujEventsBeginRequest(
+                    config.mCujType, SystemClock.elapsedRealtimeNanos(), SystemClock.uptimeNanos());
             final TrackerResult result = new TrackerResult();
             final boolean success = config.getHandler().runWithScissors(
                     () -> result.mResult = beginInternal(config), EXECUTOR_TASK_TIMEOUT);
@@ -630,7 +649,8 @@
      * @return boolean true if the tracker is ended successfully, false otherwise.
      */
     public boolean end(@CujType int cujType) {
-        EventLogTags.writeJankCujEventsEndRequest(cujType);
+        EventLogTags.writeJankCujEventsEndRequest(cujType, SystemClock.elapsedRealtimeNanos(),
+                SystemClock.uptimeNanos());
         FrameTracker tracker = getTracker(cujType);
         // Skip this call since we haven't started a trace yet.
         if (tracker == null) return false;
@@ -668,7 +688,8 @@
      * @return boolean true if the tracker is cancelled successfully, false otherwise.
      */
     public boolean cancel(@CujType int cujType) {
-        EventLogTags.writeJankCujEventsCancelRequest(cujType);
+        EventLogTags.writeJankCujEventsCancelRequest(cujType, SystemClock.elapsedRealtimeNanos(),
+                SystemClock.uptimeNanos());
         return cancel(cujType, REASON_CANCEL_NORMAL);
     }
 
@@ -923,6 +944,8 @@
                 return "LAUNCHER_CLOSE_ALL_APPS_SWIPE";
             case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME:
                 return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME";
+            case CUJ_IME_INSETS_ANIMATION:
+                return "IME_INSETS_ANIMATION";
         }
         return "UNKNOWN";
     }
@@ -1178,7 +1201,7 @@
          */
         @VisibleForTesting
         public int getDisplayId() {
-            return (mSurfaceOnly ? mContext.getDisplay() : mView.getDisplay()).getDisplayId();
+            return (mSurfaceOnly ? mContext : mView.getContext()).getDisplayId();
         }
     }
 
diff --git a/core/java/com/android/internal/os/IBinaryTransparencyService.aidl b/core/java/com/android/internal/os/IBinaryTransparencyService.aidl
index e782aa7..c8340ac 100644
--- a/core/java/com/android/internal/os/IBinaryTransparencyService.aidl
+++ b/core/java/com/android/internal/os/IBinaryTransparencyService.aidl
@@ -28,8 +28,6 @@
 interface IBinaryTransparencyService {
     String getSignedImageInfo();
 
-    List getApexInfo();
-
     void recordMeasurementsForAllPackages();
 
     parcelable ApexInfo {
@@ -60,4 +58,5 @@
     /** Test only */
     List<ApexInfo> collectAllApexInfo(boolean includeTestOnly);
     List<AppInfo> collectAllUpdatedPreloadInfo(in Bundle packagesToSkip);
+    List<AppInfo> collectAllSilentInstalledMbaInfo(in Bundle packagesToSkip);
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/KernelSingleProcessCpuThreadReader.java b/core/java/com/android/internal/os/KernelSingleProcessCpuThreadReader.java
index 4d2a08a..e2c096c1 100644
--- a/core/java/com/android/internal/os/KernelSingleProcessCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelSingleProcessCpuThreadReader.java
@@ -20,6 +20,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.expresslog.Counter;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -117,13 +118,16 @@
     public void startTrackingThreadCpuTimes() {
         if (!mIsTracking) {
             if (!startTrackingProcessCpuTimes(mPid, mCpuTimeInStateReader)) {
-                Slog.e(TAG, "Failed to start tracking process CPU times for " + mPid);
+                Slog.wtf(TAG, "Failed to start tracking process CPU times for " + mPid);
+                Counter.logIncrement("cpu.value_process_tracking_start_failure_count");
             }
             if (mSelectedThreadNativeTids.length > 0) {
                 if (!startAggregatingThreadCpuTimes(mSelectedThreadNativeTids,
                         mCpuTimeInStateReader)) {
-                    Slog.e(TAG, "Failed to start tracking aggregated thread CPU times for "
+                    Slog.wtf(TAG, "Failed to start tracking aggregated thread CPU times for "
                             + Arrays.toString(mSelectedThreadNativeTids));
+                    Counter.logIncrement(
+                            "cpu.value_aggregated_thread_tracking_start_failure_count");
                 }
             }
             mIsTracking = true;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index c6aca44..1875ecf 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -378,8 +378,12 @@
             // window, as we'll be skipping the addView in handleResumeActivity(), and
             // the token will not be updated as for a new window.
             getAttributes().token = preservedWindow.getAttributes().token;
-            mProxyOnBackInvokedDispatcher.setActualDispatcher(
-                    preservedWindow.getOnBackInvokedDispatcher());
+            final ViewRootImpl viewRoot = mDecor.getViewRootImpl();
+            if (viewRoot != null) {
+                // Clear the old callbacks and attach to the new window.
+                viewRoot.getOnBackInvokedDispatcher().clear();
+                onViewRootImplSet(viewRoot);
+            }
         }
         // Even though the device doesn't support picture-in-picture mode,
         // an user can force using it through developer options.
@@ -1938,9 +1942,9 @@
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
             case KeyEvent.KEYCODE_VOLUME_MUTE: {
-                // If we have a session send it the volume command, otherwise
-                // use the suggested stream.
-                if (mMediaController != null) {
+                // If we have a session and no active phone call send it the volume command,
+                // otherwise use the suggested stream.
+                if (mMediaController != null && !isActivePhoneCallKnown()) {
                     getMediaSessionManager().dispatchVolumeKeyEventToSessionAsSystemService(event,
                             mMediaController.getSessionToken());
                 } else {
@@ -1991,6 +1995,18 @@
         return false;
     }
 
+    private boolean isActivePhoneCallKnown() {
+        boolean isActivePhoneCallKnown = false;
+        AudioManager audioManager =
+                (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+        int audioManagerMode = audioManager.getMode();
+        if (audioManagerMode == AudioManager.MODE_IN_CALL
+                || audioManagerMode == AudioManager.MODE_IN_COMMUNICATION) {
+            isActivePhoneCallKnown = true;
+        }
+        return isActivePhoneCallKnown;
+    }
+
     private KeyguardManager getKeyguardManager() {
         if (mKeyguardManager == null) {
             mKeyguardManager = (KeyguardManager) getContext().getSystemService(
diff --git a/core/java/com/android/internal/security/VerityUtils.java b/core/java/com/android/internal/security/VerityUtils.java
index 786941f..74a9d16 100644
--- a/core/java/com/android/internal/security/VerityUtils.java
+++ b/core/java/com/android/internal/security/VerityUtils.java
@@ -81,6 +81,15 @@
         }
     }
 
+    /** Enables fs-verity for an open file without signature. */
+    public static void setUpFsverity(int fd) throws IOException {
+        int errno = enableFsverityForFdNative(fd);
+        if (errno != 0) {
+            throw new IOException("Failed to enable fs-verity on FD(" + fd + "): "
+                    + Os.strerror(errno));
+        }
+    }
+
     /** Returns whether the file has fs-verity enabled. */
     public static boolean hasFsverity(@NonNull String filePath) {
         int retval = statxForFsverityNative(filePath);
@@ -211,6 +220,7 @@
     }
 
     private static native int enableFsverityNative(@NonNull String filePath);
+    private static native int enableFsverityForFdNative(int fd);
     private static native int measureFsverityNative(@NonNull String filePath,
             @NonNull byte[] digest);
     private static native int statxForFsverityNative(@NonNull String filePath);
diff --git a/core/java/com/android/internal/statusbar/AppClipsServiceConnector.java b/core/java/com/android/internal/statusbar/AppClipsServiceConnector.java
new file mode 100644
index 0000000..287b85f
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/AppClipsServiceConnector.java
@@ -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.internal.statusbar;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * A helper class to communicate with the App Clips service running in SystemUI.
+ */
+public class AppClipsServiceConnector {
+
+    private static final String TAG = AppClipsServiceConnector.class.getSimpleName();
+
+    private final Context mContext;
+    private final Handler mHandler;
+
+    public AppClipsServiceConnector(Context context) {
+        mContext = context;
+        HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        mHandler = handlerThread.getThreadHandler();
+    }
+
+    /**
+     * @return true if the task represented by {@code taskId} can launch App Clips screenshot flow,
+     * false otherwise.
+     */
+    public boolean canLaunchCaptureContentActivityForNote(int taskId) {
+        try {
+            CompletableFuture<Boolean> future = new CompletableFuture<>();
+            connectToServiceAndProcessRequest(taskId, future);
+            return future.get();
+        } catch (Exception e) {
+            Log.d(TAG, "Exception from service\n" + e);
+        }
+
+        return false;
+    }
+
+    private void connectToServiceAndProcessRequest(int taskId, CompletableFuture<Boolean> future) {
+        ServiceConnection serviceConnection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                try {
+                    future.complete(IAppClipsService.Stub.asInterface(
+                            service).canLaunchCaptureContentActivityForNote(taskId));
+                } catch (Exception e) {
+                    Log.d(TAG, "Exception from service\n" + e);
+                }
+                future.complete(false);
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                if (!future.isDone()) {
+                    future.complete(false);
+                }
+            }
+        };
+
+        final ComponentName serviceComponent = ComponentName.unflattenFromString(
+                mContext.getResources().getString(
+                        com.android.internal.R.string.config_screenshotAppClipsServiceComponent));
+        final Intent serviceIntent = new Intent();
+        serviceIntent.setComponent(serviceComponent);
+
+        boolean bindService = mContext.bindServiceAsUser(serviceIntent, serviceConnection,
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, mHandler,
+                mContext.getUser());
+
+        // Complete the future early if service not bound.
+        if (!bindService) {
+            future.complete(false);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/statusbar/IAppClipsService.aidl b/core/java/com/android/internal/statusbar/IAppClipsService.aidl
new file mode 100644
index 0000000..013d0d3
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/IAppClipsService.aidl
@@ -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.internal.statusbar;
+
+/**
+ * A service that runs in SystemUI and helps determine if App Clips flow is supported in the
+ * current state of device. This service needs to run in SystemUI in order to communicate with the
+ * instance of app bubbles.
+ */
+interface IAppClipsService {
+    boolean canLaunchCaptureContentActivityForNote(in int taskId);
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 1c85ca2..b529a10 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -214,11 +214,11 @@
      * bar and navigation bar which are temporarily visible to the user.
      *
      * @param displayId the ID of the display to notify.
-     * @param types the internal insets types of the bars are about to show transiently.
+     * @param types the insets types of the bars are about to show transiently.
      * @param isGestureOnSystemBar whether the gesture to show the transient bar was a gesture on
      *        one of the bars itself.
      */
-    void showTransient(int displayId, in int[] types, boolean isGestureOnSystemBar);
+    void showTransient(int displayId, int types, boolean isGestureOnSystemBar);
 
     /**
      * Notifies System UI to abort the transient state of system bars, which prevents the bars being
@@ -226,9 +226,9 @@
      * bars again.
      *
      * @param displayId the ID of the display to notify.
-     * @param types the internal insets types of the bars are about to abort the transient state.
+     * @param types the insets types of the bars are about to abort the transient state.
      */
-    void abortTransient(int displayId, in int[] types);
+    void abortTransient(int displayId, int types);
 
     /**
      * Show a warning that the device is about to go to sleep due to user inactivity.
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
index 54221ce..4f827cd 100644
--- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.statusbar;
 
-import android.annotation.NonNull;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -41,15 +40,14 @@
     public final int mBehavior;
     public final int mRequestedVisibleTypes;
     public final String mPackageName;
-    public final int[] mTransientBarTypes;
+    public final int mTransientBarTypes;
     public final LetterboxDetails[] mLetterboxDetails;
 
     public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1,
             int appearance, AppearanceRegion[] appearanceRegions, int imeWindowVis,
             int imeBackDisposition, boolean showImeSwitcher, int disabledFlags2, IBinder imeToken,
             boolean navbarColorManagedByIme, int behavior, int requestedVisibleTypes,
-            String packageName, @NonNull int[] transientBarTypes,
-            LetterboxDetails[] letterboxDetails) {
+            String packageName, int transientBarTypes, LetterboxDetails[] letterboxDetails) {
         mIcons = new ArrayMap<>(icons);
         mDisabledFlags1 = disabledFlags1;
         mAppearance = appearance;
@@ -87,7 +85,7 @@
         dest.writeInt(mBehavior);
         dest.writeInt(mRequestedVisibleTypes);
         dest.writeString(mPackageName);
-        dest.writeIntArray(mTransientBarTypes);
+        dest.writeInt(mTransientBarTypes);
         dest.writeParcelableArray(mLetterboxDetails, flags);
     }
 
@@ -113,7 +111,7 @@
                     final int behavior = source.readInt();
                     final int requestedVisibleTypes = source.readInt();
                     final String packageName = source.readString();
-                    final int[] transientBarTypes = source.createIntArray();
+                    final int transientBarTypes = source.readInt();
                     final LetterboxDetails[] letterboxDetails =
                             source.readParcelableArray(null, LetterboxDetails.class);
                     return new RegisterStatusBarResult(icons, disabledFlags1, appearance,
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index afb526a..2d5bb6c 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -14,7 +14,10 @@
 
 package com.android.internal.util;
 
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Trace.TRACE_TAG_APP;
+import static android.provider.DeviceConfig.NAMESPACE_LATENCY_TRACKER;
 
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
@@ -24,6 +27,8 @@
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_SHOWN;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR;
@@ -42,9 +47,12 @@
 import static com.android.internal.util.LatencyTracker.ActionProperties.SAMPLE_INTERVAL_SUFFIX;
 import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX;
 
+import android.Manifest;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.ActivityThread;
 import android.content.Context;
 import android.os.Build;
 import android.os.ConditionVariable;
@@ -187,6 +195,16 @@
      */
     public static final int ACTION_SHOW_VOICE_INTERACTION = 19;
 
+    /**
+     * Time it takes to request IME shown animation.
+     */
+    public static final int ACTION_REQUEST_IME_SHOWN = 20;
+
+    /**
+     * Time it takes to request IME hidden animation.
+     */
+    public static final int ACTION_REQUEST_IME_HIDDEN = 21;
+
     private static final int[] ACTIONS_ALL = {
         ACTION_EXPAND_PANEL,
         ACTION_TOGGLE_RECENTS,
@@ -208,6 +226,8 @@
         ACTION_SHOW_SELECTION_TOOLBAR,
         ACTION_FOLD_TO_AOD,
         ACTION_SHOW_VOICE_INTERACTION,
+        ACTION_REQUEST_IME_SHOWN,
+        ACTION_REQUEST_IME_HIDDEN,
     };
 
     /** @hide */
@@ -232,6 +252,8 @@
         ACTION_SHOW_SELECTION_TOOLBAR,
         ACTION_FOLD_TO_AOD,
         ACTION_SHOW_VOICE_INTERACTION,
+        ACTION_REQUEST_IME_SHOWN,
+        ACTION_REQUEST_IME_HIDDEN,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Action {
@@ -259,6 +281,8 @@
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR,
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD,
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_SHOWN,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN,
     };
 
     private static LatencyTracker sLatencyTracker;
@@ -284,15 +308,30 @@
         return sLatencyTracker;
     }
 
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
     @VisibleForTesting
     public LatencyTracker() {
         mEnabled = DEFAULT_ENABLED;
 
-        // Post initialization to the background in case we're running on the main thread.
-        BackgroundThread.getHandler().post(() -> this.updateProperties(
-                DeviceConfig.getProperties(DeviceConfig.NAMESPACE_LATENCY_TRACKER)));
-        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
-                BackgroundThread.getExecutor(), this::updateProperties);
+        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(), this::updateProperties);
+        } else {
+            if (DEBUG) {
+                if (context == null) {
+                    Log.d(TAG, "No application for " + ActivityThread.currentActivityThread());
+                } else {
+                    Log.d(TAG, "Initialized the LatencyTracker."
+                            + " (No READ_DEVICE_CONFIG permission to change configs)"
+                            + " enabled=" + mEnabled + ", package=" + context.getPackageName());
+                }
+            }
+        }
     }
 
     private void updateProperties(DeviceConfig.Properties properties) {
@@ -368,6 +407,10 @@
                 return "ACTION_FOLD_TO_AOD";
             case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION:
                 return "ACTION_SHOW_VOICE_INTERACTION";
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_SHOWN:
+                return "ACTION_REQUEST_IME_SHOWN";
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN:
+                return "ACTION_REQUEST_IME_HIDDEN";
             default:
                 throw new IllegalArgumentException("Invalid action");
         }
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 3494c9e..a646df3 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -17,6 +17,8 @@
 package com.android.internal.widget;
 
 import android.app.PendingIntent;
+import android.app.RemoteLockscreenValidationResult;
+import android.app.StartLockscreenValidationRequest;
 import android.app.trust.IStrongAuthTracker;
 import android.os.Bundle;
 import android.security.keystore.recovery.WrappedApplicationKey;
@@ -93,6 +95,8 @@
             in byte[] recoveryKeyBlob,
             in List<WrappedApplicationKey> applicationKeys);
     void closeSession(in String sessionId);
+    StartLockscreenValidationRequest startRemoteLockscreenValidation();
+    RemoteLockscreenValidationResult validateRemoteLockscreen(in byte[] encryptedCredential);
     boolean hasSecureLockScreen();
     boolean tryUnlockWithCachedUnifiedChallenge(int userId);
     void removeCachedUnifiedChallenge(int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
index e56c381..5c3759f 100644
--- a/core/java/com/android/internal/widget/LockPatternChecker.java
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -1,10 +1,7 @@
 package com.android.internal.widget;
 
-import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION;
-
 import android.annotation.NonNull;
 import android.os.AsyncTask;
-import android.provider.DeviceConfig;
 
 import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
 
@@ -120,8 +117,7 @@
             @Override
             protected void onPostExecute(Boolean result) {
                 callback.onChecked(result, mThrottleTimeout);
-                if (DeviceConfig.getBoolean(NAMESPACE_AUTO_PIN_CONFIRMATION,
-                        "enable_auto_pin_confirmation", false)) {
+                if (LockPatternUtils.isAutoPinConfirmFeatureAvailable()) {
                     utils.setPinLength(userId, credentialCopy.size());
                 }
                 credentialCopy.zeroize();
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 2f51479..f72c4c3 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -28,6 +28,8 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.PropertyInvalidatedCache;
+import android.app.RemoteLockscreenValidationResult;
+import android.app.StartLockscreenValidationRequest;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.PasswordMetrics;
 import android.app.trust.IStrongAuthTracker;
@@ -63,6 +65,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.charset.StandardCharsets;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.ArrayList;
@@ -113,6 +116,13 @@
     public static final int CREDENTIAL_TYPE_PIN = 3;
     public static final int CREDENTIAL_TYPE_PASSWORD = 4;
 
+    /**
+     * Header used for the encryption and decryption of the device credential for
+     * remote device lockscreen validation.
+     */
+    public static final byte[] ENCRYPTED_REMOTE_CREDENTIALS_HEADER =
+            "encrypted_remote_credentials".getBytes(StandardCharsets.UTF_8);
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = {
             CREDENTIAL_TYPE_NONE,
@@ -681,7 +691,7 @@
      * @return true, if deviceConfig flag is set to true or the flag is not propagated and
      * defaultValue is true.
      */
-    public boolean isAutoPinConfirmFeatureAvailable() {
+    public static boolean isAutoPinConfirmFeatureAvailable() {
         return DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION,
                 FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
@@ -1822,4 +1832,29 @@
     public void removeUser(@UserIdInt int userId) {
         getLockSettingsInternal().removeUser(userId);
     }
+
+   /**
+     * Starts a session to verify lockscreen credentials provided by a remote device.
+     */
+    @NonNull
+    public StartLockscreenValidationRequest startRemoteLockscreenValidation() {
+        try {
+            return getLockSettings().startRemoteLockscreenValidation();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+   /**
+     * Verifies credentials guess from a remote device.
+     */
+    @NonNull
+    public RemoteLockscreenValidationResult validateRemoteLockscreen(
+            @NonNull byte[] encryptedCredential) {
+        try {
+            return getLockSettings().validateRemoteLockscreen(encryptedCredential);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp
index d7cbf74..200ddef 100644
--- a/core/jni/LayoutlibLoader.cpp
+++ b/core/jni/LayoutlibLoader.cpp
@@ -27,6 +27,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include "android_view_InputDevice.h"
 #include "core_jni_helpers.h"
 #include "jni.h"
 #ifdef _WIN32
@@ -100,6 +101,7 @@
 extern int register_android_util_jar_StrictJarFile(JNIEnv* env);
 extern int register_android_view_KeyCharacterMap(JNIEnv* env);
 extern int register_android_view_KeyEvent(JNIEnv* env);
+extern int register_android_view_InputDevice(JNIEnv* env);
 extern int register_android_view_MotionEvent(JNIEnv* env);
 extern int register_android_view_ThreadedRenderer(JNIEnv* env);
 extern int register_android_graphics_HardwareBufferRenderer(JNIEnv* env);
@@ -142,6 +144,7 @@
         {"android.util.jar.StrictJarFile", REG_JNI(register_android_util_jar_StrictJarFile)},
         {"android.view.KeyCharacterMap", REG_JNI(register_android_view_KeyCharacterMap)},
         {"android.view.KeyEvent", REG_JNI(register_android_view_KeyEvent)},
+        {"android.view.InputDevice", REG_JNI(register_android_view_InputDevice)},
         {"android.view.MotionEvent", REG_JNI(register_android_view_MotionEvent)},
         {"android.view.VelocityTracker", REG_JNI(register_android_view_VelocityTracker)},
         {"com.android.internal.util.VirtualRefBasePtr",
@@ -320,6 +323,41 @@
     return true;
 }
 
+// Creates an array of InputDevice from key character map files
+static void init_keyboard(JNIEnv* env, const vector<string>& keyboardPaths) {
+    jclass inputDevice = FindClassOrDie(env, "android/view/InputDevice");
+    jobjectArray inputDevicesArray =
+            env->NewObjectArray(keyboardPaths.size(), inputDevice, nullptr);
+    int keyboardId = 1;
+
+    for (const string& path : keyboardPaths) {
+        base::Result<std::shared_ptr<KeyCharacterMap>> charMap =
+                KeyCharacterMap::load(path, KeyCharacterMap::Format::BASE);
+
+        InputDeviceInfo info = InputDeviceInfo();
+        info.initialize(keyboardId, 0, 0, InputDeviceIdentifier(),
+                        "keyboard " + std::to_string(keyboardId), true, false, 0);
+        info.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+        info.setKeyCharacterMap(*charMap);
+
+        jobject inputDeviceObj = android_view_InputDevice_create(env, info);
+        if (inputDeviceObj) {
+            env->SetObjectArrayElement(inputDevicesArray, keyboardId - 1, inputDeviceObj);
+            env->DeleteLocalRef(inputDeviceObj);
+        }
+        keyboardId++;
+    }
+
+    if (bridge == nullptr) {
+        bridge = FindClassOrDie(env, "com/android/layoutlib/bridge/Bridge");
+        bridge = MakeGlobalRefOrDie(env, bridge);
+    }
+    jmethodID setInputManager = GetStaticMethodIDOrDie(env, bridge, "setInputManager",
+                                                       "([Landroid/view/InputDevice;)V");
+    env->CallStaticVoidMethod(bridge, setInputManager, inputDevicesArray);
+    env->DeleteLocalRef(inputDevicesArray);
+}
+
 } // namespace android
 
 using namespace android;
@@ -411,6 +449,13 @@
     // Use English locale for number format to ensure correct parsing of floats when using strtof
     setlocale(LC_NUMERIC, "en_US.UTF-8");
 
+    auto keyboardPathsString =
+            (jstring)env->CallStaticObjectMethod(system, getPropertyMethod,
+                                                 env->NewStringUTF("keyboard_paths"),
+                                                 env->NewStringUTF(""));
+    vector<string> keyboardPaths = parseCsv(env, keyboardPathsString);
+    init_keyboard(env, keyboardPaths);
+
     return JNI_VERSION_1_6;
 }
 
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index a8d8a43..b09a9c3 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -65,7 +65,7 @@
 public:
     NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
                                const sp<MessageQueue>& messageQueue, jint vsyncSource,
-                               jint eventRegistration);
+                               jint eventRegistration, jlong layerHandle);
 
     void dispose();
 
@@ -88,11 +88,15 @@
 
 NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
                                                        const sp<MessageQueue>& messageQueue,
-                                                       jint vsyncSource, jint eventRegistration)
+                                                       jint vsyncSource, jint eventRegistration,
+                                                       jlong layerHandle)
       : DisplayEventDispatcher(messageQueue->getLooper(),
                                static_cast<gui::ISurfaceComposer::VsyncSource>(vsyncSource),
                                static_cast<gui::ISurfaceComposer::EventRegistration>(
-                                       eventRegistration)),
+                                       eventRegistration),
+                               layerHandle != 0 ? sp<IBinder>::fromExisting(
+                                                          reinterpret_cast<IBinder*>(layerHandle))
+                                                : nullptr),
         mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
         mMessageQueue(messageQueue) {
     ALOGV("receiver %p ~ Initializing display event receiver.", this);
@@ -214,7 +218,7 @@
 }
 
 static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj,
-                        jint vsyncSource, jint eventRegistration) {
+                        jint vsyncSource, jint eventRegistration, jlong layerHandle) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
     if (messageQueue == NULL) {
         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
@@ -223,7 +227,7 @@
 
     sp<NativeDisplayEventReceiver> receiver =
             new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,
-                                           eventRegistration);
+                                           eventRegistration, layerHandle);
     status_t status = receiver->initialize();
     if (status) {
         String8 message;
@@ -236,13 +240,15 @@
     return reinterpret_cast<jlong>(receiver.get());
 }
 
-static void nativeDispose(JNIEnv* env, jclass clazz, jlong receiverPtr) {
-    NativeDisplayEventReceiver* receiver =
-            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
+static void release(NativeDisplayEventReceiver* receiver) {
     receiver->dispose();
     receiver->decStrong(gDisplayEventReceiverClassInfo.clazz); // drop reference held by the object
 }
 
+static jlong nativeGetDisplayEventReceiverFinalizer(JNIEnv*, jclass) {
+    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&release));
+}
+
 static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
     sp<NativeDisplayEventReceiver> receiver =
             reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
@@ -268,9 +274,10 @@
 
 static const JNINativeMethod gMethods[] = {
         /* name, signature, funcPtr */
-        {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
+        {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J",
          (void*)nativeInit},
-        {"nativeDispose", "(J)V", (void*)nativeDispose},
+        {"nativeGetDisplayEventReceiverFinalizer", "()J",
+         (void*)nativeGetDisplayEventReceiverFinalizer},
         // @FastNative
         {"nativeScheduleVsync", "(J)V", (void*)nativeScheduleVsync},
         {"nativeGetLatestVsyncEventData", "(J)Landroid/view/DisplayEventReceiver$VsyncEventData;",
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 97a0f50..bcb0da3 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -609,7 +609,7 @@
     if (fencePtr != 0) {
         optFence = sp<Fence>{reinterpret_cast<Fence*>(fencePtr)};
     }
-    transaction->setBuffer(ctrl, graphicBuffer, optFence, std::nullopt,
+    transaction->setBuffer(ctrl, graphicBuffer, optFence, std::nullopt, 0 /* producerId */,
                            genReleaseCallback(env, releaseCallback));
 }
 
@@ -951,6 +951,11 @@
     transaction->setDropInputMode(ctrl, static_cast<gui::DropInputMode>(mode));
 }
 
+static void nativeSurfaceFlushJankData(JNIEnv* env, jclass clazz, jlong nativeObject) {
+    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    SurfaceComposerClient::Transaction::sendSurfaceFlushJankDataTransaction(ctrl);
+}
+
 static void nativeSanitize(JNIEnv* env, jclass clazz, jlong transactionObj) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
     transaction->sanitize();
@@ -2246,6 +2251,8 @@
             (void*)nativeGetLayerId },
     {"nativeSetDropInputMode", "(JJI)V",
              (void*)nativeSetDropInputMode },
+    {"nativeSurfaceFlushJankData", "(J)V",
+            (void*)nativeSurfaceFlushJankData },
     {"nativeAddTransactionCommittedListener", "(JLandroid/view/SurfaceControl$TransactionCommittedListener;)V",
             (void*) nativeAddTransactionCommittedListener },
     {"nativeSetTrustedPresentationCallback", "(JJJLandroid/view/SurfaceControl$TrustedPresentationThresholds;)V",
diff --git a/core/jni/com_android_internal_security_VerityUtils.cpp b/core/jni/com_android_internal_security_VerityUtils.cpp
index 3e5689b..4a9e2d4 100644
--- a/core/jni/com_android_internal_security_VerityUtils.cpp
+++ b/core/jni/com_android_internal_security_VerityUtils.cpp
@@ -38,13 +38,8 @@
 
 namespace {
 
-int enableFsverity(JNIEnv *env, jobject /* clazz */, jstring filePath) {
-    ScopedUtfChars path(env, filePath);
-    if (path.c_str() == nullptr) {
-        return EINVAL;
-    }
-    ::android::base::unique_fd rfd(open(path.c_str(), O_RDONLY | O_CLOEXEC));
-    if (rfd.get() < 0) {
+int enableFsverityForFd(JNIEnv *env, jobject clazz, jint fd) {
+    if (fd < 0) {
         return errno;
     }
 
@@ -55,12 +50,21 @@
     arg.salt_size = 0;
     arg.salt_ptr = reinterpret_cast<uintptr_t>(nullptr);
 
-    if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, &arg) < 0) {
+    if (ioctl(fd, FS_IOC_ENABLE_VERITY, &arg) < 0) {
         return errno;
     }
     return 0;
 }
 
+int enableFsverity(JNIEnv *env, jobject clazz, jstring filePath) {
+    ScopedUtfChars path(env, filePath);
+    if (path.c_str() == nullptr) {
+        return EINVAL;
+    }
+    ::android::base::unique_fd rfd(open(path.c_str(), O_RDONLY | O_CLOEXEC));
+    return enableFsverityForFd(env, clazz, rfd.get());
+}
+
 // Returns whether the file has fs-verity enabled.
 // 0 if it is not present, 1 if is present, and -errno if there was an error.
 int statxForFsverity(JNIEnv *env, jobject /* clazz */, jstring filePath) {
@@ -126,6 +130,7 @@
 }
 const JNINativeMethod sMethods[] = {
         {"enableFsverityNative", "(Ljava/lang/String;)I", (void *)enableFsverity},
+        {"enableFsverityForFdNative", "(I)I", (void *)enableFsverityForFd},
         {"statxForFsverityNative", "(Ljava/lang/String;)I", (void *)statxForFsverity},
         {"measureFsverityNative", "(Ljava/lang/String;[B)I", (void *)measureFsverity},
 };
diff --git a/core/proto/android/app/profilerinfo.proto b/core/proto/android/app/profilerinfo.proto
index d318533..86261ec 100644
--- a/core/proto/android/app/profilerinfo.proto
+++ b/core/proto/android/app/profilerinfo.proto
@@ -35,4 +35,5 @@
     optional bool streaming_output = 5;
     // Denotes an agent (and its parameters) to attach for profiling.
     optional string agent = 6;
+    optional int32 clock_type = 7;
 }
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index 4f3eeb0..84c82e0 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -514,7 +514,10 @@
 
         optional string gfx_driver_whitelist_0 = 45;
 
-        // Next Tag: 46
+        optional bool  egl_blobcache_multifile = 46;
+        optional int32 egl_blobcache_multifile_limit = 47;
+
+        // Next Tag: 48
     }
     optional Ro ro = 21;
 
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index ea0ec79..8caf127 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -89,6 +89,12 @@
         // Setting for accessibility magnification for following typing.
         optional SettingProto accessibility_magnification_follow_typing_enabled = 43 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto contrast_level = 44 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto accessibility_magnification_always_on_enabled = 45 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto hearing_aid_ringtone_routing = 46 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto hearing_aid_call_routing = 47 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto hearing_aid_media_routing = 48 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto hearing_aid_system_sounds_routing = 49 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto accessibility_magnification_joystick_enabled = 50 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Accessibility accessibility = 2;
 
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 004d5d6..2f865af 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -469,5 +469,26 @@
     // Set of app ids that are exempt form low power standby
     repeated int32 allowlist = 10;
 
-    // Next tag: 11
+    // The active policy specifying exemptions
+    optional LowPowerStandbyPolicyProto policy = 11;
+
+    // Next tag: 12
+}
+
+message LowPowerStandbyPolicyProto {
+    option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+    // Name of the policy
+    optional string identifier = 1;
+
+    // Packages that are exempt from Low Power Standby restrictions
+    repeated string exempt_packages = 2;
+
+    // Exemption reasons that this policy allows
+    optional int32 allowed_reasons = 3;
+
+    // Features that this policy allows to be used
+    repeated string allowed_features = 4;
+
+    // Next tag: 5
 }
diff --git a/core/proto/android/server/syncstorageengine.proto b/core/proto/android/server/syncstorageengine.proto
index 2f35a07..7fa01d8 100644
--- a/core/proto/android/server/syncstorageengine.proto
+++ b/core/proto/android/server/syncstorageengine.proto
@@ -85,4 +85,5 @@
   repeated StatusInfo status = 1;
 
   optional bool is_job_namespace_migrated = 2;
+  optional bool is_job_attribution_fixed = 3;
 }
diff --git a/core/proto/android/server/windowmanagertransitiontrace.proto b/core/proto/android/server/windowmanagertransitiontrace.proto
index 4161f65..ab87384 100644
--- a/core/proto/android/server/windowmanagertransitiontrace.proto
+++ b/core/proto/android/server/windowmanagertransitiontrace.proto
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-syntax = "proto3";
+syntax = "proto2";
 
 package com.android.server.wm.shell;
 
@@ -36,13 +36,30 @@
     MAGIC_NUMBER_H = 0x45434152;  /* RACE (little-endian ASCII) */
   }
 
-  fixed64 magic_number = 1;  /* Must be the first field, set to value in MagicNumber */
-  int64 timestamp = 2; /* The timestamp of when the trace was started. */
-  repeated Transition transition = 3;
+  required fixed64 magic_number = 1;  /* Must be the first field, set to value in MagicNumber */
+  repeated Transition sent_transitions = 2;
+
+  // Additional debugging info only collected and dumped when explicitly requested to trace
+  repeated TransitionState transition_states = 3;
+  repeated TransitionInfo transition_info = 4;
 }
 
 message Transition {
+  optional int32 id = 1; // Not dumped in always on tracing
+  required uint64 start_transaction_id = 2;
+  required uint64 finish_transaction_id = 3;
+  required int64 create_time_ns = 4;
+  required int64 send_time_ns = 5;
+  repeated Target targets = 6;
+}
 
+message Target {
+  required int32 mode = 1;
+  required int32 layer_id = 2;
+  optional int32 window_id = 3;  // Not dumped in always on tracing
+}
+
+message TransitionState {
   enum State {
     COLLECTING = 0;
     PENDING = -1;
@@ -52,19 +69,29 @@
     FINISHED = 4;
   }
 
-  int32 id = 1;
-  int32 transition_type = 2;
-  int64 timestamp = 3;
-  State state = 5;
-  int32 flags = 6;
-  repeated ChangeInfo change = 7;
-  uint64 start_transaction_id = 8;
-  uint64 finish_transaction_id = 9;
+  required int64 time_ns = 1;
+  required int32 transition_id = 2;
+  required int32 transition_type = 3;
+  required State state = 4;
+  required int32 flags = 5;
+  repeated ChangeInfo change = 6;
+  repeated com.android.server.wm.IdentifierProto participants = 7;
 }
 
 message ChangeInfo {
-  com.android.server.wm.IdentifierProto window_identifier = 1;
-  int32 transit_mode = 2;
-  bool has_changed = 3;
-  int32 change_flags = 4;
+  required com.android.server.wm.IdentifierProto window_identifier = 1;
+  required int32 transit_mode = 2;
+  required bool has_changed = 3;
+  required int32 change_flags = 4;
+  required int32 windowing_mode = 5;
+}
+
+message TransitionInfo {
+  required int32 transition_id = 1;
+  repeated TransitionInfoChange change = 2;
+}
+
+message TransitionInfoChange {
+  required int32 layer_id = 1;
+  required int32 mode = 2;
 }
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index 607fd10..8889320 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -45,7 +45,7 @@
 message UsbHandlerProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
 
-    /* Same as android.hardware.usb.gadget.V1_0.GadgetFunction.* */
+    /* Same as android.hardware.usb.gadget.GadgetFunction.* */
     enum Function {
         FUNCTION_ADB = 1;
         FUNCTION_ACCESSORY = 2;
@@ -54,6 +54,7 @@
         FUNCTION_PTP = 16;
         FUNCTION_RNDIS = 32;
         FUNCTION_AUDIO_SOURCE = 64;
+        FUNCTION_UVC = 128;
     }
 
     repeated Function current_functions = 1;
@@ -284,7 +285,8 @@
 
     optional int32 cards_parser = 1;
     repeated UsbAlsaDeviceProto alsa_devices = 2;
-    repeated UsbMidiDeviceProto midi_devices = 3;
+    reserved 3; // previously midi_devices, now unused
+    repeated UsbAlsaMidiDeviceProto alsa_midi_devices = 4;
 }
 
 message UsbAlsaDeviceProto {
@@ -299,7 +301,7 @@
     optional string address = 6;
 }
 
-message UsbMidiDeviceProto {
+message UsbAlsaMidiDeviceProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
 
     optional int32 card = 1;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 49f4d35..f937390 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -108,6 +108,7 @@
     <protected-broadcast android:name="android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED" />
     <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED_INTERNAL" />
     <protected-broadcast android:name="android.os.action.LOW_POWER_STANDBY_ENABLED_CHANGED" />
+    <protected-broadcast android:name="android.os.action.LOW_POWER_STANDBY_POLICY_CHANGED" />
     <protected-broadcast android:name="android.os.action.ENHANCED_DISCHARGE_PREDICTION_CHANGED" />
 
     <!-- @deprecated This is rarely used and will be phased out soon. -->
@@ -1751,7 +1752,7 @@
     <!-- Allows an application to access wrist temperature data from the watch sensors.
          If you're requesting this permission, you must also request
          {@link #BODY_SENSORS_WRIST_TEMPERATURE}. Requesting this permission by itself doesn't
-         give you heart rate body sensors access.
+         give you wrist temperature body sensors access.
          <p class="note"><strong>Note: </strong> This permission is for Wear OS only.
          <p>Protection level: dangerous
 
@@ -2579,6 +2580,14 @@
     <!-- ==================================================== -->
     <eat-comment />
 
+    <!-- Allows an application to capture screen content to perform a screenshot using the intent
+         action {@link android.content.Intent#ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE}.
+         <p>Protection level: internal|role
+         <p>Intended for use by ROLE_NOTES only.
+    -->
+    <permission android:name="android.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE"
+        android:protectionLevel="internal|role" />
+
     <!-- Allows an application to get notified when a screen capture of its windows is attempted.
          <p>Protection level: normal
     -->
@@ -3245,6 +3254,411 @@
     <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SAFE_BOOT"
                 android:protectionLevel="internal|role" />
 
+    <!-- Allows an application to set policy related to restricting a user's ability to use or
+    enable and disable the microphone.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MICROPHONE"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to restricting a user's ability to use or
+    enable and disable the camera.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_CAMERA"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to keyguard.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_KEYGUARD"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to account management.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to hiding and suspending packages.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to force set a new device unlock password or a managed profile
+    challenge on current user.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to the status bar.-->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_STATUS_BAR"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to bluetooth.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_BLUETOOTH"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to fun.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_FUN"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to airplane mode.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_AIRPLANE_MODE"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to mobile networks.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MOBILE_NETWORK"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to physical media.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PHYSICAL_MEDIA"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to sms.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SMS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to usb file transfers.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_USB_FILE_TRANSFER"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to lock credentials.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK_CREDENTIALS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to Wifi.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIFI"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to screen capture.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SCREEN_CAPTURE"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to input methods.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_INPUT_METHODS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to restricting the user from configuring
+     private DNS.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_RESTRICT_PRIVATE_DNS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to the default sms application.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_DEFAULT_SMS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to profiles.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PROFILES"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to interacting with profiles (e.g. Disallowing
+    cross-profile copy and paste).
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PROFILE_INTERACTION"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to VPNs.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_VPN"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to audio output.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUDIO_OUTPUT"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to the display.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_DISPLAY"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to location.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCATION"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to factory reset.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to the wallpaper.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_WALLPAPER"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to the usage of the contents of the screen.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SCREEN_CONTENT"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to system dialogs.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to users running in the background.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_RUN_IN_BACKGROUND"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to printing.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PRINTING"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to nearby communications (e.g. Beam and
+    nearby streaming).
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_NEARBY_COMMUNICATION"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to windows.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_WINDOWS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to locale.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCALE"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to autofill.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_AUTOFILL"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to users.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_USERS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to certificates.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_CERTIFICATES"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to override APNs.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_OVERRIDE_APN"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to security logging.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SECURITY_LOGGING"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to system updates.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SYSTEM_UPDATES"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application query system updates.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to private DNS.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PRIVATE_DNS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to settings.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SETTINGS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to network logging.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_NETWORK_LOGGING"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to usb data signalling.-->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_USB_DATA_SIGNALLING"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to suspending personal apps.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SUSPEND_PERSONAL_APPS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set policy related to keeping uninstalled packages.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is
+        required to call APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_KEEP_UNINSTALLED_PACKAGES"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to accessibility.
+   <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+   APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_ACCESSIBILITY"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to common criteria mode.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to metered data.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_METERED_DATA"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to set a network-independent global HTTP proxy.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_PROXY"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to request bugreports with user consent.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_BUGREPORT"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to application user data.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_APP_USER_DATA"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to lock a profile or the device with the appropriate cross-user
+    permission.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_LOCK"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to system apps.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_SYSTEM_APPS"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to wiping data.
+        <p>{@link Manifest.permission#MANAGE_DEVICE_POLICY_ACROSS_USERS} is required to call
+        APIs protected by this permission on users different to the calling user.
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_WIPE_DATA"
+                android:protectionLevel="internal|role" />
+
+    <!-- Allows an application to manage policy related to the Memory Tagging Extension (MTE).
+    -->
+    <permission android:name="android.permission.MANAGE_DEVICE_POLICY_MTE"
+                android:protectionLevel="internal|role" />
+
     <!-- Allows an application to set device policies outside the current user
         that are critical for securing data within the current user.
         <p>Holding this permission allows the use of other held MANAGE_DEVICE_POLICY_*
@@ -4028,14 +4442,19 @@
 
     <!-- Allows a system application to be registered with credential manager without
          having to be enabled by the user.
-         @hide -->
-    <permission android:name="android.permission.SYSTEM_CREDENTIAL_PROVIDER"
+         @hide @SystemApi -->
+    <permission android:name="android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- Allows a browser to invoke credential manager APIs on behalf of another RP.
+        <p>Protection level: normal -->
+    <permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ORIGIN"
+        android:protectionLevel="normal" />
+
     <!-- Allows an application to be able to store and retrieve credentials from a remote
          device.
-         @hide -->
-    <permission android:name="android.permission.HYBRID_CREDENTIAL_PROVIDER"
+         @hide @SystemApi -->
+    <permission android:name="android.permission.PROVIDE_HYBRID_CREDENTIAL_SERVICE"
                 android:protectionLevel="signature|privileged" />
 
     <!-- ========================================= -->
@@ -4534,6 +4953,15 @@
     <permission android:name="android.permission.BIND_AUTOFILL_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by a
+         {@link android.service.assist.classification.FieldClassificationService},
+         to ensure that only the system can bind to it.
+         @SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
+         <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.BIND_FIELD_CLASSIFICATION_SERVICE"
+                android:protectionLevel="signature" />
+
     <!-- Must be required by a CredentialProviderService to ensure that only the
          system can bind to it.
          <p>Protection level: signature
@@ -4572,6 +5000,15 @@
     <permission android:name="android.permission.BIND_TEXTCLASSIFIER_SERVICE"
                 android:protectionLevel="signature" />
 
+    <!-- Must be required by a
+         {@link android.service.remotelockscreenvalidation.RemoteLockscreenValidationService}
+         to ensure that only the system can bind to it.
+         @SystemApi @hide This is not a third-party API
+         <p>Protection level: signature
+    -->
+    <permission android:name="android.permission.BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE"
+        android:protectionLevel="signature" />
+
     <!-- Must be required by a android.service.selectiontoolbar.SelectionToolbarRenderService,
           to ensure that only the system can bind to it.
           @hide This is not a third-party API (intended for OEMs and system apps).
@@ -5958,6 +6395,11 @@
     <permission android:name="android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS"
                 android:protectionLevel="signature"/>
 
+    <!-- @SystemApi Allows application to verify lockscreen credentials provided by a remote device.
+         @hide -->
+    <permission android:name="android.permission.CHECK_REMOTE_LOCKSCREEN"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows managing (adding, removing) fingerprint templates. Reserved for the system. @hide -->
     <permission android:name="android.permission.MANAGE_FINGERPRINT"
         android:protectionLevel="signature|privileged" />
@@ -6921,8 +7363,8 @@
 
     <!-- Allows an assistive application to perform actions on behalf of users inside of
          applications.
-         <p>For now, this permission is only granted to system applications fulfilling the
-         ASSISTANT role.
+         <p>For now, this permission is only granted to the Assistant application selected by
+         the user.
          <p>Protection level: internal|role
     -->
     <permission android:name="android.permission.EXECUTE_APP_ACTION"
@@ -7060,11 +7502,11 @@
     <permission android:name="android.permission.MANAGE_WEARABLE_SENSING_SERVICE"
                 android:protectionLevel="signature|privileged" />
 
-    <!-- Allows applications to use the long running jobs APIs. For more details
+    <!-- Allows applications to use the user-initiated jobs API. For more details
          see {@link android.app.job.JobInfo.Builder#setUserInitiated}.
          <p>Protection level: normal
      -->
-    <permission android:name="android.permission.RUN_LONG_JOBS"
+    <permission android:name="android.permission.RUN_USER_INITIATED_JOBS"
                 android:protectionLevel="normal"/>
 
     <!-- Allows an app access to the installer provided app metadata.
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index cb4462c..53a6836 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -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.
@@ -13,78 +13,42 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<vector android:width="24dp" android:height="24dp"
-        android:viewportWidth="24" android:viewportHeight="24"
-        xmlns:android="http://schemas.android.com/apk/res/android">
-  <path android:pathData="
-        M22.45 11.94
-        l-.58-.21
-        a1.19 1.19 0 0 1-.26-2.12
-        l.51-.34
-        a1.2 1.2 0 0 0-.83-2.19
-        l-.61.08
-        a1.2 1.2 0 0 1-1.21-1.76
-        l.29-.54
-        A1.2 1.2 0 0 0 18 3.31
-        l-.5.36
-        a1.21 1.21 0 0 1-1.9-1
-        v-.61
-        a1.2 1.2 0 0 0-2.27-.56
-        l-.26.5
-        a1.2 1.2 0 0 1-2.14 0
-        l-.28-.54
-        a1.2 1.2 0 0 0-2.27.56
-        v.61
-        a1.21 1.21 0 0 1-1.9 1
-        L6 3.31
-        a1.2 1.2 0 0 0-1.76 1.55
-        l.29.54
-        a1.2 1.2 0 0 1-1.21 1.76
-        l-.61-.08
-        a1.2 1.2 0 0 0-.83 2.19
-        l.51.34
-        a1.19 1.19 0 0 1-.26 2.12
-        l-.58.21
-        a1.21 1.21 0 0 0 .29 2.33
-        l.61.06
-        a1.2 1.2 0 0 1 .76 2
-        l-.42.46
-        a1.2 1.2 0 0 0 1.33 1.92
-        l.57-.22
-        a1.21 1.21 0 0 1 1.61 1.42
-        l-.16.59
-        a1.2 1.2 0 0 0 2.07 1.09
-        l.4-.47
-        a1.2 1.2 0 0 1 2.08.51
-        l.14.6
-        a1.2 1.2 0 0 0 2.34 0
-        l.14-.6
-        a1.2 1.2 0 0 1 2.08-.51
-        l.4.47
-        a1.2 1.2 0 0 0 2.07-1.09
-        l-.16-.59
-        a1.21 1.21 0 0 1 1.61-1.42
-        l.57.22
-        a1.2 1.2 0 0 0 1.33-1.92
-        l-.42-.46
-        a1.2 1.2 0 0 1 .76-2
-        l.61-.06
-        a1.21 1.21 0 0 0 .29-2.33
-        z
-        M12 19
-        a7 7 0 1 1 7-7 7 7 0 0 1-7 7
-        z
-        "
-        android:fillColor="#000000" />
-  <path android:pathData="
-        M9 7.75
-        a.75.75 0 1 0 0 1.5.75.75 0 1 0 0-1.5
-        z
-        M15 7.75
-        a.75.75 0 1 0 0 1.5.75.75 0 1 0 0-1.5
-        z
-        "
-        android:fillColor="#000000" />
-  <path android:strokeColor="#000000" android:strokeMiterLimit="10" android:strokeWidth="2"
-        android:pathData="M4 12h16M12 12v8" />
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:name="ring"
+        android:pathData="M 12 21 C 16.971 21 21 16.971 21 12 C 21 7.029 16.971 3 12 3 C 7.029 3 3 7.029 3 12 C 3 16.971 7.029 21 12 21 Z"
+        android:fillColor="#00000000"
+        android:strokeColor="#ffffff"
+        android:strokeWidth="2"/>
+    <group android:name="group">
+        <clip-path
+            android:pathData="M 20.5 12 C 20.5 16.694 16.694 20.5 12 20.5 C 7.306 20.5 3.5 16.694 3.5 12 C 3.5 7.306 7.306 3.5 12 3.5 C 16.694 3.5 20.5 7.306 20.5 12 Z"/>
+        <path
+            android:pathData="M 14.812 9.023 C 13.014 9.707 11.027 9.707 9.229 9.023 L 8.265 10.693 C 8.06 11.048 7.605 11.17 7.25 10.964 C 6.895 10.759 6.773 10.305 6.978 9.949 L 7.899 8.355 C 5.988 7.137 4.702 5.084 4.502 2.695 L 4.456 2.153 L 19.584 2.153 L 19.539 2.695 C 19.339 5.084 18.052 7.137 16.142 8.355 L 17.067 9.958 C 17.259 10.307 17.142 10.746 16.801 10.952 C 16.45 11.165 15.993 11.052 15.781 10.701 L 15.775 10.693 L 14.812 9.023 Z"
+            android:fillColor="#ffffff"/>
+        <group android:name="stars">
+            <path android:pathData="
+                M 7,14  h1v1h-1z
+                M 13,15 h1v1h-1z
+                M 14,11 h1v1h-1z
+
+                M 11,17 h0.5v0.5h-0.5z
+                M 10,15 h0.5v0.5h-0.5z
+                M 13,18 h0.5v0.5h-0.5z
+                M 17,15 h0.5v0.5h-0.5z
+                M 15,14 h0.5v0.5h-0.5z
+                M 18,12 h0.5v0.5h-0.5z
+                M 5,13  h0.5v0.5h-0.5z
+                M 5,10  h0.5v0.5h-0.5z
+                M 9,11  h0.5v0.5h-0.5z
+                M 8,17  h0.5v0.5h-0.5z
+                M 12,12 h0.5v0.5h-0.5z
+            " android:fillColor="#ffffff"/>
+        </group>
+    </group>
 </vector>
diff --git a/core/res/res/drawable/ic_dual_screen.xml b/core/res/res/drawable/ic_dual_screen.xml
new file mode 100644
index 0000000..26d97b7
--- /dev/null
+++ b/core/res/res/drawable/ic_dual_screen.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="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M11,35.9 L25,41.5Q25,41.5 25,41.5Q25,41.5 25,41.5V12.1Q25,12.1 25,12.1Q25,12.1 25,12.1L11,6.5V35.9Q11,35.9 11,35.9Q11,35.9 11,35.9ZM9.9,38.65Q9.05,38.3 8.525,37.575Q8,36.85 8,35.9V7Q8,5.75 8.875,4.875Q9.75,4 11,4L26,9.3Q26.9,9.6 27.45,10.375Q28,11.15 28,12.1V41.5Q28,43.1 26.675,43.975Q25.35,44.85 23.9,44.25ZM25,38V35H37Q37,35 37,35Q37,35 37,35V7Q37,7 37,7Q37,7 37,7H11V4H37Q38.25,4 39.125,4.875Q40,5.75 40,7V35Q40,36.25 39.125,37.125Q38.25,38 37,38ZM11,35.9Q11,35.9 11,35.9Q11,35.9 11,35.9V6.5Q11,6.5 11,6.5Q11,6.5 11,6.5V35.9Q11,35.9 11,35.9Q11,35.9 11,35.9Z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_thermostat.xml b/core/res/res/drawable/ic_thermostat.xml
new file mode 100644
index 0000000..23e5792
--- /dev/null
+++ b/core/res/res/drawable/ic_thermostat.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="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M26.15,19V16H37.65V19ZM26.15,13V10H42.15V13ZM14.8,41.95Q11.05,41.95 8.375,39.275Q5.7,36.6 5.7,32.85Q5.7,30.45 6.9,28.325Q8.1,26.2 10.2,24.9V10.6Q10.2,8.7 11.55,7.35Q12.9,6 14.8,6Q16.7,6 18.05,7.35Q19.4,8.7 19.4,10.6V24.9Q21.5,26.2 22.7,28.325Q23.9,30.45 23.9,32.85Q23.9,36.6 21.225,39.275Q18.55,41.95 14.8,41.95ZM8.7,32.85H20.9Q20.9,31.1 19.95,29.4Q19,27.7 17.4,27L16.4,26.55V10.6Q16.4,9.9 15.95,9.45Q15.5,9 14.8,9Q14.1,9 13.65,9.45Q13.2,9.9 13.2,10.6V26.55L12.2,27Q10.45,27.8 9.575,29.45Q8.7,31.1 8.7,32.85Z"/>
+</vector>
diff --git a/core/res/res/layout/notification_material_action_emphasized_tombstone.xml b/core/res/res/layout/notification_material_action_emphasized_tombstone.xml
new file mode 100644
index 0000000..60f10db
--- /dev/null
+++ b/core/res/res/layout/notification_material_action_emphasized_tombstone.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<com.android.internal.widget.EmphasizedNotificationButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/NotificationEmphasizedAction"
+    android:id="@+id/action0"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:layout_marginStart="12dp"
+    android:drawablePadding="6dp"
+    android:enabled="false"
+    android:gravity="center"
+    android:singleLine="true"
+    android:ellipsize="end"
+/>
diff --git a/core/res/res/values-af-watch/strings.xml b/core/res/res/values-af-watch/strings.xml
index c6c87e2..21ba346 100644
--- a/core/res/res/values-af-watch/strings.xml
+++ b/core/res/res/values-af-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Program <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensors"</string>
 </resources>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 76a4da0..53317e3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die program gebruik word."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Het toegang tot liggaamsensordata oor polstermperatuur terwyl die app gebruik word."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Gee die app toegang tot liggaamsensordata oor polstermperatuur terwyl die app gebruik word."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Het toegang tot liggaamsensordata oor polstermperatuur terwyl die app op die agtergrond is."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Gee die app toegang tot liggaamsensordata oor polstermperatuur terwyl die app op die agtergrond is."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Hierdie program kan alle kalendergebeurtenisse lees wat op jou tablet geberg is of jou kalenderdata stoor."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Hierdie program kan alle kalendergeleenthede wat op jou Android TV-toestel geberg is, lees of jou kalenderdata stoor."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android begin tans …"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet begin tans …"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Toestel begin tans …"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimeer tans berging."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Voltooi tans stelselopdatering …"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> gradeer tans op …"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimeer program <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Berei tans <xliff:g id="APPNAME">%1$s</xliff:g> voor."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Begin programme."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Voltooi herlaai."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB is aangeskakel"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-verbinding is aangeskakel"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB is aangeskakel"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-bykomstigheid is gekoppel"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tik vir meer opsies."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Laai tans gekoppelde toestel. Tik vir meer opsies."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Klaar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Skakel kortpad af"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Kleurregstelling"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Eenhandmodus"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra donker"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Bekyk tans volskerm"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Swiep van bo na onder as jy wil uitgaan."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Het dit"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Draai vir ’n beter aansig"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Verlaat gedeelde skerm vir ’n beter aansig"</string>
     <string name="done_label" msgid="7283767013231718521">"Klaar"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Ure se sirkelglyer"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minute se sirkelglyer"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloon <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vra PIN voordat jy ontspeld"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vra ontsluitpatroon voordat jy ontspeld"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vra wagwoord voordat jy ontspeld"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Laat ’n metgeselapp toe om voorgronddienste van agtergrond af te begin"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofoon is beskikbaar"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofoon is geblokkeer"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dubbelskerm"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dubbelskerm is aan"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruik tans albei skerms om inhoud te wys"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Toestel is te warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dubbelskerm is nie beskikbaar nie omdat jou foon tans te warm word"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Skakel af"</string>
 </resources>
diff --git a/core/res/res/values-am-watch/strings.xml b/core/res/res/values-am-watch/strings.xml
index d46557a..ad9b696 100644
--- a/core/res/res/values-am-watch/strings.xml
+++ b/core/res/res/values-am-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g> መተግበሪያ ከ<xliff:g id="NUMBER_1">%2$d</xliff:g>።"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"አነፍናፊዎች"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 39e010e..2ca63ef 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"መተግበሪያው ስራ ላይ በሚውልበት ጊዜ እንደ የልብ ምት፣ የሙቀት መጠን እና የደም ኦክሲጅን መቶኛ ያለ የሰውነት ዳሳሽ ውሂብን እንዲደርስ ያስችለዋል።"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ከበስተጀርባ እያለ እንደ የልብ ምት ያለ የሰውነት ዳሳሽ ውሂብን መድረስ"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"መተግበሪያው ከበስተጀርባ እያለ እንደ የልብ ምት፣ የሙቀት መጠን እና የደም ኦክሲጅን መቶኛ ያለ የሰውነት ዳሳሽ ውሂብን እንዲደርስ ያስችለዋል።"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"መተግበሪያው በጥቅም ላይ ሳለ የሰውነት ዳሳሽ የአንጓ የሙቀት መጠን ውሂብን ይድረስ።"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"መተግበሪያው በጥቅም ላይ ሳለ መተግበሪያው የሰውነት ዳሳሽ የአንጓ የሙቀት መጠን ውሂብን እንዲደርስ ይፈቅድለታል።"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"መተግበሪያው ዳራ ውስጥ ሳለ የሰውነት ዳሳሽ የአንጓ የሙቀት መጠን ውሂብን ይድረስ።"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"መተግበሪያው በዳራ ውስጥ ሳለ መተግበሪያው የሰውነት ዳሳሽ የአንጓ የሙቀት መጠን ውሂብን እንዲደርስ ይፈቅድለታል።"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"የቀን መቁጠሪያ ክስተቶችን እና ዝርዝሮችን አንብብ"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ይህ መተግበሪያ ሁሉንም በእርስዎ ጡባዊ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶችን ማንበብ ወይም የእርስዎን የቀን መቁጠሪያ ውሂብ ማስቀመጥ ይችላል።"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ይህ መተግበሪያ ሁሉንም በእርስዎ Android TV መሣሪያ ላይ የተከማቹ የቀን መቁጠሪያ ክስተቶችን ማንበብ ወይም የእርስዎን የቀን መቁጠሪያ ውሂብ ማስቀመጥ ይችላል።"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android በመጀመር ላይ ነው…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ጡባዊ በመጀመር ላይ ነው…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"መሣሪያ በመጀመር ላይ ነው…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ማከማቻን በማመቻቸት ላይ።"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"የስርዓት ዝማኔን በመጨረስ ላይ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> በማላቅ ላይ…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"መተግበሪያዎች በአግባቡ በመጠቀም ላይ <xliff:g id="NUMBER_0">%1$d</xliff:g> ከ <xliff:g id="NUMBER_1">%2$d</xliff:g> ፡፡"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>ን ማዘጋጀት።"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"መተግበሪያዎችን በማስጀመር ላይ፡፡"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"አጨራረስ ማስነሻ፡፡"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP በዩኤስቢ በኩል በርቷል"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"ዩኤስቢን እንደ ሞደም መሰካት በርቷል"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI በዩኤስቢ በኩል በርቷል"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"የዩኤስቢ ተቀጥላ ተገናኝቷል"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"የተገናኘ መሣሪያን ኃይል በመሙላት ላይ። ለተጨማሪ አማራጮች መታ ያድርጉ።"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ተከናውኗል"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"አቋራጩን አጥፋ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"አቋራጭ ይጠቀሙ"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ተቃራኒ ቀለም"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"የቀለም ማስተካከያ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"የአንድ እጅ ሁነታ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ተጨማሪ ደብዛዛ"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"ሙሉ ገጽ በማሳየት ላይ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ለመውጣት፣ ከላይ ወደታች ጠረግ ያድርጉ።"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ገባኝ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ለተሻለ ዕይታ ያሽከርክሩ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ለተሻለ ዕይታ የተከፈለ ማያ ገጽን ትተው ይውጡ"</string>
     <string name="done_label" msgid="7283767013231718521">"ተከናውኗል"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"የሰዓታት ክብ ተንሸራታች"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"የደቂቃዎች ክብ ተንሸራታች"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ስራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2ኛ ስራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3ኛ ስራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ን አባዛ"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ከመንቀል በፊት ፒን ጠይቅ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ስርዓተ-ጥለት ጠይቅ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"አጃቢ መተግበሪያ ከዳራ የፊት አገልግሎቶችን እንዲጀምር ያስችላል።"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"ማይክሮፎን ይገኛል"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"ማይክሮፎን ታግዷል"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ባለሁለት ማያ ገጽ"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ባለሁለት ማያ ገጽ በርቷል"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ይዘትን ለማሳየት ሁለቱንም ማሳያዎች እየተጠቀመ ነው"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"መሣሪያ በጣም ሞቋል"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ስልክዎ በጣም እየሞቀ ስለሆነ ባለሁለት ማያ ገጽ አይገኝም"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"አጥፋ"</string>
 </resources>
diff --git a/core/res/res/values-ar-watch/strings.xml b/core/res/res/values-ar-watch/strings.xml
index 3bc89f6..a8ca4cc 100644
--- a/core/res/res/values-ar-watch/strings.xml
+++ b/core/res/res/values-ar-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"التطبيق <xliff:g id="NUMBER_0">%1$d</xliff:g> من <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"أجهزة الاستشعار"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 5a64dbe..adfe708 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -462,14 +462,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"يتيح هذا الإذن للتطبيق بالوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عندما يكون التطبيق قيد الاستخدام."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"الوصول في الخلفية إلى بيانات استشعار الجسم، مثل معدّل نبضات القلب"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"يتيح هذا الإذن للتطبيق الوصول إلى بيانات أجهزة استشعار الجسم، مثل معدّل نبضات القلب ودرجة الحرارة ونسبة الأكسجين في الدم، وذلك عند استخدام التطبيق في الخلفية."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"الوصول إلى بيانات درجة حرارة المعصم من خلال جهاز استشعار الجسم عندما يكون التطبيق قيد الاستخدام"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"يسمح هذا الإذن للتطبيق بالوصول إلى بيانات درجة حرارة المعصم من خلال جهاز استشعار الجسم، وذلك عندما يكون التطبيق قيد الاستخدام."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"الوصول إلى بيانات درجة حرارة المعصم من خلال جهاز استشعار الجسم عندما يكون التطبيق مفعّلاً في الخلفية"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"يسمح هذا الإذن للتطبيق بالوصول إلى بيانات درجة حرارة المعصم من خلال جهاز استشعار الجسم، وذلك عندما يكون التطبيق مفعّلاً في الخلفية."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"قراءة أحداث التقويم والتفاصيل"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"يمكن لهذا التطبيق قراءة جميع أحداث التقويم المخزَّنة على الجهاز اللوحي ومشاركة بيانات التقويم أو حفظها."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏يمكن لهذا التطبيق قراءة جميع أحداث التقويم المخزَّنة على جهاز Android TV ومشاركة بيانات التقويم أو حفظها."</string>
@@ -1253,10 +1249,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"‏جارٍ تشغيل Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"جارٍ بدء تشغيل الجهاز اللوحي…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"جارٍ بدء تشغيل الجهاز…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"جارٍ تحسين مساحة التخزين."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"جارٍ إنهاء تحديث النظام…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"جارٍ ترقية <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"جارٍ تحسين التطبيق <xliff:g id="NUMBER_0">%1$d</xliff:g> من <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"جارٍ تحضير <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"بدء التطبيقات."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"جارٍ إعادة التشغيل."</string>
@@ -1368,6 +1362,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"‏تمّ تفعيل PTP عبر USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"‏تمّ تفعيل التوصيل عبر USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"‏تمّ تفعيل MIDI عبر USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"‏تم توصيل ملحق USB."</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"انقر للحصول على المزيد من الخيارات."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"جارٍ شحن الجهاز المتصل. انقر لعرض خيارات أكثر."</string>
@@ -1716,7 +1712,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"تم"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"إيقاف الاختصار"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استخدام الاختصار"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"قلب الألوان"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"تصحيح الألوان"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"وضع \"التصفح بيد واحدة\""</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"زيادة تعتيم الشاشة"</string>
@@ -1854,6 +1851,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"جارٍ العرض بملء الشاشة"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"للخروج، مرر بسرعة من أعلى إلى أسفل."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"حسنًا"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"يمكنك تدوير الجهاز لرؤية شاشة معاينة الكاميرا بشكل أوضح."</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"يمكنك الخروج من وضع \"تقسيم الشاشة\" لرؤية شاشة معاينة الكاميرا بشكل أوضح."</string>
     <string name="done_label" msgid="7283767013231718521">"تم"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"شريط التمرير الدائري للساعات"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"شريط التمرير الدائري للدقائق"</string>
@@ -1865,6 +1864,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> المخصص للعمل"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"العمل الثاني <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"العمل الثالث <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"نسخة طبق الأصل عن \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"طلب إدخال رقم التعريف الشخصي قبل إزالة التثبيت"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال النقش الخاص بإلغاء القفل قبل إزالة التثبيت"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string>
@@ -2319,4 +2319,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"يسمح هذا الإذن للتطبيق المصاحب ببدء الخدمات التي تعمل في المقدّمة من الخلفية."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"الميكروفون متاح."</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"تم حظر الميكروفون."</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"استخدام الشاشتين"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ميزة \"استخدام الشاشتين\" مفعّلة"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"يستخدم \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" كلتا الشاشتين لعرض المحتوى."</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"الجهاز ساخن للغاية"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ميزة \"استخدام الشاشتين\" غير متاحة لأن هاتفك ساخن للغاية."</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"إيقاف"</string>
 </resources>
diff --git a/core/res/res/values-as-watch/strings.xml b/core/res/res/values-as-watch/strings.xml
index f72042e..5dc8863 100644
--- a/core/res/res/values-as-watch/strings.xml
+++ b/core/res/res/values-as-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g>টা এপৰ ভিতৰত <xliff:g id="NUMBER_0">%1$d</xliff:g>টা"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"ছেন্সৰসমূহ"</string>
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 608e628..becc303 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"এপ্‌টো ব্যৱহাৰ কৰি থকাৰ সময়ত এপ্‌টোক হৃদস্পন্দনৰ হাৰ, উষ্ণতা আৰু তেজত অক্সিজেনৰ শতকৰা হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"নেপথ্যত থকাৰ সময়ত হৃদস্পন্দনৰ হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰক"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এপ্‌টো নেপথ্যত থকাৰ সময়ত এপ্‌টোক হৃদস্পন্দনৰ হাৰ, উষ্ণতা আৰু তেজত অক্সিজেনৰ শতকৰা হাৰৰ দৰে শৰীৰৰ ছেন্সৰৰ ডেটা এক্সেছ কৰিবলৈ অনুমতি দিয়ে।"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"এপ্‌টো ব্যৱহাৰ হৈ থকাৰ সময়ত শৰীৰৰ ছেন্সৰ জৰিয়তে মণিবন্ধৰ উষ্ণতাৰ ডেটা এক্সেছ কৰে।"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"এপ্‌টো ব্যৱহাৰ হৈ থকাৰ সময়ত এপ্‌টোক শৰীৰৰ ছেন্সৰ জৰিয়তে মণিবন্ধৰ উষ্ণতাৰ ডেটা এক্সেছ কৰাৰ অনুমতি দিয়ে।"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"এপ্‌টো নেপথ্যত থকাৰ সময়ত শৰীৰৰ ছেন্সৰ জৰিয়তে মণিবন্ধৰ উষ্ণতাৰ ডেটা এক্সেছ কৰে।"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"এপ্‌টো নেপথ্যত থকাৰ সময়ত এপ্‌টোক শৰীৰৰ ছেন্সৰ জৰিয়তে মণিবন্ধৰ উষ্ণতাৰ ডেটা এক্সেছ কৰাৰ অনুমতি দিয়ে।"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"কেলেণ্ডাৰৰ কাৰ্যক্ৰম আৰু সবিশেষ পঢ়িব পাৰে"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"এই এপ্‌টোৱে আপোনাৰ টেবলেটটোত সংৰক্ষিত আটাইবোৰ কেলেণ্ডাৰ কাৰ্যক্ৰম পঢ়িব পাৰে আৰু আপোনাৰ কেলেণ্ডাৰৰ ডেটা শ্বেয়াৰ বা ছেভ কৰিব পাৰে।"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"এই এপ্‌টোৱে আপোনাৰ Android TV ডিভাইচটোত ষ্ট’ৰ কৰি ৰখা আটাইবোৰ কেলেণ্ডাৰৰ অনুষ্ঠান পঢ়িব পাৰে আৰু আপোনাৰ কেলেণ্ডাৰৰ ডেটা শ্বেয়াৰ অথবা ছেভ কৰিব পাৰে।"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android আৰম্ভ কৰি থকা হৈছে…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"টেবলেটটো আৰম্ভ হৈছে…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ডিভাইচটো আৰম্ভ হৈছে…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ষ্ট’ৰেজ অপ্টিমাইজ কৰি থকা হৈছে।"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"ছিষ্টেম আপডে’ট সম্পূৰ্ণ কৰা হৈছে…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক আপগ্ৰেড কৰি থকা হৈছে…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g>ৰ ভিতৰত <xliff:g id="NUMBER_0">%1$d</xliff:g> এপ্ অপ্টিমাইজ কৰি থকা হৈছে৷"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>সাজু কৰি থকা হৈছে।"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"আৰম্ভ হৈ থকা এপসমূহ।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"বুট কাৰ্য সমাপ্ত কৰিছে।"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"ইউএছবিৰ জৰিয়তে পিটিপি অন কৰা হ’ল"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"ইউএছবি টেডাৰিং অন কৰা হ’ল"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"ইউএছবিৰ জৰিয়তে এমআইডিআই অন কৰা হ’ল"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"ইউএছবি সহায়ক সামগ্ৰী সংযোগ কৰা হ’ল"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"অধিক বিকল্পৰ বাবে টিপক।"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"সংযুক্ত ডিভাইচ চ্চাৰ্জ কৰি থকা হৈছে। অধিক বিকল্পৰ বাবে টিপক।"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"কৰা হ’ল"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"শ্বৰ্টকাট অফ কৰক"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শ্বৰ্টকাট ব্যৱহাৰ কৰক"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ৰং শুধৰণী"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এখন হাতেৰে ব্যৱহাৰ কৰাৰ ম’ড"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"এক্সট্ৰা ডিম"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"স্ক্ৰীন পূৰ্ণৰূপত চাই আছে"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"বাহিৰ হ\'বলৈ ওপৰৰপৰা তললৈ ছোৱাইপ কৰক।"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"বুজি পালোঁ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ভালকৈ চাবলৈ ঘূৰাওক"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ভালকৈ চাবলৈ বিভাজিত স্ক্ৰীনৰ পৰা বাহিৰ হওক"</string>
     <string name="done_label" msgid="7283767013231718521">"সম্পন্ন কৰা হ’ল"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ঘড়ীৰ বৃত্তাকাৰ শ্লাইডাৰ"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"মিনিটৰ বৃত্তাকাৰ শ্লাইডাৰ"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"কৰ্মস্থান <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"২য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"৩য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"ক্ল’ন <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"আনপিন কৰাৰ পূৰ্বে পিন দিবলৈ কওক"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন কৰাৰ পূৰ্বে আনলক আৰ্হি দিবলৈ কওক"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন কৰাৰ পূৰ্বে পাছৱৰ্ড দিবলৈ কওক"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"এটা সহযোগী এপক নেপথ্যৰ পৰা অগ্ৰভূমি সেৱাসমূহ আৰম্ভ কৰিবলৈ দিয়ে।"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"মাইক্ৰ’ফ’নটো উপলব্ধ"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"মাইক্ৰ’ফ’নটো অৱৰোধ কৰি থোৱা আছে"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"দ্বৈত স্ক্ৰীন"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ডুৱেল স্ক্ৰীন অন আছে"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ সমল দেখুৱাবলৈ দুয়োখন ডিছপ্লে’ ব্যৱহাৰ কৰি আছে"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ডিভাইচটো অতি বেছি গৰম হৈছে"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"আপোনাৰ ফ’নটো অতি বেছি গৰম হোৱাৰ বাবে ডুৱেল স্ক্ৰীন উপলব্ধ নহয়"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"অফ কৰক"</string>
 </resources>
diff --git a/core/res/res/values-az-watch/strings.xml b/core/res/res/values-az-watch/strings.xml
index dbd2337..cf1b7a5 100644
--- a/core/res/res/values-az-watch/strings.xml
+++ b/core/res/res/values-az-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Tətbiq <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensorlar"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 40af5eb..e554984 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tətbiqə istifadə zamanı ürək döyüntüsü, temperatur və qanda oksigen faizi kimi bədən sensoru datasına giriş icazəsi verir."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Arxa fonda olarkən ürək döyüntüsü kimi bədən sensoru datasına giriş"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tətbiqə arxa fonda olarkən ürək döyüntüsü, temperatur və qanda oksigen faizi kimi bədən sensoru datasına giriş icazəsi verir."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Tətbiq istifadə edilərkən bədən sensoru bilək temperaturu datasına giriş."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Tətbiq istifadə edilərkən tətbiqin bədən sensoru bilək temperaturu datasına girişinə imkan verir."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Tətbiq arxa fonda olarkən bədən sensoru bilək temperaturu datasına giriş."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Tətbiq arxa fonda olarkən tətbiqin bədən sensoru bilək temperaturu datasına girişinə imkan verir."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Təqvim təqdirləri və detallarını oxuyun"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu tətbiq planşetdə yerləşdirilmiş və təqvim datasında yadda saxlanmış bütün təqvim tədbirlərini oxuya bilər."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu tətbiq Android TV cihazında saxlanılan bütün təqvim tədbirlərini oxuya, həmçinin təqvim datasını paylaşa və ya yadda saxlaya bilər."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android işə başlayır..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Planşet başlayır…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Cihaz başlayır…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Yaddaş optimallaşdırılır."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Sistem güncəlləmələri tamamlanır…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> təkmilləşdirilir…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> əddədən <xliff:g id="NUMBER_0">%1$d</xliff:g> tətbiq optimallaşır."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> proqramının hazırlanması."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Tətbiqlər başladılır."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Yükləmə başa çatır."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB vasitəsilə PTP aktiv edildi"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-modem aktivdir"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB vasitəsilə MIDI aktiv edildi"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB aksesuarı qoşulub"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Əlavə seçimlər üçün tıklayın."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Qoşulmuş cihaza enerji doldurulur. Əlavə seçimlər üçün klikləyin."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hazırdır"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Qısayolu Deaktiv edin"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Qısayol İstifadə edin"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Rəng İnversiyası"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Rəng korreksiyası"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Birəlli rejim"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Əlavə tündləşmə"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Tam ekrana baxış"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Çıxmaq üçün yuxarıdan aşağı sürüşdürün."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Anladım"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Daha yaxşı görünüş üçün fırladın"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Daha yaxşı görünüş üçün bölünmüş ekrandan çıxın"</string>
     <string name="done_label" msgid="7283767013231718521">"Hazırdır"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Dairəvi saat slayderi"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Dairəvi dəqiqə slayderi"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"İş <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ci İş <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-cü İş <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kopyalayın: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ayırmadan öncə PIN istənilsin"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Qrafik açar istənilsin"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ayırmadan öncə parol istənilsin"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Kompanyon tətbiqinə ön fon xidmətlərini arxa fondan başlatmaq icazəsi verir."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon əlçatandır"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon blok edilib"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"İkili ekran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"İkili ekran aktivdir"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> məzmunu göstərmək üçün hər iki displeydən istifadə edir"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Cihaz çox isinib"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Telefonunuz çox isindiyi üçün İkili Ekran əlçatan deyil"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Deaktiv edin"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn-watch/strings.xml b/core/res/res/values-b+sr+Latn-watch/strings.xml
index 699c148..da58726 100644
--- a/core/res/res/values-b+sr+Latn-watch/strings.xml
+++ b/core/res/res/values-b+sr+Latn-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikacija <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Senzori"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 0f39f41..63d2e66 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok se aplikacija koristi."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima senzora za telo, kao što je puls, u pozadini"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji da pristupa podacima senzora za telo, kao što su puls, temperatura i procenat kiseonika u krvi dok je aplikacija u pozadini."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Pristupajte podacima o temperaturi sa senzora za telo na ručnom zglobu dok se aplikacija koristi."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Dozvoljava aplikaciji da pristupa podacima o temperaturi sa senzora za telo na ručnom zglobu dok se aplikacija koristi."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Pristupajte podacima o temperaturi sa senzora za telo na ručnom zglobu dok je aplikacija u pozadini."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Dozvoljava aplikaciji da pristupa podacima o temperaturi sa senzora za telo na ručnom zglobu dok je aplikacija u pozadini."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i podataka iz kalendara"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na tabletu, kao i da deli ili čuva podatke iz kalendara."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može da čita sve događaje iz kalendara koje čuvate na Android TV uređaju, kao i da deli ili čuva podatke iz kalendara."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android se pokreće…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet se pokreće…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Uređaj se pokreće…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Memorija se optimizuje."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ažuriranje sistema se dovršava…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> se nadograđuje…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizovanje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Priprema se <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Završavanje pokretanja."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Režim PTP preko USB-a je uključen"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB privezivanje je uključeno"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Režim MIDI preko USB-a je uključen"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB dodatak je povezan"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Dodirnite za još opcija."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Povezani uređaj se puni. Dodirnite za još opcija."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Korekcija boja"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednom rukom"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjeno"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se ceo ekran"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Da biste izašli, prevucite nadole odozgo."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Važi"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotirajte radi boljeg prikaza"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Izađite iz podeljenog ekrana radi boljeg prikaza"</string>
     <string name="done_label" msgid="7283767013231718521">"Gotovo"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač za sate"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač za minute"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloniraj <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Dozvoljava pratećoj aplikaciji da pokrene usluge u prvom planu iz pozadine."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon je dostupan"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvojni ekran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dvojni ekran je uključen"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi oba ekrana za prikazivanje sadržaja"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Uređaj je previše zagrejan"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojni ekran je nedostupan jer je telefon previše zagrejan"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Isključi"</string>
 </resources>
diff --git a/core/res/res/values-be-watch/strings.xml b/core/res/res/values-be-watch/strings.xml
index 73e6643..75e6307 100644
--- a/core/res/res/values-be-watch/strings.xml
+++ b/core/res/res/values-be-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Праграма <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Датчыкі"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 6d1135f..14626a0 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Праграма ў час яе выкарыстання будзе мець доступ да даных датчыкаў цела, такіх як пульс, тэмпература і працэнт утрымання ў крыві кіслароду."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ да даных датчыкаў цела, такіх як пульс, у фонавым рэжыме"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Праграма ў час яе працы ў фонавым рэжыме будзе мець доступ да даных датчыкаў цела, такіх як пульс, тэмпература і працэнт утрымання ў крыві кіслароду."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Доступ праграмы ў час яе выкарыстання да даных пра тэмпературу з датчыка цела, які знаходзіцца на запясці."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Праграма ў час яе выкарыстання будзе мець доступ да даных пра тэмпературу з датчыка цела, які знаходзіцца на запясці."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Доступ праграмы ў фонавым рэжыме да даных пра тэмпературу з датчыка цела, які знаходзіцца на запясці."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Праграма ў час яе працы ў фонавым рэжыме будзе мець доступ да даных пра тэмпературу з датчыка цела, які знаходзіцца на запясці."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Чытаць падзеі календара і падрабязныя звесткі"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Гэта праграма можа чытаць усе падзеі календара, захаваныя на вашым планшэце, і абагульваць ці захоўваць даныя календара."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Гэта праграма можа счытваць усе падзеі календара, захаваныя на прыладзе Android TV, і абагульваць ці захоўваць яго даныя."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android запускаецца..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Запуск планшэта…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Запуск прылады…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Аптымізацыя сховішча."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Завяршэнне абнаўлення сістэмы…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> абнаўляецца…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Аптымізацыя прыкладання <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Падрыхтоўка <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск прыкладанняў."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завяршэнне загрузкі."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Перадача фота (PTP) праз USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Рэжым USB-мадэма"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI праз USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-прылада падключана"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Дакраніцеся, каб убачыць іншыя параметры."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Падключаная прылада зараджаецца. Дакраніцеся, каб убачыць іншыя параметры."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Гатова"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Дэактываваць камбінацыю хуткага доступу"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колераў"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Карэкцыя колераў"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Рэжым кіравання адной рукой"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дадатковае памяншэнне яркасці"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Прагляд у поўнаэкранным рэжыме"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Для выхаду правядзіце зверху ўніз."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Зразумела"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Павярнуць для лепшага прагляду"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Выйсці з рэжыму падзеленага экрана для лепшага прагляду"</string>
     <string name="done_label" msgid="7283767013231718521">"Гатова"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Кругавы паўзунок гадзін"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Кругавы паўзунок хвілін"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (праца)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Другая праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трэцяя праца <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Кланіраваць \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запытваць PIN-код перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запытваць пароль перад адмацаваннем"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Спадарожная праграма зможа запускаць актыўныя сэрвісы з фонавага рэжыму."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Мікрафон даступны"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Мікрафон заблакіраваны"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Двайны экран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Уключана функцыя \"Двайны экран\""</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" выкарыстоўвае абодва экраны для паказу змесціва"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Прылада моцна нагрэлася"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Функцыя \"Двайны экран\" недаступная, бо тэлефон моцна награваецца"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Выключыць"</string>
 </resources>
diff --git a/core/res/res/values-bg-watch/strings.xml b/core/res/res/values-bg-watch/strings.xml
index b5554ca..7977f66 100644
--- a/core/res/res/values-bg-watch/strings.xml
+++ b/core/res/res/values-bg-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Прилож. <xliff:g id="NUMBER_0">%1$d</xliff:g> от <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Сензори"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index cfe18d4..4e389d8 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Разрешава на приложението да осъществява достъп до данните от сензорите за тяло, като например тези за сърдечен ритъм, температура и процент на кислорода в кръвта, докато то се използва."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Достъп до данните от сензорите за тяло (напр. за сърдечен ритъм) на заден план"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Разрешава на приложението да осъществява достъп до данните от сензорите за тяло, като например тези за сърдечен ритъм, температура и процент на кислорода в кръвта, докато то се изпълнява на заден план."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Достъп до данните за температурата, измерена на китката от сензорите за тяло, докато приложението се използва."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Дава на приложението достъп до данните за температурата, измерена на китката от сензорите за тяло. Разрешението е в сила, докато приложението се използва."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Достъп до данните за температурата, измерена на китката от сензорите за тяло, докато приложението работи на заден план."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Дава на приложението достъп до данните за температурата, измерена на китката от сензорите за тяло. Разрешението е в сила, докато приложението работи на заден план."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Четене на събития и подробности от календара"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Това приложение може да чете всички съхранявани на таблета ви събития в календара и да споделя или запазва данни в календара ви."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Това приложение може да чете всички съхранявани на устройството ви с Android TV събития в календара и да споделя или запазва данни в календара ви."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android се стартира…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Таблетът се стартира…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Устройството се стартира…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Хранилището се оптимизира."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Системната актуализация завършва…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> се надстройва…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Оптимизира се приложение <xliff:g id="NUMBER_0">%1$d</xliff:g> от <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> се подготвя."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Приложенията се стартират."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Зареждането завършва."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режимът PTP през USB е включен"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Тетърингът през USB е включен"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Режимът MIDI през USB е включен"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Аксесоарът за USB е свързан"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Докоснете за още опции."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Свързаното устройство се зарежда. Докоснете за още опции."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Изключване на прекия път"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Използване на пряк път"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Инвертиране на цветовете"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Корекция на цветове"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Работа с една ръка"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Доп. затъмн."</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Изглед на цял екран"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"За изход плъзнете пръст надолу от горната част."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Разбрах"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Завъртете за по-добър изглед"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Излезте от разделения екран за по-добър изглед"</string>
     <string name="done_label" msgid="7283767013231718521">"Готово"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Кръгов плъзгач за часовете"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Кръгов плъзгач за минутите"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> за работа"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Втори служебен профил (<xliff:g id="LABEL">%1$s</xliff:g>)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трети служебен профил (<xliff:g id="LABEL">%1$s</xliff:g>)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Копие на <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запитване за ПИН код преди освобождаване"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитване за фигура за отключване преди освобождаване"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитване за парола преди освобождаване"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Разрешава на дадено придружаващо приложение да стартира услуги на преден план, докато се изпълнява на заден план."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофонът е налице"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофонът е блокиран"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Двоен екран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Функцията за двоен екран е включена"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Приложението <xliff:g id="APP_NAME">%1$s</xliff:g> използва и двата екрана, за да показва съдържание"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Устройството е твърде топло"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Функцията за двоен екран не е налице, защото телефонът ви е твърде топъл"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Изключване"</string>
 </resources>
diff --git a/core/res/res/values-bn-watch/strings.xml b/core/res/res/values-bn-watch/strings.xml
index 3d02cea..c98d372 100644
--- a/core/res/res/values-bn-watch/strings.xml
+++ b/core/res/res/values-bn-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="NUMBER_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"সেন্সরগুলি"</string>
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index e02d75d..5899463 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"এই অ্যাপ ব্যবহার করার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"অ্যাপ ব্যাকগ্রাউন্ডে চলার সময়, হার্ট রেটের মতো বডি সেন্সর ডেটার অ্যাক্সেস দিন"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"এই অ্যাপ ব্যাকগ্রাউন্ডে চলার সময় বডি সেন্সর ডেটা অ্যাক্সেস করার অনুমতি দেওয়া হয়। এর মধ্যে হার্ট রেট, তাপমাত্রা এবং রক্তে অক্সিজেনের পরিমাণের শতাংশ সম্পর্কিত তথ্যও আছে।"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"অ্যাপ ব্যবহার করার সময়, দেহের তাপমাত্রা সংক্রান্ত বডি সেন্সর ডেটা অ্যাক্সেস করা।"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"অ্যাপ ব্যবহার করার সময়, দেহের তাপমাত্রা সংক্রান্ত বডি সেন্সর ডেটা অ্যাক্সেস করার ক্ষেত্রে অ্যাপকে অনুমতি দেয়।"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"অ্যাপ ব্যাকগ্রাউন্ডে চলার সময়, দেহের তাপমাত্রা সংক্রান্ত বডি সেন্সর ডেটা অ্যাক্সেস করা।"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"অ্যাপ ব্যাকগ্রাউন্ডে চলার সময়, দেহের তাপমাত্রা সংক্রান্ত বডি সেন্সর ডেটা অ্যাক্সেস করার ক্ষেত্রে অ্যাপকে অনুমতি দেয়।"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"ক্যালেন্ডারের ইভেন্ট এবং বিশদ বিবরণ পড়ুন"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"এই অ্যাপটি আপনার ট্যাবলেটে সংরক্ষিত সমস্ত ক্যালেন্ডার ইভেন্ট পড়তে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সংরক্ষণ করতে পারে৷"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"এই অ্যাপ আপনার Android TV ডিভাইসে সেভ করা সব ক্যালেন্ডার ইভেন্ট পড়তে পারে এবং আপনার ক্যালেন্ডারের ডেটা শেয়ার বা সেভ করতে পারে।"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android চালু হচ্ছে…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ট্যাবলেট চালু করা হচ্ছে…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ডিভাইস চালু করা হচ্ছে…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"স্টোরেজ অপ্টিমাইজ করা হচ্ছে৷"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"সিস্টেম আপডেট শেষ করা হচ্ছে…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> আপগ্রেড করা হচ্ছে…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="NUMBER_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান অপ্টিমাইজ করা হচ্ছে৷"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> প্রস্তুত করা হচ্ছে৷"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"অ্যাপ্লিকেশানগুলি শুরু করা হচ্ছে৷"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"চালু করা সম্পূর্ণ হচ্ছে৷"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB এর মাধ্যমে PTP চালু করা হয়েছে"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB টিথারিং চালু করা হয়েছে"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB এর মাধ্যমে MIDI চালু করা হয়েছে"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"ইউএসবি অ্যাক্সেসরি কানেক্ট করা হয়েছে"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"আরও বিকল্পের জন্য আলতো চাপুন৷"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"সংযুক্ত ডিভাইস চার্জ করা হচ্ছে। আরও বিকল্প দেখতে ট্যাপ করুন।"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"হয়ে গেছে"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"শর্টকাট বন্ধ করুন"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শর্টকাট ব্যবহার করুন"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"রঙ উল্টানো"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"রঙ সংশোধন করা"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এক হাতে ব্যবহার করার মোড"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিরিক্ত কম আলো"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"পূর্ণ স্ক্রিনে দেখা হচ্ছে"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"প্রস্থান করতে উপর থেকে নিচের দিকে সোয়াইপ করুন"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"বুঝেছি"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"আরও ভাল ক্যামেরা ভিউ পাওয়ার জন্য ঘোরান"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"আরও ভাল ক্যামেরা ভিউ পাওয়ার জন্য স্প্লিট স্ক্রিন থেকে বেরিয়ে আসুন"</string>
     <string name="done_label" msgid="7283767013231718521">"সম্পন্ন হয়েছে"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"বৃত্তাকার ঘণ্টা নির্বাচকের স্লাইডার"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"বৃত্তাকার মিনিট নির্বাচকের স্লাইডার"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"কর্মক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"দ্বিতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"তৃতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ক্লোন"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"আনপিন করার আগে পিন চান"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"কম্প্যানিয়ন অ্যাপকে, ব্যাকগ্রাউন্ড থেকে ফোরগ্রাউন্ড পরিষেবা চালু করার অনুমতি দেয়।"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"মাইক্রোফোন উপলভ্য আছে"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"মাইক্রোফোন ব্লক করা হয়েছে"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ডুয়াল স্ক্রিন"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"\'ডুয়াল স্ক্রিন\' চালু করা আছে"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"কন্টেন্ট দেখানোর জন্য <xliff:g id="APP_NAME">%1$s</xliff:g> দুটি ডিসপ্লে ব্যবহার করছে"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ডিভাইস খুব গরম হয়ে গেছে"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"আপনার ফোন খুব বেশি গরম হয়ে যাচ্ছে বলে \'ডুয়াল স্ক্রিন\' উপলভ্য নেই"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"বন্ধ করুন"</string>
 </resources>
diff --git a/core/res/res/values-bs-watch/strings.xml b/core/res/res/values-bs-watch/strings.xml
index f51d3bf..da58726 100644
--- a/core/res/res/values-bs-watch/strings.xml
+++ b/core/res/res/values-bs-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. aplikac. od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Senzori"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 3c1925b..6a1e062 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Dozvoljava aplikaciji dok se koristi da pristupa podacima tjelesnih senzora kao što su puls, temperatura i postotak kisika u krvi."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima tjelesnih senzora, kao što je puls, dok je u pozadini"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Dozvoljava aplikaciji dok je u pozadini da pristupa podacima tjelesnih senzora kao što su puls, temperatura i postotak kisika u krvi."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Pristup podacima tjelesnog senzora o temperaturi zgloba šake dok se aplikacija koristi."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Dozvoljava aplikaciji dok se koristi da pristupa podacima tjelesnog senzora o temperaturi zgloba šake."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Pristup podacima tjelesnog senzora o temperaturi zgloba šake dok je aplikacija u pozadini."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Dozvoljava aplikaciji dok je u pozadini da pristupa podacima tjelesnog senzora o temperaturi zgloba šake."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja kalendara i detalja"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ova aplikacija može čitati sve događaje u kalendaru pohranjene na vašem tabletu i sačuvati podatke kalendara."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ova aplikacija može čitati sve događaje u kalendaru na vašem Android TV uređaju i dijeliti ili sačuvati podatke kalendara."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android se pokreće..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Pokretanje tableta…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Pokretanje uređaja…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimiziranje pohrane."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Dovršavanje ažuriranja sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> se nadograđuje…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimiziranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripremanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Pokretanje pri kraju."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Uključen je način rada PTP putem USB-a"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Dijeljenje internetske veze putem USB-a je uključeno"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Uključen je način rada MIDI putem USB-a"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Povezan je USB periferni uređaj"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Dodirnite za više opcija."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Punjenje povezanog uređaja. Dodirnite za više opcija."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečicu"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Ispravka boja"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Način rada jednom rukom"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjeno"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Prikazuje se cijeli ekran"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Da izađete, prevucite odozgo nadolje."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Razumijem"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotirajte za bolji prikaz"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Izađite iz podijeljenog ekrana za bolji prikaz"</string>
     <string name="done_label" msgid="7283767013231718521">"Gotovo"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač za odabir sata"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač za minute"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloniranje aplikacije <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN prije nego se otkači"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje prije poništavanja kačenja"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku prije nego se otkači"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Dozvoljava pratećoj aplikaciji da iz pozadine pokrene usluge u prvom planu."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon je dostupan"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dupli ekran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dupli ekran je uključen"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> koristi oba ekrana za prikazivanje sadržaja"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Uređaj je previše zagrijan"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dupli ekran nije dostupan je se telefon previše zagrijava"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Isključi"</string>
 </resources>
diff --git a/core/res/res/values-ca-watch/strings.xml b/core/res/res/values-ca-watch/strings.xml
index 7bb483a..21ba346 100644
--- a/core/res/res/values-ca-watch/strings.xml
+++ b/core/res/res/values-ca-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplicació <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensors"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 41496a5..82947e7 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -47,7 +47,7 @@
     <string name="needPuk2" msgid="3910763547447344963">"Escriu el PUK2 per desbloquejar la SIM."</string>
     <string name="enablePin" msgid="2543771964137091212">"No és correcte; activa el bloqueig de RUIM/SIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents; si no l\'encertes, la SIM es bloquejarà.</item>
       <item quantity="other">Et queden <xliff:g id="NUMBER_1">%d</xliff:g> intents; si no l\'encertes, la SIM es bloquejarà.</item>
       <item quantity="one">Et queda <xliff:g id="NUMBER_0">%d</xliff:g> intent; si no l\'encertes, la SIM es bloquejarà.</item>
     </plurals>
@@ -179,7 +179,7 @@
     <string name="low_memory" product="watch" msgid="3479447988234030194">"L\'emmagatzematge del rellotge està ple. Suprimeix uns quants fitxers per alliberar espai."</string>
     <string name="low_memory" product="tv" msgid="6663680413790323318">"L\'espai d\'emmagatzematge del dispositiu Android TV és ple. Suprimeix alguns fitxers per alliberar espai."</string>
     <string name="low_memory" product="default" msgid="2539532364144025569">"L\'emmagatzematge del telèfon és ple. Suprimeix uns quants fitxers per alliberar espai."</string>
-    <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{L\'autoritat de certificació s\'ha instal·lat}many{Certificate authorities installed}other{Les autoritats de certificació s\'han instal·lat}}"</string>
+    <string name="ssl_ca_cert_warning" msgid="7233573909730048571">"{count,plural, =1{L\'autoritat de certificació s\'ha instal·lat}many{Les autoritats de certificació s\'han instal·lat}other{Les autoritats de certificació s\'han instal·lat}}"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Per un tercer desconegut"</string>
     <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Per l\'administrador del teu perfil de treball"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Per <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
@@ -253,7 +253,7 @@
     <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Utilitza aquesta opció en la majoria de circumstàncies. Et permet fer un seguiment del progrés de l\'informe, introduir més dades sobre el problema i fer captures de pantalla. És possible que ometi seccions poc utilitzades que requereixen molt de temps."</string>
     <string name="bugreport_option_full_title" msgid="7681035745950045690">"Informe complet"</string>
     <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilitza aquesta opció perquè la interferència en el sistema sigui mínima si el dispositiu no respon o va massa lent, o bé si necessites totes les seccions de l\'informe. No et permet introduir més dades ni fer més captures de pantalla."</string>
-    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a # segon.}many{Taking screenshot for bug report in # seconds.}other{Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a # segons.}}"</string>
+    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a # segon.}many{Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a # segons.}other{Es farà una captura de pantalla de l\'informe d\'errors d\'aquí a # segons.}}"</string>
     <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"S\'ha fet la captura de pantalla amb l\'informe d\'errors"</string>
     <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"No s\'ha pogut fer la captura de pantalla amb l\'informe d\'errors"</string>
     <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Mode silenciós"</string>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet que l\'aplicació accedeixi a les dades del sensor corporal, com ara la freqüència cardíaca, la temperatura i el percentatge d\'oxigen a la sang, mentre s\'utilitza."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accedir a dades del sensor corporal, com la freqüència cardíaca, en segon pla"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet que l\'aplicació accedeixi a les dades del sensor corporal, com ara la freqüència cardíaca, la temperatura i el percentatge d\'oxigen a la sang, mentre es troba en segon pla."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Accedir a les dades de la temperatura del canell del sensor corporal mentre s\'utilitza l\'aplicació."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permet que l\'aplicació accedeixi a les dades de la temperatura del canell del sensor corporal mentre s\'utilitza l\'aplicació."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Accedir a les dades de la temperatura del canell del sensor corporal mentre l\'aplicació es troba en segon pla."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permet que l\'aplicació accedeixi a les dades de la temperatura del canell del sensor corporal mentre l\'aplicació es troba en segon pla."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Aquesta aplicació pot llegir els esdeveniments i la informació del calendari"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aquesta aplicació pot llegir tots els esdeveniments del calendari emmagatzemats a la tauleta i compartir o desar les dades del teu calendari."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aquesta aplicació pot llegir tots els esdeveniments del calendari emmagatzemats al dispositiu Android TV i compartir o desar les dades del calendari."</string>
@@ -1094,7 +1090,7 @@
     <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració per tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interaccionar amb el telèfon."</string>
     <string name="oneMonthDurationPast" msgid="4538030857114635777">"Fa 1 mes"</string>
     <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Fa més d\'1 mes"</string>
-    <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Darrer dia (#)}many{Last # days}other{# darrers dies}}"</string>
+    <string name="last_num_days" msgid="2393660431490280537">"{count,plural, =1{Darrer dia (#)}many{# darrers dies}other{# darrers dies}}"</string>
     <string name="last_month" msgid="1528906781083518683">"Darrer mes"</string>
     <string name="older" msgid="1645159827884647400">"Més antigues"</string>
     <string name="preposition_for_date" msgid="2780767868832729599">"el <xliff:g id="DATE">%s</xliff:g>"</string>
@@ -1121,14 +1117,14 @@
     <string name="duration_hours_shortest_future" msgid="2979276794547981674">"d\'aquí a <xliff:g id="COUNT">%d</xliff:g> h"</string>
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"d\'aquí a <xliff:g id="COUNT">%d</xliff:g> d"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"d\'aquí a <xliff:g id="COUNT">%d</xliff:g> a"</string>
-    <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Fa # minut}many{# minutes ago}other{Fa # minuts}}"</string>
-    <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Fa # hora}many{# hours ago}other{Fa # hores}}"</string>
-    <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Fa # dia}many{# days ago}other{Fa # dies}}"</string>
-    <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Fa # any}many{# years ago}other{Fa # anys}}"</string>
-    <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minut}many{# minutes}other{# minuts}}"</string>
-    <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# hora}many{# hours}other{# hores}}"</string>
-    <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dia}many{# days}other{# dies}}"</string>
-    <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# any}many{# years}other{# anys}}"</string>
+    <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Fa # minut}many{Fa # minuts}other{Fa # minuts}}"</string>
+    <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Fa # hora}many{Fa # hores}other{Fa # hores}}"</string>
+    <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Fa # dia}many{Fa # dies}other{Fa # dies}}"</string>
+    <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Fa # any}many{Fa # anys}other{Fa # anys}}"</string>
+    <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minut}many{# minuts}other{# minuts}}"</string>
+    <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# hora}many{# hores}other{# hores}}"</string>
+    <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# dia}many{# dies}other{# dies}}"</string>
+    <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# any}many{# anys}other{# anys}}"</string>
     <string name="VideoView_error_title" msgid="5750686717225068016">"Problema amb el vídeo"</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"Aquest vídeo no és vàlid per a la reproducció en aquest dispositiu."</string>
     <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"No es pot reproduir aquest vídeo."</string>
@@ -1177,7 +1173,7 @@
     <string name="not_checked" msgid="7972320087569023342">"no seleccionat"</string>
     <string name="selected" msgid="6614607926197755875">"seleccionat"</string>
     <string name="not_selected" msgid="410652016565864475">"no seleccionat"</string>
-    <string name="rating_label" msgid="1837085249662154601">"{rating,plural, =1{1 estrella de {max}}many{# stars out of {max}}other{# estrelles de {max}}}"</string>
+    <string name="rating_label" msgid="1837085249662154601">"{rating,plural, =1{1 estrella de {max}}many{# estrelles de {max}}other{# estrelles de {max}}}"</string>
     <string name="in_progress" msgid="2149208189184319441">"en curs"</string>
     <string name="whichApplication" msgid="5432266899591255759">"Completa l\'acció mitjançant"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"Completa l\'acció amb %1$s"</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"S\'està iniciant Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"S\'està iniciant la tauleta…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"S\'està iniciant el dispositiu…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"S\'està optimitzant l\'emmagatzematge."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Completant l\'actualització del sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"S\'està actualitzant <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"S\'està optimitzant l\'aplicació <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"S\'està preparant <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"S\'estan iniciant les aplicacions."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"S\'està finalitzant l\'actualització."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"S\'ha activat el mode PTP per USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"S\'ha activat la compartició de xarxa per USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"S\'ha activat el mode MIDI per USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"S\'ha connectat un accessori USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Toca per veure més opcions."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"S\'està carregant el dispositiu connectat. Toca per veure més opcions."</string>
@@ -1516,7 +1512,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Omet"</string>
     <string name="no_matches" msgid="6472699895759164599">"No s\'ha trobat cap coincidència"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Troba-ho a la pàgina"</string>
-    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidència}many{# of {total}}other{# de {total}}}"</string>
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidència}many{# de {total}}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Fet"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"S\'està esborrant l\'emmagatzematge compartit…"</string>
     <string name="share" msgid="4157615043345227321">"Comparteix"</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Fet"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactiva la drecera"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilitza la drecera"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversió de colors"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correcció de color"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode d\'una mà"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuació extra"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Mode de pantalla completa"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Per sortir, llisca cap avall des de la part superior."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Entesos"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira per a una millor visualització"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Surt de la pantalla dividida per a una millor visualització"</string>
     <string name="done_label" msgid="7283767013231718521">"Fet"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Control circular de les hores"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Control circular dels minuts"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2n <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3r <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sol·licita el PIN per deixar de fixar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string>
@@ -1874,14 +1874,14 @@
     <string name="data_saver_description" msgid="4995164271550590517">"Per reduir l\'ús de dades, la funció Estalvi de dades evita que determinades aplicacions enviïn o rebin dades en segon pla. L\'aplicació que estiguis fent servir podrà accedir a les dades, però menys sovint. Això vol dir, per exemple, que les imatges no es mostraran fins que no les toquis."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"Vols activar l\'Estalvi de dades?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Activa"</string>
-    <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Durant 1 minut (fins a les {formattedTime})}many{For # minutes (until {formattedTime})}other{Durant # minuts (fins a les {formattedTime})}}"</string>
-    <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Durant 1 min (fins a les {formattedTime})}many{For # min (until {formattedTime})}other{Durant # min (fins a les {formattedTime})}}"</string>
-    <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Durant 1 hora (fins a les {formattedTime})}many{For # hours (until {formattedTime})}other{Durant # hores (fins a les {formattedTime})}}"</string>
-    <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{Durant 1 h (fins a les {formattedTime})}many{For # hr (until {formattedTime})}other{Durant # h (fins a les {formattedTime})}}"</string>
-    <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Durant 1 minut}many{For # minutes}other{Durant # minuts}}"</string>
-    <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Durant 1 min}many{For # min}other{Durant # min}}"</string>
-    <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Durant 1 hora}many{For # hours}other{Durant # hores}}"</string>
-    <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Durant 1 h}many{For # hr}other{Durant # h}}"</string>
+    <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{Durant 1 minut (fins a les {formattedTime})}many{Durant # minuts (fins a les {formattedTime})}other{Durant # minuts (fins a les {formattedTime})}}"</string>
+    <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{Durant 1 min (fins a les {formattedTime})}many{Durant # min (fins a les {formattedTime})}other{Durant # min (fins a les {formattedTime})}}"</string>
+    <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{Durant 1 hora (fins a les {formattedTime})}many{Durant # hores (fins a les {formattedTime})}other{Durant # hores (fins a les {formattedTime})}}"</string>
+    <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{Durant 1 h (fins a les {formattedTime})}many{Durant # h (fins a les {formattedTime})}other{Durant # h (fins a les {formattedTime})}}"</string>
+    <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{Durant 1 minut}many{Durant # minuts}other{Durant # minuts}}"</string>
+    <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{Durant 1 min}many{Durant # min}other{Durant # min}}"</string>
+    <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{Durant 1 hora}many{Durant # hores}other{Durant # hores}}"</string>
+    <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{Durant 1 h}many{Durant # h}other{Durant # h}}"</string>
     <string name="zen_mode_until_next_day" msgid="1403042784161725038">"Finalitza: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_until" msgid="2250286190237669079">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string>
@@ -2016,7 +2016,7 @@
     <string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Desa per a emplenament automàtic"</string>
     <string name="autofill_error_cannot_autofill" msgid="6528827648643138596">"El contingut no es pot emplenar automàticament"</string>
     <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Cap suggeriment d\'emplenament automàtic"</string>
-    <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{1 suggeriment d\'emplenament automàtic}many{# autofill suggestions}other{# suggeriments d\'emplenament automàtic}}"</string>
+    <string name="autofill_picker_some_suggestions" msgid="5560549696296202701">"{count,plural, =1{1 suggeriment d\'emplenament automàtic}many{# suggeriments d\'emplenament automàtic}other{# suggeriments d\'emplenament automàtic}}"</string>
     <string name="autofill_save_title" msgid="7719802414283739775">"Vols desar-ho a "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
     <string name="autofill_save_title_with_type" msgid="3002460014579799605">"Vols desar <xliff:g id="TYPE">%1$s</xliff:g> a "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string>
     <string name="autofill_save_title_with_2types" msgid="3783270967447869241">"Vols desar <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> a "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
@@ -2121,7 +2121,7 @@
     <string name="mime_type_presentation_ext" msgid="8761049335564371468">"Presentació <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
     <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"El Bluetooth es mantindrà activat durant el mode d\'avió"</string>
     <string name="car_loading_profile" msgid="8219978381196748070">"S\'està carregant"</string>
-    <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} i # fitxer}many{{file_name} + # files}other{{file_name} i # fitxers}}"</string>
+    <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} i # fitxer}many{{file_name} i # fitxers}other{{file_name} i # fitxers}}"</string>
     <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"No hi ha cap suggeriment de persones amb qui compartir"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Llista d\'aplicacions"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Aquesta aplicació no té permís de gravació, però pot capturar àudio a través d\'aquest dispositiu USB."</string>
@@ -2303,7 +2303,7 @@
     <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"No es pot accedir a la càmera del telèfon des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"No es pot accedir a la càmera de la tauleta des del teu <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
     <string name="vdm_secure_window" msgid="161700398158812314">"No s\'hi pot accedir mentre s\'està reproduint en continu. Prova-ho al telèfon."</string>
-    <string name="vdm_pip_blocked" msgid="4036107522497281397">"No es pot veure el mode de pantalla en pantalla durant la reproducció en continu"</string>
+    <string name="vdm_pip_blocked" msgid="4036107522497281397">"No es pot veure el mode d\'imatge sobre imatge durant la reproducció en continu"</string>
     <string name="system_locale_title" msgid="711882686834677268">"Valor predeterminat del sistema"</string>
     <string name="default_card_name" msgid="9198284935962911468">"TARGETA <xliff:g id="CARDNUMBER">%d</xliff:g>"</string>
     <string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Permís del perfil del rellotge perquè l\'aplicació complementària gestioni els rellotges"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permet que una aplicació complementària iniciï serveis en primer pla des d\'un segon pla."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"El micròfon està disponible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"El micròfon està bloquejat"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Pantalla dual"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La pantalla dual està activada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> està utilitzant les dues pantalles per mostrar contingut"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositiu està massa calent"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"La pantalla dual no està disponible perquè el telèfon està massa calent"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactiva"</string>
 </resources>
diff --git a/core/res/res/values-cs-watch/strings.xml b/core/res/res/values-cs-watch/strings.xml
index c94cc4d..6c9d718 100644
--- a/core/res/res/values-cs-watch/strings.xml
+++ b/core/res/res/values-cs-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikace <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Senzory"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 2e2c3e2..1ed9ac2 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Poskytuje aplikaci přístup k datům z tělesných senzorů, jako je tepová frekvence, teplota a procento nasycení krve kyslíkem, během používání aplikace."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Přístup k datům z tělesných senzorů, jako je tepová frekvence, při běhu na pozadí"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Poskytuje aplikaci přístup k datům z tělesných senzorů, jako je tepová frekvence, teplota a procento nasycení krve kyslíkem, při běhu na pozadí."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Má přístup k údajům o teplotě zápěstí z tělesného senzoru během používání aplikace."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Poskytuje aplikaci přístup k údajům o teplotě zápěstí z tělesného senzoru během používání aplikace."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Má přístup k údajům o teplotě zápěstí z tělesného senzoru při běhu na pozadí."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Poskytuje aplikaci přístup k údajům o teplotě zápěstí z tělesného senzoru při běhu na pozadí."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Čtení událostí v kalendáři včetně podrobností"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Tato aplikace může číst všechny události v kalendáři uložené v tabletu a sdílet či ukládat data kalendáře."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Tato aplikace může číst všechny události v kalendáři uložené v zařízení Android TV a sdílet či ukládat data kalendáře."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Spouštění systému Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet se spouští…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Zařízení se spouští…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Probíhá optimalizace úložiště."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Dokončování aktualizace systému…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> se upgraduje…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimalizování aplikace <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Příprava aplikace <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Spouštění aplikací."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Dokončování inicializace."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Byl zapnut režim PTP přes USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Byl zapnut tethering přes USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Byl zapnut režim MIDI přes USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Je připojeno příslušenství USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Klepnutím zobrazíte další možnosti."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Nabíjení připojeného zařízení. Klepnutím zobrazíte další možnosti."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hotovo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vypnout zkratku"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použít zkratku"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Korekce barev"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jedné ruky"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Velmi tmavé"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazení celé obrazovky"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Režim ukončíte přejetím prstem shora dolů."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Rozumím"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Otočte obrazovku, abyste lépe viděli"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Ukončete režim rozdělené obrazovky, abyste lépe viděli"</string>
     <string name="done_label" msgid="7283767013231718521">"Hotovo"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kruhový posuvník hodin"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kruhový posuvník minut"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Pracovní <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Před uvolněním požádat o PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Umožňuje doprovodné aplikaci spouštět z pozadí služby v popředí."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon je dostupný"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je zablokován"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvojitá obrazovka"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Je zapnutá funkce Dvojitá obrazovka"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> používá k zobrazení obsahu oba displeje"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Zařízení je příliš horké"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojitá obrazovka není k dispozici, protože se telefon příliš zahřívá"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Vypnout"</string>
 </resources>
diff --git a/core/res/res/values-da-watch/strings.xml b/core/res/res/values-da-watch/strings.xml
index 498fce1..fa296b6 100644
--- a/core/res/res/values-da-watch/strings.xml
+++ b/core/res/res/values-da-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensorer"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 7bd5556..c7806c7 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -214,7 +214,7 @@
     <string name="silent_mode" msgid="8796112363642579333">"Lydløs"</string>
     <string name="turn_on_radio" msgid="2961717788170634233">"Slå trådløs til"</string>
     <string name="turn_off_radio" msgid="7222573978109933360">"Slå trådløs fra"</string>
-    <string name="screen_lock" msgid="2072642720826409809">"Skærmlås"</string>
+    <string name="screen_lock" msgid="2072642720826409809">"Skærm­lås"</string>
     <string name="power_off" msgid="4111692782492232778">"Sluk"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"Ringeren er deaktiveret"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"Ringervibrering"</string>
@@ -238,7 +238,7 @@
     <string name="global_actions" product="tablet" msgid="4412132498517933867">"Valgmuligheder for tabletcomputeren"</string>
     <string name="global_actions" product="tv" msgid="3871763739487450369">"Valgmuligheder for Android TV"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"Indstillinger for telefon"</string>
-    <string name="global_action_lock" msgid="6949357274257655383">"Skærmlås"</string>
+    <string name="global_action_lock" msgid="6949357274257655383">"Skærm­lås"</string>
     <string name="global_action_power_off" msgid="4404936470711393203">"Sluk"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"Afbryderknap"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"Genstart"</string>
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tillader, at appen kan få adgang til kropssensordata, f.eks. pulsen, temperaturen og iltmætningen af blodet, mens appen er i brug."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Få adgang til kropssensordata, f.eks. pulsen, mens appen er i baggrunden"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tillader, at appen kan få adgang til kropssensordata, f.eks. pulsen, temperaturen og iltmætningen af blodet, mens appen er i baggrunden."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Få adgang til temperaturdata for kropssensoren på håndleddet, mens appen er i brug."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Tillader, at appen kan få adgang til temperaturdata for kropssensoren på håndleddet, mens appen er i brug."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Få adgang til temperaturdata for kropssensoren på håndleddet, mens appen er i baggrunden."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Tillader, at appen kan få adgang til temperaturdata for kropssensoren på håndleddet, mens appen er i baggrunden."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Læs kalenderbegivenheder og -info"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Denne app kan læse alle kalenderbegivenheder, der er gemt på din tablet, og dele eller gemme dine kalenderdata."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Denne app kan læse alle kalenderbegivenheder, der er gemt på din Android TV-enhed, og dele eller gemme dine kalenderdata."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android starter..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Denne tablet starter…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Enheden starter…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Lageret optimeres."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Afslutter systemopdatering…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> opgraderer…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimerer app <xliff:g id="NUMBER_0">%1$d</xliff:g> ud af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Forbereder <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Åbner dine apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Gennemfører start."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB er slået til"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Netdeling via USB er slået til"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB er slået til"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-tilbehør er tilsluttet"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tryk for at se flere muligheder."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Den tilsluttede enhed oplades. Tryk for at få flere valgmuligheder."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Udfør"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Deaktiver genvej"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Brug genvej"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Ombytning af farver"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Farvekorrigering"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndstilstand"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dæmpet belysning"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visning i fuld skærm"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Stryg ned fra toppen for at afslutte."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK, det er forstået"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Roter, og få en bedre visning"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Afslut opdelt skærm, og få en bedre visning"</string>
     <string name="done_label" msgid="7283767013231718521">"Udfør"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Cirkulær timevælger"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Cirkulær minutvælger"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> – arbejde"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> til arbejde"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> til arbejde"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon af <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Bed om pinkode inden frigørelse"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Bed om oplåsningsmønster ved deaktivering"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bed om adgangskode inden frigørelse"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Tillader, at en medfølgende app kan starte tjenester i forgrunden via tilladelser til tjenester i baggrunden."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofonen er tilgængelig"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonen er blokeret"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dobbeltskærm"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dobbeltskærm er aktiveret"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger begge skærme til at vise indhold"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Enheden er for varm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dobbeltskærm er ikke tilgængelig, fordi din telefon er for varm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Deaktiver"</string>
 </resources>
diff --git a/core/res/res/values-de-watch/strings.xml b/core/res/res/values-de-watch/strings.xml
index c910425..3f693a9 100644
--- a/core/res/res/values-de-watch/strings.xml
+++ b/core/res/res/values-de-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensoren"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index bf79e13..11c1219 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App in Benutzung ist."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zugriff auf Daten des Körpersensors, etwa Herzfrequenz, wenn im Hintergrund"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App im Hintergrund ist."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Auf Daten des Körpersensors zur Hauttemperatur am Handgelenk zugreifen, während die App verwendet wird."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Ermöglicht der App, auf Daten des Körpersensors zur Hauttemperatur am Handgelenk zuzugreifen, während die App verwendet wird."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Auf Daten des Körpersensors zur Hauttemperatur am Handgelenk zugreifen, während die App im Hintergrund ausgeführt wird."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Ermöglicht der App, auf Daten des Körpersensors zur Hauttemperatur am Handgelenk zuzugreifen, während die App im Hintergrund ausgeführt wird."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendertermine und Details lesen"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Diese App kann alle auf deinem Tablet gespeicherten Kalendertermine lesen und deine Kalenderdaten teilen oder speichern."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Diese App kann alle auf deinem Android TV-Gerät gespeicherten Kalendertermine lesen und die Kalenderdaten teilen oder speichern."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android wird gestartet…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet wird gestartet…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Gerät wird gestartet…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Speicher wird optimiert"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Systemupdate wird beendet…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Für <xliff:g id="APPLICATION">%1$s</xliff:g> wird gerade ein Upgrade ausgeführt…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> wird vorbereitet"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps werden gestartet..."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Start wird abgeschlossen..."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP über USB aktiviert"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-Tethering aktiviert"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI über USB aktiviert"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Mit USB-Zubehör verbunden"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Für weitere Optionen tippen."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Verbundenes Gerät wird aufgeladen. Für weitere Optionen tippen."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Fertig"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Verknüpfung deaktivieren"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Farbkorrektur"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhandmodus"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradunkel"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Vollbildmodus wird aktiviert"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Zum Beenden von oben nach unten wischen"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ok"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Drehen, um die Ansicht zu verbessern"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Modus für geteilten Bildschirm beenden, um die Ansicht zu verbessern"</string>
     <string name="done_label" msgid="7283767013231718521">"Fertig"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kreisförmiger Schieberegler für Stunden"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kreisförmiger Schieberegler für Minuten"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vor dem Beenden nach PIN fragen"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vor dem Beenden nach Entsperrungsmuster fragen"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vor dem Beenden nach Passwort fragen"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Ermöglicht einer Companion-App, Dienste im Vordergrund aus dem Hintergrund zu starten."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon ist verfügbar"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon ist blockiert"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual Screen ist aktiviert"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> nutzt zum Anzeigen von Inhalten beide Displays"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Gerät ist zu warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen ist nicht verfügbar, weil dein Smartphone zu warm ist"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Deaktivieren"</string>
 </resources>
diff --git a/core/res/res/values-el-watch/strings.xml b/core/res/res/values-el-watch/strings.xml
index f0d7621..4d5b10d 100644
--- a/core/res/res/values-el-watch/strings.xml
+++ b/core/res/res/values-el-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Εφαρμογή <xliff:g id="NUMBER_0">%1$d</xliff:g> από <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Αισθητήρες"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e17f78f..c7f851e 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -301,7 +301,7 @@
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"Ημερολόγιο"</string>
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"έχει πρόσβαση στο ημερολόγιό σας"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
-    <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και να διαβάζει μηνύματα SMS"</string>
+    <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και διαβάζει μηνύματα SMS"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"Αρχεία"</string>
     <string name="permgroupdesc_storage" msgid="5378659041354582769">"πρόσβαση στα αρχεία της συσκευής σας"</string>
     <string name="permgrouplab_readMediaAural" msgid="1858331312624942053">"Μουσική και ήχος"</string>
@@ -309,7 +309,7 @@
     <string name="permgrouplab_readMediaVisual" msgid="4724874717811908660">"Φωτογραφίες και βίντεο"</string>
     <string name="permgroupdesc_readMediaVisual" msgid="4080463241903508688">"πρόσβαση στις φωτογραφίες και τα βίντεο στη συσκευή σας"</string>
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"Μικρόφωνο"</string>
-    <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογραφεί"</string>
+    <string name="permgroupdesc_microphone" msgid="1047786732792487722">"ηχογράφηση"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Σωματική δραστ/τητα"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"πρόσβαση στη σωματική σας δραστηριότητα"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"Κάμερα"</string>
@@ -319,7 +319,7 @@
     <string name="permgrouplab_calllog" msgid="7926834372073550288">"Αρχεία καταγρ. κλήσ."</string>
     <string name="permgroupdesc_calllog" msgid="2026996642917801803">"ανάγνωση και εγγραφή αρχείου καταγραφής τηλεφωνικών κλήσεων"</string>
     <string name="permgrouplab_phone" msgid="570318944091926620">"Τηλέφωνο"</string>
-    <string name="permgroupdesc_phone" msgid="270048070781478204">"πραγματοποιεί και να διαχειρίζεται τηλ/κές κλήσεις"</string>
+    <string name="permgroupdesc_phone" msgid="270048070781478204">"πραγματοποιεί και διαχειρίζεται τηλ/κές κλήσεις"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"Αισθητήρες σώματος"</string>
     <string name="permgroupdesc_sensors" msgid="2610631290633747752">"πρόσβαση στα δεδομένα αισθητήρα σχετικά με τις ζωτικές ενδείξεις σας"</string>
     <string name="permgrouplab_notifications" msgid="5472972361980668884">"Ειδοποιήσεις"</string>
@@ -366,7 +366,7 @@
     <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Επιτρέπει στην εφαρμογή την ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου και έχουν ληφθεί από τη συσκευή σας. Ειδοποιήσεις που μεταδίδονται μέσω κινητού παραδίδονται σε ορισμένες τοποθεσίες για να σας προειδοποιήσουν για καταστάσεις έκτακτης ανάγκης. Κακόβουλες εφαρμογές ενδέχεται να παρεμποδίσουν την απόδοση ή τη λειτουργία της συσκευής σας κατά τη λήψη μετάδοσης μέσω κινητού σχετικά με μια επείγουσα κατάσταση."</string>
     <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"διαβάζει ροές δεδομένων στις οποίες έχετε εγγραφεί"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Επιτρέπει στην εφαρμογή τη λήψη λεπτομερειών σχετικά με τις τρέχουσες συγχρονισμένες ροές δεδομένων."</string>
-    <string name="permlab_sendSms" msgid="7757368721742014252">"στέλνει και να διαβάζει μηνύματα SMS"</string>
+    <string name="permlab_sendSms" msgid="7757368721742014252">"στέλνει και διαβάζει μηνύματα SMS"</string>
     <string name="permdesc_sendSms" msgid="6757089798435130769">"Επιτρέπει στην εφαρμογή των αποστολή μηνυμάτων SMS. Αυτό μπορεί να προκαλέσει μη αναμενόμενες χρεώσεις. Οι κακόβουλες εφαρμογές ενδέχεται να σας κοστίσουν χρήματα, αποστέλλοντας μηνύματα χωρίς την έγκρισή σας."</string>
     <string name="permlab_readSms" msgid="5164176626258800297">"διαβάζει τα μηνύματα κειμένου (SMS ή MMS)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα μηνύματα SMS (κειμένου) που είναι αποθηκευμένα στο tablet που χρησιμοποιείτε."</string>
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Επιτρέπει στην εφαρμογή να αποκτά πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, θερμοκρασία και ποσοστό οξυγόνου στο αίμα, ενώ η εφαρμογή χρησιμοποιείται."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, στο παρασκήνιο"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Επιτρέπει στην εφαρμογή να αποκτά πρόσβαση σε δεδομένα αισθητήρων σώματος, όπως καρδιακό ρυθμό, θερμοκρασία και ποσοστό οξυγόνου στο αίμα, ενώ η εφαρμογή βρίσκεται στο παρασκήνιο."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Πρόσβαση στα δεδομένα θερμοκρασίας καρπού του αισθητήρα σώματος όταν η εφαρμογή είναι σε χρήση."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στα δεδομένα θερμοκρασίας καρπού του αισθητήρα σώματος όταν η εφαρμογή είναι σε χρήση."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Πρόσβαση στα δεδομένα θερμοκρασίας καρπού του αισθητήρα σώματος όταν η εφαρμογή βρίσκεται στο παρασκήνιο."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στα δεδομένα θερμοκρασίας καρπού του αισθητήρα σώματος όταν η εφαρμογή βρίσκεται στο παρασκήνιο."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Ανάγνωση συμβάντων ημερολογίου και λεπτομερειών"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στο tablet που χρησιμοποιείτε και να μοιραστεί ή να αποθηκεύσει τα δεδομένα ημερολογίου σας."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Αυτή η εφαρμογή μπορεί να διαβάσει όλα τα συμβάντα ημερολογίου που είναι αποθηκευμένα στη συσκευή Android TV και να μοιραστεί ή να αποθηκεύσει τα δεδομένα ημερολογίου σας."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Εκκίνηση Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Εκκίνηση tablet…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Εκκίνηση συσκευής…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Βελτιστοποίηση αποθηκευτικού χώρου."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ολοκλήρωση ενημέρωσης συστήματος…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> αναβαθμίζεται…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Βελτιστοποίηση της εφαρμογής <xliff:g id="NUMBER_0">%1$d</xliff:g> από <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Προετοιμασία <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Έναρξη εφαρμογών."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Ολοκλήρωση εκκίνησης."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Η λειτουργία PTP μέσω USB ενεργοποιήθηκε"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Η σύνδεση μέσω USB ενεργοποιήθηκε"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Η λειτουργία MIDI μέσω USB ενεργοποιήθηκε"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Συνδέθηκε αξεσουάρ USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Πατήστε για περισσότερες επιλογές."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Φόρτιση συνδεδεμένης συσκευής. Πατήστε για περισσότερες επιλογές."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Τέλος"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Απενεργοποίηση συντόμευσης"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Χρήση συντόμευσης"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Διόρθωση χρωμάτων"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Λειτουργία ενός χεριού"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Επιπλέον μείωση φωτεινότητας"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Προβολή σε πλήρη οθόνη"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Για έξοδο, σύρετε προς τα κάτω από το επάνω μέρος."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Το κατάλαβα"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Περιστρέψτε την οθόνη για καλύτερη προβολή"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Εξέλθετε από τον διαχωρισμό οθόνης για καλύτερη προβολή"</string>
     <string name="done_label" msgid="7283767013231718521">"Τέλος"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Κυκλικό ρυθμιστικό ωρών"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Κυκλικό ρυθμιστικό λεπτών"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Εργασία <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> εργασίας 2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> εργασίας 3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Κλώνος <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Να γίνεται ερώτηση για το PIN, πριν από το ξεκαρφίτσωμα"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Επιτρέπει σε μια συνοδευτική εφαρμογή να εκκινεί υπηρεσίες στο προσκήνιο από το παρασκήνιο."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Το μικρόφωνο είναι διαθέσιμο"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Το μικρόφωνο έχει αποκλειστεί"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Διπλή οθόνη"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Η λειτουργία διπλής οθόνης είναι ενεργή"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί και τις δύο οθόνες για να εμφανίζει περιεχόμενο"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Η θερμοκρασία της συσκευής είναι πολύ υψηλή"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Η λειτουργία διπλής οθόνης δεν είναι διαθέσιμη επειδή η θερμοκρασία του τηλεφώνου αυξάνεται υπερβολικά"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Απενεργοποίηση"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU-watch/strings.xml b/core/res/res/values-en-rAU-watch/strings.xml
index c738395..21ba346 100644
--- a/core/res/res/values-en-rAU-watch/strings.xml
+++ b/core/res/res/values-en-rAU-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensors"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 04cdfd9..8ecd973 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Access body sensor wrist temperature data while the app is in use."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Allows the app to access body sensor wrist temperature data, while the app is in use."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Access body sensor wrist temperature data while the app is in the background."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Allows the app to access body sensor wrist temperature data, while the app is in the background."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android is starting…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet is starting…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Device is starting…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimising storage."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finishing system update…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> is upgrading…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
@@ -1364,6 +1358,7 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB turned on"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB tethering turned on"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB turned on"</string>
+    <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Device connected as webcam"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB accessory connected"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tap for more options."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Charging connected device. Tap for more options."</string>
@@ -1712,7 +1707,7 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Done"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
+    <string name="color_inversion_feature_name" msgid="2672824491933264951">"Colour inversion"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Colour correction"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
@@ -1850,6 +1845,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string>
     <string name="done_label" msgid="7283767013231718521">"Done"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string>
@@ -1861,6 +1858,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
@@ -2315,4 +2313,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Allows a companion app to start foreground services from background."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microphone is available"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual Screen is on"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
 </resources>
diff --git a/core/res/res/values-en-rCA-watch/strings.xml b/core/res/res/values-en-rCA-watch/strings.xml
index c738395..21ba346 100644
--- a/core/res/res/values-en-rCA-watch/strings.xml
+++ b/core/res/res/values-en-rCA-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensors"</string>
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index cbe8013..c73c0f1 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in use."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Access body sensor wrist temperature data while the app is in use."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Allows the app to access body sensor wrist temperature data, while the app is in use."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Access body sensor wrist temperature data while the app is in the background."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Allows the app to access body sensor wrist temperature data, while the app is in the background."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android is starting…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet is starting…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Device is starting…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimizing storage."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finishing system update…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> is upgrading…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizing app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
@@ -1364,6 +1358,7 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB turned on"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB tethering turned on"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB turned on"</string>
+    <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Device connected as Webcam"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB accessory connected"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tap for more options."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Charging connected device. Tap for more options."</string>
@@ -1712,7 +1707,7 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Done"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour inversion"</string>
+    <string name="color_inversion_feature_name" msgid="2672824491933264951">"Color inversion"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Color correction"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-Handed mode"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
@@ -1850,6 +1845,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string>
     <string name="done_label" msgid="7283767013231718521">"Done"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string>
@@ -1861,6 +1858,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
@@ -2315,4 +2313,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Allows a companion app to start foreground services from background."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microphone is available"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual screen is on"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB-watch/strings.xml b/core/res/res/values-en-rGB-watch/strings.xml
index c738395..21ba346 100644
--- a/core/res/res/values-en-rGB-watch/strings.xml
+++ b/core/res/res/values-en-rGB-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensors"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a43067a..0116992 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Access body sensor wrist temperature data while the app is in use."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Allows the app to access body sensor wrist temperature data, while the app is in use."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Access body sensor wrist temperature data while the app is in the background."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Allows the app to access body sensor wrist temperature data, while the app is in the background."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android is starting…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet is starting…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Device is starting…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimising storage."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finishing system update…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> is upgrading…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
@@ -1364,6 +1358,7 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB turned on"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB tethering turned on"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB turned on"</string>
+    <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Device connected as webcam"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB accessory connected"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tap for more options."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Charging connected device. Tap for more options."</string>
@@ -1712,7 +1707,7 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Done"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
+    <string name="color_inversion_feature_name" msgid="2672824491933264951">"Colour inversion"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Colour correction"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
@@ -1850,6 +1845,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string>
     <string name="done_label" msgid="7283767013231718521">"Done"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string>
@@ -1861,6 +1858,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
@@ -2315,4 +2313,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Allows a companion app to start foreground services from background."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microphone is available"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual Screen is on"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN-watch/strings.xml b/core/res/res/values-en-rIN-watch/strings.xml
index c738395..21ba346 100644
--- a/core/res/res/values-en-rIN-watch/strings.xml
+++ b/core/res/res/values-en-rIN-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensors"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 02bea3d..5fa28a0 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in use."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Access body sensor data, like heart rate, while in the background"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Allows the app to access body sensor data, such as heart rate, temperature and blood oxygen percentage, while the app is in the background."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Access body sensor wrist temperature data while the app is in use."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Allows the app to access body sensor wrist temperature data, while the app is in use."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Access body sensor wrist temperature data while the app is in the background."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Allows the app to access body sensor wrist temperature data, while the app is in the background."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"This app can read all calendar events stored on your Android TV device and share or save your calendar data."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android is starting…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet is starting…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Device is starting…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimising storage."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finishing system update…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> is upgrading…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparing <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starting apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finishing boot."</string>
@@ -1364,6 +1358,7 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB turned on"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB tethering turned on"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB turned on"</string>
+    <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Device connected as webcam"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB accessory connected"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tap for more options."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Charging connected device. Tap for more options."</string>
@@ -1712,7 +1707,7 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Done"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Turn off Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
+    <string name="color_inversion_feature_name" msgid="2672824491933264951">"Colour inversion"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Colour correction"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
@@ -1850,6 +1845,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"To exit, swipe down from the top."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Exit split screen for a better view"</string>
     <string name="done_label" msgid="7283767013231718521">"Done"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Hours circular slider"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minutes circular slider"</string>
@@ -1861,6 +1858,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string>
@@ -2315,4 +2313,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Allows a companion app to start foreground services from background."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microphone is available"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual Screen is on"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
 </resources>
diff --git a/core/res/res/values-en-rXC-watch/strings.xml b/core/res/res/values-en-rXC-watch/strings.xml
index 6d029e2..4ed361d 100644
--- a/core/res/res/values-en-rXC-watch/strings.xml
+++ b/core/res/res/values-en-rXC-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎App ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‏‎Sensors‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index d111611..9bdc49b 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in use.‎‏‎‎‏‎"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎Access body sensor data, like heart rate, while in the background‎‏‎‎‏‎"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‏‎Allows the app to access body sensor data, such as heart rate, temperature, and blood oxygen percentage, while the app is in the background.‎‏‎‎‏‎"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‎Access body sensor wrist temperature data while the app is in use.‎‏‎‎‏‎"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎Allows the app to access body sensor wrist temperature data, while the app is in use.‎‏‎‎‏‎"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎Access body sensor wrist temperature data while the app is in the background.‎‏‎‎‏‎"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‎Allows the app to access body sensor wrist temperature data, while the app is in the background.‎‏‎‎‏‎"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎Read calendar events and details‎‏‎‎‏‎"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎This app can read all calendar events stored on your tablet and share or save your calendar data.‎‏‎‎‏‎"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎This app can read all calendar events stored on your Android TV device and share or save your calendar data.‎‏‎‎‏‎"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎Android is starting…‎‏‎‎‏‎"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎Tablet is starting…‎‏‎‎‏‎"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎Device is starting…‎‏‎‎‏‎"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎Optimizing storage.‎‏‎‎‏‎"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎Finishing system update…‎‏‎‎‏‎"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is upgrading…‎‏‎‎‏‎"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎Optimizing app ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎Preparing ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎Starting apps.‎‏‎‎‏‎"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎Finishing boot.‎‏‎‎‏‎"</string>
@@ -1364,6 +1358,7 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎PTP via USB turned on‎‏‎‎‏‎"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎USB tethering turned on‎‏‎‎‏‎"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎MIDI via USB turned on‎‏‎‎‏‎"</string>
+    <string name="usb_uvc_notification_title" msgid="2030032862673400008">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎Device connected as Webcam‎‏‎‎‏‎"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‎USB accessory connected‎‏‎‎‏‎"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎Tap for more options.‎‏‎‎‏‎"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎Charging connected device. Tap for more options.‎‏‎‎‏‎"</string>
@@ -1712,7 +1707,7 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎Done‎‏‎‎‏‎"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎Turn off Shortcut‎‏‎‎‏‎"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎Use Shortcut‎‏‎‎‏‎"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Color Inversion‎‏‎‎‏‎"</string>
+    <string name="color_inversion_feature_name" msgid="2672824491933264951">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎Color inversion‎‏‎‎‏‎"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎Color correction‎‏‎‎‏‎"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‎One-Handed mode‎‏‎‎‏‎"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎Extra dim‎‏‎‎‏‎"</string>
@@ -1850,6 +1845,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎Viewing full screen‎‏‎‎‏‎"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‎To exit, swipe down from the top.‎‏‎‎‏‎"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎Got it‎‏‎‎‏‎"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‎Rotate for a better view‎‏‎‎‏‎"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎Exit split screen for a better view‎‏‎‎‏‎"</string>
     <string name="done_label" msgid="7283767013231718521">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎Done‎‏‎‎‏‎"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎Hours circular slider‎‏‎‎‏‎"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎Minutes circular slider‎‏‎‎‏‎"</string>
@@ -1861,6 +1858,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎Work ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎2nd Work ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎3rd Work ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎Clone ‎‏‎‎‏‏‎<xliff:g id="LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎Ask for PIN before unpinning‎‏‎‎‏‎"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎Ask for unlock pattern before unpinning‎‏‎‎‏‎"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎Ask for password before unpinning‎‏‎‎‏‎"</string>
@@ -2315,4 +2313,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎Allows a companion app to start foreground services from background.‎‏‎‎‏‎"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎Microphone is available‎‏‎‎‏‎"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎Microphone is blocked‎‏‎‎‏‎"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎Dual screen‎‏‎‎‏‎"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎Dual screen is on‎‏‎‎‏‎"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is using both displays to show content‎‏‎‎‏‎"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎Device is too warm‎‏‎‎‏‎"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎Dual Screen is unavailable because your phone is getting too warm‎‏‎‎‏‎"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‎Turn off‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS-watch/strings.xml b/core/res/res/values-es-rUS-watch/strings.xml
index adaa477..dea270b 100644
--- a/core/res/res/values-es-rUS-watch/strings.xml
+++ b/core/res/res/values-es-rUS-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensores"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index dad0231..03df43c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -47,7 +47,7 @@
     <string name="needPuk2" msgid="3910763547447344963">"Escribe el código PUK2 para desbloquear la tarjeta SIM."</string>
     <string name="enablePin" msgid="2543771964137091212">"Error; habilita el bloqueo de SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Tienes <xliff:g id="NUMBER_1">%d</xliff:g> intentos más antes de que se bloquee la tarjeta SIM.</item>
       <item quantity="other">Tienes <xliff:g id="NUMBER_1">%d</xliff:g> intentos más antes de que se bloquee la tarjeta SIM.</item>
       <item quantity="one">Tienes <xliff:g id="NUMBER_0">%d</xliff:g> un intento más antes de que se bloquee la tarjeta SIM.</item>
     </plurals>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que la app acceda a datos del sensor corporal, como el ritmo cardíaco, la temperatura y el porcentaje de oxígeno en sangre, mientras la app está en uso."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accede a datos del sensor corporal, como el ritmo cardíaco, en segundo plano"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que la app acceda a datos del sensor corporal, como el ritmo cardíaco, la temperatura y el porcentaje de oxígeno en sangre, mientras la app está en segundo plano."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Accede a los datos de temperatura de la muñeca del sensor corporal mientras la app está en uso."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite que, mientras esté en uso, la app acceda a los datos de temperatura de la muñeca del sensor corporal."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Accede a los datos de temperatura de la muñeca del sensor corporal mientras la app está en segundo plano."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite que, mientras esté en segundo plano, la app acceda a los datos de temperatura de la muñeca del sensor corporal."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Leer eventos y detalles del calendario"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta app puede leer todos los eventos del calendario de tu tablet y compartir o guardar los datos correspondientes."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta app puede leer todos los eventos del calendario guardados en el dispositivo Android TV, así como compartir o almacenar los datos correspondientes."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Iniciando Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Iniciando tablet…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Iniciando dispositivo…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimizando almacenamiento"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalizando actualización del sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Se está actualizando <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizando la aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalizando el inicio"</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Se activó el modo PTP mediante USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Se activó la conexión mediante dispositivo móvil por USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Se activó el modo MIDI mediante USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accesorio USB conectado"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Presiona para ver más opciones."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Cargando el dispositivo conectado. Presiona para ver más opciones."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Listo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Corrección de colores"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo de una mano"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visualización en pantalla completa"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo hacia abajo desde la parte superior."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira la pantalla para obtener una mejor vista"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sal de la pantalla dividida para obtener una mejor vista"</string>
     <string name="done_label" msgid="7283767013231718521">"Listo"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Control deslizante circular de horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Control deslizante circular de minutos"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicitar PIN para quitar fijación"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicitar desbloqueo para quitar fijación"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para quitar fijación"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que una aplicación complementaria inicie servicios en primer plano desde el segundo plano."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"El micrófono está disponible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"El micrófono está bloqueado"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Pantalla dual"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La Pantalla dual está activada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas pantallas para mostrar contenido"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositivo está muy caliente"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"La Pantalla dual no está disponible porque el teléfono se está calentando demasiado"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
 </resources>
diff --git a/core/res/res/values-es-watch/strings.xml b/core/res/res/values-es-watch/strings.xml
index 4b094e6..dea270b 100644
--- a/core/res/res/values-es-watch/strings.xml
+++ b/core/res/res/values-es-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensores"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index abec04b..cd1e270 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -47,7 +47,7 @@
     <string name="needPuk2" msgid="3910763547447344963">"Introduce el código PUK2 para desbloquear la SIM."</string>
     <string name="enablePin" msgid="2543771964137091212">"Error, habilitar bloqueo de SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Te quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos para bloquear la tarjeta SIM.</item>
       <item quantity="other">Te quedan <xliff:g id="NUMBER_1">%d</xliff:g> intentos para bloquear la tarjeta SIM.</item>
       <item quantity="one">Te queda <xliff:g id="NUMBER_0">%d</xliff:g> intento para bloquear la tarjeta SIM.</item>
     </plurals>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que la aplicación acceda a datos del sensor corporal, como la frecuencia cardiaca, la temperatura y el porcentaje de oxígeno en sangre, mientras se usa."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acceso en segundo plano a datos del sensor corporal, como la frecuencia cardiaca"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que la aplicación acceda a datos del sensor corporal, como la frecuencia cardiaca, la temperatura y el porcentaje de oxígeno en sangre, mientras está en segundo plano."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Acceder a los datos de temperatura de la muñeca del sensor corporal mientras la aplicación está en uso."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite que la aplicación acceda a los datos de temperatura de la muñeca del sensor corporal mientras está en uso."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Acceder a los datos de temperatura de la muñeca del sensor corporal mientras la aplicación está en segundo plano."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite que la aplicación acceda a los datos de temperatura de la muñeca del sensor corporal mientras está en segundo plano."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Leer eventos y detalles del calendario"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta aplicación puede leer los eventos de calendario almacenados en tu tablet y compartir o guardar los datos de tu calendario."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta aplicación puede ver los eventos de calendario almacenados en tu dispositivo Android TV y compartir o guardar los datos de tu calendario."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android se está iniciando…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"El tablet se está iniciando…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"El dispositivo se está iniciando…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimizando almacenamiento."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalizando actualización del sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> se está actualizando…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>..."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicaciones"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalizando inicio..."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Modo PTP por USB activado"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Modo de conexión compartida por USB activado"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Modo MIDI por USB activado"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accesorio USB conectado"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Toca para ver más opciones."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Cargando el dispositivo conectado. Toca para ver más opciones."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hecho"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Corrección de color"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo Una mano"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Modo de pantalla completa"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para salir, desliza el dedo de arriba abajo."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gira la pantalla para verlo mejor"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sal de la pantalla dividida para verlo mejor"</string>
     <string name="done_label" msgid="7283767013231718521">"Hecho"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Control deslizante circular de horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Control deslizante circular de minutos"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicitar PIN para desactivar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir patrón de desbloqueo para dejar de fijar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para desactivar"</string>
@@ -1953,7 +1953,7 @@
     <string name="work_mode_off_message" msgid="7319580997683623309">"Accede a tus aplicaciones y notificaciones de trabajo"</string>
     <string name="work_mode_turn_on" msgid="3662561662475962285">"Activar"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergencia"</string>
-    <string name="work_mode_dialer_off_message" msgid="2193299184850387465">"Consigue acceso a tus aplicaciones y llamadas de trabajo"</string>
+    <string name="work_mode_dialer_off_message" msgid="2193299184850387465">"Solicita acceso a tus aplicaciones y llamadas de trabajo"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que una aplicación complementaria inicie servicios en primer plano desde el segundo plano."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"El micrófono está disponible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"El micrófono está bloqueado"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Cámara Dual"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La función Cámara Dual está activada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas pantallas para mostrar contenido"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositivo está demasiado caliente"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Cámara Dual no está disponible porque el teléfono se está calentando demasiado"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
 </resources>
diff --git a/core/res/res/values-et-watch/strings.xml b/core/res/res/values-et-watch/strings.xml
index bcbe94b..4888bc1 100644
--- a/core/res/res/values-et-watch/strings.xml
+++ b/core/res/res/values-et-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Rakendus <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Andurid"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index f246539..4821636 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lubab rakendusel pääseda juurde kehaanduri andmetele, nagu pulss, temperatuur ja vere hapnikusisaldus, kui rakendust kasutatakse."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Juurdepääs kehaanduri andmetele, nagu pulss, kui rakendus töötab taustal"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lubab rakendusel pääseda juurde kehaanduri andmetele, nagu pulss, temperatuur ja vere hapnikusisaldus, kui rakendus töötab taustal."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Juurdepääs kehaanduri randmetemperatuuri andmetele, kui rakendust kasutatakse."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Lubab rakendusel pääseda juurde kehaanduri randmetemperatuuri andmetele, kui rakendust kasutatakse."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Juurdepääs kehaanduri randmetemperatuuri andmetele, kui rakendus töötab taustal."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Lubab rakendusel pääseda juurde kehaanduri randmetemperatuuri andmetele, kui rakendus töötab taustal."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendrisündmuste ja üksikasjade lugemine"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"See rakendus saab kõiki teie tahvelarvutisse salvestatud kalendrisündmusi lugeda ja teie kalendriandmeid jagada või salvestada."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"See rakendus saab kõiki teie Android TV seadmesse salvestatud kalendrisündmusi lugeda ja teie kalendriandmeid jagada või salvestada."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android käivitub ..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tahvelarvuti käivitub …"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Seade käivitub …"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Salvestusruumi optimeerimine."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Süsteemivärskenduse lõpuleviimine …"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Rakenduse <xliff:g id="APPLICATION">%1$s</xliff:g> versiooni uuendatakse …"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. rakenduse <xliff:g id="NUMBER_1">%2$d</xliff:g>-st optimeerimine."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> ettevalmistamine."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Rakenduste käivitamine."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Käivitamise lõpuleviimine."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP USB kaudu on sisse lülitatud"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB kaudu jagamine on sisse lülitatud"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI USB kaudu on sisse lülitatud"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB lisatarvik on ühendatud"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Puudutage lisavalikute nägemiseks."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Ühendatud seadet laetakse. Puudutage lisavalikute nägemiseks."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Valmis"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Lülita otsetee välja"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Värvide korrigeerimine"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Ühekäerežiim"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Eriti tume"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Kuvamine täisekraanil"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Väljumiseks pühkige ülevalt alla."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Selge"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Pöörake parema vaate jaoks"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Parema vaate jaoks väljuge jagatud ekraanikuvast"</string>
     <string name="done_label" msgid="7283767013231718521">"Valmis"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Ringikujuline tunniliugur"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Ringikujuline minutiliugur"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Töö <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. töö <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. töö <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Rakenduse <xliff:g id="LABEL">%1$s</xliff:g> kloon"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Enne vabastamist küsi PIN-koodi"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Lubab kaasrakendusel taustal käivitada esiplaanil olevaid teenuseid."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon on saadaval"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon on blokeeritud"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Kahe ekraani režiim"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Kahe ekraani režiim on sisse lülitatud"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> kasutab sisu kuvamiseks mõlemat ekraani"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Seade on liiga kuum"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Kahe ekraani režiim pole saadaval, kuna teie telefon läheb liiga kuumaks"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Lülita välja"</string>
 </resources>
diff --git a/core/res/res/values-eu-watch/strings.xml b/core/res/res/values-eu-watch/strings.xml
index d7051bf..7bb5e9d 100644
--- a/core/res/res/values-eu-watch/strings.xml
+++ b/core/res/res/values-eu-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> aplikaz."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sentsoreak"</string>
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 86e804c..d45baa5 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -455,17 +455,13 @@
     <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="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) atzitzeko baimena ematen die aplikazio horiei."</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>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Atzitu gorputz-sentsoreen datuak (adib., bihotz-maiztasunarenak) atzeko planoan"</string>
-    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikazioak atzeko planoan egon bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) atzitzeko baimena ematen die aplikazio horiei."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikazioak atzeko planoan egon bitartean, gorputz-sentsoreen datuak (besteak beste, bihotz-maiztasuna, tenperatura eta odolean dagoen oxigenoaren ehunekoa) erabiltzeko baimena ematen die aplikazio horiei."</string>
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Atzitu gorputz-sentsoreek eskumuturrean neurtutako tenperaturaren datuak aplikazioak erabili bitartean."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Aplikazioak erabili bitartean, gorputz-sentsoreek eskumuturrean neurtutako tenperaturaren datuak erabiltzeko baimena ematen die aplikazioei."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Atzitu gorputz-sentsoreek eskumuturrean neurtutako tenperaturaren datuak aplikazioak atzeko planoan exekutatu bitartean."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Aplikazioak atzeko planoan exekutatu bitartean, gorputz-sentsoreek eskumuturrean neurtutako tenperaturaren datuak erabiltzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"irakurri egutegiko gertaerak eta xehetasunak"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikazioak tabletan gordetako egutegiko gertaerak irakur ditzake eta egutegiko datuak parteka eta gorde ditzake."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikazioak Android TV gailuan gordeta dituzun egutegiko gertaerak irakur ditzake, baita egutegiko datuak partekatu eta gorde ere."</string>
@@ -475,7 +471,7 @@
     <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Android TV gailuan egutegiko gertaerak gehitzeko eta gehitutakoak kentzeko edo aldatzeko aukera dute aplikazioek. Gainera, egutegien jabeenak diruditen mezuak bidal ditzakete, edo gertaerak aldatu jabeei ezer esan gabe."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Telefonoko gertaerak gehitzeko, kentzeko edo aldatzeko aukera du aplikazioak. Gainera, egutegien jabeenak diruditen mezuak bidal ditzake, eta gertaerak alda ditzake jabeei beraiei jakinarazi gabe."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"atzitu kokapen-hornitzaileen komando gehigarriak"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Kokapen-hornitzailearen agindu gehigarriak atzitzeko baimena ematen die aplikazioei. Horrela, agian aplikazioek GPSaren edo bestelako kokapenaren iturburuen funtzionamenduan eragina izan dezakete."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Kokapen-hornitzailearen agindu gehigarriak erabiltzeko baimena ematen die aplikazioei. Horrela, agian aplikazioek GPSaren edo bestelako kokapenaren iturburuen funtzionamenduan eragina izan dezakete."</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"lortu kokapen zehatza aurreko planoan bakarrik"</string>
     <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Abian denean, aplikazioak kokapen zehatza lor dezake kokapen-zerbitzuen bidez. Aplikazioak kokapena lortu ahal izateko, kokapen-zerbitzuek aktibatuta egon behar dute gailuan. Bateria-erabilera areagotzen du horrek."</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"atzitu gutxi gorabeherako kokapena aurreko planoan bakarrik"</string>
@@ -498,21 +494,21 @@
     <string name="permdesc_camera" msgid="5240801376168647151">"Aplikazioak abian den bitartean erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko."</string>
     <string name="permlab_backgroundCamera" msgid="7549917926079731681">"Argazkiak atera eta bideoak grabatu atzeko planoan."</string>
     <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Aplikazioak edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko."</string>
-    <string name="permlab_systemCamera" msgid="3642917457796210580">"eman sistemako kamerak atzitzeko baimena aplikazio edo zerbitzu bati argazkiak ateratzeko eta bideoak grabatzeko"</string>
+    <string name="permlab_systemCamera" msgid="3642917457796210580">"eman sistemako kamerak erabiltzeko baimena aplikazio edo zerbitzu bati argazkiak ateratzeko eta bideoak grabatzeko"</string>
     <string name="permdesc_systemCamera" msgid="5938360914419175986">"Pribilegioa duen edo sistemakoa den aplikazio honek edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko. Halaber, android.permission.CAMERA baimena izan behar du aplikazioak."</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"eman jakinarazpenak jasotzeko baimena aplikazioari edo zerbitzuari kamerak ireki edo ixten direnean."</string>
     <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Kamera ireki edo itxi dela (eta zer aplikaziorekin) dioten jakinarazpenak jaso ditzake aplikazio honek."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"kontrolatu dardara"</string>
     <string name="permdesc_vibrate" msgid="8733343234582083721">"Bibragailua kontrolatzeko baimena ematen die aplikazioei."</string>
-    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dardara-egoera atzitzeko baimena ematen die aplikazioei."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Dardara-egoera erabiltzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"deitu zuzenean telefono-zenbakietara"</string>
     <string name="permdesc_callPhone" msgid="5439809516131609109">"Telefono-zenbakietara zuk esku hartu gabe deitzeko baimena ematen die aplikazioei. Horrela, ustekabeko gastuak edo deiak eragin daitezke. Asmo txarreko aplikazioek erabil dezakete zuk berretsi gabeko deiak eginda gastuak eragiteko."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"atzitu IMS dei-zerbitzua"</string>
     <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Zuk ezer egin beharrik gabe deiak egiteko IMS zerbitzua erabiltzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"irakurri telefonoaren egoera eta identitatea"</string>
-    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Gailuaren telefono-eginbideak atzitzeko baimena ematen die aplikazioei. Baimen horrek aplikazioari telefono-zenbakia eta gailu IDak zein diren, deirik aktibo dagoen eta deia zer zenbakirekin konektatuta dagoen zehazteko baimena ematen die aplikazioei."</string>
+    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Gailuaren telefono-eginbideak erabiltzeko baimena ematen die aplikazioei. Baimen horrek aplikazioari telefono-zenbakia eta gailu IDak zein diren, deirik aktibo dagoen eta deia zer zenbakirekin konektatuta dagoen zehazteko baimena ematen die aplikazioei."</string>
     <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"irakurri oinarrizko egoera telefonikoa eta identitatea"</string>
-    <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Gailuaren oinarrizko eginbide telefonikoak atzitzeko baimena ematen dio aplikazioari."</string>
+    <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Gailuaren oinarrizko eginbide telefonikoak erabiltzeko baimena ematen dio aplikazioari."</string>
     <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"bideratu deiak sistemaren bidez"</string>
     <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Deiak sistemaren bidez bideratzea baimentzen die aplikazioei, deien zerbitzua ahal bezain ona izan dadin."</string>
     <string name="permlab_callCompanionApp" msgid="3654373653014126884">"ikusi eta kontrolatu deiak sistemaren bidez."</string>
@@ -522,7 +518,7 @@
     <string name="permlab_acceptHandover" msgid="2925523073573116523">"jarraitu beste aplikazio batean hasitako deia"</string>
     <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Beste aplikazio batean hasitako dei batekin jarraitzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"irakurri telefono-zenbakiak"</string>
-    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Gailuaren telefono-zenbakiak atzitzeko baimena ematen die aplikazioei."</string>
+    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Gailuaren telefono-zenbakiak erabiltzeko baimena ematen die aplikazioei."</string>
     <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"mantendu piztuta autoko pantaila"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"eragotzi tableta inaktibo ezartzea"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"Android TV gailua inaktibo ezar dadin eragotzi"</string>
@@ -671,7 +667,7 @@
     <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Sakatu hau aurpegi-eredua ezabatzeko eta, gero, gehitu aurpegia berriro"</string>
     <string name="face_setup_notification_title" msgid="8843461561970741790">"Konfiguratu aurpegi bidez desblokeatzeko eginbidea"</string>
     <string name="face_setup_notification_content" msgid="5463999831057751676">"Telefonoa desblokeatzeko, begira iezaiozu"</string>
-    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Aurpegi bidez desblokeatzeko aukera erabiltzeko, aktibatu "<b>"kamera atzitzeko baimena"</b>" Ezarpenak &gt; Pribatutasuna atalean"</string>
+    <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Aurpegi bidez desblokeatzeko aukera erabiltzeko, aktibatu "<b>"kamera erabiltzeko baimena"</b>" Ezarpenak &gt; Pribatutasuna atalean"</string>
     <string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Konfiguratu telefonoa desblokeatzeko modu gehiago"</string>
     <string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Sakatu hau hatz-marka bat gehitzeko"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Hatz-marka bidez desblokeatzea"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android abiarazten ari da…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tableta abiarazten ari da…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Gailua abiarazten ari da…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Memoria optimizatzen."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Sistema eguneratzen amaitzen…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> bertsio-berritzen ari da…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> aplikazio optimizatzen."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> prestatzen."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Aplikazioak abiarazten."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Bertsio-berritzea amaitzen."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Aktibatuta dago USB bidezko PTP modua"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Aktibatuta dago USB bidez konexioa partekatzeko aukera"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Aktibatuta dago USB bidezko MIDI modua"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB osagarri bat konektatu da"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Sakatu aukera gehiago ikusteko."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Konektatutako gailua kargatzen ari da. Sakatu aukera gehiago ikusteko."</string>
@@ -1476,14 +1472,14 @@
     <string name="ime_action_default" msgid="8265027027659800121">"Abiarazi"</string>
     <string name="dial_number_using" msgid="6060769078933953531">"Markatu zenbakia \n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"Sortu kontaktu bat\n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
-    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Aplikazio hauetako bat edo gehiago kontua orain eta etorkizunean atzitzeko baimena eskatzen ari dira."</string>
+    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Aplikazio hauetako bat edo gehiago kontua orain eta etorkizunean erabiltzeko baimena eskatzen ari dira."</string>
     <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Eskaera onartu nahi duzu?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"Sarbide-eskaera"</string>
     <string name="allow" msgid="6195617008611933762">"Eman baimena"</string>
     <string name="deny" msgid="6632259981847676572">"Ukatu"</string>
     <string name="permission_request_notification_title" msgid="1810025922441048273">"Baimena eskatu da"</string>
     <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Baimena eskatu da \n<xliff:g id="ACCOUNT">%s</xliff:g> konturako."</string>
-    <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> aplikazioak <xliff:g id="ACCOUNT">%2$s</xliff:g> kontua atzitzeko baimena\neskatu du."</string>
+    <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"<xliff:g id="APP">%1$s</xliff:g> aplikazioak <xliff:g id="ACCOUNT">%2$s</xliff:g> kontua erabiltzeko baimena\neskatu du."</string>
     <string name="forward_intent_to_owner" msgid="4620359037192871015">"Laneko profiletik kanpo ari zara aplikazioa erabiltzen"</string>
     <string name="forward_intent_to_work" msgid="3620262405636021151">"Laneko profilean ari zara aplikazioa erabiltzen"</string>
     <string name="input_method_binding_label" msgid="1166731601721983656">"Idazketa-metodoa"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Eginda"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desaktibatu lasterbidea"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Koloreen zuzenketa"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Esku bakarreko modua"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Are ilunago"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Pantaila osoko ikuspegia"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Irteteko, pasatu hatza goitik behera."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ados"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Biratu pantaila ikuspegi hobea lortzeko"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Irten pantaila zatitutik ikuspegi hobea lortzeko"</string>
     <string name="done_label" msgid="7283767013231718521">"Eginda"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Ordua aukeratzeko ikuspegi zirkularra"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minutuak aukeratzeko ikuspegi zirkularra"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Laneko <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Laneko 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Laneko 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> aplikazioaren klona"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Eskatu PINa aingura kendu aurretik"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Eskatu pasahitza aingura kendu aurretik"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Aurreko planoko zerbitzuak atzeko planotik abiarazteko baimena ematen die aplikazio osagarriei."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Erabilgarri dago mikrofonoa"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Blokeatuta dago mikrofonoa"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Bi pantailako modua"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Bi pantailako modua aktibatuta dago"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> bi pantailak erabiltzen ari da edukia erakusteko"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Gailua beroegi dago"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Bi pantailako modua ez dago erabilgarri telefonoa berotzen ari delako"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Itzali"</string>
 </resources>
diff --git a/core/res/res/values-fa-watch/strings.xml b/core/res/res/values-fa-watch/strings.xml
index 979dfe4..4bd0216 100644
--- a/core/res/res/values-fa-watch/strings.xml
+++ b/core/res/res/values-fa-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"برنامه <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"حسگرها"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index e1a8322..f4eb123 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"به برنامه اجازه می‌دهد تا زمانی که درحال استفاده است، به داده‌های حسگر بدن، مثل ضربان قلب، دما، و درصد اکسیژن خون دسترسی داشته باشد."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"دسترسی به داده‌های حسگر بدن، مثل ضربان قلب، درحین اجرا در پس‌زمینه"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"به برنامه اجازه می‌دهد تا زمانی که در پس‌زمینه درحال اجرا است، به داده‌های حسگر بدن، مثل ضربان قلب، دما، و درصد اکسیژن خون دسترسی داشته باشد."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"دسترسی به داده‌های دمای مچ دست حسگر بدن درحین استفاده از برنامه."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"به برنامه اجازه می‌دهد تا زمانی که درحال استفاده است، به داده‌های دمای مچ دست حسگر بدن دسترسی داشته باشد."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"دسترسی به داده‌های دمای مچ دست حسگر بدن وقتی برنامه در پس‌زمینه است."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"به برنامه اجازه می‌دهد تا زمانی که در پس‌زمینه است، به داده‌های دمای مچ دست حسگر بدن دسترسی داشته باشد."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"خواندن رویدادها و جزئیات تقویم"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"این برنامه می‌تواند همه رویدادهای تقویم ذخیره‌شده در رایانه لوحی شما را بخواند و داده‌های تقویم شما را به اشتراک بگذارد یا ذخیره کند."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏این برنامه می‌تواند همه رویدادهای تقویم را که در Android TV شما ذخیره‌شده بخواند، و داده‌های تقویم شما را هم‌رسانی یا ذخیره کند."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"‏Android در حال راه‌اندازی است..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"رایانه لوحی درحال راه‌اندازی است…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"دستگاه درحال راه‌اندازی است…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"بهینه‌سازی فضای ذخیره‌سازی."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"درحال اتمام به‌روزرسانی سیستم…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> درحال ارتقا است...."</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"در حال بهینه‌سازی برنامهٔ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"آماده‌سازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"درحال آغاز کردن برنامه‌ها."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"درحال اتمام راه‌اندازی."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"‏PTP ازطریق USB روشن شد"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"‏اشتراک‌گذاری اینترنت با USB روشن شد"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"‏MIDI ازطریق USB روشن شد"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"‏وسیله جانبی USB متصل است"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"برای گزینه‌های بیشتر ضربه بزنید."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"درحال شارژ کردن دستگاه متصل‌‌شده. برای گزینه‌های بیشتر، ضربه بزنید."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"تمام"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"خاموش کردن میان‌بر"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استفاده از میان‌بر"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"وارونگی رنگ"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"تصحیح رنگ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"حالت یک‌دستی"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"بسیار کم‌نور"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"مشاهده در حالت تمام صفحه"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"برای خروج، انگشتتان را از بالای صفحه به پایین بکشید."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"متوجه شدم"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"برای دید بهتر، دستگاه را بچرخانید"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"برای دید بهتر، از صفحهٔ دونیمه خارج شوید"</string>
     <string name="done_label" msgid="7283767013231718521">"تمام"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"لغزنده دایره‌ای ساعت"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"لغزنده دایره‌ای دقیقه"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> محل کار"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"کار دوم <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"کار سوم <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"همسانه <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"درخواست کد پین قبل از برداشتن پین"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"درخواست الگوی بازگشایی قفل قبل‌از برداشتن سنجاق"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"درخواست گذرواژه قبل از برداشتن سنجاق"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"به برنامه همراه اجازه می‌دهد سرویس‌های پیش‌نما را از پس‌زمینه راه‌اندازی کند."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"میکروفون دردسترس است"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"میکروفون مسدود شد"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"صفحه دوتایی"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"«صفحه دوتایی» روشن است"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> از هر دو نمایشگر برای نمایش محتوا استفاده می‌کند"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"دستگاه بیش‌ازحد گرم شده است"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"«صفحه دوتایی» دردسترس نیست زیرا تلفن بیش‌ازحد گرم شده است"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"خاموش کردن"</string>
 </resources>
diff --git a/core/res/res/values-fi-watch/strings.xml b/core/res/res/values-fi-watch/strings.xml
index 536fdba..d565979c3 100644
--- a/core/res/res/values-fi-watch/strings.xml
+++ b/core/res/res/values-fi-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Sovellus <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Anturit"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 297278e..f50560b 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Myöntää sovellukselle pääsyn kehoanturidataan, esim. sykkeeseen, lämpötilaan ja veren happipitoisuuteen, kun sovellusta käytetään."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pääsy kehoanturidataan, esim. sykkeeseen, kun käynnissä taustalla"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Myöntää sovellukselle pääsyn kehoanturidataan, esim. sykkeeseen, lämpötilaan ja veren happipitoisuuteen, kun sovellus on käynnissä taustalla."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Pääsy kehoanturin ranteen lämpötiladataan, kun sovellusta käytetään."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Myöntää sovellukselle pääsyn kehoanturin ranteen lämpötiladataan, kun sovellusta käytetään."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Pääsy kehoanturin ranteen lämpötiladataan, kun sovellus on käynnissä taustalla."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Myöntää sovellukselle pääsyn kehoanturin ranteen lämpötiladataan, kun sovellus on käynnissä taustalla."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lue kalenterin tapahtumia ja tietoja"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Tämä sovellus voi lukea kaikkia tabletille tallennettuja kalenteritapahtumia sekä jakaa tai tallentaa kalenteritietoja."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Tämä sovellus voi lukea kaikkia Android TV ‑laitteeseen tallennettuja kalenteritapahtumia sekä jakaa tai tallentaa kalenteritietoja."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android käynnistyy…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tabletti käynnistyy…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Laite käynnistyy…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimoidaan tallennustilaa."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Viimeistellään järjestelmäpäivitystä…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> päivittyy…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimoidaan sovellusta <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Valmistellaan: <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Käynnistetään sovelluksia."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Viimeistellään päivitystä."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP USB:n kautta on käytössä"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Internetin jakaminen USB:n kautta on käytössä"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI USB:n kautta on käytössä"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-lisälaite yhdistetty"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Näet lisää vaihtoehtoja napauttamalla."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Ladataan yhdistettyä laitetta. Napauta nähdäksesi lisää vaihtoehtoja."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Valmis"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Poista pikanäppäin käytöstä"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Käytä pikanäppäintä"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Käänteiset värit"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Värinkorjaus"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Yhden käden moodi"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Erittäin himmeä"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Koko ruudun tilassa"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Sulje palkki pyyhkäisemällä alas ruudun ylälaidasta."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Selvä"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Kierrä, niin saat paremman näkymän"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Poistu jaetulta näytöltä, niin saat paremman näkymän"</string>
     <string name="done_label" msgid="7283767013231718521">"Valmis"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Tuntien ympyränmuotoinen liukusäädin"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minuuttien ympyränmuotoinen liukusäädin"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (työ)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Toinen <xliff:g id="LABEL">%1$s</xliff:g>, työ"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Kolmas <xliff:g id="LABEL">%1$s</xliff:g>, työ"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloonaa <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pyydä PIN ennen irrotusta"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Sallii kumppanisovelluksen aloittaa etualan palveluja taustalla."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofoni on käytettävissä"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofoni on estetty"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Kaksoisnäyttö"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Kaksoisnäyttö on päällä"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> käyttää molempia näyttöjä sisällön näyttämiseen"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Laite on liian lämmin"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Kaksoisnäyttö ei ole käytettävissä, koska puhelin on liian lämmin"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Laita pois päältä"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA-watch/strings.xml b/core/res/res/values-fr-rCA-watch/strings.xml
index a3316ab..dc71b35 100644
--- a/core/res/res/values-fr-rCA-watch/strings.xml
+++ b/core/res/res/values-fr-rCA-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Appli <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Capteurs"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index adc0f98..eadb4ef 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -48,7 +48,7 @@
     <string name="enablePin" msgid="2543771964137091212">"Opération infructueuse. Activez le verrouillage SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM soit verrouillée.</item>
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM soit verrouillée.</item>
       <item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM soit verrouillée.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"Code IIEM"</string>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'application."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels (comme la fréq. card.) en arrière-plan"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'application s\'exécute en arrière-plan."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Accéder aux données relatives à la température au poignet des capteurs corporels pendant l\'utilisation de l\'application."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permet à l\'application d\'accéder aux données relatives à la température au poignet des capteurs corporels pendant l\'utilisation de l\'application."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Accéder aux données relatives à la température au poignet des capteurs corporels pendant que l\'application s\'exécute en arrière-plan."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permet à l\'application d\'accéder aux données relatives à la température au poignet des capteurs corporels pendant que l\'application s\'exécute en arrière-plan."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et leurs détails"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android en cours de démarrage..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Démarrage de la tablette en cours…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Démarrage de l\'appareil en cours…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimisation du stockage."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalisation de la m. à j. syst. en cours…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Mise à niveau de <xliff:g id="APPLICATION">%1$s</xliff:g> en cours…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Mode PTP par USB activé"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Partage de connexion USB activé"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Mode MIDI par USB activé"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accessoire USB connecté"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Touchez pour afficher plus d\'options."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Chargement de l\'appareil connecté. Touchez l\'écran pour afficher plus d\'options."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"OK"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Désactiver le raccourci"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correction des couleurs"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode Une main"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Très sombre"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Affichage plein écran"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Pour quitter, balayez vers le bas à partir du haut."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Faire pivoter pour obtenir un meilleur affichage"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Quitter l\'écran partagé pour obtenir un meilleur affichage"</string>
     <string name="done_label" msgid="7283767013231718521">"Terminé"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Curseur circulaire des heures"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Curseur circulaire des minutes"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g> professionnel(le)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g> professionnel(le)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le NIP avant d\'annuler l\'épinglage"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant d\'annuler l\'épinglage"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permet à une application compagnon en arrière-plan de lancer des services d\'avant-plan."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Le microphone est accessible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Le microphone est bloqué"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Double écran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Le double écran est activé"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise les deux écrans pour afficher le contenu"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"L\'appareil est trop chaud"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Le double écran n\'est pas accessible, car votre téléphone est trop chaud"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Désactiver"</string>
 </resources>
diff --git a/core/res/res/values-fr-watch/strings.xml b/core/res/res/values-fr-watch/strings.xml
index f0574b5..dc71b35 100644
--- a/core/res/res/values-fr-watch/strings.xml
+++ b/core/res/res/values-fr-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Appli <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Capteurs"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ea481cd..f488f92 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -48,7 +48,7 @@
     <string name="enablePin" msgid="2543771964137091212">"Échec de l\'opération. Veuillez activer le verrouillage de la carte SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne soit verrouillée.</item>
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne soit verrouillée.</item>
       <item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne soit verrouillée.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"Code IMEI"</string>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en cours d\'utilisation."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données de capteurs corporels (comme le pouls) en arrière-plan"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'appli d\'accéder aux données des capteurs corporels (fréquence cardiaque, température, taux d\'oxygène dans le sang, etc.) quand l\'appli est en arrière-plan."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Accédez aux données des capteurs corporels relatives à la température du poignet quand l\'appli est en cours d\'utilisation."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permet à l\'appli d\'accéder aux données des capteurs corporels relatives à la température du poignet quand l\'appli est en cours d\'utilisation."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Accédez aux données des capteurs corporels relatives à la température du poignet quand l\'appli est en arrière-plan."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permet à l\'appli d\'accéder aux données des capteurs corporels relatives à la température du poignet quand l\'appli est en arrière-plan."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et les détails associés"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda enregistrés sur votre tablette et partager ou enregistrer vos données d\'agenda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements de l\'agenda enregistrés sur votre appareil Android TV, et partager ou enregistrer les données de votre agenda."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Démarrage d\'Android en cours"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Démarrage de la tablette…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Démarrage de l\'appareil…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimisation du stockage en cours…"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalisation de la mise à jour du système…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Mise à jour de l\'application <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB activé"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Partage de connexion via USB activé"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB activé"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accessoire USB connecté"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Appuyez ici pour plus d\'options."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Recharge de l\'appareil connecté. Appuyez ici pour plus d\'options."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"OK"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Désactiver le raccourci"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correction des couleurs"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode une main"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Encore moins lumineux"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Affichage en plein écran"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Pour quitter, balayez l\'écran du haut vers le bas."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Faites pivoter pour mieux voir"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Quittez l\'écran partagé pour mieux voir"</string>
     <string name="done_label" msgid="7283767013231718521">"OK"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Curseur circulaire des heures"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Curseur circulaire des minutes"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (pro)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g> professionnelle"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g> professionnelle"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Cloner <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le code avant de retirer l\'épingle"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Autorise une application associée à lancer des services de premier plan à partir de l\'arrière-plan."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Le micro est disponible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Le micro est bloqué"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Double écran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Double écran activé"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise les deux écrans pour afficher du contenu"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"L\'appareil est trop chaud"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Double écran n\'est pas disponible, car votre téléphone surchauffe"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Désactiver"</string>
 </resources>
diff --git a/core/res/res/values-gl-watch/strings.xml b/core/res/res/values-gl-watch/strings.xml
index 4b094e6..dea270b 100644
--- a/core/res/res/values-gl-watch/strings.xml
+++ b/core/res/res/values-gl-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensores"</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 735a4d5d..53a01eb 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -393,7 +393,7 @@
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"usar datos en segundo plano"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Esta aplicación pode usar datos en segundo plano. Por este motivo, quizais aumente o uso de datos."</string>
     <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Planificar accións para que se leven a cabo nun momento determinado"</string>
-    <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Esta aplicación pode planificar o traballo para que se leve a cabo nun momento determinado no futuro. Isto tamén supón que a aplicación poderá executarse cando non esteas usando o dispositivo de forma activa."</string>
+    <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Esta aplicación pode planificar accións para que se leven a cabo nun momento determinado no futuro. Isto tamén supón que a aplicación poderá executarse cando non esteas usando o dispositivo de forma activa."</string>
     <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Planificar alarmas ou recordatorios de eventos"</string>
     <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Esta aplicación pode planificar accións (por exemplo, alarmas ou recordatorios) para enviarche notificacións nun momento determinado no futuro."</string>
     <string name="permlab_persistentActivity" msgid="464970041740567970">"facer que a aplicación se execute sempre"</string>
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que a aplicación acceda aos datos dos sensores corporais (por exemplo, a frecuencia cardíaca, a temperatura ou a porcentaxe de osíxeno en sangue) mentres se estea utilizando."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acceso en segundo plano aos datos dos sensores corporais, como a frecuencia cardíaca"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que a aplicación acceda aos datos dos sensores corporais (por exemplo, a frecuencia cardíaca, a temperatura ou a porcentaxe de osíxeno en sangue) mentres se estea executando en segundo plano."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Acceder aos datos de temperatura do sensor corporal do pulso mentres se está utilizando a aplicación."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite que a aplicación acceda aos datos de temperatura do sensor corporal do pulso mentres se está utilizando a aplicación."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Acceder aos datos de temperatura do sensor corporal do pulso mentres a aplicación está en segundo plano."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite que a aplicación acceda aos datos de temperatura do sensor corporal do pulso mentres a aplicación está en segundo plano."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler os detalles e os eventos do calendario"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta aplicación pode ler todos os eventos do calendario almacenados na túa tableta e compartir ou gardar os datos do calendario."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta aplicación pode ler todos os eventos do calendario almacenados no dispositivo Android TV e compartir ou gardar os datos do calendario."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Estase iniciando Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"A tableta estase iniciando…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"O dispositivo estase iniciando…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimizando almacenamento."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalizando actualización do sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Actualizando <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando aplicacións."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Está finalizando o arranque"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Activouse o modo PTP por USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Activouse a conexión compartida por USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Activouse o modo MIDI por USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Conectouse un accesorio USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Toca para ver máis opcións."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Cargando o dispositivo conectado. Toca para ver máis opcións."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Feito"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar atallo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Corrección da cor"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo dunha soa man"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Vendo pantalla completa"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para saír, pasa o dedo cara abaixo desde a parte superior."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendido"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Xira a pantalla para que se vexa mellor"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sae da pantalla dividida para que se vexa mellor"</string>
     <string name="done_label" msgid="7283767013231718521">"Feito"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Control desprazable circular das horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Control desprazable circular dos minutos"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2.º <xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3.º <xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonar <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de soltar a fixación"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrón de desbloqueo antes de soltar a fixación"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir contrasinal antes de soltar a fixación"</string>
@@ -2312,7 +2312,13 @@
     <string name="permlab_deliverCompanionMessages" msgid="3931552294842980887">"Enviar mensaxes complementarias"</string>
     <string name="permdesc_deliverCompanionMessages" msgid="2170847384281412850">"Permite que unha aplicación complementaria envíe mensaxes complementarias a outros dispositivos."</string>
     <string name="permlab_startForegroundServicesFromBackground" msgid="6363004936218638382">"Desde un segundo plano iniciar servizos en primeiro plano"</string>
-    <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que nun segundo plano unha aplicación complementaria inicie servizos en primeiro plano."</string>
+    <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que unha aplicación complementaria, desde un segundo plano, inicie servizos en primeiro plano."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"O micrófono está dispoñible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"O micrófono está bloqueado"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Pantalla dual"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"A pantalla dual está activada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas as pantallas para mostrar contido"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está demasiado quente"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A pantalla dual non está dispoñible porque o teléfono está quentando demasiado"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
 </resources>
diff --git a/core/res/res/values-gu-watch/strings.xml b/core/res/res/values-gu-watch/strings.xml
index 3a03f359..8d38a68 100644
--- a/core/res/res/values-gu-watch/strings.xml
+++ b/core/res/res/values-gu-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g> માંથી <xliff:g id="NUMBER_0">%1$d</xliff:g> ઍપ્લિકેશન."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"સેન્સર્સ"</string>
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 00bddbb..51eaf87 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ઍપ ઉપયોગમાં હોય, ત્યારે ઍપને હૃદયના ધબકારા, તાપમાન અને લોહીમાં ઑક્સિજનની ટકાવારી જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ઍપ બૅકગ્રાઉન્ડમાં હોય, ત્યારે હૃદયના ધબકારા જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરો"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ઍપ બૅકગ્રાઉન્ડમાં હોય, ત્યારે ઍપને હૃદયના ધબકારા, તાપમાન અને લોહીમાં ઑક્સિજનની ટકાવારી જેવા બૉડી સેન્સર ડેટાનો ઍક્સેસ કરવાની મંજૂરી આપે છે."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ઍપનો ઉપયોગ થઈ રહ્યો હોય ત્યારે કાંડા મારફતે મપાયેલા શરીરના તાપમાન સંબંધિત બૉડી સેન્સરનો ડેટા ઍક્સેસ કરો."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ઍપનો ઉપયોગ થઈ રહ્યો હોય ત્યારે કાંડા મારફતે મપાયેલા શરીરના તાપમાન સંબંધિત બૉડી સેન્સરનો ડેટા ઍક્સેસ કરવાની ઍપને મંજૂરી આપે છે."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"બૅકગ્રાઉન્ડમાં ઍપ ચાલી રહી હોય ત્યારે કાંડા મારફતે મપાયેલા શરીરના તાપમાન સંબંધિત બૉડી સેન્સરનો ડેટા ઍક્સેસ કરો."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"બૅકગ્રાઉન્ડમાં ઍપ ચાલી રહી હોય ત્યારે કાંડા મારફતે મપાયેલા શરીરના તાપમાન સંબંધિત બૉડી સેન્સરનો ડેટા ઍક્સેસ કરવાની ઍપને મંજૂરી આપે છે."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"કૅલેન્ડર ઇવેન્ટ્સ અને વિગતો વાંચો"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"આ ઍપ્લિકેશન, તમારા ટેબ્લેટ પર સંગ્રહિત તમામ કૅલેન્ડર ઇવેન્ટ્સને વાંચી શકે છે અને તમારા કૅલેન્ડર ડેટાને શેર કરી અથવા સાચવી શકે છે."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"આ ઍપ, તમારા Android TV ડિવાઇસ પર સંગ્રહિત બધા કૅલેન્ડર ઇવેન્ટને વાંચી શકે છે અને તમારા કૅલેન્ડર ડેટાને શેર કરી અથવા સાચવી શકે છે."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android પ્રારંભ થઈ રહ્યું છે…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ટૅબ્લેટ શરૂ થઈ રહ્યું છે…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ઉપકરણ શરૂ થઈ રહ્યું છે…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"સંગ્રહ ઓપ્ટિમાઇઝ કરી રહ્યું છે."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"સિસ્ટમ અપડેટ સમાપ્ત કરી રહ્યાં છીએ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> અપગ્રેડ થઈ રહી છે…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> માંથી <xliff:g id="NUMBER_0">%1$d</xliff:g> ઍપ્લિકેશન ઓપ્ટિમાઇઝ કરી રહ્યું છે."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> તૈયાર કરી રહ્યું છે."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ઍપ્લિકેશનો શરૂ કરી રહ્યાં છે."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"બૂટ સમાપ્ત કરી રહ્યાં છે."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB મારફતે PTP ચાલુ કર્યું"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USBથી ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ કરી"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB મારફતે MIDI ચાલુ કર્યું"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ઍક્સેસરી કનેક્ટ કરેલ છે"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"વધુ વિકલ્પો માટે ટૅપ કરો."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"કનેક્ટ કરેલ ઉપકરણ ચાર્જ થઈ રહ્યું છે. વધુ વિકલ્પો માટે ટૅપ કરો."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"થઈ ગયું"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"શૉર્ટકટ બંધ કરો"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"શૉર્ટકટનો ઉપયોગ કરો"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"વિપરીત રંગમાં બદલવું"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"રંગ સુધારણા"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"એક-હાથે વાપરો મોડ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"એક્સ્ટ્રા ડિમ"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"પૂર્ણ સ્ક્રીન પર જુઓ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"બહાર નીકળવા માટે, ટોચ પરથી નીચે સ્વાઇપ કરો."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"સમજાઈ ગયું"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"બહેતર વ્યૂ માટે ફેરવો"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"બહેતર વ્યૂ માટે, વિભાજિત સ્ક્રીનમાંથી બહાર નીકળો"</string>
     <string name="done_label" msgid="7283767013231718521">"થઈ ગયું"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"કલાકનું વર્તુળાકાર સ્લાઇડર"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"મિનિટનું વર્તુળાકાર સ્લાઇડર"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ઑફિસ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ની ક્લોન"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"અનપિન કરતા પહેલાં પિન માટે પૂછો"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"સાથી ઍપને બૅકગ્રાઉન્ડમાંથી ફૉરગ્રાઉન્ડ સેવાઓ શરૂ કરવાની મંજૂરી આપે છે."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"માઇક્રોફોન ઉપલબ્ધ છે"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"માઇક્રોફોનને બ્લૉક કરવામાં આવ્યો છે"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ડ્યૂઅલ સ્ક્રીન"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ડ્યૂઅલ સ્ક્રીન ચાલુ છે"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"કન્ટેન્ટ બતાવવા માટે <xliff:g id="APP_NAME">%1$s</xliff:g> બન્ને ડિસ્પ્લેનો ઉપયોગ કરી રહી છે"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ડિવાઇસ ખૂબ જ ગરમ છે"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ડ્યૂઅલ સ્ક્રીન અનુપલબ્ધ છે કારણ કે તમારો ફોન ખૂબ જ ગરમ થઈ રહ્યો છે"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"બંધ કરો"</string>
 </resources>
diff --git a/core/res/res/values-hi-watch/strings.xml b/core/res/res/values-hi-watch/strings.xml
index f4c82f1..e73ce77 100644
--- a/core/res/res/values-hi-watch/strings.xml
+++ b/core/res/res/values-hi-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> ऐप."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"संवेदक"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 65b1242..58fb413 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"इससे ऐप्लिकेशन को इस्तेमाल करने के दौरान, उसे बॉडी सेंसर के डेटा को ऐक्सेस करने की अनुमति मिलती है. इसमें धड़कन की दर, शरीर का तापमान, और खून में ऑक्सीजन का प्रतिशत जैसी जानकारी शामिल होती है."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"बैकग्राउंड में चलने के दौरान, धड़कन की दर जैसे बॉडी सेंसर डेटा का ऐक्सेस दें"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"इससे ऐप्लिकेशन के बैकग्राउंड में चलने के दौरान, उसे बॉडी सेंसर के डेटा को ऐक्सेस करने की अनुमति मिलती है. इसमें धड़कन की दर, शरीर का तापमान, और खून में ऑक्सीजन का प्रतिशत जैसी जानकारी शामिल होती है."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ऐप्लिकेशन को यह अनुमति दें कि जब उसे इस्तेमाल किया जा रहा हो, तब वह आपके शरीर के उस तापमान का डेटा ऐक्सेस कर पाए जो बॉडी सेंसर ने सोते समय रिकॉर्ड किया है."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"इससे ऐप्लिकेशन, आपके शरीर के उस तापमान का डेटा ऐक्सेस कर पाएगा जो बॉडी सेंसर ने सोते समय रिकॉर्ड किया है. इस डेटा का ऐक्सेस उस समय मिलेगा जब ऐप्लिकेशन का इस्तेमाल किया जा रहा हो."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ऐप्लिकेशन को यह अनुमति दें कि बैकग्राउंड में चलते समय, वह आपके शरीर के उस तापमान का डेटा ऐक्सेस कर पाए जो बॉडी सेंसर ने सोते समय रिकॉर्ड किया है."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"इससे ऐप्लिकेशन, आपके शरीर के उस तापमान का डेटा ऐक्सेस कर पाएगा जो बॉडी सेंसर ने सोते समय रिकॉर्ड किया है. इस डेटा का ऐक्सेस उस समय मिलेगा जब ऐप्लिकेशन बैकग्राउंड में चल रहा होगा."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"कैलेंडर इवेंट और विवरण पढ़ें"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यह ऐप्लिकेशन आपके टैबलेट पर संग्रहित सभी कैलेंडर इवेंट पढ़ सकता है और आपका कैलेंडर डेटा शेयर कर सकता है या सहेज सकता है."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"यह ऐप्लिकेशन आपके टीवी पर सेव किए गए सभी कैलेंडर इवेंट को पढ़ सकता है. इसके अलावा यह आपके कैलेंडर का डेटा शेयर कर सकता है या सेव कर सकता है."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android प्रारंभ हो रहा है…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"टैबलेट चालू हो रहा है…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"डिवाइस चालू हो रहा है…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"मेमोरी ऑप्‍टिमाइज़ हो रही है."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"सिस्टम अपडेट पूरा होने वाला है…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> अपग्रेड हो रहा है…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> में से <xliff:g id="NUMBER_0">%1$d</xliff:g> ऐप्स  अनुकूलित हो रहा है."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> तैयार हो रहा है."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ऐप्स  प्रारंभ होने वाले हैं"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बूट खत्म हो रहा है."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"यूएसबी के ज़रिए पीटीपी की सुविधा चालू की गई"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"यूएसबी टेदरिंग की सुविधा चालू की गई"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"यूएसबी के ज़रिए एमआईडीआई (मिडी) की सुविधा चालू की गई"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"यूएसबी ऐक्सेसरी कनेक्ट हो गई है"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ज़्यादा विकल्पों के लिए टैप करें."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"जोड़ा गया डिवाइस चार्ज हो रहा है. ज़्यादा विकल्पों के लिए टैप करें."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"हो गया"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"शॉर्टकट बंद करें"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट का उपयोग करें"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"रंग बदलने की सुविधा"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"रंग में सुधार करने की सुविधा"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"वन-हैंडेड मोड"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"स्क्रीन की रोशनी को सामान्य लेवल से और कम करने की सुविधा"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"आप पूरे स्क्रीन पर देख रहे हैं"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"बाहर निकलने के लिए, ऊपर से नीचे स्वा‍इप करें."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ठीक है"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"बेहतर व्यू पाने के लिए, डिवाइस की स्क्रीन को घुमाएं"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"बेहतर व्यू पाने के लिए, स्प्लिट स्क्रीन मोड बंद करें"</string>
     <string name="done_label" msgid="7283767013231718521">"हो गया"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"घंटो का चक्राकार स्लाइडर"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"मिनटों का चक्राकार स्लाइडर"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"दफ़्तर का <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"दूसरा काम <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"तीसरा काम <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> का क्लोन"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करने से पहले पिन के लिए पूछें"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"इससे साथी ऐप्लिकेशन को बैकग्राउंड में फ़ोरग्राउंड सेवाएं चलाने की अनुमति मिलती है."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"माइक्रोफ़ोन इस्तेमाल किया जा सकता है"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"माइक्रोफ़ोन को ब्लॉक किया गया है"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ड्यूअल स्क्रीन"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ड्यूअल स्क्रीन की सुविधा चालू है"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>, कॉन्टेंट दिखाने के लिए दोनों डिसप्ले का इस्तेमाल कर रहा है"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"आपका फ़ोन बहुत गर्म हो गया है"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ड्यूअल स्क्रीन की सुविधा अभी उपलब्ध नहीं है, क्योंकि आपका फ़ोन बहुत गर्म हो रहा है"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"बंद करें"</string>
 </resources>
diff --git a/core/res/res/values-hr-watch/strings.xml b/core/res/res/values-hr-watch/strings.xml
index 699c148..da58726 100644
--- a/core/res/res/values-hr-watch/strings.xml
+++ b/core/res/res/values-hr-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikacija <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Senzori"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 85a4c45..44dbcf9 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Omogućuje aplikaciji pristup podacima s biometrijskih senzora, kao što su puls, temperatura i postotak kisika u krvi, dok se aplikacija upotrebljava."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Pristup podacima s biometrijskih senzora, kao što je puls, dok je u pozadini"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Omogućuje aplikaciji pristup podacima s biometrijskih senzora, kao što su puls, temperatura i postotak kisika u krvi, dok je aplikacija u pozadini."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Pristupite podacima o temperaturi na zapešću s biometrijskog senzora dok se aplikacija koristi."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Omogućuje aplikaciji da pristupi podacima o temperaturi na zapešću s biometrijskog senzora dok se aplikacija koristi."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Pristupite podacima o temperaturi na zapešću s biometrijskog senzora dok je aplikacija u pozadini."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Omogućuje aplikaciji da pristupi podacima o temperaturi na zapešću s biometrijskog senzora dok je aplikacija u pozadini."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Čitanje događaja i pojedinosti kalendara"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikacija može čitati sve kalendarske događaje pohranjene na tabletu i dijeliti ili spremati podatke iz vašeg kalendara."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikacija može čitati sve kalendarske događaje pohranjene na Android TV uređaju i dijeliti ili spremati podatke iz vašeg kalendara."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Pokretanje Androida..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet se pokreće…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Uređaj se pokreće…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimiziranje pohrane."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Dovršavanje ažuriranja sustava…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Nadogradnja aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimiziranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripremanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Pokretanje aplikacija."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Završetak inicijalizacije."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Uključen je PTP putem USB-a"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Uključeno je modemsko povezivanje putem USB-a"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Uključen je MIDI putem USB-a"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Priključen je USB dodatak"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Dodirnite za više opcija."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Povezani se uređaj puni. Dodirnite za više opcija."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gotovo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Isključi prečac"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Korekcija boja"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Način rada jednom rukom"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Još tamnije"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Gledanje preko cijelog zaslona"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Za izlaz prijeđite prstom od vrha prema dolje."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Shvaćam"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zakrenite kako biste bolje vidjeli"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Zatvorite podijeljeni zaslon kako biste bolje vidjeli"</string>
     <string name="done_label" msgid="7283767013231718521">"Gotovo"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kružni klizač sati"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kružni klizač minuta"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> za posao"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> za posao"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> za posao"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloniraj <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN radi otkvačivanja"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje radi otkvačivanja"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži zaporku radi otkvačivanja"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Popratnoj aplikaciji omogućuje da iz pozadine pokrene usluge u prednjem planu."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon je dostupan"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvostruki zaslon"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Uključen je dvostruki zaslon"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> upotrebljava oba zaslona za prikazivanje sadržaja"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Uređaj se pregrijao"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvostruki zaslon nije podržan jer se vaš telefon pregrijao"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Isključi"</string>
 </resources>
diff --git a/core/res/res/values-hu-watch/strings.xml b/core/res/res/values-hu-watch/strings.xml
index a038ffa..b8053c1 100644
--- a/core/res/res/values-hu-watch/strings.xml
+++ b/core/res/res/values-hu-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>. alkalmazás"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Érzékelők"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0c9a6cd..842932f 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelők adataihoz (pl. pulzusszám, testhőmérséklet és véroxigénszint), miközben az alkalmazás használatban van."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Hozzáférés a testérzékelők adataihoz (pl. pulzusszám) a háttérben"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelők adataihoz (pl. pulzusszám, testhőmérséklet és véroxigénszint), miközben az alkalmazás a háttérben van."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Hozzáférés a testérzékelő által a csuklón mért hőmérsékletadatokhoz, miközben az alkalmazás használatban van."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelő által a csuklón mért hőmérsékletadatokhoz, miközben az alkalmazás használatban van."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Hozzáférés a testérzékelő által a csuklón mért hőmérsékletadatokhoz, miközben az alkalmazás a háttérben van."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a testérzékelő által a csuklón mért hőmérsékletadatokhoz, miközben az alkalmazás a háttérben van."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Naptáresemények és a naptári adatok olvasása"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Az alkalmazás olvashatja a táblagépen tárolt összes naptáreseményt, és megoszthatja vagy mentheti a naptáradatokat."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Az alkalmazás olvashatja az Android TV eszközön tárolt összes naptáreseményt, és megoszthatja vagy mentheti a naptáradatokat."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Az Android indítása…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"A táblagép indítása…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Az eszköz indítása…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Tárhely-optimalizálás."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"A rendszerfrissítés befejezése…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> frissítése folyamatban van"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Alkalmazás optimalizálása: <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> előkészítése."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Kezdő alkalmazások."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Rendszerindítás befejezése."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Az USB-n keresztüli PTP be van kapcsolva"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Az USB-internetmegosztás be van kapcsolva"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Az USB-n keresztüli MIDI be van kapcsolva"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-kiegészítő csatlakoztatva"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Koppintson a további beállítások megjelenítéséhez."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Folyamatban van a csatlakoztatott eszköz töltése. Koppintson a további lehetőségekhez."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Kész"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Billentyűparancs kikapcsolása"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Billentyűparancs használata"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Színek invertálása"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Színjavítás"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Egykezes mód"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extrasötét"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Megtekintése teljes képernyőn"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Kilépéshez csúsztassa ujját fentről lefelé."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Értem"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Forgassa el a jobb élmény érdekében"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lépjen ki az osztott képernyős módból a jobb élmény érdekében"</string>
     <string name="done_label" msgid="7283767013231718521">"Kész"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Óra kör alakú csúszkája"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Perc kör alakú csúszkája"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> klónozása"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-kód kérése a kitűzés feloldásához"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Feloldási minta kérése a rögzítés feloldásához"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Jelszó kérése a rögzítés feloldásához"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Lehetővé teszi a társalkalmazások számára, hogy előtérben futó szolgáltatásokat indítsanak a háttérből."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"A mikrofon rendelkezésre áll"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"A mikrofon le van tiltva"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Két képernyő"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"A Két képernyő funkció be van kapcsolva"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> mindkét kijelzőt használja a tartalmak megjelenítésére"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Az eszköz túl meleg"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A Két képernyő funkció nem áll rendelkezésre, mert a telefon melegedni kezdett"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Kikapcsolás"</string>
 </resources>
diff --git a/core/res/res/values-hy-watch/strings.xml b/core/res/res/values-hy-watch/strings.xml
index a8197d3..4966e04 100644
--- a/core/res/res/values-hy-watch/strings.xml
+++ b/core/res/res/values-hy-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Հավելված <xliff:g id="NUMBER_0">%1$d</xliff:g>՝ <xliff:g id="NUMBER_1">%2$d</xliff:g>-ից:"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Սենսորներ"</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 3c2b686..8b9ae43 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Հավելվածին հասանելի է դարձնում մարմնի սենսորների տվյալները (օրինակ՝ սրտի զարկերի հաճախականությունը, ջերմաստիճանը, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշները) հավելվածի օգտագործման ժամանակ։"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Մարմնի սենսորների տվյալների հասանելիություն ֆոնային ռեժիմում"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Հավելվածին հասանելի է դարձնում մարմնի սենսորների տվյալները (օրինակ՝ սրտի զարկերի հաճախականությունը, ջերմաստիճանը, արյան մեջ թթվածնի տոկոսային պարունակության ցուցանիշները), երբ հավելվածն աշխատում է ֆոնային ռեժիմում։"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Մարմնի սենսորների՝ դաստակի ջերմաստիճանի մասին տվյալների հասանելիություն հավելվածի օգտագործման ընթացքում։"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Գործարկված հավելվածին հասանելի է դարձնում մարմնի սենսորների՝ դաստակի ջերմաստիճանի մասին տվյալները։"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Մարմնի սենսորների՝ դաստակի ջերմաստիճանի մասին տվյալների հասանելիություն ֆոնային ռեժիմում։"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Ֆոնային ռեժիմում գործարկված հավելվածին հասանելի է դարձնում մարմնի սենսորների՝ դաստակի ջերմաստիճանի մասին տվյալները։"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Կարդալ օրացույցի միջոցառումները և տվյալները"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր պլանշետում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Այս հավելվածը կարող է կարդալ օրացույցի՝ ձեր Android TV սարքում պահված բոլոր միջոցառումները, ինչպես նաև հրապարակել կամ պահել ձեր օրացույցի տվյալները:"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android-ը մեկնարկում է…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Պլանշետը միանում է…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Սարքը միանում է…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Պահեստի օպտիմալացում:"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Համակարգի թարմացումը շուտով կվերջանա…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը նորացվում է…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Օպտիմալացվում է հավելված <xliff:g id="NUMBER_0">%1$d</xliff:g>-ը <xliff:g id="NUMBER_1">%2$d</xliff:g>-ից:"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը պատրաստվում է:"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Հավելվածները մեկնարկում են:"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Բեռնումն ավարտվում է:"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP ռեժիմը USB-ի միջոցով միացավ"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB մոդեմի ռեժիմը միացավ"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI ռեժիմը USB-ի միջոցով միացավ"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Միացվել է USB լրասարք"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Միացված սարքի լիցքավորում: Հպեք՝ ավելի շատ ընտրանքների համար:"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Պատրաստ է"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Անջատել դյուրանցումը"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Օգտագործել դյուրանցումը"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Գունաշրջում"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Գունաշտկում"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Մեկ ձեռքի ռեժիմ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Հավելյալ խամրեցում"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Լիաէկրան դիտում"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Դուրս գալու համար վերևից սահահարվածեք դեպի ներքև:"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Պարզ է"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Պտտեք՝ դիտակերպը լավացնելու համար"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Դուրս եկեք կիսված էկրանի ռեժիմից՝ դիտակերպը լավացնելու համար"</string>
     <string name="done_label" msgid="7283767013231718521">"Պատրաստ է"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Ժամերի ընտրություն թվատախտակից"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Րոպեների ընտրություն թվատախտակից"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Աշխատանքային <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>-ի կլոն"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Հարցնել PIN կոդը"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Հարցնել ապակողպող նախշը"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Հարցնել գաղտնաբառը"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Թույլատրում է ուղեկցող հավելվածին ակտիվ ծառայություններ գործարկել ֆոնային ռեժիմից։"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Խոսափողը հասանելի է"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Խոսափողն արգելափակված է"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Կրկնակի էկրան"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Կրկնակի էկրանը միացված է"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը երկու էկրաններն էլ օգտագործում է բովանդակություն ցուցադրելու համար"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Սարքը գերտաքացել է"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Կրկնակի էկրանն անհասանելի է, քանի որ ձեր հեռախոսը գերտաքանում է"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Անջատել"</string>
 </resources>
diff --git a/core/res/res/values-in-watch/strings.xml b/core/res/res/values-in-watch/strings.xml
index e7dc878..4d64473 100644
--- a/core/res/res/values-in-watch/strings.xml
+++ b/core/res/res/values-in-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensor"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ce78f79..08031d4 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Mengizinkan aplikasi mengakses data sensor tubuh, seperti detak jantung, suhu, dan persentase oksigen dalam darah, saat aplikasi sedang digunakan."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Mengakses data sensor tubuh, seperti detak jantung, saat ada di latar belakang"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Mengizinkan aplikasi mengakses data sensor tubuh, seperti detak jantung, suhu, dan persentase oksigen dalam darah, saat aplikasi berada di latar belakang."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Mengakses data suhu pergelangan tangan sensor tubuh saat aplikasi sedang digunakan."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Mengizinkan aplikasi mengakses data suhu pergelangan tangan sensor tubuh, saat aplikasi sedang digunakan."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Mengakses data suhu pergelangan tangan sensor tubuh saat aplikasi sedang berada di latar belakang."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Mengizinkan aplikasi mengakses data suhu pergelangan tangan sensor tubuh, saat aplikasi sedang berada di latar belakang."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara kalender dan detailnya"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Aplikasi ini dapat membaca semua acara kalender yang tersimpan di tablet dan membagikan atau menyimpan data kalender."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Aplikasi ini dapat membaca semua acara kalender yang tersimpan di perangkat Android TV dan membagikan atau menyimpan data kalender."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Memulai Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Menyalakan tablet…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Menyalakan perangkat…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Mengoptimalkan penyimpanan."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Menyelesaikan update sistem…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> sedang ditingkatkan versinya…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Mengoptimalkan aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Menyiapkan <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Memulai aplikasi."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Menyelesaikan boot."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB diaktifkan"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tethering USB diaktifkan"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB diaktifkan"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Aksesori USB terhubung"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Ketuk untuk opsi lainnya."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Mengisi daya perangkat yang terhubung. Ketuk untuk opsi lainnya."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Selesai"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Nonaktifkan Pintasan"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Koreksi warna"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode satu tangan"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra redup"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Melihat layar penuh"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Untuk keluar, geser layar ke bawah dari atas."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Mengerti"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Putar posisi layar untuk mendapatkan tampilan yang lebih baik"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Keluar dari layar terpisah untuk mendapatkan tampilan yang lebih baik"</string>
     <string name="done_label" msgid="7283767013231718521">"Selesai"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Penggeser putar jam"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Penggeser putar menit"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Kantor <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Upaya ke-2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Upaya ke-3 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Meminta PIN sebelum melepas sematan"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Meminta pola pembukaan kunci sebelum melepas sematan"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Meminta sandi sebelum melepas sematan"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Mengizinkan aplikasi pendamping memulai layanan latar depan dari latar belakang."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon tersedia"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon diblokir"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Layar ganda"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Layar ganda aktif"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> menggunakan kedua layar untuk menampilkan konten"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Suhu perangkat terlalu panas"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Layar ganda tidak tersedia karena suhu ponsel terlalu panas"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Nonaktifkan"</string>
 </resources>
diff --git a/core/res/res/values-is-watch/strings.xml b/core/res/res/values-is-watch/strings.xml
index 7286ac0..041a534 100644
--- a/core/res/res/values-is-watch/strings.xml
+++ b/core/res/res/values-is-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Forrit <xliff:g id="NUMBER_0">%1$d</xliff:g> af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Skynjarar"</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index cba0380..c14c43e 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Veitir forritinu aðgang að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig og súrefnismettun í blóði á meðan forritið er í notkun."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Aðgangur að gögnum líkamsskynjara, t.d. um hjartslátt, meðan það er í bakgrunni"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Veitir forritinu aðgang að gögnum frá líkamsskynjurum, svo sem um hjartslátt, hitastig og súrefnismettun í blóði á meðan forritið keyrir í bakgrunni."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Aðgangur að gögnum um úlnliðshita frá líkamsskynjurum á meðan forritið er í notkun."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Veitir forritinu aðgang að gögnum um úlnliðshita frá líkamsskynjurum á meðan forritið er í notkun."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Aðgangur að gögnum um úlnliðshita frá líkamsskynjurum á meðan forritið er í bakgrunni."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Veitir forritinu aðgang að gögnum um úlnliðshita frá líkamsskynjurum á meðan forritið er í bakgrunni."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lesa dagatalsviðburði og upplýsingar"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Þetta forrit getur lesið alla dagatalsviðburði sem eru vistaðir í spjaldtölvunni og deilt eða vistað dagatalsgögnin þín."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Þetta forrit getur lesið alla dagatalsviðburði sem eru vistaðir í Android TV og deilt eða vistað dagatalsgögnin þín."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android er að ræsast…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Spjaldtölvan kveikir á sér…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Tækið kveikir á sér…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Fínstillir geymslu."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Lýkur við kerfisuppfærslu…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> uppfærir…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Fínstillir forrit <xliff:g id="NUMBER_0">%1$d</xliff:g> af <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Undirbýr <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Ræsir forrit."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Lýkur ræsingu."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Kveikt er á PTP yfir USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Kveikt er á USB-tjóðrun"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Kveikt er á MIDI yfir USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-aukabúnaður tengdur"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Ýttu til að sjá fleiri valkosti."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Hleður tengt tæki. Ýttu til að sjá fleiri valkosti."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Lokið"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Slökkva á flýtileið"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Nota flýtileið"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Umsnúningur lita"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Litaleiðrétting"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhent stilling"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mjög dökkt"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Notar allan skjáinn"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Strjúktu niður frá efri brún til að hætta."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ég skil"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Snúðu til að sjá betur"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lokaðu skjáskiptingu til að sjá betur"</string>
     <string name="done_label" msgid="7283767013231718521">"Lokið"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Valskífa fyrir klukkustundir"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Valskífa fyrir mínútur"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu (2)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu (3)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Afrit af <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Biðja um PIN-númer til að losa"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Biðja um opnunarmynstur til að losa"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Biðja um aðgangsorð til að losa"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Leyfir fylgiforriti að ræsa forgrunnsþjónustur úr bakgrunni."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Hljóðnemi er í boði"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Lokað er fyrir hljóðnemann"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Tveir skjáir"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Kveikt er á tveimur skjám"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> er að nota báða skjái til að sýna efni"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Tækið er of heitt"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Tveir skjáir eru ekki í boði vegna þess að síminn er of heitur"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Slökkva"</string>
 </resources>
diff --git a/core/res/res/values-it-watch/strings.xml b/core/res/res/values-it-watch/strings.xml
index e74d3d7..e22f614 100644
--- a/core/res/res/values-it-watch/strings.xml
+++ b/core/res/res/values-it-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> di <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensori"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index bfa9666..3d376a9 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -47,7 +47,7 @@
     <string name="needPuk2" msgid="3910763547447344963">"Digita il codice PUK2 per sbloccare la SIM."</string>
     <string name="enablePin" msgid="2543771964137091212">"Operazione non riuscita; attiva blocco SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM venga bloccata.</item>
       <item quantity="other">Hai ancora <xliff:g id="NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM venga bloccata.</item>
       <item quantity="one">Hai ancora <xliff:g id="NUMBER_0">%d</xliff:g> tentativo a disposizione prima che la SIM venga bloccata.</item>
     </plurals>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Autorizza l\'app ad accedere ai dati dei sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in uso."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accesso ai dati dei sensori del corpo, come il battito cardiaco, in background"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Autorizza l\'app ad accedere ai dati dei sensori del corpo, ad esempio battito cardiaco, temperatura e percentuale di ossigeno nel sangue, mentre l\'app è in background."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Accesso ai dati della temperatura del polso misurata dal sensore del corpo mentre l\'app è in uso."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Consente all\'app, mentre è in uso, di accedere ai dati della temperatura del polso misurata dal sensore del corpo."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Accesso ai dati della temperatura del polso misurata dal sensore del corpo mentre l\'app è in background."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Consente all\'app, mentre è in background, di accedere ai dati della temperatura del polso misurata dal sensore del corpo."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"lettura di eventi di calendario e dettagli"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Questa app può leggere tutti gli eventi di calendario memorizzati sul tablet e condividere o salvare i dati di calendario."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Questa app può leggere tutti gli eventi di calendario memorizzati sul dispositivo Android TV e condividere o salvare i dati di calendario."</string>
@@ -1034,7 +1030,7 @@
     <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Selettore utente"</string>
     <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Stato"</string>
     <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Fotocamera"</string>
-    <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Controlli media"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Controlli multimediali"</string>
     <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Riordino dei widget iniziato."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Riordino dei widget terminato."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminato."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Avvio di Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Avvio del tablet…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Avvio del dispositivo…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Ottimizzazione archiviazione."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Completamento aggiornamento di sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Upgrade dell\'app <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Ottimizzazione applicazione <xliff:g id="NUMBER_0">%1$d</xliff:g> di <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> in preparazione."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Avvio app."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Conclusione dell\'avvio."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Modalità PTP tramite USB attivata"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tethering USB attivato"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Modalità MIDI tramite USB attivata"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accessorio USB collegato"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tocca per altre opzioni."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Dispositivo collegato in carica. Tocca per altre opzioni."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Fine"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Disattiva scorciatoia"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usa scorciatoia"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversione dei colori"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correzione del colore"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modalità a una mano"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Attenuazione extra"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visualizzazione a schermo intero"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Per uscire, scorri dall\'alto verso il basso."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ruota per migliorare l\'anteprima"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Esci dallo schermo diviso per migliorare l\'anteprima"</string>
     <string name="done_label" msgid="7283767013231718521">"Fine"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Dispositivo di scorrimento circolare per le ore"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Dispositivo di scorrimento circolare per i minuti"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> lavoro"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> di lavoro (2°)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> di lavoro (3°)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (clone)"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Richiedi il PIN per lo sblocco"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Richiedi sequenza di sblocco prima di sbloccare"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Richiedi password prima di sbloccare"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Consente a un\'app complementare di avviare servizi in primo piano dal background."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microfono disponibile"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfono bloccato"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Doppio schermo"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Doppio schermo attivo"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> sta usando entrambi i display per mostrare contenuti"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Il dispositivo è troppo caldo"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Il doppio schermo non è disponibile perché il telefono si sta surriscaldando"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Disattiva"</string>
 </resources>
diff --git a/core/res/res/values-iw-watch/strings.xml b/core/res/res/values-iw-watch/strings.xml
index 3f0912f..d03a499 100644
--- a/core/res/res/values-iw-watch/strings.xml
+++ b/core/res/res/values-iw-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"אפליקציה <xliff:g id="NUMBER_0">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"חיישנים"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7315331..a88e373 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של חיישני גוף, כמו דופק, חום גוף ושיעור החמצן בדם, כשנעשה שימוש באפליקציה."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"גישה לנתונים של חיישני גוף, כמו דופק, כשהאפליקציה פועלת ברקע"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של חיישני גוף, כמו דופק, חום גוף ושיעור החמצן בדם, כשהאפליקציה פועלת ברקע."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"הרשאת גישה לנתונים של החיישן הלביש, כמו טמפרטורת פרק כף היד, כשנעשה שימוש באפליקציה."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של החיישן הלביש, כמו טמפרטורת פרק כף היד, כשנעשה שימוש באפליקציה."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"הרשאת גישה לנתונים של החיישן הלביש, כמו טמפרטורת פרק כף היד, כשהאפליקציה פועלת ברקע."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ההרשאה מאפשרת לאפליקציה לגשת לנתונים של החיישן הלביש, כמו טמפרטורת פרק כף היד, כשהאפליקציה פועלת ברקע."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"קריאה של אירועי יומן והפרטים שלהם"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים בטאבלט, ולשתף או לשמור את נתוני היומן."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏האפליקציה הזו יכולה לקרוא את כל אירועי היומן המאוחסנים במכשיר ה-Android TV, ולשתף או לשמור את נתוני היומן."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"‏הפעלת Android מתחילה…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"הטאבלט בתהליך הפעלה…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"הפעלת המכשיר מתחילה…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"מתבצעת אופטימיזציה של האחסון."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"עדכון המערכת לקראת סיום…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> בתהליך שדרוג…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"מתבצעת אופטימיזציה של אפליקציה <xliff:g id="NUMBER_0">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"המערכת מכינה את <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"מתבצעת הפעלה של אפליקציות."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"תהליך האתחול בשלבי סיום."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"‏PTP באמצעות USB מופעל"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"‏שיתוף אינטרנט בין מכשירים באמצעות USB מופעל"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"‏MIDI באמצעות USB מופעל"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"‏אביזר USB מחובר"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"יש להקיש להצגת אפשרויות נוספות."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"המכשיר המחובר בטעינה. יש להקיש לאפשרויות נוספות."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"סיום"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"השבתת קיצור הדרך"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"שימוש בקיצור הדרך"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"היפוך צבעים"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"תיקון צבע"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"מצב שימוש ביד אחת"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"מעומעם במיוחד"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"צפייה במסך מלא"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"כדי לצאת, פשוט מחליקים אצבע מלמעלה למטה."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"הבנתי"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"מסובבים כדי לראות טוב יותר"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"צריך לצאת מהמסך המפוצל כדי לראות טוב יותר"</string>
     <string name="done_label" msgid="7283767013231718521">"סיום"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"מחוון שעות מעגלי"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"מחוון דקות מעגלי"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"עבודה <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> שני בעבודה"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> שלישי בעבודה"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"שכפול של <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"יש לבקש קוד אימות לפני ביטול הצמדה"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"ההרשאה הזו מאפשרת לאפליקציה נלווית להפעיל מהרקע שירותים שפועלים בחזית."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"המיקרופון זמין"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"המיקרופון חסום"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"מצב שני מסכים"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"מצב שני מסכים מופעל"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בשני המסכים כדי להציג תוכן"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"המכשיר חם מדי"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"מצב שני מסכים לא זמין כי הטלפון נהיה חם מדי"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"השבתה"</string>
 </resources>
diff --git a/core/res/res/values-ja-watch/strings.xml b/core/res/res/values-ja-watch/strings.xml
index 62b7007..05ee203 100644
--- a/core/res/res/values-ja-watch/strings.xml
+++ b/core/res/res/values-ja-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"アプリ<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"センサー"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 52d018c..9e6e667 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"アプリの使用時に、心拍数、体温、血中酸素濃度など、ボディセンサー データにアクセスすることをアプリに許可します。"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"バックグラウンド動作時の、心拍数などのボディセンサー データへのアクセス"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"バックグラウンドでのアプリの動作時に、心拍数、体温、血中酸素濃度など、ボディセンサー データにアクセスすることをアプリに許可します。"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"アプリの使用中にボディセンサーの手首の体温データにアクセスします。"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"アプリの使用中に、ボディセンサーの手首の体温データへのアクセスをアプリに許可します。"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"アプリのバックグラウンド実行中に、ボディセンサーの手首の体温データにアクセスします。"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"アプリのバックグラウンド実行中に、ボディセンサーの手首の体温データへのアクセスをアプリに許可します。"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"カレンダーの予定と詳細を読み取り"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"このアプリは、お使いのタブレットに保存されたカレンダーの予定をすべて読み取り、カレンダーのデータを共有したり、保存したりできます。"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"このアプリは、Android TV デバイスに保存されているカレンダーの予定をすべて読み取り、カレンダーのデータを共有したり、保存したりできます。"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Androidの起動中…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"タブレットの起動中…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"デバイスの起動中…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ストレージを最適化しています。"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"システム アップデートの完了中…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」をアップグレードしています…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g>個中<xliff:g id="NUMBER_0">%1$d</xliff:g>個のアプリを最適化しています。"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>をペア設定しています。"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"アプリを起動しています。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ブートを終了しています。"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB PTP モード ON"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB テザリング ON"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB MIDI モード ON"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB アクセサリが接続されました"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"タップしてその他のオプションを表示します。"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"接続されているデバイスを充電しています。タップすると、他の項目が表示されます。"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"完了"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ショートカットを OFF にする"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ショートカットを使用"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"色反転"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"色補正"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"片手モード"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"さらに輝度を下げる"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"全画面表示"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"終了するには、上から下にスワイプします。"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"画面を回転させて見やすくしましょう"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"分割画面を終了して見やすくしましょう"</string>
     <string name="done_label" msgid="7283767013231718521">"完了"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"円形スライダー(時)"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"円形スライダー(分)"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"仕事の<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 番目の仕事用<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 番目の仕事用<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> のクローン"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"オフライン再生を解除する前にPINの入力を求める"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"画面固定を解除する前にロック解除パターンの入力を求める"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"オフライン再生を解除する前にパスワードの入力を求める"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"バックグラウンドからのフォアグラウンド サービスの起動をコンパニオン アプリに許可します。"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"マイクを利用できます"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"マイクがブロックされています"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"デュアル スクリーン"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"デュアル スクリーン: ON"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>は 2 画面でコンテンツを表示しています"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"デバイスが熱くなりすぎています"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"スマートフォンが熱くなりすぎているため、デュアル スクリーンを使用できません"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"オフにする"</string>
 </resources>
diff --git a/core/res/res/values-ka-watch/strings.xml b/core/res/res/values-ka-watch/strings.xml
index 1b7ebca..e91e2d3 100644
--- a/core/res/res/values-ka-watch/strings.xml
+++ b/core/res/res/values-ka-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"აპი <xliff:g id="NUMBER_0">%1$d</xliff:g>, სულ <xliff:g id="NUMBER_1">%2$d</xliff:g>-დან."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"სენსორები"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index c0fa6a0..831707c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -311,7 +311,7 @@
     <string name="permgrouplab_microphone" msgid="2480597427667420076">"მიკროფონი"</string>
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"აუდიოს ჩაწერა"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"ფიზიკური აქტივობა"</string>
-    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ფიზიკური აქტივობაზე წვდომა"</string>
+    <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"ფიზიკურ აქტივობაზე წვდომა"</string>
     <string name="permgrouplab_camera" msgid="9090413408963547706">"კამერა"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"ფოტოებისა და ვიდეოების გადაღება"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"ახლომახლო მოწყობილობები"</string>
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"საშუალებას აძლევს აპს, მისი გამოყენებისას, წვდომა ჰქონდეს სხეულის სენსორების მონაცემებზე, როგორიცაა გულისცემა, ტემპერატურა და სისხლში ჟანგბადის პროცენტული შემცველობა."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"აპის ფონურ რეჟიმში მუშაობისას, სხეულის სენსორების მონაცემებზე წვდომა, როგორიცაა გულისცემა"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"საშუალებას აძლევს აპს, ფონურ რეჟიმში მუშაობისას, წვდომა ჰქონდეს სხეულის სენსორების მონაცემებზე, როგორიცაა გულისცემა, ტემპერატურა და სისხლში ჟანგბადის პროცენტული შემცველობა."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"სხეულის სენსორის მაჯის ტემპერატურის მონაცემებზე წვდომა აპის მუშაობისას."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"საშუალებას აძლევს აპს, მუშაობისას წვდომა ჰქონდეს სხეულის სენსორის მაჯის ტემპერატურის მონაცემებზე."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"სხეულის სენსორის მაჯის ტემპერატურის მონაცემებზე წვდომა აპის ფონურ რეჟმში მუშაობისას."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"საშუალებას აძლევს აპს, ფონურ რეჟიმში მუშაობისას წვდომა ჰქონდეს სხეულის სენსორის მაჯის ტე,პერატურის მონაცემებზე."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"კალენდრის მოვლენებისა და დეტალების წაკითხვა"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ამ აპს შეუძლია თქვენს ტაბლეტში შენახული კალენდრის ყველა მოვლენის წაკითხვა და თქვენი კალენდრის მონაცემების გაზიარება ან შენახვა."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ამ აპს შეუძლია თქვენს Android TV მოწყობილობაზე შენახული კალენდრის ყველა მოვლენის წაკითხვა და თქვენი კალენდრის მონაცემების გაზიარება ან შენახვა."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android იწყება…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"მიმდინარეობს ტაბლეტის ჩართვა…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"მიმდინარეობს მოწყობილობის ჩართვა…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"მეხსიერების ოპტიმიზირება."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"სისტემის განახლება სრულდება…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> ახალ ვერსიაზე გადადის…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"მიმდინარეობს აპლიკაციების ოპტიმიზაცია. დასრულებულია <xliff:g id="NUMBER_0">%1$d</xliff:g>, სულ <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"ემზადება <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"აპების ჩართვა"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ჩატვირთვის დასასრული."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"ჩართულია PTP, USB-ს მეშვეობით"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB ტეტერინგი ჩართულია"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"ჩართულია MIDI, USB-ს მეშვეობით"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB აქსესუარი დაკავშირებულია"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"შეეხეთ დამატებითი ვარიანტების სანახავად."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"დაკავშირებული მოწყობილობა იტენება. შეეხეთ დამატებითი ვარიანტებისთვის."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"მზადაა"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"მალსახმობის გამორთვა"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"მალსახმობის გამოყენება"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ფერთა ინვერსია"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ფერთა კორექცია"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ცალი ხელის რეჟიმი"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"დამატებითი დაბინდვა"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"სრულ ეკრანზე ნახვა"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"გამოსვლისათვის, გაასრიალეთ ზემოდან ქვემოთ."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"გასაგებია"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"შეატრიალეთ უკეთესი ხედისთვის"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"უკეთესი ხედვისთვის გამოდით გაყოფილი ეკრანიდან"</string>
     <string name="done_label" msgid="7283767013231718521">"დასრულდა"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"საათების წრიული სლაიდერი"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"წუთების წრიული სლაიდერი"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"მე-2 სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"მე-3 სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> კლონის შექმნა"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ფიქსაციის მოხსნამდე PIN-ის მოთხოვნა"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ფიქსაციის მოხსნამდე განბლოკვის ნიმუშის მოთხოვნა"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"საშუალებას აძლევს კომპანიონ აპს, რომ გაუშვას უპირატესი სერვისები ფონური რეჟიმიდან."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"მიკროფონი ხელმისაწვდომია"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"მიკროფონი დაბლოკილია"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ორმაგი ეკრანი"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ორმაგი ეკრანი ჩართულია"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> იყენებს ორივე ეკრანს შინაარსის საჩვენებლად"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"მოწყობილობა ძალიან თბილია"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ორმაგი ეკრანი მიუწვდომელია, რადგან თქვენი ტელეფონი ძალიან თბება"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"გამორთვა"</string>
 </resources>
diff --git a/core/res/res/values-kk-watch/strings.xml b/core/res/res/values-kk-watch/strings.xml
index b992f96..6eb05ba 100644
--- a/core/res/res/values-kk-watch/strings.xml
+++ b/core/res/res/values-kk-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> бағдарлама."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Сенсорлар"</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 68ebba9..2923f22 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Жұмыс кезінде қолданбаға дене датчигінен алынған жүрек қағысы, температура, қандағы оттегі пайызы сияқты деректі пайдалануға рұқсат береді."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондық режимде дене датчигінен алынған жүрек қағысы сияқты деректі пайдалану"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Фондық режимде қолданбаға дене датчигінен алынған жүрек қағысы, температура, қандағы оттегі пайызы сияқты деректі пайдалануға рұқсат береді."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Қолданба пайдаланылып жатқанда оған қолдағы дене датчигінен алынған деректі пайдалануға рұқсат беру."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Қолданба пайдаланылып жатқанда оған қолдағы дене датчигінен алынған деректі пайдалануға рұқсат береді."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Фондық режимдегі қолданбаға қолдағы дене датчигінен алынған деректі пайдалануға рұқсат беру."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Фондық режимдегі қолданбаға қолдағы дене датчигінен алынған деректі пайдалануға рұқсат береді."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Күнтізбе оқиғалары мен мәліметтерін оқу"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бұл қолданба планшетте сақталған барлық күнтізбе оқиғаларын оқи алады және күнтізбе деректерін бөлісе не сақтай алады."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бұл қолданба Android TV құрылғыңызда сақталған барлық күнтізбе оқиғаларын оқи алады және күнтізбе деректерін бөлісе не сақтай алады."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android іске қосылуда…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Планшет іске қосылуда…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Құрылғы іске қосылуда…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Қойманы оңтайландыру."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Жүйелік жаңарту аяқталуда…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> жаңартылуда…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ішінен <xliff:g id="NUMBER_0">%1$d</xliff:g> қолданба оңтайландырылуда."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> дайындалуда."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Қолданбалар іске қосылуда."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Қосуды аяқтауда."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP режимі USB арқылы қосылды"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB тетеринг режимі қосылды"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI режимі USB арқылы қосылды"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB жабдығы жалғанған"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Қосымша опциялар үшін түртіңіз."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Жалғанған құрылғы зарядталуда. Қосымша параметрлер үшін түртіңіз."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Дайын"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Төте жолды өшіру"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Төте жолды пайдалану"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Түс инверсиясы"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Түсті түзету"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бір қолмен басқару режимі"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Экранды қарайту"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Толық экранда көру"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Шығу үшін жоғарыдан төмен қарай сырғытыңыз."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Түсінікті"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Жақсырақ көру үшін бұрыңыз."</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Жақсырақ көру үшін экранды бөлу режимінен шығыңыз."</string>
     <string name="done_label" msgid="7283767013231718521">"Дайын"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Сағаттар айналымының қозғалтқышы"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Минут айналымын қозғалтқыш"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Жұмыс <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ші жұмыс профилі (<xliff:g id="LABEL">%1$s</xliff:g>)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-ші жұмыс профилі (<xliff:g id="LABEL">%1$s</xliff:g>)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> клондау"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Босату алдында PIN кодын сұрау"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Босату алдында бекітпесін ашу өрнегін сұрау"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Босату алдында құпия сөзді сұрау"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Қосымша қолданбаға экрандық режимдегі қызметтерді фоннан іске қосуға рұқсат беріледі."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофон қолжетімді."</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон бөгелген."</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Қос экран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Қос экран функциясы қосулы"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы контентті көрсету үшін екі дисплейді де пайдаланады."</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Құрылғы қатты қызып кетті."</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Қос экран функциясы істемейді, себебі телефон қатты қызып кетеді."</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Өшіру"</string>
 </resources>
diff --git a/core/res/res/values-km-watch/strings.xml b/core/res/res/values-km-watch/strings.xml
index 0ac6ced..dd72ee4 100644
--- a/core/res/res/values-km-watch/strings.xml
+++ b/core/res/res/values-km-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"កម្មវិធី <xliff:g id="NUMBER_0">%1$d</xliff:g> នៃ <xliff:g id="NUMBER_1">%2$d</xliff:g>។"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"ឧបករណ៍ចាប់សញ្ញា"</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index ee39924..7c3f038 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូង សីតុណ្ហភាព និងភាគរយនៃអុកស៊ីសែនក្នុងឈាមជាដើម ខណៈពេលកំពុងប្រើកម្មវិធី។"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូងជាដើម ខណៈពេលស្ថិតនៅផ្ទៃខាងក្រោយ"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើទិន្នន័យឧបករណ៍ចាប់សញ្ញារាងកាយ ដូចជាចង្វាក់បេះដូង សីតុណ្ហភាព និងភាគរយនៃអុកស៊ីសែនក្នុងឈាមជាដើម ខណៈពេលដែលកម្មវិធីស្ថិតនៅផ្ទៃខាងក្រោយ។"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ចូលប្រើ​ទិន្នន័យសីតុណ្ហភាពកដៃ​ពីសេនស័ររាងកាយ នៅពេល​កំពុងប្រើកម្មវិធី។"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"អនុញ្ញាតឱ្យកម្មវិធីចូលប្រើ​ទិន្នន័យសីតុណ្ហភាពកដៃ​ពីសេនស័ររាងកាយ នៅពេល​កំពុងប្រើកម្មវិធី។"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ចូលប្រើ​ទិន្នន័យសីតុណ្ហភាព​កដៃពីសេនស័ររាងកាយ នៅពេល​កម្មវិធីស្ថិត​នៅផ្ទៃខាងក្រោយ។"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"អនុញ្ញាតឱ្យ​កម្មវិធីចូលប្រើ​ទិន្នន័យសីតុណ្ហភាព​កដៃពីសេនស័ររាងកាយ នៅពេល​កម្មវិធីស្ថិត​នៅផ្ទៃខាងក្រោយ។"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"អាន​ព្រឹត្តិការណ៍​ប្រតិទិន​ និង​ព័ត៌មាន​លម្អិត"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"កម្មវិធី​នេះ​អាច​ធ្វើការ​អាន​ព្រឹត្តិការណ៍​ប្រតិទិន​ទាំងអស់​ ដែល​ផ្ទុក​នៅលើ​ថេប្លេត​របស់​អ្នក​ និង​ចែករំលែក​ ឬ​រក្សាទុក​ទិន្នន័យ​ប្រតិទិន​របស់​អ្នក​។"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"កម្មវិធីនេះ​អាចអានព្រឹត្តិការណ៍​ក្នុងប្រតិទិន​ទាំងអស់​ដែលបានរក្សាទុក​នៅក្នុងឧបករណ៍ Android TV របស់អ្នក និង​ចែករំលែក ឬរក្សាទុក​ទិន្នន័យ​ប្រតិទិន​របស់អ្នក។"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android កំពុង​ចាប់ផ្ដើម…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ថេប្លេត​កំពុង​ចាប់ផ្ដើម…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ឧបករណ៍​កំពុង​ចាប់ផ្ដើម…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"កំពុងធ្វើឲ្យឧបករណ៍ផ្ទុកមានប្រសិទ្ធភាព។"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"កំពុងបញ្ចប់​បច្ចុប្បន្នភាព​ប្រព័ន្ធ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> អាប់គ្រេត…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"ធ្វើ​ឲ្យ​កម្មវិធី​ប្រសើរ​ឡើង <xliff:g id="NUMBER_0">%1$d</xliff:g> នៃ <xliff:g id="NUMBER_1">%2$d</xliff:g> ។"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"កំពុងរៀបចំ <xliff:g id="APPNAME">%1$s</xliff:g>។"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ចាប់ផ្ដើម​កម្មវិធី។"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"បញ្ចប់​ការ​ចាប់ផ្ដើម។"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"មុខងារ PTP តាម​ USB ត្រូវបានបើក"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"ការភ្ជាប់តាម USB ត្រូវបានបើក"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"មុខងារ​ MIDI តាម USB ត្រូវបានបើក"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"បាន​ភ្ជាប់​ជាមួយ​គ្រឿង​បរិក្ខារ USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ប៉ះសម្រាប់ជម្រើសជាច្រើនទៀត"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"កំពុងសាកថ្ម​ឧបករណ៍​ដែលបានភ្ជាប់។ សូមចុចសម្រាប់​ជម្រើសបន្ថែម។"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"រួចរាល់"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"បិទ​ផ្លូវកាត់"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ប្រើប្រាស់​ផ្លូវកាត់"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"បញ្ច្រាស​ពណ៌"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ការកែតម្រូវ​ពណ៌"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"មុខងារប្រើដៃម្ខាង"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ពន្លឺតិចខ្លាំង"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"កំពុងមើលពេញអេក្រង់"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ដើម្បីចាកចេញ សូមអូសពីលើចុះក្រោម។"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"យល់ហើយ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"បង្វិលដើម្បីមើលបានកាន់តែច្បាស់"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ចេញពីមុខងារ​បំបែកអេក្រង់ដើម្បីមើលបានកាន់តែច្បាស់"</string>
     <string name="done_label" msgid="7283767013231718521">"រួចរាល់"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"គ្រាប់​រំកិល​រង្វង់​ម៉ោង"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"គ្រាប់​រំកិល​រង្វង់​នាទី"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g>​ការងារ"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> ការងារទី 2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> ការងារទី 3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"ក្លូន <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"សួរ​រក​កូដ PIN មុន​ពេលដកខ្ទាស់"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"សួរ​រក​លំនាំ​ដោះ​សោ​មុន​ពេលដោះខ្ទាស់"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"សួរ​រក​ពាក្យ​សម្ងាត់​មុន​ពេល​ផ្ដាច់"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"អនុញ្ញាតឱ្យកម្មវិធីដៃគូចាប់ផ្តើមសេវាកម្មផ្ទៃខាងមុខពីផ្ទៃខាងក្រោយ។"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"អាចប្រើ​មីក្រូហ្វូនបាន"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"មីក្រូហ្វូនត្រូវ​បានទប់ស្កាត់"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"អេក្រង់ពីរ"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"អេក្រង់ពីរត្រូវបានបើក"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងប្រើផ្ទាំងអេក្រង់ទាំងពីរដើម្បីបង្ហាញខ្លឹមសារ"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ឧបករណ៍ក្តៅពេក"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"អេក្រង់ពីរមិនអាចប្រើបានទេ ដោយសារទូរសព្ទរបស់អ្នកឡើងក្តៅពេក"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"បិទ"</string>
 </resources>
diff --git a/core/res/res/values-kn-watch/strings.xml b/core/res/res/values-kn-watch/strings.xml
index 30a00d3..b5cf763 100644
--- a/core/res/res/values-kn-watch/strings.xml
+++ b/core/res/res/values-kn-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="NUMBER_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"ಸೆನ್ಸರ್‌ಗಳು"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index d23a53e..fab5b3a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ ಮತ್ತು ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಎಂಬಂತಹ ದೇಹದ ಸೆನ್ಸರ್‌ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ಹಿನ್ನಲೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತದಂತಹ ದೇಹದ ಸೆನ್ಸರ್‌ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ಆ್ಯಪ್ ಹಿನ್ನಲೆಯಲ್ಲಿರುವಾಗ ಹೃದಯ ಬಡಿತ, ತಾಪಮಾನ ಮತ್ತು ರಕ್ತದ ಆಮ್ಲಜನಕದ ಶೇಕಡಾವಾರು ಎಂಬಂತಹ ದೇಹದ ಸೆನ್ಸರ್‌ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ದೇಹದ ಸೆನ್ಸರ್‌ನಿಂದ ಮಣಿಕಟ್ಟಿನ ತಾಪಮಾನದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ದೇಹದ ಸೆನ್ಸರ್‌ನಿಂದ ಮಣಿಕಟ್ಟಿನ ತಾಪಮಾನದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ಆ್ಯಪ್ ಹಿನ್ನೆಲೆಯಲ್ಲಿರುವಾಗ ದೇಹದ ಸೆನ್ಸರ್‌ನಿಂದ ಮಣಿಕಟ್ಟಿನ ತಾಪಮಾನದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ಆ್ಯಪ್ ಹಿನ್ನೆಲೆಯಲ್ಲಿರುವಾಗ ದೇಹದ ಸೆನ್ಸರ್‌ನಿಂದ ಮಣಿಕಟ್ಟಿನ ತಾಪಮಾನದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳು ಮತ್ತು ವಿವರಗಳನ್ನು ಓದಿ"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹವಾಗಿರುವ ಎಲ್ಲಾ ಕ್ಯಾಲೆಂಡರ್ ಈವೆಂಟ್‌ಗಳನ್ನು ಓದಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು ಅಥವಾ ಉಳಿಸಬಹುದು."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ಟ್ಯಾಬ್ಲೆಟ್ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ಸಾಧನವನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ಸಂಗ್ರಹಣೆಯನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"ಸಿಸ್ಟಮ್ ಅಪ್‌ಡೇಟ್ ಮುಕ್ತಾಯಗೊಳ್ಳುತ್ತಿದೆ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> ಅಪ್‌ಗ್ರೇಡ್ ಆಗುತ್ತಿದೆ..."</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="NUMBER_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ಬೂಟ್ ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB ಮೂಲಕ PTP ಆನ್‌ ಆಗಿದೆ"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB ಟೆಥರಿಂಗ್ ಆನ್ ಆಗಿದೆ"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB ಮೂಲಕ MIDI ಆನ್‌ ಆಗಿದೆ"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ಪರಿಕರವನ್ನು ಸಂಪರ್ಕಿಸಲಾಗಿದೆ"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸಾಧನವನ್ನು ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ. ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ಶಾರ್ಟ್‌ಕಟ್‌ ಆಫ್ ಮಾಡಿ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸಿ"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ಬಣ್ಣ ವಿಲೋಮ"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ಒಂದು ಕೈ ಮೋಡ್‌"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ಇನ್ನಷ್ಟು ಮಬ್ಬು"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"ಪೂರ್ಣ ಪರದೆಯನ್ನು ವೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ನಿರ್ಗಮಿಸಲು, ಮೇಲಿನಿಂದ ಕೆಳಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ತಿಳಿಯಿತು"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ಅತ್ಯುತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ತಿರುಗಿಸಿ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ಅತ್ಯುತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಸ್ಪ್ಲಿಟ್‌ ಸ್ಕ್ರೀನ್‌ನಿಂದ ನಿರ್ಗಮಿಸಿ"</string>
     <string name="done_label" msgid="7283767013231718521">"ಮುಗಿದಿದೆ"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ಗಂಟೆಗಳ ವೃತ್ತಾಕಾರ ಸ್ಲೈಡರ್"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"ನಿಮಿಷಗಳ ವೃತ್ತಾಕಾರ ಸ್ಲೈಡರ್"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ಕೆಲಸ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 ನೇ ಕೆಲಸದ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 ನೇ ಕೆಲಸದ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ಕ್ಲೋನ್"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಪಿನ್‌ ಕೇಳು"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ಅನ್‌ಪಿನ್ ಮಾಡಲು ಪಾಸ್‌ವರ್ಡ್ ಕೇಳು"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"ಮುನ್ನೆಲೆ ಸೇವೆಗಳನ್ನು ಹಿನ್ನೆಲೆಯಿಂದ ಪ್ರಾರಂಭಿಸಲು ಕಂಪ್ಯಾನಿಯನ್ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"ಮೈಕ್ರೊಫೋನ್ ಲಭ್ಯವಿದೆ"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ಡ್ಯೂಯಲ್ ಸ್ಕ್ರೀನ್"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ಡ್ಯೂಯಲ್ ಸ್ಕ್ರೀನ್ ಆನ್ ಆಗಿದೆ"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"ವಿಷಯವನ್ನು ತೋರಿಸಲು <xliff:g id="APP_NAME">%1$s</xliff:g> ಎರಡೂ ಡಿಸ್‌ಪ್ಲೇಗಳನ್ನು ಬಳಸುತ್ತದೆ"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ಸಾಧನವು ತುಂಬಾ ಬಿಸಿಯಾಗಿದೆ"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ನಿಮ್ಮ ಫೋನ್ ತುಂಬಾ ಬಿಸಿಯಾಗುವುದರಿಂದ ಡ್ಯೂಯಲ್ ಸ್ಕ್ರೀನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ಆಫ್ ಮಾಡಿ"</string>
 </resources>
diff --git a/core/res/res/values-ko-watch/strings.xml b/core/res/res/values-ko-watch/strings.xml
index 1a14bcd..a9cbb63 100644
--- a/core/res/res/values-ko-watch/strings.xml
+++ b/core/res/res/values-ko-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"앱 <xliff:g id="NUMBER_1">%2$d</xliff:g>개 중 <xliff:g id="NUMBER_0">%1$d</xliff:g>개"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"센서"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a52259a..6b800a8 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"앱이 사용 중에 심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서 데이터에 액세스하도록 허용합니다."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"백그라운드에서 심박수와 같은 생체 신호 센서 데이터에 액세스"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"앱이 백그라운드에서 심박수, 체온, 혈중 산소 농도와 같은 생체 신호 센서 데이터에 액세스하도록 허용합니다."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"앱 사용 중에 생체 신호 센서 손목 온도 데이터에 액세스합니다"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"앱이 사용 중에 생체 신호 센서 손목 온도 데이터에 액세스하도록 허용합니다."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"앱이 백그라운드에 있을 때 생체 신호 센서 손목 온도 데이터에 액세스합니다"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"앱이 백그라운드에서 생체 신호 센서 손목 온도 데이터에 액세스하도록 허용합니다."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"캘린더 일정 및 세부정보 읽기"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"이 앱은 태블릿에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"앱이 Android TV 기기에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string>
@@ -636,7 +632,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>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android가 시작되는 중…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"태블릿을 시작하는 중…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"기기를 시작하는 중…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"저장소 최적화 중"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"시스템 업데이트를 완료하는 중…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> 업그레이드 중…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"앱 <xliff:g id="NUMBER_1">%2$d</xliff:g>개 중 <xliff:g id="NUMBER_0">%1$d</xliff:g>개 최적화 중"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> 준비 중..."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"앱을 시작하는 중입니다."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"부팅 완료"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB를 통해 PTP 사용 설정됨"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB 테더링 사용 설정됨"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB를 통해 MIDI 사용 설정됨"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB 액세서리 연결됨"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"옵션을 더 보려면 탭하세요."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"연결된 기기를 충전합니다. 옵션을 더 보려면 탭하세요."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"완료"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"단축키 사용 중지"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"단축키 사용"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"색상 반전"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"색상 보정"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"한 손 모드"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"더 어둡게"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"전체 화면 모드"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"종료하려면 위에서 아래로 스와이프합니다."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"확인"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"카메라 미리보기 화면이 잘 보이도록 회전하세요."</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"카메라 미리보기 화면이 잘 보이도록 화면 분할을 종료하세요."</string>
     <string name="done_label" msgid="7283767013231718521">"완료"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"시간 원형 슬라이더"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"분 원형 슬라이더"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"두 번째 업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"세 번째 업무용<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> 복사"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"고정 해제 이전에 PIN 요청"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"고정 해제 시 잠금 해제 패턴 요청"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"고정 해제 이전에 비밀번호 요청"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"호환 앱이 백그라운드에서 포그라운드 서비스를 시작할 수 있게 허용합니다."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"마이크 사용 가능"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"마이크가 차단됨"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"듀얼 스크린"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"듀얼 스크린 켜짐"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 두 화면을 모두 사용하여 콘텐츠를 표시합니다."</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"기기 온도가 너무 높음"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"휴대전화 온도가 너무 높아지고 있으므로 듀얼 스크린을 사용할 수 없습니다."</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"사용 중지"</string>
 </resources>
diff --git a/core/res/res/values-ky-watch/strings.xml b/core/res/res/values-ky-watch/strings.xml
index fa1c47c..4095282 100644
--- a/core/res/res/values-ky-watch/strings.xml
+++ b/core/res/res/values-ky-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колднм."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Сенсорлор"</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 67a890d..b4a0ccd 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Иштеп жатканда колдонмо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Фондо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушун көрүү"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Колдонмо фондо дене сенсорлорунун көрсөткүчтөрүн, мисалы, жүрөктүн согушу, температура жана кандагы кычкылтектин пайызын көрө алат."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Колдонмо иштеп жатканда, дене сенсорлорунун температура тууралуу маалыматын көрүү."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Колдонмо иштеп жатканда, дене сенсорлорунун температура тууралуу маалыматын көрө алат."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Колдонмо фондо иштеп жатканда, дене сенсорлорунун температура тууралуу маалыматын көрүү."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Колдонмо фондо дене сенсорлорунун температура тууралуу маалыматын көрө алат."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Жылнаамадагы иш-чараларды жана алардын чоо-жайын окуу"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Бул колдонмо планшетиңизде сакталган жылнаамадагы иш-чаралардын баарын окуп жана андагы маалыматтарды бөлүшүп же сактай алат."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Бул колдонмо Android TV түзмөгүңүздө сакталган жылнаама иш-чараларынын баарын окуп, ошондой эле жылнаама дайындарын бөлүшүп же сактай алат."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android жүргүзүлүүдө…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Планшет күйгүзүлүүдө…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Түзмөк күйүгүзүлүүдө…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Сактагыч ыңгайлаштырылууда."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Система жаңырып бүтөйүн деп калды…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> жаңыртылууда..."</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо оптималдаштырылууда."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> даярдалууда."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Колдонмолорду иштетип баштоо"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөлүүдө"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB аркылуу PTP режими күйгүзүлдү"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB модем күйгүзүлдү"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB аркылуу MIDI режими күйгүзүлдү"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB шайманы туташты"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Кошумча параметрлерди ачуу үчүн таптап коюңуз."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Туташкан түзмөк кубатталууда. Дагы параметрлерди көрүү үчүн таптап коюңуз."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Бүттү"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Кыска жолду өчүрүү"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Кыска жолду колдонуу"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстөрдү инверсиялоо"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Түстөрдү тууралоо"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бир кол режими"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Кошумча караңгылатуу"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Толук экран режими"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Чыгуу үчүн экранды ылдый сүрүп коюңуз."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Түшүндүм"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Жакшыраак көрүү үчүн буруңуз"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Жакшыраак көрүү үчүн экранды бөлүү режиминен чыгыңыз"</string>
     <string name="done_label" msgid="7283767013231718521">"Даяр"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Саат жебеси"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Мүнөт жебеси"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> клону"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бошотуудан мурун PIN суралсын"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бошотуудан мурун графикалык ачкыч суралсын"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Бошотуудан мурун сырсөз суралсын"</string>
@@ -2000,7 +2000,7 @@
     <string name="app_category_social" msgid="2278269325488344054">"Социалдык жана коммуникация"</string>
     <string name="app_category_news" msgid="1172762719574964544">"Жаңылыктар жана журналдар"</string>
     <string name="app_category_maps" msgid="6395725487922533156">"Карталар жана чабыттоо"</string>
-    <string name="app_category_productivity" msgid="1844422703029557883">"Өндүрүш категориясы"</string>
+    <string name="app_category_productivity" msgid="1844422703029557883">"Майнаптуулук"</string>
     <string name="app_category_accessibility" msgid="6643521607848547683">"Атайын мүмкүнчүлүктөр"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Түзмөктүн сактагычы"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"USB аркылуу мүчүлүштүктөрдү аныктоо"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Көмөкчү колдонмого активдүү кызматтарды фондо иштетүүгө уруксат берет."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофон жеткиликтүү"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон бөгөттөлгөн"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Кош экран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Кош экран күйүк"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> контентти эки түзмөктө тең көрсөтүүдө"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Түзмөк ысып кетти"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Телефонуңуз ысып кеткендиктен, Кош экран функциясы жеткиликсиз"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Өчүрүү"</string>
 </resources>
diff --git a/core/res/res/values-lo-watch/strings.xml b/core/res/res/values-lo-watch/strings.xml
index 1a42725..e83751a 100644
--- a/core/res/res/values-lo-watch/strings.xml
+++ b/core/res/res/values-lo-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"ແອັບ <xliff:g id="NUMBER_0">%1$d</xliff:g> ໃນ <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"ເຊັນເຊີ"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index e890cc6..ad7c77f 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ ແລະ ເປີເຊັນອອກຊິເຈນໃນເລືອດ, ໃນຂະນະທີ່ໃຊ້ແອັບຢູ່."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ໃນຂະນະທີ່ແອັບຢູ່ໃນພື້ນຫຼັງ"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນເຊັນເຊີຮ່າງກາຍ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຫົວໃຈ, ອຸນຫະພູມ ແລະ ເປີເຊັນອອກຊິເຈນໃນເລືອດ, ໃນຂະນະທີ່ແອັບຢູ່ໃນພື້ນຫຼັງ."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ເຂົ້າເຖິງຂໍ້ມູນອຸນຫະພູມຢູ່ຂໍ້ມືຈາກເຊັນເຊີຮ່າງກາຍໃນຂະນະທີ່ນຳໃຊ້ແອັບ."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນອຸນຫະພູມຢູ່ຂໍ້ມືຈາກເຊັນເຊີຮ່າງກາຍໃນຂະນະທີ່ນຳໃຊ້ແອັບ."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ເຂົ້າເຖິງຂໍ້ມູນອຸນຫະພູມຢູ່ຂໍ້ມືຈາກເຊັນເຊີຮ່າງກາຍໃນຂະນະທີ່ແອັບເຮັດວຽກໃນພື້ນຫຼັງ."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ອະນຸຍາດໃຫ້ແອັບເຂົ້າເຖິງຂໍ້ມູນອຸນຫະພູມຢູ່ຂໍ້ມືຈາກເຊັນເຊີຮ່າງກາຍໃນຂະນະທີ່ແອັບເຮັດວຽກໃນພື້ນຫຼັງ."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Read calendar events and details"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"This app can read all calendar events stored on your tablet and share or save your calendar data."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ແອັບນີ້ສາມາດອ່ານນັດໝາຍປະຕິທິນທັງໝົດທີ່ບັນທຶກໄວ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານ ແລະ ແບ່ງປັນ ຫຼື ບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"ກຳ​ລັງ​ເລີ່ມລະ​ບົບ​ Android …"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ກຳລັງເລີ່ມແທັບເລັດ…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ກຳລັງເລີ່ມອຸປະກອນ…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ການ​ປັບ​ບ່ອນ​ເກັບ​ຂໍ້​ມູນ​ໃຫ້​ເໝາະ​ສົມ."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"ກຳລັງສຳເລັດການອັບເດດລະບົບ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"ກຳລັງອັບເກຣດ<xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"ກຳລັງ​ປັບປຸງ​ປະສິດທິພາບ​ແອັບຯ​ທີ <xliff:g id="NUMBER_0">%1$d</xliff:g> ຈາກ​ທັງ​ໝົດ <xliff:g id="NUMBER_1">%2$d</xliff:g> ແອັບຯ."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"ກຳ​ລັງ​ກຽມ <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ກຳລັງເປີດແອັບຯ."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ກຳລັງສຳເລັດການເປີດລະບົບ."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"ເປີດໂໝດ PTP ຜ່ານ USB ແລ້ວ"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"ເປີດໂໝດ USB tethering ແລ້ວ"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"ເປີດໃຊ້ MIDI ຜ່ານ USB ແລ້ວ"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"ເຊື່ອມຕໍ່ອຸປະກອນເສີມ USB ແລ້ວ"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ກຳລັງສາກອຸປະກອນທີ່ເຊື່ອມຕໍ່. ແຕະເພື່ອເບິ່ງຕົວເລືອກເພີ່ມເຕີມ."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ແລ້ວໆ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ປິດປຸ່ມລັດ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ໃຊ້ປຸ່ມລັດ"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ການປີ້ນສີ"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ການແກ້ໄຂສີ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ໂໝດມືດຽວ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ຫຼຸດແສງເປັນພິເສດ"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"ການ​ເບິ່ງ​ເຕັມ​ໜ້າ​ຈໍ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ຫາກຕ້ອງການອອກ, ໃຫ້ຮູດຈາກທາງເທິງລົງມາທາງລຸ່ມ."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ໄດ້​ແລ້ວ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ໝຸນເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ອອກຈາກແບ່ງໜ້າຈໍເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string>
     <string name="done_label" msgid="7283767013231718521">"ແລ້ວໆ"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ໂຕໝຸນປັບຊົ່ວໂມງ"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"ໂຕໝຸນປັບນາທີ"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"​ບ່ອນ​ເຮັດ​ວຽກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ບ່ອນເຮັດວຽກທີ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ບ່ອນເຮັດວຽກທີ 3 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"ໂຄລນ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"​ຖາມ​ຫາ PIN ກ່ອນ​ຍົກ​ເລີກ​ການປັກ​ໝຸດ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"​ຖາມ​ຫາ​ຮູບ​ແບບ​ປົດ​ລັອກ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"​ຖາມ​ຫາ​ລະ​ຫັດ​ຜ່ານ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"ອະນຸຍາດຈາກເບື້ອງຫຼັງໃຫ້ແອັບຊ່ວຍເຫຼືອເລີ່ມໃຊ້ບໍລິການທີ່ເຮັດວຽກຢູ່ເບື້ອງໜ້າ."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"ໄມໂຄຣໂຟນພ້ອມໃຫ້ນຳໃຊ້"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"ໄມໂຄຣໂຟນຖືກບລັອກໄວ້"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ໜ້າຈໍຄູ່"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ເປີດໜ້າຈໍຄູ່ຢູ່"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ຈໍສະແດງຜົນທັງສອງເພື່ອສະແດງເນື້ອຫາ"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ອຸປະກອນຮ້ອນເກີນໄປ"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ໜ້າຈໍຄູ່ບໍ່ພ້ອມໃຫ້ນຳໃຊ້ເນື່ອງຈາກໂທລະສັບຂອງທ່ານຮ້ອນເກີນໄປ"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ປິດໄວ້"</string>
 </resources>
diff --git a/core/res/res/values-lt-watch/strings.xml b/core/res/res/values-lt-watch/strings.xml
index e8ec6bb..bf6e92a 100644
--- a/core/res/res/values-lt-watch/strings.xml
+++ b/core/res/res/values-lt-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g> programa iš <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Jutikliai"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 0c43543..8e28dff 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Leidžiama programai pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą ir deguonies procentinę dalį kraujyje, kai programa naudojama."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Prieiga prie kūno jutiklių duomenų, pvz., pulso dažnio, kai veikia fone"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Leidžiama programai pasiekti kūno jutiklių duomenis, pvz., pulso dažnį, temperatūrą ir deguonies procentinę dalį kraujyje, kai programa veikia fone."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Pasiekti kūno jutiklio riešo temperatūros duomenis, kol programa naudojama."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Leidžiama programai pasiekti kūno jutiklio riešo temperatūros duomenis, kol programa naudojama."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Pasiekti kūno jutiklio riešo temperatūros duomenis, kol programa veikia fone."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Leidžiama programai pasiekti kūno jutiklio riešo temperatūros duomenis, kol programa veikia fone."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Skaityti kalendoriaus įvykius arba išsamią informaciją"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ši programa gali nuskaityti visus planšetiniame kompiuteryje saugomus kalendoriaus įvykius ir bendrinti arba išsaugoti kalendoriaus duomenis."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ši programa gali nuskaityti visus „Android TV“ įrenginyje saugomus kalendoriaus įvykius ir bendrinti arba išsaugoti kalendoriaus duomenis."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Paleidžiama „Android“…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Planšetinis kompiuteris paleidžiamas…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Įrenginys paleidžiamas…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimizuojama saugykla."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Baigiama atnaujinti sistemą…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"„<xliff:g id="APPLICATION">%1$s</xliff:g>“ naujovinama..."</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimizuojama <xliff:g id="NUMBER_0">%1$d</xliff:g> progr. iš <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Ruošiama „<xliff:g id="APPNAME">%1$s</xliff:g>“."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Paleidžiamos programos."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Užbaigiamas paleidimas."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP režimas naudojant USB įjungtas"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB įrenginio kaip modemo naudojimas įjungtas"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI režimas naudojant USB įjungtas"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Prijungtas USB priedas"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Įkraunamas prijungtas įrenginys. Palieskite, jei reikia daugiau parinkčių."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Atlikta"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Išjungti spartųjį klavišą"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Naudoti spartųjį klavišą"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Spalvų inversija"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Spalvų taisymas"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Vienos rankos režimas"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Itin blanku"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Peržiūrima viso ekrano režimu"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Jei norite išeiti, perbraukite žemyn iš viršaus."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Supratau"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Pasukite, kad geriau matytumėte vaizdą"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Išeikite iš išskaidyto ekrano režimo, kad geriau matytumėte vaizdą"</string>
     <string name="done_label" msgid="7283767013231718521">"Atlikta"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Apskritas valandų šliaužiklis"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Apskritas minučių šliaužiklis"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-asis darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-iasis darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"„<xliff:g id="LABEL">%1$s</xliff:g>“ kopija"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Prašyti PIN kodo prieš atsegant"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Prašyti atrakinimo piešinio prieš atsegant"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Prašyti slaptažodžio prieš atsegant"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Leidžiama papildomai programai paleisti priekinio plano paslaugas fone."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofonas pasiekiamas"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonas užblokuotas"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvigubas ekranas"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Įjungtas dvigubas ekranas"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ naudoja abu ekranus turiniui rodyti"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Įrenginys per daug kaista"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvigubas ekranas nepasiekiamas, nes telefonas per daug kaista"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Išjungti"</string>
 </resources>
diff --git a/core/res/res/values-lv-watch/strings.xml b/core/res/res/values-lv-watch/strings.xml
index 61e9bfc..e22f614 100644
--- a/core/res/res/values-lv-watch/strings.xml
+++ b/core/res/res/values-lv-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. lietotne no <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensori"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 47233ff..b699549 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -240,7 +240,7 @@
     <string name="global_actions" product="tv" msgid="3871763739487450369">"Android TV opcijas"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"Tālruņa opcijas"</string>
     <string name="global_action_lock" msgid="6949357274257655383">"Ekrāna bloķētājs"</string>
-    <string name="global_action_power_off" msgid="4404936470711393203">"Izslēgt strāvas padevi"</string>
+    <string name="global_action_power_off" msgid="4404936470711393203">"Izslēgt"</string>
     <string name="global_action_power_options" msgid="1185286119330160073">"Barošana"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"Restartēt"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"Ārkārtas situācija"</string>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ļauj lietotnei piekļūt ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, temperatūrai un procentuālajam skābekļa daudzumam asinīs, kamēr lietotne tiek izmantota."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Piekļuve ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, fonā"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ļauj lietotnei piekļūt ķermeņa sensoru datiem, piemēram, sirdsdarbības ātrumam, temperatūrai un procentuālajam skābekļa daudzumam asinīs, kamēr lietotne darbojas fonā."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Piekļuve ķermeņa sensora noteiktajiem plaukstas locītavas temperatūras datiem, kamēr lietotne tiek izmantota."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Ļauj lietotnei piekļūt ķermeņa sensora noteiktajiem plaukstas locītavas temperatūras datiem, kamēr lietotne tiek izmantota."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Piekļuve ķermeņa sensora noteiktajiem plaukstas locītavas temperatūras datiem, kamēr lietotne darbojas fonā."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Ļauj lietotnei piekļūt ķermeņa sensora noteiktajiem plaukstas locītavas temperatūras datiem, kamēr lietotne darbojas fonā."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lasīt kalendāra pasākumus un informāciju"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Šī lietotne var lasīt visus kalendāra pasākumus, kas saglabāti planšetdatorā, un kopīgot vai saglabāt jūsu kalendāra datus."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Šī lietotne var lasīt visus kalendāra pasākumus, kas saglabāti Android TV ierīcē, un kopīgot vai saglabāt jūsu kalendāra datus."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Notiek Android palaišana…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Notiek planšetdatora palaišana…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Notiek ierīces palaišana…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Notiek krātuves optimizēšana."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Notiek sistēmas atjauninājuma pabeigšana"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Notiek lietotnes <xliff:g id="APPLICATION">%1$s</xliff:g> jaunināšana…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Tiek optimizēta <xliff:g id="NUMBER_0">%1$d</xliff:g>. lietotne no <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Notiek lietotnes <xliff:g id="APPNAME">%1$s</xliff:g> sagatavošana."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Notiek lietotņu palaišana."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Tiek pabeigta sāknēšana."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Ieslēgts PTP režīms, izmantojot USB savienojumu"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Ieslēgta USB piesaiste"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Ieslēgts MIDI režīms, izmantojot USB savienojumu"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB piederums ir pievienots"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Pieskarieties, lai skatītu citas opcijas."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Pievienotā ierīce tiek uzlādēta. Pieskarieties, lai skatītu citas opcijas."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gatavs"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Izslēgt saīsni"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Izmantot saīsni"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Krāsu inversija"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Krāsu korekcija"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Vienas rokas režīms"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Papildu aptumšošana"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Skatīšanās pilnekrāna režīmā"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Lai izietu, no augšdaļas velciet lejup."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Labi"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Lai uzlabotu skatu, pagrieziet ekrānu."</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lai uzlabotu skatu, izejiet no ekrāna sadalīšanas režīma."</string>
     <string name="done_label" msgid="7283767013231718521">"Gatavs"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Stundu apļveida slīdnis"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Minūšu apļveida slīdnis"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Darbā: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. darba profils: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. darba profils: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (klons)"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Prasīt PIN kodu pirms atspraušanas"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pirms atspraušanas pieprasīt atbloķēšanas kombināciju"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pirms atspraušanas pieprasīt paroli"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Ļauj palīglietotnei sākt priekšplāna pakalpojumus no fona."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofons ir pieejams."</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofons ir bloķēts."</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Divu ekrānu režīms"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Ieslēgts divu ekrānu režīms"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> satura rādīšanai izmanto abus displejus."</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Ierīce ir pārāk sakarsusi"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Divu ekrānu režīms nav pieejams, jo tālrunis sāk pārāk sakarst."</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Izslēgt"</string>
 </resources>
diff --git a/core/res/res/values-mk-watch/strings.xml b/core/res/res/values-mk-watch/strings.xml
index ac3cf09..7977f66 100644
--- a/core/res/res/values-mk-watch/strings.xml
+++ b/core/res/res/values-mk-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Апликац. <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Сензори"</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6c4bcb1..4524b39 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозволува апликацијата да пристапува до податоци од телесните сензори, како што се пулс, температура и процент на кислород во телото, додека се користи апликацијата."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Пристап до податоци од телесните сензори, како пулсот, додека работи во заднина"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозволува апликацијата да пристапува до податоци од телесните сензори, како што се пулс, температура и процент на кислород во телото, додека апликацијата работи во заднина."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Пристап до податоците за температура на зглобот од телесниот сензор додека се користи апликацијата."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Дозволува апликацијата да пристапува до податоците за температура на зглобот од телесниот сензор додека се користи апликацијата."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Пристап до податоците за температура на зглобот од телесниот сензор додека апликацијата работи во заднина."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Дозволува апликацијата да пристапува до податоците за температура на зглобот од телесниот сензор додека апликацијата работи во заднина."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Чита настани и детали од календарот"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Апликацијава може да ги чита сите настани во календарот складирани во вашиот таблет и да ги споделува или зачувува податоците од календарот."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Апликацијава може да ги чита сите настани во календарот складирани во вашиот уред Android TV и да ги споделува или зачувува податоците од календарот."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android стартува…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Таблетот стартува…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Уредот стартува…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Оптимизирање на складирањето."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Завршува системската надградба…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> се надградува…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Се оптимизира апликација <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Се подготвува <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Се стартуваат апликациите."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Подигањето завршува."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Вклучен е PTP преку USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Вклучен е интернет преку USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Вклучен е MIDI преку USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Поврзан е USB-додаток"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Допрете за повеќе опции."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Се полни поврзаниот уред. Допрете за повеќе опции."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Исклучи ја кратенката"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи кратенка"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија на бои"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Корекција на боите"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим со една рака"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнително затемнување"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Се прикажува на цел екран"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"За да излезете, повлечете одозгора надолу."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Сфатив"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ротирајте за подобар приказ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"За подобар приказ, излезете од поделениот екран"</string>
     <string name="done_label" msgid="7283767013231718521">"Готово"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Приказ на часови во кружно движење"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Приказ на минути во кружно движење"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Работа <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Втора деловна <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трета деловна <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонирајте го <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Побарај PIN пред откачување"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Дозволува придружна апликација да започне услуги во преден план од заднината."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофонот е достапен"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофонот е блокиран"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Двоен екран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Вклучен е двоен екран"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ги користи двата екрани за да прикажува содржини"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Уредот е претопол"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Двојниот екран е недостапен бидејќи вашиот телефон станува претопол"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Исклучи"</string>
 </resources>
diff --git a/core/res/res/values-ml-watch/strings.xml b/core/res/res/values-ml-watch/strings.xml
index f3e3a31..807f1a9 100644
--- a/core/res/res/values-ml-watch/strings.xml
+++ b/core/res/res/values-ml-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> അപ്ലിക്കേഷൻ."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"സെൻസറുകൾ"</string>
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 9652af5..51c1763 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ അതിനെ ഹൃദയമിടിപ്പ്, ശരീരോഷ്മാവ്, രക്തത്തിലെ ഓക്സിജൻ ശതമാനം എന്നിവ പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്‌സസ് ചെയ്യാൻ അനുവദിക്കുന്നു."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"പശ്ചാത്തലത്തിലുള്ളപ്പോൾ ഹൃദയമിടിപ്പ് പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്‌സസ് ചെയ്യുക"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ആപ്പ് പശ്ചാത്തലത്തിലുള്ളപ്പോൾ അതിനെ ഹൃദയമിടിപ്പ്, ശരീരോഷ്മാവ്, രക്തത്തിലെ ഓക്സിജൻ ശതമാനം എന്നിവ പോലുള്ള ബോഡി സെൻസർ ഡാറ്റ ആക്‌സസ് ചെയ്യാൻ അനുവദിക്കുന്നു."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"കണങ്കയ്യിലൂടെ അറിയാനാകുന്ന ശരീരോഷ്‌മാവ് സംബന്ധിച്ച ബോഡി സെൻസർ ഡാറ്റ, ആപ്പ് പ്രവർത്തിച്ചുകൊണ്ടിരിക്കുമ്പോൾ ആക്‌സസ് ചെയ്യുക."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"കണങ്കയ്യിലൂടെ അറിയാനാകുന്ന ശരീരോഷ്‌മാവ് സംബന്ധിച്ച ബോഡി സെൻസർ ഡാറ്റ, ആപ്പ് പ്രവർത്തിച്ചുകൊണ്ടിരിക്കുമ്പോൾ ആക്‌സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"കണങ്കയ്യിലൂടെ അറിയാനാകുന്ന ശരീരോഷ്‌മാവ് സംബന്ധിച്ച ബോഡി സെൻസർ ഡാറ്റ, ആപ്പ് പശ്ചാത്തലത്തിൽ പ്രവർത്തിക്കുമ്പോൾ ആക്‌സസ് ചെയ്യുക."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"കണങ്കയ്യിലൂടെ അറിയാനാകുന്ന ശരീരോഷ്‌മാവ് സംബന്ധിച്ച ബോഡി സെൻസർ ഡാറ്റ, ആപ്പ് പശ്ചാത്തലത്തിൽ പ്രവർത്തിക്കുമ്പോൾ ആക്‌സസ് ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"കലണ്ടർ ഇവന്റുകളും വിശദാംശങ്ങളും വായിക്കുക"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ഈ ആപ്പിന് നിങ്ങളുടെ ടാബ്‌ലെറ്റിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ വിവരങ്ങൾ പങ്കിടാനും അല്ലെങ്കിൽ സംരക്ഷിക്കാനും കഴിയും."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ഈ ആപ്പിന് നിങ്ങളുടെ Android TV-യിൽ സംഭരിച്ചിരിക്കുന്ന എല്ലാ കലണ്ടർ ഇവന്റുകളും വായിക്കാനും നിങ്ങളുടെ കലണ്ടർ ഡാറ്റ പങ്കിടാനോ സംരക്ഷിക്കാനോ സാധിക്കുകയും ചെയ്യും."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android ആരംഭിക്കുന്നു…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ടാബ്‌ലെറ്റ് ആരംഭിക്കുന്നു…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ഉപകരണം ആരംഭിക്കുന്നു…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"സ്റ്റോറേജ്  ഒപ്‌റ്റിമൈസ് ചെയ്യുന്നു."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"സിസ്‌റ്റം അപ്‌ഡേറ്റ് പൂർത്തിയാക്കുന്നു…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> അപ്ഗ്രേഡ് ചെയ്യുന്നു…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> അപ്ലിക്കേഷൻ ഓപ്റ്റിമൈസ് ചെയ്യുന്നു."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> തയ്യാറാക്കുന്നു."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"അപ്ലിക്കേഷനുകൾ ആരംഭിക്കുന്നു."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ബൂട്ട് ചെയ്യൽ പൂർത്തിയാകുന്നു."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB വഴിയുള്ള PTP ഓണാക്കി"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB ടെതറിംഗ് ഓണാക്കി"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB വഴിയുള്ള MIDI ഓണാക്കി"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ആക്‌സസറി കണക്റ്റ് ചെയ്തു"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"കണക്‌റ്റ് ചെയ്‌ത ഉപകരണം ചാർജ് ചെയ്യുന്നു. കൂടുതൽ ഓപ്ഷനുകൾക്ക് ടാപ്പ് ചെയ്യുക."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"പൂർത്തിയാക്കി"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"കുറുക്കുവഴി ‌ഓഫാക്കുക"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"കുറുക്കുവഴി ഉപയോഗിക്കുക"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"നിറം ശരിയാക്കൽ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ഒറ്റക്കൈ മോഡ്"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"കൂടുതൽ ഡിം ചെയ്യൽ"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"പൂർണ്ണ സ്‌ക്രീനിൽ കാണുന്നു"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"അവസാനിപ്പിക്കാൻ, മുകളിൽ നിന്ന് താഴോട്ട് സ്വൈപ്പ് ചെയ്യുക."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"മനസ്സിലായി"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"മികച്ച കാഴ്‌ചയ്‌ക്കായി റൊട്ടേറ്റ് ചെയ്യുക"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"മികച്ച കാഴ്‌ചയ്‌ക്കായി സ്‌ക്രീൻ വിഭജന മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string>
     <string name="done_label" msgid="7283767013231718521">"പൂർത്തിയാക്കി"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ചാക്രികമായി മണിക്കൂറുകൾ ദൃശ്യമാകുന്ന സ്ലൈഡർ"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"ചാക്രികമായി മിനിറ്റുകൾ ദൃശ്യമാകുന്ന സ്ലൈഡർ"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ഔദ്യോഗികം <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"രണ്ടാമത്തെ ഔദ്യോഗിക <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"മൂന്നാമത്തെ ഔദ്യോഗിക <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"ക്ലോൺ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ചെയ്യുംമുമ്പ് പിൻ ചോദിക്കൂ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"അൺപിന്നിനുമുമ്പ് അൺലോക്ക് പാറ്റേൺ ആവശ്യപ്പെടൂ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"അൺപിന്നിനുമുമ്പ് പാസ്‌വേഡ് ആവശ്യപ്പെടൂ"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"പശ്ചാത്തലത്തിൽ നിന്ന് ഫോർഗ്രൗണ്ട് സേവനങ്ങൾ ആരംഭിക്കാൻ സഹകാരി ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"മൈക്രോഫോൺ ലഭ്യമാണ്"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"മൈക്രോഫോൺ ബ്ലോക്ക് ചെയ്‌തു"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ഡ്യുവൽ സ്ക്രീൻ"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ഡ്യുവൽ സ്ക്രീൻ ഓണാണ്"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"ഉള്ളടക്കം കാണിക്കാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> രണ്ട് ഡിസ്പ്ലേകളും ഉപയോഗിക്കുന്നു"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ഉപകരണത്തിന് ചൂട് കൂടുതലാണ്"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"നിങ്ങളുടെ ഫോൺ വളരെയധികം ചൂടാകുന്നതിനാൽ ഡ്യുവൽ സ്‌ക്രീൻ ലഭ്യമല്ല"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ഓഫാക്കുക"</string>
 </resources>
diff --git a/core/res/res/values-mn-watch/strings.xml b/core/res/res/values-mn-watch/strings.xml
index d46592e..b00580f 100644
--- a/core/res/res/values-mn-watch/strings.xml
+++ b/core/res/res/values-mn-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>-ны <xliff:g id="NUMBER_1">%2$d</xliff:g> апп."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Мэдрэгч"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 5f9c268..181fa72 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -299,7 +299,7 @@
     <string name="permgrouplab_location" msgid="1858277002233964394">"Байршил"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"энэ төхөөрөмжийн байршилд хандалт хийх"</string>
     <string name="permgrouplab_calendar" msgid="6426860926123033230">"Календарь"</string>
-    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Календарь руу хандах"</string>
+    <string name="permgroupdesc_calendar" msgid="6762751063361489379">"Календарьд хандах"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Мессеж"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS мессежийг илгээх, харах"</string>
     <string name="permgrouplab_storage" msgid="17339216290379241">"Файлууд"</string>
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Аппыг ашиглаж байх үедээ зүрхний хэм, температур болон цусны хүчилтөрөгчийн хувь зэрэг биеийн мэдрэгчийн өгөгдөлд хандах боломжтой."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Ард нь байх үед зүрхний хэм зэрэг биеийн мэдрэгчийн өгөгдөлд хандаарай"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Апп ард нь байх үед зүрхний хэм, температур, цусны хүчилтөрөгчийн хувь зэрэг биеийн мэдрэгчийн өгөгдөлд хандах боломжтой."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Аппыг ашиглаж байх үед биеийн мэдрэгчийн бугуйн температурын өгөгдөлд хандана."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Аппыг ашиглаж байх үед биеийн мэдрэгчийн бугуйн температурын өгөгдөлд хандахыг аппад зөвшөөрнө."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Аппыг ард байх үед биеийн мэдрэгчийн бугуйн температурын өгөгдөлд хандана."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Аппыг ард байх үед биеийн мэдрэгчийн бугуйн температурын өгөгдөлд хандахыг аппад зөвшөөрнө."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Календарийн арга хэмжээ, дэлгэрэнгүйг унших"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Энэ апп таны таблетад хадгалсан календарийн бүх арга хэмжээг унших, календарийн өгөгдлийг хуваалцах, хадгалах боломжтой."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Энэ апп таны Android TV төхөөрөмжид хадгалсан календарийн бүх арга хэмжээг унших болон таны календарийн өгөгдлийг хуваалцах эсвэл хадгалах боломжтой."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Андройд эхэлж байна..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Таблетыг эхлүүлж байна…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Төхөөрөмжийг эхлүүлж байна…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Хадгалалтыг сайжруулж байна."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Системийн шинэчлэлтийг дуусгаж байна…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г сайжруулж байна…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g>-н <xliff:g id="NUMBER_0">%1$d</xliff:g> апп-г тохируулж байна."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Бэлдэж байна <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Апп-г эхлүүлж байна."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Эхлэлийг дуусгаж байна."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB-р PTP горимд асаасан"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB модем болгохыг асаасан"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB-р MIDI горимд асаасан"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB нэмэлт хэрэгслийг холбосон"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Бусад сонголтыг харахын тулд товшино уу."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Холбосон төхөөрөмжийг цэнэглэж байна. Бусад сонголтыг харах бол товшино уу."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Болсон"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Товчлолыг унтраах"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Товчлол ашиглах"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Өнгө хувиргалт"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Өнгөний засвар"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Нэг гарын горим"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Хэт бүүдгэр"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Бүтэн дэлгэцээр үзэж байна"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Гарахаар бол дээрээс нь доош нь чирнэ үү."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ойлголоо"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Харагдах байдлыг сайжруулах бол эргүүлнэ үү"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Харагдах байдлыг сайжруулах бол дэлгэцийг хуваах горимоос гарна уу"</string>
     <string name="done_label" msgid="7283767013231718521">"Дууссан"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Цаг гүйлгэгч"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Минут гүйлгэгч"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Ажлын <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 дахь ажил <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 дахь ажил <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клон <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бэхэлснийг болиулахаасаа өмнө ПИН асуух"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бэхэлснийг болиулахаас өмнө түгжээ тайлах хээ асуух"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Дэмжигч аппад нүүрэн талын үйлчилгээнүүдийг ардаас эхлүүлэхийг зөвшөөрнө."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофоныг ашиглах боломжгүй байна"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофоныг блоклосон байна"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Хоёр дэлгэц"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Хоёр дэлгэц асаалттай байна"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> контент харуулахын тулд хоёр дэлгэцийг хоёуланг нь ашиглаж байна"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Төхөөрөмж хэт халуун байна"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Таны утас хэт халж байгаа тул Хоёр дэлгэц боломжгүй байна"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Унтраах"</string>
 </resources>
diff --git a/core/res/res/values-mr-watch/strings.xml b/core/res/res/values-mr-watch/strings.xml
index 311a720..0bc7ad6 100644
--- a/core/res/res/values-mr-watch/strings.xml
+++ b/core/res/res/values-mr-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अ‍ॅप"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"सेन्सर"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index e6dd0bb..923dcde 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ॲप वापरात असताना हार्ट रेट, तापमान आणि रक्तातील ऑक्सिजनची टक्केवारी यांसारखा शरीर सेन्सर डेटा अ‍ॅक्सेस करण्याची अनुमती ॲपला देते."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"बॅकग्राउंडमध्ये असताना, हार्ट रेट यासारखा शरीर सेन्सर डेटा अ‍ॅक्सेस करा"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ॲप हे बॅकग्राउंडमध्ये असताना हार्ट रेट, तापमान आणि रक्तातील ऑक्सिजनची टक्केवारी यांसारखा शरीर सेन्सर डेटा अ‍ॅक्सेस करण्याची अनुमती ॲपला द्या."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ॲप वापरात असताना, शरीर सेन्सर मनगट तापमान डेटा अ‍ॅक्सेस करा."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ॲप वापरात असताना, शरीर सेन्सर मनगट तापमान डेटा अ‍ॅक्सेस करण्याची ॲपला अनुमती देते."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ॲप बॅकग्राउंडमध्ये असताना, शरीर सेन्सर मनगट तापमान डेटा अ‍ॅक्सेस करा."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ॲप बॅकग्राउंडमध्ये असताना, शरीर सेन्सर मनगट तापमान डेटा अ‍ॅक्सेस करण्याची ॲपला अनुमती देते."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"हा अ‍ॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"हे अ‍ॅप तुमच्या Android TV डिव्हाइसवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android सुरू करत आहे…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"टॅबलेट सुरू होत आहे…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"डिव्‍हाइस सुरू होत आहे…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"संचयन ऑप्टिमाइझ करत आहे."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"सिस्‍टम अपडेट संपत आहे…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> श्रेणीसुधारित करत आहे…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अ‍ॅप ऑप्टिमाइझ करत आहे."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> तयार करत आहे."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"अ‍ॅप्स सुरू करत आहे."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बूट समाप्त होत आहे."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB मार्फत PTP सुरू केले"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB टेदरिंग सुरू केले"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB मार्फत MIDI सुरू केले"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB अ‍ॅक्सेसरी कनेक्ट केली आहे"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"अधिक पर्यायांसाठी टॅप करा."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"चार्जर लावलेले डिव्हाइस. आणखी पर्यायांसाठी टॅप करा"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"पूर्ण झाले"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"शॉर्टकट बंद करा"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट वापरा"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"रंगांची उलटापालट"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"रंग सुधारणा"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एकहाती मोड"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"आणखी डिम"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"पूर्ण स्क्रीनवर पाहत आहात"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"बाहेर पडण्यासाठी, वरून खाली स्वाइप करा."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"समजले"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"अधिक चांगल्या दृश्यासाठी फिरवा"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"अधिक चांगल्या दृश्यासाठी स्प्लिट स्क्रीनमधून बाहेर पडा"</string>
     <string name="done_label" msgid="7283767013231718521">"पूर्ण झाले"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"तास परिपत्रक स्लायडर"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"मिनिटे परिपत्रक स्लायडर"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> क्लोन केलेले"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करण्‍यापूर्वी पिन विचारा"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करण्‍यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करण्‍यापूर्वी संकेतशब्दासाठी विचारा"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"सहयोगी अ‍ॅपला बॅकग्राउंडमधून फोरग्राउंड सेवा सुरू करण्याची अनुमती देते."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"मायक्रोफोन उपलब्ध आहे"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"मायक्रोफोन ब्लॉक केलेला आहे"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ड्युअल स्क्रीन"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ड्युअल स्क्रीन सुरू आहे"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"आशय दाखवण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> दोन्ही डिस्प्ले वापरत आहे"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"डिव्हाइस खूप गरम आहे"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"तुमचा फोन खूप गरम होत असल्यामुळे ड्युअल स्क्रीन उपलब्ध नाही"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"बंद करा"</string>
 </resources>
diff --git a/core/res/res/values-ms-watch/strings.xml b/core/res/res/values-ms-watch/strings.xml
index 10379c9..cadbbbd 100644
--- a/core/res/res/values-ms-watch/strings.xml
+++ b/core/res/res/values-ms-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Penderia"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 364c325..cc0e947 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl digunakan."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Akses data penderia tubuh, seperti kadar denyut jantung, semasa di latar"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Membenarkan apl mengakses data penderia tubuh, seperti kadar denyut jantung, suhu dan peratusan oksigen darah, semasa apl berjalan di latar belakang."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Akses data suhu pergelangan tangan penderia tubuh semasa apl digunakan."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Membenarkan apl mengakses data suhu pergelangan tangan penderia tubuh semasa apl digunakan."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Akses data suhu pergelangan tangan penderia tubuh semasa apl berjalan di latar belakang."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Membenarkan apl mengakses data suhu pergelangan tangan penderia tubuh semasa apl berjalan di latar belakang."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Baca acara dan butiran kalendar"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Apl ini boleh membaca semua acara kalendar yang disimpan pada tablet anda dan berkongsi atau menyimpan data kalendar anda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Apl ini boleh membaca semua acara kalendar yang disimpan pada peranti Android TV anda dan berkongsi atau menyimpan data kalendar anda."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android sedang dimulakan…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet sedang dimulakan…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Peranti sedang dimulakan…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Mengoptimumkan storan."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Menyelesaikan kemas kini sistem…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> sedang ditingkatkan…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Mengoptimumkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Menyediakan <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Memulakan apl."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"But akhir."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP melalui USB dihidupkan"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Penambatan USB dihidupkan"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI melalui USB dihidupkan"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Aksesori USB disambungkan"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Ketik untuk mendapatkan lagi pilihan."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Mengecas peranti tersambung. Ketik untuk mendapatkan lagi pilihan."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Selesai"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Matikan pintasan"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Pembetulan warna"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mod sebelah tangan"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Amat malap"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Melihat skrin penuh"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Untuk keluar, leret dari atas ke bawah."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Faham"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Putar untuk mendapatkan paparan yang lebih baik"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Keluar daripada skrin pisah untuk mendapatkan paparan yang lebih baik"</string>
     <string name="done_label" msgid="7283767013231718521">"Selesai"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Penggelangsar bulatan jam"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Penggelangsar bulatan minit"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Kerja <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> kerja ke-2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> kerja ke-3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> Klon"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Minta PIN sebelum menyahsemat"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Minta corak buka kunci sebelum menyahsemat"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Minta kata laluan sebelum menyahsemat"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Benarkan apl rakan memulakan perkhidmatan latar depan dari latar."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon tersedia"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon disekat"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dwiskrin"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dwiskrin dihidupkan"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> menggunakan kedua-dua paparan untuk menunjukkan kandungan"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Peranti terlalu panas"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dwiskrin tidak tersedia kerana telefon anda terlalu panas"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Matikan"</string>
 </resources>
diff --git a/core/res/res/values-my-watch/strings.xml b/core/res/res/values-my-watch/strings.xml
index 9270741..c471b3831 100644
--- a/core/res/res/values-my-watch/strings.xml
+++ b/core/res/res/values-my-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g>၏  <xliff:g id="NUMBER_0">%1$d</xliff:g> ‌အသေးစားဆော့ဝဲ"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"အာရုံခံကိရိယာများ"</string>
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 0a8990c..1018e1e9 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"အက်ပ်သုံးစဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"နောက်ခံတွင်ဖွင့်စဉ် နှလုံးခုန်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာ သုံးခြင်း"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"နောက်ခံတွင်အက်ပ်ဖွင့်စဉ် နှလုံးခုန်နှုန်း၊ အပူချိန်၊ သွေးတွင်း အောက်ဆီဂျင်ရာခိုင်နှုန်းကဲ့သို့ ခန္ဓာကိုယ်အာရုံခံစနစ် ဒေတာများသုံးရန် အက်ပ်ကိုခွင့်ပြုသည်။"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"အက်ပ်သုံးနေစဉ် ခန္ဓာကိုယ် အာရုံခံကိရိယာမှ လက်ကောက်ဝတ်အပူချိန်ဒေတာကို သုံးပါ။"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"အက်ပ်သုံးနေစဉ် ခန္ဓာကိုယ် အာရုံခံကိရိယာမှ လက်ကောက်ဝတ်အပူချိန်ဒေတာသုံးရန် အက်ပ်ကို ခွင့်ပြုသည်။"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"နောက်ခံတွင် အက်ပ်ဖွင့်ထားစဉ် ခန္ဓာကိုယ် အာရုံခံကိရိယာမှ လက်ကောက်ဝတ်အပူချိန်ဒေတာကို သုံးပါ။"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"နောက်ခံတွင် အက်ပ်ဖွင့်ထားစဉ် ခန္ဓာကိုယ် အာရုံခံကိရိယာမှ လက်ကောက်ဝတ်အပူချိန်ဒေတာသုံးရန် အက်ပ်ကို ခွင့်ပြုသည်။"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"ပြက္ခဒိန်ဖြစ်ရပ်များနှင့် အသေးစိတ်အချက်အလက်များကို ဖတ်ခြင်း"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ဤအက်ပ်သည် သင့်တက်ဘလက်တွင် သိမ်းဆည်းထားသည့် ပြက္ခဒိန်ဖြစ်ရပ်များကို ကြည့်ရှုနိုင်ပြီး သင့်ပြက္ခဒိန်ဒေတာများကို မျှဝေခြင်းနှင့် သိမ်းဆည်းခြင်းတို့ ပြုလုပ်နိုင်ပါသည်။"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ဤအက်ပ်သည် သင့် Android TV စက်ပစ္စည်းတွင် သိမ်းဆည်းထားသည့် ပြက္ခဒိန်ဖြစ်ရပ်များအားလုံးကို ဖတ်နိုင်ပြီး သင်၏ ပြက္ခဒိန်ဒေတာများကို မျှဝေခြင်း သို့မဟုတ် သိမ်းဆည်းခြင်းတို့ ပြုလုပ်နိုင်သည်။"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android စတင်နေ…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"တက်ဘလက် စတင်နေသည်…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"စက်ပစ္စည်း စတင်နေသည်…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"သိုလှောင်မှုအား ပြုပြင်ခြင်း။"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"စနစ်အပ်ဒိတ်ကို အပြီးသတ်နေသည်…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> ကို အဆင့်မြှင့်တင်နေပါသည်…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g> ထဲက အက်ပ်<xliff:g id="NUMBER_1">%2$d</xliff:g>ကို ဆီလျော်အောင် လုပ်နေ"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> အားပြင်ဆင်နေသည်။"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"အက်ပ်များကို စတင်နေ"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"လုပ်ငန်းစနစ်ထည့်သွင်း၍ ပြန်လည်စတင်ရန် ပြီးပါပြီ"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB မှတစ်ဆင့် PTP ကို အသုံးပြုရန် ဖွင့်ထားသည်"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB မှတစ်ဆင့် မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးရန် ဖွင့်ထားသည်"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB မှတစ်ဆင့် MIDI ကို အသုံးပြုရန် ဖွင့်ထားသည်"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB တွဲဖက်ပစ္စည်းကို ချိတ်ဆက်ထားသည်"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ချိတ်ဆက်ထားသည့် စက်ပစ္စည်းကို အားသွင်းနေသည်။ နောက်ထပ်ရွေးချယ်စရာများအတွက် တို့ပါ။"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ပြီးပြီ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ဖြတ်လမ်းလင့်ခ်ကို ပိတ်ရန်"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ဖြတ်လမ်းလင့်ခ်ကို သုံးရန်"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"အရောင် ပြောင်းပြန်လှန်ခြင်း"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"အရောင် အမှန်ပြင်ခြင်း"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"လက်တစ်ဖက်သုံးမုဒ်"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ပိုမှိန်ခြင်း"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"မျက်နှာပြင်အပြည့် ကြည့်နေသည်"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ထွက်ရန် အပေါ်မှ အောက်သို့ ဆွဲချပါ။"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ရပါပြီ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ပိုကောင်းသောမြင်ကွင်းအတွက် လှည့်ပါ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ပိုကောင်းသောမြင်ကွင်းအတွက် မျက်နှာပြင် ခွဲ၍ပြသခြင်းမှ ထွက်ပါ"</string>
     <string name="done_label" msgid="7283767013231718521">"ပြီးပါပြီ"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"နာရီရွေးချက်စရာ"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"မိနစ်လှည့်သော ရွေ့လျားတန်"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"အလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ဒုတိယအလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"တတိယအလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ပုံတူပွား"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ပင်မဖြုတ်မီမှာ PIN ကို မေးကြည့်ရန်"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ပင်မဖြုတ်မီမှာ သော့ဖွင့် ရေးဆွဲမှုပုံစံကို မေးကြည့်ရန်"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"နောက်ခံမှနေ၍ မျက်နှာစာဝန်ဆောင်မှုများ စတင်ရန် တွဲဖက် အက်ပ်ကို ခွင့်ပြုသည်။"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"မိုက်ခရိုဖုန်း သုံးနိုင်သည်"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"မိုက်ခရိုဖုန်း ပိတ်ထားသည်"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"စခရင်နှစ်ခု"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"‘စခရင်နှစ်ခု’ ဖွင့်ထားသည်"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အကြောင်းအရာကို ဖန်သားပြင်နှစ်ခုစလုံးတွင် ပြနေသည်"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"စက်ပစ္စည်း အလွန်ပူနေသည်"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"သင့်ဖုန်း အလွန်ပူနေသဖြင့် ‘စခရင်နှစ်ခု’ သုံး၍မရပါ"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ပိတ်ရန်"</string>
 </resources>
diff --git a/core/res/res/values-nb-watch/strings.xml b/core/res/res/values-nb-watch/strings.xml
index d126fe0..fa296b6 100644
--- a/core/res/res/values-nb-watch/strings.xml
+++ b/core/res/res/values-nb-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensorer"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d646c76..35296a9 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gir appen tilgang til data fra kroppssensorer, for eksempel puls, temperatur og oksygenmetning i blodet, når den er i bruk."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Tilgang til data fra kroppssensorer, for eksempel puls, når den er i bakgrunnen"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gir appen tilgang til data fra kroppssensorer, for eksempel puls, temperatur og oksygenmetning i blodet, når den er i bakgrunnen."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Tilgang til data fra kroppssensorer for håndleddstemperatur mens appen er i bruk."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Gir appen tilgang til data fra kroppssensorer for håndleddstemperatur mens appen er i bruk."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Tilgang til data fra kroppssensorer for håndleddstemperatur mens appen er i bakgrunnen."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Gir appen tilgang til data fra kroppssensorer for håndleddstemperatur mens appen er i bakgrunnen."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Les kalenderaktivitet og detaljer"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Denne appen kan lese all kalenderaktivitet som er lagret på nettbrettet ditt, og dele eller lagre kalenderdataene."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Denne appen kan lese all kalenderaktivitet som er lagret på Android TV-enheten din, og dele eller lagre kalenderdataene."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android starter …"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Nettbrettet starter …"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Enheten starter …"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimaliser lagring."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Fullfører systemoppdateringen …"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> oppgraderes …"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimaliserer app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Forbereder <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Starter apper."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Ferdigstiller oppstart."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB er slått på"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-internettdeling er slått på"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB er slått på"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-tilbehør er tilkoblet"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Trykk for å få flere alternativ."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Den tilkoblede enheten lades. Trykk for å se flere alternativer."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Ferdig"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Slå av snarveien"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Fargekorrigering"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndsmodus"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dimmet"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visning i fullskjerm"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Sveip ned fra toppen for å avslutte."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Skjønner"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Roter for å få en bedre visning"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Avslutt delt skjerm for å få en bedre visning"</string>
     <string name="done_label" msgid="7283767013231718521">"Ferdig"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Sirkulær glidebryter for timer"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Sirkulær glidebryter for minutter"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Jobb-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Andre <xliff:g id="LABEL">%1$s</xliff:g> for jobben"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Tredje <xliff:g id="LABEL">%1$s</xliff:g> for jobben"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Krev PIN-kode for å løsne app"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Krev opplåsingsmønster for å løsne apper"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Krev passord for å løsne apper"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Lar en følgeapp starte forgrunnstjenester fra bakgrunnen."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofonen er tilgjengelig"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonen er blokkert"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dobbel skjerm"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dobbel skjerm er på"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruker begge skjermene til å vise innhold"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Enheten er for varm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dobbel skjerm er ikke tilgjengelig fordi telefonen begynner å bli for varm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Slå av"</string>
 </resources>
diff --git a/core/res/res/values-ne-watch/strings.xml b/core/res/res/values-ne-watch/strings.xml
index 54002fc9ea..8c0df82 100644
--- a/core/res/res/values-ne-watch/strings.xml
+++ b/core/res/res/values-ne-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g> को <xliff:g id="NUMBER_0">%1$d</xliff:g> अनुप्रयोग।"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"सेन्सरहरू"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index d300beb..e1de195 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"यसले यो एप प्रयोग गरिँदै गरेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ब्याकग्राउन्डमा चलेका बेला हृदयको गति जस्ता बडी सेन्सरसम्बन्धी डेटा हेरियोस् र प्रयोग गरियोस्"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"यसले यो एप ब्याकग्राउन्डमा चलेका बेला यसलाई हृदयको गति, शरीरको तापक्रम तथा रगतमा रहेको अक्सिजनको प्रतिशत जस्ता बडी सेन्सरसम्बन्धी डेटा हेर्ने तथा प्रयोग गर्ने अनुमति दिन्छ।"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"यो एप प्रयोग भइरहेका बेला बडी सेन्सरले रेकर्ड गरेको नाडीको तापक्रमसम्बन्धी डेटा प्रयोग गर्ने अनुमति।"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"यसले यो एप प्रयोग भइरहेका बेला यो एपलाई बडी सेन्सरले रेकर्ड गरेको नाडीको तापक्रमसम्बन्धी डेटा प्रयोग गर्ने अनुमति दिन्छ।"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"यो एप ब्याकग्राउन्डमा चलिरहेका बेला बडी सेन्सरले रेकर्ड गरेको नाडीको तापक्रमसम्बन्धी डेटा प्रयोग गर्ने अनुमति।"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"यसले यो एप ब्याकग्राउन्डमा चलिरहेका बेला यो एपलाई बडी सेन्सरले रेकर्ड गरेको नाडीको तापक्रमसम्बन्धी डेटा प्रयोग गर्ने अनुमति दिन्छ।"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"पात्रोका कार्यक्रम र विवरणहरू पढ्ने"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"यस एपले तपाईंको ट्याब्लेटमा भण्डारण गरिएका पात्रो सम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"यस एपले तपाईंको Android टिभी डिभाइसमा भण्डारण गरिएका पात्रोसम्बन्धी सबै कार्यक्रमहरू पढ्न र तपाईंको पात्रोको डेटा आदान प्रदान वा सुरक्षित गर्न सक्छ।"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android शुरू हुँदैछ..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ट्याब्लेट सुरु हुँदै छ…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"यन्त्र सुरु हुँदै छ…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"भण्डारण आफू अनुकूल गर्दै।"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"सिस्टम अपडेट सम्पन्न गरिँदै छ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> को स्तरवृद्धि हुँदैछ…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"एप अनुकुल हुँदै <xliff:g id="NUMBER_0">%1$d</xliff:g> को <xliff:g id="NUMBER_1">%2$d</xliff:g>।"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> तयारी गर्दै।"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"सुरुवात एपहरू।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"बुट पुरा हुँदै।"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB मार्फत PTP सेवा सक्रिय गरियो"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB टेदरिङ सेवा सक्रिय गरियो"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB मार्फत MIDI सेवा सक्रिय गरियो"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB सहायक उपकरण जडान गरियो"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"कनेक्ट गरिएको डिभाइस चार्ज गर्दै। थप विकल्पहरूका लागि ट्याप गर्नुहोस्।"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"सम्पन्न भयो"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"सर्टकटलाई निष्क्रिय पार्नुहोस्"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"कलर इन्भर्सन"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"रङ सच्याउने सुविधा"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एक हाते मोड"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"अझै मधुरो"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"पूरा पर्दा हेर्दै"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"बाहिर निस्कन, माथिबाट तल स्वाइप गर्नुहोस्।"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"बुझेँ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"अझ राम्रो दृश्य हेर्न चाहनुहुन्छ भने रोटेट गर्नुहोस्"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"अझ राम्रो दृश्य हेर्न चाहनुहुन्छ भने \"स्प्लिट स्क्रिन\" बाट बाहिरिनुहोस्"</string>
     <string name="done_label" msgid="7283767013231718521">"भयो"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"घन्टा गोलाकार स्लाइडर"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"मिनेट गोलाकार स्लाइडर"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"कार्यालयको दोस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"कार्यालयको तेस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> क्लोन गर्नुहोस्"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन गर्नुअघि PIN मागियोस्"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन गर्नअघि अनलक प्याटर्न माग्नुहोस्"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"यसले सहयोगी एपलाई ब्याकग्राउन्डमा फोरग्राउन्ड सेवाहरू चलाउने अनुमति दिन्छ।"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"माइक्रोफोन अनम्युट गरिएको छ"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"माइक्रोफोन म्युट गरिएको छ"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"डुअल स्क्रिन"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"डुअल स्क्रिन अन छ"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले सामग्री देखाउन दुई वटै डिस्प्ले प्रयोग गरिरहेको छ"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"डिभाइस ज्यादै तातेको छ"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"तपाईंको फोन ज्यादै तातिरहेको हुनाले डुअल स्क्रिन उपलब्ध छैन"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"अफ गर्नुहोस्"</string>
 </resources>
diff --git a/core/res/res/values-nl-watch/strings.xml b/core/res/res/values-nl-watch/strings.xml
index 0222164..3f693a9 100644
--- a/core/res/res/values-nl-watch/strings.xml
+++ b/core/res/res/values-nl-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensoren"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 9b6b896..6c6c0b4 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"De app heeft toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app wordt gebruikt."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Toegang tot gegevens van lichaamssensoren, zoals hartslag, op de achtergrond"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"De app heeft toegang tot gegevens van lichaamssensoren, zoals hartslag, temperatuur en zuurstofpercentage in het bloed, terwijl de app op de achtergrond wordt uitgevoerd."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Toegang tot gegevens van de lichaamssensor voor polstemperatuur terwijl de app in gebruik is."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Geeft de app toegang tot gegevens van de lichaamssensor voor polstemperatuur terwijl de app in gebruik is."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Toegang tot gegevens van de lichaamssensor voor polstemperatuur terwijl de app op de achtergrond wordt uitgevoerd."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Geeft de app toegang tot gegevens van de lichaamssensor voor polstemperatuur terwijl de app op de achtergrond wordt uitgevoerd."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Agenda-afspraken en -gegevens lezen"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Deze app kan alle agenda-afspraken lezen die zijn opgeslagen op je tablet en je agendagegevens delen of opslaan."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Deze app kan alle agenda-afspraken lezen die zijn opgeslagen op je Android TV-apparaat en je agendagegevens delen of opslaan."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android wordt gestart…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet wordt gestart…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Apparaat wordt gestart…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Opslagruimte wordt geoptimaliseerd."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Systeemupdate voltooien…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> upgraden…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> van <xliff:g id="NUMBER_1">%2$d</xliff:g> optimaliseren."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> voorbereiden."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps starten."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Opstarten afronden."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB staat aan"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB-tethering staat aan"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB staat aan"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-accessoire verbonden"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tik voor meer opties."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Verbonden apparaat wordt opgeladen. Tik voor meer opties."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Klaar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Sneltoets uitzetten"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Kleurcorrectie"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met 1 hand"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dimmen"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Volledig scherm wordt getoond"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Swipe omlaag vanaf de bovenkant van het scherm om af te sluiten."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ik snap het"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Draai voor een betere weergave"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Sluit het gesplitste scherm voor een betere weergave"</string>
     <string name="done_label" msgid="7283767013231718521">"Klaar"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Ronde schuifregelaar voor uren"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Ronde schuifregelaar voor minuten"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Werk <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g>, werk"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g>, werk"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloon van <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vraag pin voor losmaken"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vraag om ontgrendelingspatroon voor losmaken"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vraag wachtwoord voor losmaken"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Hiermee kan een bijbehorende app services op de voorgrond vanuit de achtergrond starten."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microfoon is beschikbaar"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfoon is geblokkeerd"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dubbel scherm"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dubbel scherm is aan"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt beide schermen om content te tonen"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Het apparaat is te warm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dubbel scherm is niet beschikbaar, omdat je telefoon te warm wordt"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Uitzetten"</string>
 </resources>
diff --git a/core/res/res/values-or-watch/strings.xml b/core/res/res/values-or-watch/strings.xml
index 75de26d..8b11631 100644
--- a/core/res/res/values-or-watch/strings.xml
+++ b/core/res/res/values-or-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଆପ୍‍ରୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଟି।"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"ସେନ୍ସର୍‍"</string>
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index c2560da..0cbe22e 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ଏହି ଆପଟି ବ୍ୟବହାରରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ଏବଂ ତାପମାତ୍ରା, ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ଏହି ଆପଟି ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ହାର୍ଟ ରେଟ, ତାପମାତ୍ରା ଏବଂ ରକ୍ତରେ ଅମ୍ଳଜାନ ଶତକଡ଼ା ପରି ବଡି ସେନ୍ସର ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ଆପଟି ବ୍ୟବହାରରେ ଥିବା ସମୟରେ ବଡି ସେନ୍ସର ରିଷ୍ଟ ତାପମାତ୍ରା ଡାଟାକୁ ଆକ୍ସେସ କରନ୍ତୁ।"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ଆପଟି ବ୍ୟବହାରରେ ଥିବା ସମୟରେ, ବଡି ସେନ୍ସର ରିଷ୍ଟ ତାପମାତ୍ରା ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ଆପଟି ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ ବଡି ସେନ୍ସର ରିଷ୍ଟ ତାପମାତ୍ରା ଡାଟାକୁ ଆକ୍ସେସ କରନ୍ତୁ।"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ଆପଟି ପୃଷ୍ଠପଟରେ ଥିବା ସମୟରେ, ବଡି ସେନ୍ସର ରିଷ୍ଟ ତାପମାତ୍ରା ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"କ୍ୟାଲେଣ୍ଡର୍‍ ଇଭେଣ୍ଟ ଏବଂ ବିବରଣୀ ପଢ଼େ"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ଆପଣଙ୍କ ଟାବଲେଟ୍‌ରେ ଷ୍ଟୋର୍‍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ଏହି ଆପ୍‍ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍‍ କରିପାରେ କିମ୍ବା ସେଭ୍‍ କରିପାରେ।"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ଏହି ଆପ୍ ଆପଣଙ୍କ Android TV ଡିଭାଇସ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇଥିବା ସମସ୍ତ କ୍ୟାଲେଣ୍ଡର ଇଭେଣ୍ଟ ପଢ଼ିପାରେ ଏବଂ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର ଡାଟା ସେୟାର୍ କରିପାରେ କିମ୍ବା ସେଭ୍ କରିପାରେ।"</string>
@@ -1081,13 +1077,13 @@
     <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_hint" msgid="455364685740251925">"ସନ୍ଧାନ…"</string>
-    <string name="searchview_description_search" msgid="1045552007537359343">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
+    <string name="search_go" msgid="2141477624421347086">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+    <string name="search_hint" msgid="455364685740251925">"ସର୍ଚ୍ଚ କରନ୍ତୁ…"</string>
+    <string name="searchview_description_search" msgid="1045552007537359343">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="searchview_description_query" msgid="7430242366971716338">"କ୍ୱେରୀ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="searchview_description_clear" msgid="1989371719192982900">"କ୍ୱେରୀ ଖାଲି କରନ୍ତୁ"</string>
     <string name="searchview_description_submit" msgid="6771060386117334686">"କ୍ୱେରୀ ଦାଖଲ କରନ୍ତୁ"</string>
-    <string name="searchview_description_voice" msgid="42360159504884679">"ଭଏସ୍‍ ସର୍ଚ୍ଚ"</string>
+    <string name="searchview_description_voice" msgid="42360159504884679">"ଭଏସ ସର୍ଚ୍ଚ"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"’ସ୍ପର୍ଶ କରି ଏକ୍ସପ୍ଲୋର୍‍ କରନ୍ତୁ’ ସକ୍ଷମ କରିବେ?"</string>
     <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ’ସ୍ପର୍ଶ କରି ଏକ୍ସପ୍ଲୋର୍ କରନ୍ତୁ’ ସକ୍ଷମ କରିବାକୁ ଚାହେଁ। ’ସ୍ପର୍ଶ କରି ଏକ୍ସପ୍ଲୋର୍ କରନ୍ତୁ’ ଅନ୍‌ ଥିବାବେଳେ, ଆପଣଙ୍କ ଆଙ୍ଗୁଠି ତଳେ କ’ଣ ଅଛି, ତାହାର ବ୍ୟାଖ୍ୟା ଦେଖିପାରିବେ କିମ୍ବା ଟାବ୍‍ଲେଟ୍‍ ସହ କଥାବାର୍ତ୍ତା କରିବାକୁ ଜେଶ୍ଚର୍‌ କରିପାରିବେ।"</string>
     <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ’ସ୍ପର୍ଶ କରି ଏକ୍ସପ୍ଲୋର୍ କରନ୍ତୁ’ ସକ୍ଷମ କରିବାକୁ ଚାହେଁ। ’ସ୍ପର୍ଶ କରି ଏକ୍ସପ୍ଲୋର୍ କରନ୍ତୁ’ ଅନ୍‌ ଥିବାବେଳେ, ଆପଣଙ୍କ ଆଙ୍ଗୁଠି ତଳେ କ’ଣ ଅଛି, ତାହାର ବ୍ୟାଖ୍ୟା ଦେଖିପାରିବେ କିମ୍ବା ଫୋନ୍‍ ସହ କଥାବାର୍ତ୍ତା କରିବାକୁ ଜେଶ୍ଚର୍‌ କରିପାରିବେ।"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"ଆଣ୍ଡ୍ରଏଡ୍ ଆରମ୍ଭ ହେଉଛି…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ଟାବଲେଟ୍ ଆରମ୍ଭ ହେଉଛି…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ଡିଭାଇସ୍ ଆରମ୍ଭ ହେଉଛି…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ଷ୍ଟୋରେଜ୍‍ ବଢ଼ାଯାଉଛି"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"ସିଷ୍ଟମ୍ ଅପଡେଟ୍ ସମାପ୍ତ ହେଉଛି…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅପଗ୍ରେଡ୍‍ କରାଯାଉଛି…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g>ରୁ <xliff:g id="NUMBER_0">%1$d</xliff:g> ଆପ୍‍ ଅନୁକୂଳନ କରୁଛି।"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> ପ୍ରସ୍ତୁତ କରାଯାଉଛି।"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ଆପ୍‍ ଆରମ୍ଭ କରାଯାଉଛି।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ବୁଟ୍‍ ସମାପ୍ତ କରୁଛି।"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB ମାଧ୍ୟମରେ PTPକୁ ଚାଲୁ କରାଗଲା"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB ଟିଥରିଙ୍ଗ ଚାଲୁ କରାଗଲା"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB ମାଧ୍ୟମରେ MIDIକୁ ଚାଲୁ କରାଗଲା"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ଆକ୍ସେସୋରୀ ଯୋଡ଼ାଗଲା"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି। ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
@@ -1468,7 +1464,7 @@
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"ଜୁମ୍ ନିୟନ୍ତ୍ରଣ ପାଇଁ ଦୁଇଥର ଟାପ୍‌ କରନ୍ତୁ"</string>
     <string name="gadget_host_error_inflating" msgid="2449961590495198720">"ୱିଜେଟ୍‍ ଯୋଡ଼ିପାରିବ ନାହିଁ।"</string>
     <string name="ime_action_go" msgid="5536744546326495436">"ଯାଆନ୍ତୁ"</string>
-    <string name="ime_action_search" msgid="4501435960587287668">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
+    <string name="ime_action_search" msgid="4501435960587287668">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="ime_action_send" msgid="8456843745664334138">"ପଠାନ୍ତୁ"</string>
     <string name="ime_action_next" msgid="4169702997635728543">"ପରବର୍ତ୍ତୀ"</string>
     <string name="ime_action_done" msgid="6299921014822891569">"ହୋଇଗଲା"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ହୋଇଗଲା"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ଶର୍ଟକଟ୍‍ ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ରଙ୍ଗ ବଦଳାଇବାର ସୁବିଧା"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ଏକ-ହାତ ମୋଡ୍"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ଅତ୍ୟଧିକ ଡିମ"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନରେ ଦେଖାଯାଉଛି"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ବାହାରିବା ପାଇଁ, ଉପରୁ ତଳକୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ।"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ବୁଝିଗଲି"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ରୋଟେଟ କରନ୍ତୁ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନରୁ ବାହାରି ଯାଆନ୍ତୁ"</string>
     <string name="done_label" msgid="7283767013231718521">"ହୋଇଗଲା"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ଘଣ୍ଟା ସର୍କୁଲାର୍‍ ସ୍ଲାଇଡର୍‍"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"ମିନିଟ୍ସ ସର୍କୁଲାର୍‍ ସ୍ଲାଇଡର୍‍"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ୱାର୍କ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2ୟ କାର୍ଯ୍ୟ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3ୟ କାର୍ଯ୍ୟ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> କ୍ଲୋନ"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ PIN ପଚାରନ୍ତୁ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ଲକ୍‌ ଖୋଲିବା ପାଟର୍ନ ପଚାରନ୍ତୁ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ପାସ୍‌ୱର୍ଡ ପଚାରନ୍ତୁ"</string>
@@ -1943,7 +1943,7 @@
     <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"ପ୍ରସ୍ତାବିତ ଅଞ୍ଚଳଗୁଡ଼ିକ"</string>
     <string name="language_picker_section_all" msgid="1985809075777564284">"ସମସ୍ତ ଭାଷା"</string>
     <string name="region_picker_section_all" msgid="756441309928774155">"ସମସ୍ତ ଅଞ୍ଚଳ"</string>
-    <string name="locale_search_menu" msgid="6258090710176422934">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
+    <string name="locale_search_menu" msgid="6258090710176422934">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="app_suspended_title" msgid="888873445010322650">"ଆପ୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="app_suspended_default_message" msgid="6451215678552004172">"ବର୍ତ୍ତମାନ <xliff:g id="APP_NAME_0">%1$s</xliff:g> ଉପଲବ୍ଧ ନାହିଁ। ଏହା <xliff:g id="APP_NAME_1">%2$s</xliff:g> ଦ୍ଵାରା ପରିଚାଳିତ ହେଉଛି।"</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"ପୃଷ୍ଠପଟରୁ ଫୋରଗ୍ରାଉଣ୍ଡ ସେବାଗୁଡ଼ିକ ଆରମ୍ଭ କରିବାକୁ ଏକ ସହଯୋଗୀ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"ମାଇକ୍ରୋଫୋନ ଉପଲବ୍ଧ ଅଛି"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"ମାଇକ୍ରୋଫୋନକୁ ବ୍ଲକ କରାଯାଇଛି"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ଡୁଆଲ ସ୍କ୍ରିନ"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ଡୁଆଲ ସ୍କ୍ରିନ ଚାଲୁ ଅଛି"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"ବିଷୟବସ୍ତୁ ଦେଖାଇବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଉଭୟ ଡିସପ୍ଲେକୁ ବ୍ୟବହାର କରୁଛି"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ଡିଭାଇସ ବହୁତ ଗରମ ଅଛି"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ଆପଣଙ୍କ ଫୋନ ବହୁତ ଗରମ ହେଉଥିବା ଯୋଗୁଁ ଡୁଆଲ ସ୍କ୍ରିନ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ବନ୍ଦ କରନ୍ତୁ"</string>
 </resources>
diff --git a/core/res/res/values-pa-watch/strings.xml b/core/res/res/values-pa-watch/strings.xml
index c98b307..b1eb3a7 100644
--- a/core/res/res/values-pa-watch/strings.xml
+++ b/core/res/res/values-pa-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"ਐਪ <xliff:g id="NUMBER_1">%2$d</xliff:g> ਦਾ <xliff:g id="NUMBER_0">%1$d</xliff:g>"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"ਸੰੰਵੇਦਕ"</string>
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 4086ab7..a41cde1 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ਜਦੋਂ ਐਪ ਵਰਤੋਂ ਵਿੱਚ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ \'ਤੇ ਦਿਲ ਦੀ ਧੜਕਣ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ਜਦੋਂ ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੋਵੇ, ਤਾਂ ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਦਿਲ ਦੀ ਧੜਕਣ, ਤਾਪਮਾਨ, ਖੂਨ ਵਿੱਚ ਮੌਜੂਦ ਆਕਸੀਜਨ ਦੀ ਫ਼ੀਸਦ ਵਰਗੇ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਦੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ਐਪ ਦੇ ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ, ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਵੱਲੋਂ ਤੁਹਾਡੇ ਸੌਣ ਵੇਲੇ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾਣ ਵਾਲੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ।"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ਐਪ ਦੇ ਵਰਤੋਂ ਵਿੱਚ ਹੋਣ \'ਤੇ, ਐਪ ਨੂੰ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਵੱਲੋਂ ਤੁਹਾਡੇ ਸੌਣ ਵੇਲੇ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾਣ ਵਾਲੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ਐਪ ਦੇ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਦੇ ਹੋਣ \'ਤੇ, ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਵੱਲੋਂ ਤੁਹਾਡੇ ਸੌਣ ਵੇਲੇ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾਣ ਵਾਲੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ।"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ਐਪ ਦੇ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਦੇ ਹੋਣ \'ਤੇ, ਐਪ ਨੂੰ ਸਰੀਰ ਸੰਬੰਧੀ ਸੈਂਸਰ ਵੱਲੋਂ ਤੁਹਾਡੇ ਸੌਣ ਵੇਲੇ ਰਿਕਾਰਡ ਕੀਤੇ ਜਾਣ ਵਾਲੇ ਡਾਟੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"ਕੈਲੰਡਰ ਵਰਤਾਰਿਆਂ ਅਤੇ ਵੇਰਵਿਆਂ ਨੂੰ ਪੜ੍ਹੋ"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ਇਹ ਐਪ ਤੁਹਾਡੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਸਟੋਰ ਕੀਤੇ ਸਾਰੇ ਕੈਲੰਡਰ ਇਵੈਂਟਾਂ ਨੂੰ ਪੜ੍ਹ ਸਕਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਡਾਟੇ ਨੂੰ ਸਾਂਝਾ ਜਾਂ ਰੱਖਿਅਤ ਕਰ ਸਕਦੀ ਹੈ।"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ਟੈਬਲੈੱਟ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"ਡੀਵਾਈਸ ਚਾਲੂ ਹੋ ਰਿਹਾ ਹੈ…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ਸਟੋਰੇਜ ਅਨੁਕੂਲ ਹੋ ਰਹੀ ਹੈ।"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"ਸਿਸਟਮ ਅੱਪਡੇਟ ਪੂਰਾ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> ਅੱਪਗ੍ਰੇਡ ਹੋ ਰਹੀ ਹੈ…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g> <xliff:g id="NUMBER_1">%2$d</xliff:g> ਦਾ ਐਪ ਅਨੁਕੂਲ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ਐਪਸ ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ਬੂਟ ਪੂਰਾ ਕਰ ਰਿਹਾ ਹੈ।"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB ਰਾਹੀਂ PTP ਚਾਲੂ ਹੈ"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB ਰਾਹੀਂ MIDI ਚਾਲੂ ਹੈ"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ਐਕਸੈਸਰੀ ਕਨੈਕਟ ਹੋਈ"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"ਕਨੈਕਟ ਕੀਤਾ ਡੀਵਾਈਸ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ। ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ।"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ਹੋ ਗਿਆ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ਸ਼ਾਰਟਕੱਟ ਬੰਦ ਕਰੋ"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"ਰੰਗ ਪਲਟਨਾ"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ਰੰਗ ਸੁਧਾਈ"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ਇੱਕ ਹੱਥ ਮੋਡ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ਜ਼ਿਆਦਾ ਘੱਟ ਚਮਕ"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦੇਖੋ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ਬਾਹਰ ਜਾਣ ਲਈ, ਉਪਰੋਂ ਹੇਠਾਂ ਸਵਾਈਪ ਕਰੋ।"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ਸਮਝ ਲਿਆ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਅਨੁਭਵ ਲਈ ਘੁਮਾਓ"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਅਨੁਭਵ ਲਈ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਤੋਂ ਬਾਹਰ ਆਓ"</string>
     <string name="done_label" msgid="7283767013231718521">"ਹੋ ਗਿਆ"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ਘੰਟੇ ਸਰਕੁਲਰ ਸਲਾਈਡਰ"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"ਮਿੰਟ ਸਰਕੁਲਰ ਸਲਾਈਡਰ"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ਕੰਮ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ਦੂਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ਤੀਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ਦਾ ਕਲੋਨ"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"ਸੰਬੰਧੀ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਤੋਂ ਫੋਰਗ੍ਰਾਊਂਡ ਸੇਵਾਵਾਂ ਸ਼ੁਰੂ ਕਰਨ ਦੀ ਆਗਿਆ ਮਿਲਦੀ ਹੈ।"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਉਪਲਬਧ ਹੈ"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ਦੋਹਰੀ ਸਕ੍ਰੀਨ"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ਦੋਹਰੀ ਸਕ੍ਰੀਨ ਚਾਲੂ ਹੈ"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਸਮੱਗਰੀ ਨੂੰ ਦਿਖਾਉਣ ਲਈ ਦੋਵੇਂ ਡਿਸਪਲੇਆਂ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ਡੀਵਾਈਸ ਬਹੁਤ ਗਰਮ ਹੈ"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ਦੋਹਰੀ ਸਕ੍ਰੀਨ ਵਿਸ਼ੇਸ਼ਤਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ ਕਿਉਂਕਿ ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ਬੰਦ ਕਰੋ"</string>
 </resources>
diff --git a/core/res/res/values-pl-watch/strings.xml b/core/res/res/values-pl-watch/strings.xml
index 582b18e..2d81625 100644
--- a/core/res/res/values-pl-watch/strings.xml
+++ b/core/res/res/values-pl-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikacja <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Czujniki"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f57ec7e..927d84b 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Zezwala aplikacji na dostęp do danych z czujników na ciele, takich jak tętno, temperatura i poziom saturacji, gdy aplikacja ta jest używana."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zezwól na dostęp do danych z czujników na ciele, np. tętna, podczas używania aplikacji w tle"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Zezwala aplikacji na dostęp do danych z czujników na ciele, takich jak tętno, temperatura i poziom saturacji, gdy aplikacja ta jest używana w tle."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Dostęp do pochodzących z czujnika na ciele danych temperatury na nadgarstku, kiedy aplikacja jest w użyciu."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Zezwala na dostęp aplikacji do pochodzących z czujnika na ciele danych temperatury na nadgarstku, kiedy aplikacja jest w użyciu."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Dostęp do pochodzących z czujnika na ciele danych temperatury na nadgarstku, kiedy aplikacja działa w tle."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Zezwala na dostęp aplikacji do pochodzących z czujnika na ciele danych temperatury na nadgarstku, kiedy aplikacja działa w tle."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Odczytywanie wydarzeń i informacji z kalendarza"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacja może odczytywać wszystkie zapisane na tablecie wydarzenia z kalendarza i udostępniać oraz zapisywać dane kalendarza."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacja może odczytywać wszystkie wydarzenia z kalendarza zapisane na urządzeniu z Androidem TV oraz udostępniać i zapisywać dane z kalendarza."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android się uruchamia…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet się uruchamia…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Urządzenie się uruchamia…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optymalizacja pamięci."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Kończę aktualizację systemu…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Uaktualniam aplikację <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optymalizowanie aplikacji <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Przygotowuję aplikację <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Uruchamianie aplikacji."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Kończenie uruchamiania."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Tryb PTP przez USB włączony"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tethering USB włączony"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Tryb MIDI przez USB włączony"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Podłączono akcesorium USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Kliknij, by wyświetlić więcej opcji."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Ładowanie połączonego urządzenia. Kliknij, by wyświetlić więcej opcji."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"OK"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Wyłącz skrót"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Korekcja kolorów"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tryb jednej ręki"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatkowe przyciemnienie"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Włączony pełny ekran"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Aby wyjść, przesuń palcem z góry na dół."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Obróć, aby lepiej widzieć"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Zamknij podzielony ekran, aby lepiej widzieć"</string>
     <string name="done_label" msgid="7283767013231718521">"Gotowe"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kołowy suwak godzin"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kołowy suwak minut"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (służbowy)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon aplikacji <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Podaj PIN, aby odpiąć"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Aby odpiąć, poproś o wzór odblokowania"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Aby odpiąć, poproś o hasło"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Zezwala aplikacji towarzyszącej na uruchamianie usług działających na pierwszym planie, podczas gdy sama działa w tle."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon jest dostępny"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon jest zablokowany"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Podwójny ekran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Włączono podwójny ekran"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> korzysta z obu wyświetlaczy, aby pokazać treści"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Urządzenie jest za ciepłe"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Podwójny ekran jest niedostępny, ponieważ telefon za bardzo się nagrzewa"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Wyłącz"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR-watch/strings.xml b/core/res/res/values-pt-rBR-watch/strings.xml
index 04178e0..dea270b 100644
--- a/core/res/res/values-pt-rBR-watch/strings.xml
+++ b/core/res/res/values-pt-rBR-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensores"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 6fc8ce5..3a391f6 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -48,7 +48,7 @@
     <string name="enablePin" msgid="2543771964137091212">"Falha. Ative o bloqueio do chip/R-UIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="one">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip será bloqueado.</item>
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip será bloqueado.</item>
       <item quantity="other">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip será bloqueado.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em uso."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acessar dados do sensor corporal, como a frequência cardíaca, segundo plano"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em segundo plano."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Acessar dados de temperatura do sensor corporal no pulso enquanto o app está em uso."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite que o app acesse dados de temperatura do sensor corporal no pulso enquanto está em uso."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Acessar dados de temperatura do sensor corporal no pulso enquanto o app está em segundo plano."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite que o app acesse dados de temperatura do sensor corporal no pulso enquanto está em segundo plano."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos da agenda"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Este app pode ler todos os eventos da agenda armazenados no seu tablet e compartilhar ou salvar os dados da sua agenda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Este app pode ler todos os eventos da agenda armazenados no seu dispositivo Android TV e compartilhar ou salvar os dados da sua agenda."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"O Android está iniciando..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"O tablet está iniciando…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"O dispositivo está iniciando…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Otimizando o armazenamento."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Concluindo atualização do sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> está fazendo upgrade…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Concluindo a inicialização."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB ativado"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tethering USB ativado"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB ativado"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Acessório USB conectado"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Toque para ver mais opções."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Carregando dispositivo conectado. Toque para ver mais opções."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Concluído"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer a tela"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização em tela cheia"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize de cima para baixo."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendi"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gire a tela para ter uma visualização melhor"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Saia da tela dividida para ter uma visualização melhor"</string>
     <string name="done_label" msgid="7283767013231718521">"Concluído"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Controle deslizante circular das horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Controle deslizante circular dos minutos"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Segundo <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Terceiro <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (clone)"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de liberar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que um app complementar em segundo plano inicie serviços em primeiro plano."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"O microfone está disponível"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"O microfone está bloqueado"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Tela dupla"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"A tela dupla está ativada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está usando as duas telas para mostrar conteúdo"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está muito quente"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A tela dupla está indisponível porque o smartphone está ficando muito quente"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desativar"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT-watch/strings.xml b/core/res/res/values-pt-rPT-watch/strings.xml
index a1cdd89..dea270b 100644
--- a/core/res/res/values-pt-rPT-watch/strings.xml
+++ b/core/res/res/values-pt-rPT-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplicação <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensores"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f7b9e69..0137434 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -47,7 +47,7 @@
     <string name="needPuk2" msgid="3910763547447344963">"Introduza o PUK2 para desbloquear o SIM."</string>
     <string name="enablePin" msgid="2543771964137091212">"Ação sem êxito. Ative o bloqueio do SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado.</item>
       <item quantity="other">Tem mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado.</item>
       <item quantity="one">Tem mais <xliff:g id="NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado.</item>
     </plurals>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite à app aceder a dados de sensores de corpo, como ritmo cardíaco, temperatura e percentagem de oxigénio no sangue, enquanto está a ser usada."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Aceder a dados de sensores de corpo, como ritmo cardíaco, quando em seg. plano"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite à app aceder a dados de sensores de corpo, como ritmo cardíaco, temperatura e percentagem de oxigénio no sangue, enquanto está em segundo plano."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Aceda a dados de temperatura do pulso de sensores de corpo enquanto a app está a ser usada."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite à app aceder a dados de temperatura do pulso de sensores de corpo enquanto a app está a ser usada."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Aceda a dados de temperatura do pulso de sensores de corpo enquanto a app está em segundo plano."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite à app aceder a dados de temperatura do pulso de sensores de corpo enquanto a app está em segundo plano."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos do calendário"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Esta app pode ler todos os eventos do calendário armazenados no seu tablet e partilhar ou guardar os dados do calendário."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Esta app pode ler todos os eventos do calendário armazenados no seu dispositivo Android TV e partilhar ou guardar os dados do calendário."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"O Android está a iniciar…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"O tablet está a iniciar…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"O dispositivo está a iniciar…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"A otimizar o armazenamento."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"A concluir a atualização do sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"O <xliff:g id="APPLICATION">%1$s</xliff:g> está a ser atualizado…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"A otimizar a app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"A preparar o <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"A iniciar aplicações"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"A concluir o arranque."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"O PTP por USB está ativado"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"A ligação USB via telemóvel está ativada"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"O MIDI através de USB está ativado"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Acessório USB ligado"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Toque para obter mais opções."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"A carregar o dispositivo ligado. Toque para obter mais opções."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Concluído"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atalho"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção da cor"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mais escuro"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização de ecrã inteiro"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize rapidamente para baixo a partir da parte superior."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rode para uma melhor visualização"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Saia do ecrã dividido para uma melhor visualização"</string>
     <string name="done_label" msgid="7283767013231718521">"Concluído"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Controlo de deslize circular das horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Controlo de deslize circular dos minutos"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2.º <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3.º <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonar <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de soltar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de soltar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir palavra-passe antes de soltar"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que uma app associada em segundo plano inicie serviços em primeiro plano."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"O microfone está disponível"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"O microfone está bloqueado"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dois ecrãs"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"A funcionalidade Dois ecrãs está ativada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a usar ambos os ecrãs para mostrar conteúdo"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está a ficar demasiado quente"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A funcionalidade Dois ecrãs está indisponível porque o seu telemóvel está a ficar demasiado quente"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desativar"</string>
 </resources>
diff --git a/core/res/res/values-pt-watch/strings.xml b/core/res/res/values-pt-watch/strings.xml
index 04178e0..dea270b 100644
--- a/core/res/res/values-pt-watch/strings.xml
+++ b/core/res/res/values-pt-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensores"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 6fc8ce5..3a391f6 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -48,7 +48,7 @@
     <string name="enablePin" msgid="2543771964137091212">"Falha. Ative o bloqueio do chip/R-UIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="one">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip será bloqueado.</item>
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
+      <item quantity="many">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip será bloqueado.</item>
       <item quantity="other">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o chip será bloqueado.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"IMEI"</string>
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em uso."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Acessar dados do sensor corporal, como a frequência cardíaca, segundo plano"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite que o app acesse dados do sensor corporal, como a frequência cardíaca, a temperatura e a porcentagem de oxigênio no sangue, enquanto o app está em segundo plano."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Acessar dados de temperatura do sensor corporal no pulso enquanto o app está em uso."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite que o app acesse dados de temperatura do sensor corporal no pulso enquanto está em uso."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Acessar dados de temperatura do sensor corporal no pulso enquanto o app está em segundo plano."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite que o app acesse dados de temperatura do sensor corporal no pulso enquanto está em segundo plano."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Ler detalhes e eventos da agenda"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Este app pode ler todos os eventos da agenda armazenados no seu tablet e compartilhar ou salvar os dados da sua agenda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Este app pode ler todos os eventos da agenda armazenados no seu dispositivo Android TV e compartilhar ou salvar os dados da sua agenda."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"O Android está iniciando..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"O tablet está iniciando…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"O dispositivo está iniciando…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Otimizando o armazenamento."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Concluindo atualização do sistema…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> está fazendo upgrade…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Iniciando apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Concluindo a inicialização."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB ativado"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tethering USB ativado"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB ativado"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Acessório USB conectado"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Toque para ver mais opções."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Carregando dispositivo conectado. Toque para ver mais opções."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Concluído"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desativar atalho"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer a tela"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visualização em tela cheia"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Para sair, deslize de cima para baixo."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Entendi"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Gire a tela para ter uma visualização melhor"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Saia da tela dividida para ter uma visualização melhor"</string>
     <string name="done_label" msgid="7283767013231718521">"Concluído"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Controle deslizante circular das horas"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Controle deslizante circular dos minutos"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Segundo <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Terceiro <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (clone)"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de liberar"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite que um app complementar em segundo plano inicie serviços em primeiro plano."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"O microfone está disponível"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"O microfone está bloqueado"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Tela dupla"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"A tela dupla está ativada"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está usando as duas telas para mostrar conteúdo"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está muito quente"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A tela dupla está indisponível porque o smartphone está ficando muito quente"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desativar"</string>
 </resources>
diff --git a/core/res/res/values-ro-watch/strings.xml b/core/res/res/values-ro-watch/strings.xml
index 7dfedbb..da58726 100644
--- a/core/res/res/values-ro-watch/strings.xml
+++ b/core/res/res/values-ro-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplic. <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Senzori"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b9c90b1..5053850 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permite aplicației să acceseze date de la senzorii corporali, cum ar fi pulsul, temperatura și procentul de oxigen din sânge, în timpul folosirii aplicației."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Să acceseze date de la senzorii corporali, precum pulsul, când rulează în fundal"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permite aplicației să acceseze date de la senzorii corporali, cum ar fi pulsul, temperatura și procentul de oxigen din sânge, în timp ce aplicația rulează în fundal."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Accesează date despre temperatura încheieturii de la senzorii corporali în timpul folosirii aplicației."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Permite aplicației să acceseze date despre temperatura încheieturii de la senzorii corporali în timpul folosirii aplicației."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Accesează date despre temperatura încheieturii de la senzorii corporali în timp ce aplicația rulează în fundal."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Permite aplicației să acceseze date despre temperatura încheieturii de la senzorii corporali în timp ce aplicația rulează în fundal."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"să citească evenimentele din calendar și detaliile"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Această aplicație poate să citească toate evenimentele din calendar stocate pe tabletă și să trimită sau să salveze datele din calendar."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Această aplicație poate să citească toate evenimentele din calendar stocate pe dispozitivul Android TV și să trimită sau să salveze datele din calendar."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android pornește..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Pornește tableta…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Pornește dispozitivul…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Se optimizează stocarea."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Se finalizează actualizarea sistemului…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Se face upgrade pentru <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Se optimizează aplicația <xliff:g id="NUMBER_0">%1$d</xliff:g> din <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Se pregătește <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Se pornesc aplicațiile."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Se finalizează pornirea."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP prin USB este activat"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Tetheringul prin USB este activat"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI prin USB este activat"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Accesoriu USB conectat"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Atinge pentru mai multe opțiuni."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Se încarcă dispozitivul conectat. Atinge pentru mai multe opțiuni."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Gata"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Dezactivează comanda rapidă"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Folosește comanda rapidă"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversarea culorilor"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Corecția culorilor"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modul cu o mână"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminozitate redusă suplimentar"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Vizualizare pe ecran complet"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Pentru a ieși, glisează de sus în jos."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Am înțeles"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotește pentru o previzualizare mai bună"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Ieși din ecranul împărțit pentru o previzualizare mai bună"</string>
     <string name="done_label" msgid="7283767013231718521">"Terminat"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Selector circular pentru ore"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Selector circular pentru minute"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> de serviciu"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (2)"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (3)"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonă pentru <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicită codul PIN înainte de a anula fixarea"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicită mai întâi modelul pentru deblocare"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicită parola înainte de a anula fixarea"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permite unei aplicații partenere să inițieze servicii în prim-plan din fundal."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Microfonul este disponibil"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfonul este blocat"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Funcția Dual screen este activată"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește ambele ecrane pentru a afișa conținut"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Dispozitivul este prea cald"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Funcția Dual Screen este indisponibilă, deoarece telefonul s-a încălzit prea tare"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Dezactivează"</string>
 </resources>
diff --git a/core/res/res/values-ru-watch/strings.xml b/core/res/res/values-ru-watch/strings.xml
index 02f068b..b8416c3 100644
--- a/core/res/res/values-ru-watch/strings.xml
+++ b/core/res/res/values-ru-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Приложение <xliff:g id="NUMBER_0">%1$d</xliff:g> из <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Датчики"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b7a3f60..9f54512 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Когда приложение используется, это разрешение предоставляет ему доступ к данным нательных датчиков (например, пульсу, температуре, уровню кислорода в крови)."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ к данным нательных датчиков, когда приложение работает в фоновом режиме"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Когда приложение работает в фоновом режиме, это разрешение предоставляет ему доступ к данным нательных датчиков (например, пульсу, температуре, уровню кислорода в крови)."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Доступ к данным с нательных датчиков о температуре запястья (при использовании приложения)"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Когда приложение используется, это разрешение предоставляет ему доступ к данным о температуре запястья, которые собираются нательными датчиками."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Доступ к данным с нательных датчиков о температуре запястья (при работе приложения в фоновом режиме)"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Когда приложение работает в фоновом режиме, это разрешение предоставляет ему доступ к данным о температуре запястья, которые собираются нательными датчиками."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Чтение мероприятий и данных"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре планшета."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Приложение может считывать, отправлять и сохранять информацию о мероприятиях в календаре устройства Android TV."</string>
@@ -638,7 +634,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>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Запуск Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Запуск планшета…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Запуск устройства…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Оптимизация хранилища…"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Завершение обновления системы…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Обновление приложения \"<xliff:g id="APPLICATION">%1$s</xliff:g>\"…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Оптимизация приложения <xliff:g id="NUMBER_0">%1$d</xliff:g> из <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Подготовка приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"..."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск приложений."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Окончание загрузки..."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP включен"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Режим USB-модема включен"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Режим MIDI включен"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-устройство подключено"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Нажмите, чтобы показать дополнительные параметры."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Подключенное устройство заряжается. Нажмите, чтобы увидеть другие настройки."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Деактивировать быстрое включение"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Использовать быстрое включение"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверсия цветов"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Коррекция цвета"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим управления одной рукой"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнительное уменьшение яркости"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Полноэкранный режим"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Чтобы выйти, проведите по экрану сверху вниз."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"ОК"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Поверните, чтобы лучше видеть."</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Выйдите из режима разделения экрана, чтобы лучше видеть."</string>
     <string name="done_label" msgid="7283767013231718521">"Готово"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Выбор часов на циферблате"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Выбор минут на циферблате"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Рабочий <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Задача 2: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Задача 3: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонировать <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запрашивать PIN-код"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запрашивать графический ключ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запрашивать пароль"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Сопутствующее приложение сможет запускать активные службы из фонового режима."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофон доступен."</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон заблокирован."</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Двойной экран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Двойной экран включен"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> показывает контент на обоих экранах."</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Устройство перегрелось"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Двойной экран недоступен из-за перегрева телефона."</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Отключить"</string>
 </resources>
diff --git a/core/res/res/values-si-watch/strings.xml b/core/res/res/values-si-watch/strings.xml
index 6d08c1b..bab95aa 100644
--- a/core/res/res/values-si-watch/strings.xml
+++ b/core/res/res/values-si-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g> හි <xliff:g id="NUMBER_1">%2$d</xliff:g> යෙදුම."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"සංවේදක"</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index edb7dc2..fe40fef 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"යෙදුම භාවිතයේ පවතින අතරතුර හෘද ස්පන්දන වේගය, උෂ්ණත්වය සහ රුධිර ඔක්සිජන් ප්‍රතිශතය වැනි ශරීර සංවේදක දත්ත වෙත ප්‍රවේශ වීමට යෙදුමට අවසර දෙයි."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"පසුබිමේ ඇති අතරතුර හෘද ස්පන්දන වේගය වැනි ශරීර සංවේදක දත්ත වෙත ප්‍රවේශ වන්න"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"යෙදුම පසුබිමේ ඇති අතර හෘද ස්පන්දන වේගය, උෂ්ණත්වය සහ රුධිර ඔක්සිජන් ප්‍රතිශතය වැනි ශරීර සංවේදක දත්ත වෙත ප්‍රවේශ වීමට යෙදුමට අවසර දෙයි."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"යෙදුම භාවිතයේ පවතින අතරේ ශරීර සංවේදක මැණික් කටුවේ උෂ්ණත්ව දත්ත වෙත ප්‍රවේශ වන්න."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"යෙදුම භාවිතයේ ඇති අතරේ, ශරීර සංවේදක මැණික් කටුවේ උෂ්ණත්ව දත්ත වෙත ප්‍රවේශ වීමට යෙදුමට ඉඩ දෙයි."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"යෙදුම පසුබිමේ ඇති අතරේ ශරීර සංවේදක මැණික් කටුවේ උෂ්ණත්ව දත්ත වෙත ප්‍රවේශ වන්න."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"යෙදුම පසුබිමේ ඇති අතරේ, ශරීර සංවේදක මැණික් කටුවේ උෂ්ණත්ව දත්ත වෙත ප්‍රවේශ වීමට යෙදුමට ඉඩ දෙයි."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"දින දර්ශන සිදුවීම් හා විස්තර කියවන්න"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"මෙම යෙදුමට ඔබගේ ටැබ්ලට් පරිගණකය මත ගබඩා වී ඇති සියලු දින දර්ශන කියවීමට සහ සහ ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට සහ සුරැකීමට හැකිය."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"මෙම යෙදුමට ඔබගේ Android TV මත ගබඩා කර ඇති සියලු දින දර්ශන සිදුවීම් කියවීමට සහ ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ සුරැකීමට හැකිය."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android ආරම්භ කරමින්…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ටැබ්ලට් පරිගණකය ආරම්භ කරමින්…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"උපාංගය ආරම්භ කරමින්…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"ආචයනය ප්‍රශස්තිකරණය කිරීම."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"පද්ධති යාවත්කාලීනය අවසන් කරමින්…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> උත්ශ්‍රේණි කරමින්…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> කින් <xliff:g id="NUMBER_0">%1$d</xliff:g> වැනි යෙදුම ප්‍රශස්ත කරමින්."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> සූදානම් කරමින්."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"යෙදුම් ආරම්භ කරමින්."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"ඇරඹුම අවසාන කරමින්."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB හරහා PTP ක්‍රියාත්මකයි"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB ටෙදරින් ක්‍රියාත්මකයි"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB හරහා MIDI ක්‍රියාත්මකයි"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB උපාංගය සම්බන්ධ කර ඇත"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"සම්බන්ධිත උපාංගය ආරෝපණය කරමින්. තවත් විකල්ප සඳහා තට්ටු කරන්න."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"නිමයි"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"කෙටිමඟ ක්‍රියාවිරහිත කරන්න"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"කෙටිමඟ භාවිතා කරන්න"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"වර්ණ අපවර්තනය"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"වර්ණ නිවැරදි කිරීම"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"තනි අත් ප්‍රකාරය"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"තවත් අඳුරු"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"මුළු තිරය බලමින්"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"ඉවත් වීමට, ඉහළ සිට පහළට ස්වයිප් කරන්න"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"වැටහුණි"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"වඩා හොඳ දසුනක් සඳහා කරකවන්න"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"වඩා හොඳ දර්ශනයක් සඳහා බෙදුම් තිරයෙන් පිටවන්න"</string>
     <string name="done_label" msgid="7283767013231718521">"අවසන්"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"පැය කවාකාර සර්පනය"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"මිනිත්තු කවාකාර සර්පනය"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2වන වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3වන වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ක්ලෝන කරන්න"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ගැලවීමට පෙර PIN විමසන්න"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"පසුබිමේ සිට පෙරබිම් සේවා ආරම්භ කිරීමට සහායක යෙදුමකට ඉඩ දෙයි."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"මයික්‍රෆෝනය තිබේ"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"මයික්‍රෆෝනය අවහිර කර ඇත"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ද්විත්ව තිරය"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"ද්විත්ව තිරය සක්‍රීයයි"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"අන්තර්ගතය පෙන්වීමට <xliff:g id="APP_NAME">%1$s</xliff:g> සංදර්ශන දෙකම භාවිත කරයි"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"උපාංගය ඉතා උණුසුම් වේ"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ඔබේ දුරකථනය ඉතා උණුසුම් නිසා ද්විත්ව තිරය ලබා ගත නොහැක"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"අක්‍රිය කරන්න"</string>
 </resources>
diff --git a/core/res/res/values-sk-watch/strings.xml b/core/res/res/values-sk-watch/strings.xml
index 39cce8b..6c9d718 100644
--- a/core/res/res/values-sk-watch/strings.xml
+++ b/core/res/res/values-sk-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikácia <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Senzory"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index af6cc59..e208111 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Poskytne aplikácii prístup k dátam telových senzorov, ako sú pulz, teplota a saturácia krvi kyslíkom počas používania aplikácie."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Prístup k dátam telových senzorov (napríklad pulzu) počas spustenia na pozadí"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Poskytne aplikácii prístup k dátam telových senzorov, ako sú pulz, teplota a saturácia krvi kyslíkom počas spustenia aplikácie na pozadí."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Prístup k údajom o teplote zápästia z telového senzora počas používania aplikácie."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Umožňuje aplikácii prístup k údajom o teplote zápästia z telového senzora počas používania aplikácie."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Prístup k údajom o teplote zápästia z telového senzora, keď je aplikácia na pozadí."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Umožňuje aplikácii prístup k údajom o teplote zápästia z telového senzora, keď je aplikácia na pozadí."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Čítanie udalostí kalendára a podrobností"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Táto aplikácia môže čítať všetky udalosti kalendára uložené vo vašom tablete a zdieľať alebo ukladať dáta kalendára."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Táto aplikácia môže čítať všetky udalosti kalendára uložené vo vašom zariadení Android TV a zdieľať alebo ukladať údaje kalendára."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Systém Android sa spúšťa…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet sa spúšťa…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Zariadenie sa spúšťa…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimalizuje sa úložisko"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Dokončuje sa aktualizácia systému…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> sa inovuje…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Prebieha optimalizácia aplikácie <xliff:g id="NUMBER_0">%1$d</xliff:g> z <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripravuje sa aplikácia <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Prebieha spúšťanie aplikácií."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Prebieha dokončovanie spúšťania."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Bol zapnutý režim PTP cez USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Bol zapnutý tethering cez USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Bol zapnutý režim MIDI cez USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Bolo pripojené príslušenstvo USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Klepnutím zobrazíte ďalšie možnosti."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Pripojené zariadenie sa nabíja. Ďalšie možností získate klepnutím."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hotovo"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vypnúť skratku"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Úprava farieb"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednej ruky"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mimoriadne stmavenie"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazenie na celú obrazovku"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Ukončíte potiahnutím zhora nadol."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Dobre"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Otočte zariadenie pre lepšie zobrazenie"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Ukončite rozdelenú obrazovku pre lepšie zobrazenie"</string>
     <string name="done_label" msgid="7283767013231718521">"Hotovo"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kruhový posúvač hodín"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kruhový posúvač minút"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Práca – <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klonovať <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pred odopnutím požiadať o číslo PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred uvoľnením požiadať o bezpečnostný vzor"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odopnutím požiadať o heslo"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Umožňuje sprievodnej aplikácii spúšťať služby na popredí z pozadia."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofón je k dispozícii"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofón je blokovaný"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvojitá obrazovka"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dvojitá obrazovka je zapnutá"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> zobrazuje obsah na oboch obrazovkách"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Zariadenie je príliš horúce"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojitá obrazovka nie je k dispozícii, pretože telefón sa prehrieva"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Vypnúť"</string>
 </resources>
diff --git a/core/res/res/values-sl-watch/strings.xml b/core/res/res/values-sl-watch/strings.xml
index 8e15da5..0afcaa3 100644
--- a/core/res/res/values-sl-watch/strings.xml
+++ b/core/res/res/values-sl-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. aplikac. od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Tipala"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e33b67d..6772274 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi, ko je aplikacija v uporabi."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Dostop do podatkov tipal telesnih funkcij, kot je srčni utrip, ko je v ozadju"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij, kot so srčni utrip, temperatura, odstotek kisika v krvi, ko je aplikacija v ozadju."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Dostop do podatkov tipal telesnih funkcij o temperaturi na zapestju, ko je aplikacija v uporabi."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij o temperaturi na zapestju, ko je aplikacija v uporabi."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Dostop do podatkov tipal telesnih funkcij o temperaturi na zapestju, ko je aplikacija v ozadju."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Aplikaciji dovoljuje dostop do podatkov tipal telesnih funkcij o temperaturi na zapestju, ko je aplikacija v ozadju."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Branje dogodkov v koledarjih in podrobnosti koledarjev"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v tabličnem računalniku, ter shrani podatke koledarja ali jih deli z drugimi."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v napravi Android TV, ter shrani podatke koledarja ali jih deli z drugimi."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android se zaganja …"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablični računalnik se zaganja …"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Naprava se zaganja …"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Optimiziranje shrambe."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Zaključevanje posodobitve sistema …"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> se nadgrajuje …"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimiranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Pripravljanje aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Zagon aplikacij."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Dokončevanje zagona."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Vklopljen je način PTP prek USB-ja"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Vklopljen je internet prek USB-ja"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Vklopljen je način MIDI prek USB-ja"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Dodatek USB je priključen"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Dotaknite se za več možnosti."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Polnjenje baterije v povezani napravi. Dotaknite se za več možnosti."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Končano"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Izklopi bližnjico"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Uporabi bližnjico"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Popravljanje barv"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enoročni način"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjen zaslon"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Vklopljen je celozaslonski način"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Zaprete ga tako, da z vrha s prstom povlečete navzdol."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Razumem"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zasukajte za boljši pregled."</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Zaprite razdeljeni zaslon za boljši pregled."</string>
     <string name="done_label" msgid="7283767013231718521">"Dokončano"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Okrogli drsnik za ure"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Okrogli drsnik za minute"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> za delo"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. službeni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. službeni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon aplikacije <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Zahtevaj PIN pred odpenjanjem"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odpenjanjem vprašaj za geslo"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Spremljevalni aplikaciji dovoljuje, da storitve v ospredju zažene iz ozadja."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon je na voljo"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvojni zaslon"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dvojni zaslon je vklopljen"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> uporablja oba zaslona za prikaz vsebine."</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Naprava se pregreva"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojni zaslon ni na voljo, ker se telefon pregreva."</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Izklopi"</string>
 </resources>
diff --git a/core/res/res/values-sq-watch/strings.xml b/core/res/res/values-sq-watch/strings.xml
index 4285532..093d3b1 100644
--- a/core/res/res/values-sq-watch/strings.xml
+++ b/core/res/res/values-sq-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Aplikacioni <xliff:g id="NUMBER_0">%1$d</xliff:g> nga <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensorët"</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index b3e3108..e3025d5 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Lejon aplikacionin që të ketë qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës, temperatura dhe përqindja e oksigjenit në gjak ndërkohë që aplikacioni është në përdorim."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Qasje te të dhënat e sensorit të trupit, si rrahjet e zemrës kur është në sfond"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Lejon aplikacionin që të ketë qasje te të dhënat e sensorit të trupit, si p.sh. rrahjet e zemrës, temperatura dhe përqindja e oksigjenit në gjak ndërkohë që aplikacioni është në sfond."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Qasu te të dhënat e temperaturës së kyçit të dorës nga sensori i trupit ndërsa aplikacioni është në përdorim."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Lejon aplikacionin të ketë qasje te të dhënat e temperaturës së kyçit të dorës nga sensori i trupit, ndërsa aplikacioni është në përdorim."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Qasu te të dhënat e temperaturës së kyçit të dorës nga sensori i trupit ndërsa aplikacioni është në sfond."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Lejon aplikacionin të ketë qasje te të dhënat e temperaturës së kyçit të dorës nga sensori i trupit, ndërsa aplikacioni është në sfond."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lexo ngjarjet e kalendarit dhe detajet"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ky aplikacion mund të lexojë të gjitha ngjarjet e kalendarit të ruajtura në tabletin tënd dhe të ndajë ose të ruajë të dhënat e kalendarit."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ky aplikacion mund të lexojë të gjitha ngjarjet e kalendarit të ruajtura në pajisjen tënde Android TV dhe të ndajë ose të ruajë të dhënat e kalendarit."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"\"Androidi\" po fillon…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tableti po niset…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Pajisja po niset…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Po përshtat ruajtjen."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Po përfundon përditësimi i sistemit…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> po përmirësohet…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Po përshtat aplikacionin <xliff:g id="NUMBER_0">%1$d</xliff:g> nga gjithsej <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Po përgatit <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Aplikacionet e fillimit."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Po përfundon nisjen."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP nëpërmjet USB-së u aktivizua"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Ndarja e internetit përmes USB-së u aktivizua"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI nëpërmjet USB-së u aktivizua"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Aksesori i USB-së u lidh"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Trokit për më shumë opsione."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Pajisja e lidhur po karikohet. Trokit për opsione të tjera."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"U krye"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Çaktivizo shkurtoren"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Anasjellja e ngjyrës"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Korrigjimi i ngjyrës"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modaliteti i përdorimit me një dorë"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Shumë më i zbehtë"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Po shikon ekranin e plotë"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Për të dalë, rrëshqit nga lart poshtë."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"E kuptova"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rrotullo për një pamje më të mirë"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Dil nga ekrani i ndarë për një pamje më të mirë"</string>
     <string name="done_label" msgid="7283767013231718521">"U krye"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Rrëshqitësi rrethor i orëve"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Rrëshqitësi rrethor i minutave"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Puna <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> i dytë i punës"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> i tretë i punës"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klonim i <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Zhgozhdimi kërkon PIN-in"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Kërko motivin e shkyçjes para heqjes së gozhdimit"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Lejon një aplikacion shoqërues të fillojë shërbimet në plan të parë nga sfondi."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofoni ofrohet"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofoni është i bllokuar"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Ekran i dyfishtë"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Ekrani i dyfishtë është aktiv"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> po i përdor të dyja ekranet për të shfaqur përmbajtje"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Pajisja është shumë e nxehtë"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"\"Ekrani i dyfishtë\" nuk ofrohet sepse telefoni yt po nxehet shumë"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Çaktivizoje"</string>
 </resources>
diff --git a/core/res/res/values-sr-watch/strings.xml b/core/res/res/values-sr-watch/strings.xml
index 054fdf8..7977f66 100644
--- a/core/res/res/values-sr-watch/strings.xml
+++ b/core/res/res/values-sr-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Апликација <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Сензори"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index fd55aa2e..7771805 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -459,14 +459,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док се апликација користи."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Приступ подацима сензора за тело, као што је пулс, у позадини"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Дозвољава апликацији да приступа подацима сензора за тело, као што су пулс, температура и проценат кисеоника у крви док је апликација у позадини."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Приступајте подацима о температури са сензора за тело на ручном зглобу док се апликација користи."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Дозвољава апликацији да приступа подацима о температури са сензора за тело на ручном зглобу док се апликација користи."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Приступајте подацима о температури са сензора за тело на ручном зглобу док је апликација у позадини."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Дозвољава апликацији да приступа подацима о температури са сензора за тело на ручном зглобу док је апликација у позадини."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Читање догађаја и података из календара"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ова апликација може да чита све догађаје из календара које чувате на таблету, као и да дели или чува податке из календара."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ова апликација може да чита све догађаје из календара које чувате на Android TV уређају, као и да дели или чува податке из календара."</string>
@@ -1250,10 +1246,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android се покреће…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Таблет се покреће…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Уређај се покреће…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Меморија се оптимизује."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Ажурирање система се довршава…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> се надограђује…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Оптимизовање апликације <xliff:g id="NUMBER_0">%1$d</xliff:g> од <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Припрема се <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Покретање апликација."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завршавање покретања."</string>
@@ -1365,6 +1359,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP преко USB-а је укључен"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB привезивање је укључено"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Режим MIDI преко USB-а је укључен"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB додатак је повезан"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Додирните за још опција."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Повезани уређај се пуни. Додирните за још опција."</string>
@@ -1713,7 +1709,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Искључи пречицу"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Корекција боја"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим једном руком"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамњено"</string>
@@ -1851,6 +1848,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Приказује се цео екран"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Да бисте изашли, превуците надоле одозго."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Важи"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Ротирајте ради бољег приказа"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Изађите из подељеног екрана ради бољег приказа"</string>
     <string name="done_label" msgid="7283767013231718521">"Готово"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Кружни клизач за сате"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Кружни клизач за минуте"</string>
@@ -1862,6 +1861,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> на послу"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. пословни <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. пословни имејл <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонирај <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Тражи PIN пре откачињања"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string>
@@ -2316,4 +2316,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Дозвољава пратећој апликацији да покрене услуге у првом плану из позадине."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Микрофон је доступан"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон је блокиран"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Двојни екран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Двојни екран је укључен"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи оба екрана за приказивање садржаја"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Уређај је превише загрејан"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Двојни екран је недоступан јер је телефон превише загрејан"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Искључи"</string>
 </resources>
diff --git a/core/res/res/values-sv-watch/strings.xml b/core/res/res/values-sv-watch/strings.xml
index d126fe0..fa296b6 100644
--- a/core/res/res/values-sv-watch/strings.xml
+++ b/core/res/res/values-sv-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensorer"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index eec2656..e013077 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Tillåter att appen får åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur och blodets syrehalt, medan appen används."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Åtkomst till data från kroppssensorer, t.ex. puls, i bakgrunden"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Tillåter att appen får åtkomst till data från kroppssensorer, t.ex. puls, kroppstemperatur och blodets syrehalt, medan appen är i bakgrunden."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Åtkomst till data om handledstemperatur från kroppssensorer medan appen används."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Tillåter att appen får åtkomst till data om handledstemperatur från kroppssensorer medan appen används."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Åtkomst till data om handledstemperatur från kroppssensorer medan appen är i bakgrunden."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Tillåter att appen får åtkomst till data om handledstemperatur från kroppssensorer medan appen är i bakgrunden."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Läsa kalenderhändelser och kalenderuppgifter"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Appen kan läsa alla kalenderhändelser som sparats på surfplattan och dela eller spara uppgifter i din kalender."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Appen kan läsa alla kalenderhändelser som sparats på Android TV-enheten och dela eller spara uppgifter i din kalender."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android startar …"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Surfplattan startar …"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Enheten startar …"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Lagringsutrymmet optimeras."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Systemuppdatering avslutas …"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> uppgraderas …"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Optimerar app <xliff:g id="NUMBER_0">%1$d</xliff:g> av <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> förbereds."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Appar startas."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Uppgraderingen är klar."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"PTP via USB har aktiverats"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Internetdelning via USB har aktiverats"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB har aktiverats"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB-tillbehör anslutet"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Tryck för fler alternativ."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Den anslutna enheten laddas. Tryck om du vill ha fler alternativ."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Klar"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Inaktivera kortkommandot"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Använd kortkommandot"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverterade färger"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Färgkorrigering"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhandsläge"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradimmat"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Visar på fullskärm"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Svep nedåt från skärmens överkant för att avsluta."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotera för att få en bättre vy"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Stäng delad skärm för att få en bättre vy"</string>
     <string name="done_label" msgid="7283767013231718521">"Klart"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Cirkelreglage för timmar"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Cirkelreglage för minuter"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> för arbetet"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Andra <xliff:g id="LABEL">%1$s</xliff:g> för jobbet"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Tredje <xliff:g id="LABEL">%1$s</xliff:g> för jobbet"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klona <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Be om pinkod innan skärmen slutar fästas"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Be om upplåsningsmönster innan skärmen slutar fästas"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Be om lösenord innan skärmen slutar fästas"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Tillåter att en tillhörande app startar förgrundstjänster i bakgrunden."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofonen är tillgänglig"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonen är blockerad"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dubbel skärm"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dubbel skärm är på"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> använder båda skärmarna för att visa innehåll"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Enheten är för varm"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dubbel skärm kan inte användas eftersom telefonen börjar bli för varm"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Stäng av"</string>
 </resources>
diff --git a/core/res/res/values-sw-watch/strings.xml b/core/res/res/values-sw-watch/strings.xml
index 0257a56..bf6b2c5 100644
--- a/core/res/res/values-sw-watch/strings.xml
+++ b/core/res/res/values-sw-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Programu ya <xliff:g id="NUMBER_0">%1$d</xliff:g> kati ya <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Vihisi"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index f0bb94b..618d14a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Hurushusu programu ifikie data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, halijoto na asilimia ya oksijeni kwenye damu wakati programu inatumika."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Fikia data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, wakati programu inatumika chinichini"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Hurushusu programu ifikie data ya vitambuzi shughuli za mwili, kama vile mapigo ya moyo, halijoto na asilimia ya oksijeni kwenye damu wakati programu inatumika chinichini."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Fikia data ya kitambuzi cha halijoto ya kifundo cha mkono, wakati programu inatumika."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Huruhusu programu kufikia data ya kitambuzi cha halijoto ya kifundo cha mkono, wakati programu inatumika."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Fikia data ya kitambuzi cha halijoto ya kifundo cha mkono, wakati programu inatumika chinichini."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Huruhusu programu kufikia data ya kitambuzi cha halijoto ya kifundo cha mkono, wakati programu inatumika chinichini."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Soma matukio na maelezo ya kalenda"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Programu hii inaweza kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kompyuta yako kibao na kushiriki au kuhifadhi data yako ya kalenda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Programu hii inaweza kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye kifaa chako cha Android TV na kushiriki au kuhifadhi data ya kalenda yako."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Inawasha Android..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Kompyuta kibao inawaka…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Kifaa kiwaka…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Inaboresha hifadhi."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Inakamilisha sasisho la mfumo…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> inapata toleo jipya…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Inaboresha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> kutoka <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Inaandaa <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Programu zinaanza"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Inamaliza kuwasha."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Umewasha hali ya PTP kupitia USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Umewasha hali ya kusambaza mtandao ukitumia USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Umewasha hali ya MIDI kupitia USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Imeunganisha kifuasi cha USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Gusa ili upate chaguo zaidi."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Inachaji kifaa kilichounganishwa. Gusa ili upate chaguo zaidi."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Nimemaliza"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Zima kipengele cha Njia ya Mkato"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tumia Njia ya Mkato"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Usahihishaji wa rangi"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Hali ya kutumia kwa mkono mmoja"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Kipunguza mwangaza zaidi"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Unatazama skrini nzima"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Ili kuondoka, telezesha kidole kutoka juu hadi chini."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Nimeelewa"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zungusha ili upate mwonekano bora"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Funga skrini iliyogawanywa ili upate mwonekano bora"</string>
     <string name="done_label" msgid="7283767013231718521">"Imekamilika"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Kitelezi cha mviringo wa saa"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Kitelezi cha mviringo wa dakika"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Ya kazini <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> ya 2 ya Kazini"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> ya 3 ya Kazini"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Nakala ya <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Itisha PIN kabla hujabandua"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Omba mchoro wa kufungua kabla hujabandua"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Omba nenosiri kabla hujabandua"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Huruhusu programu oanifu kuanzisha huduma zinazoonekana kwenye skrini kutoka katika huduma zinazoendelea chinichini."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Maikrofoni inapatikana"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Maikrofoni imezuiwa"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Hali ya skrini mbili"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Umewasha kipengele cha hali ya skrini mbili"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumia skrini zote kuonyesha maudhui"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Kifaa kina joto sana"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Kipengele cha Hali ya Skrini Mbili hakipatikani kwa sababu simu yako inapata joto sana"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Zima"</string>
 </resources>
diff --git a/core/res/res/values-ta-watch/strings.xml b/core/res/res/values-ta-watch/strings.xml
index 97539aa..baaa696 100644
--- a/core/res/res/values-ta-watch/strings.xml
+++ b/core/res/res/values-ta-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"ஆப்ஸ்: <xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"உணர்விகள்"</string>
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 80a9ee9..ff656b4 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ஆப்ஸ் பயன்பாட்டில் இருக்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார் தரவை அணுக ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"பின்னணியில் இயங்கும்போது இதயத் துடிப்பு போன்ற உடல் சென்சார் தரவை அணுகுதல்"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ஆப்ஸ் பின்னணியில் இயங்கும்போது இதயத் துடிப்பு, வெப்பநிலை, ரத்த ஆக்ஸிஜன் சதவீதம் போன்ற உடல் சென்சார் தரவை அணுக ஆப்ஸை அனுமதிக்கிறது."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ஆப்ஸ் பயன்பாட்டில் இருக்கும்போது உடல் சென்சார் மணிக்கட்டு வெப்பநிலைத் தரவை அணுகுதல்."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ஆப்ஸ் பயன்பாட்டில் இருக்கும்போது உடல் சென்சார் மணிக்கட்டு வெப்பநிலைத் தரவை அணுகுவதற்கு ஆப்ஸை அனுமதிக்கும்."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ஆப்ஸ் பின்னணியில் இயங்கும்போது உடல் சென்சார் மணிக்கட்டு வெப்பநிலைத் தரவை அணுகுதல்."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ஆப்ஸ் பின்னணியில் இயங்கும்போது உடல் சென்சார் மணிக்கட்டு வெப்பநிலைத் தரவை அணுகுவதற்கு ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"கேலெண்டர் நிகழ்வுகளையும் விவரங்களையும் படிக்கலாம்"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள கேலெண்டர் நிகழ்வுகள் அனைத்தையும் படிக்கலாம், உங்கள் கேலெண்டர் தரவைப் பகிரலாம் அல்லது சேமிக்கலாம்."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"உங்கள் Android TVயில் சேமித்துள்ள அனைத்துக் கேலெண்டர் நிகழ்வுகளையும் இந்த ஆப்ஸால் தெரிந்துகொள்ள முடியும். அத்துடன் உங்களின் கேலெண்டர் தரவைப் பகிரவும் சேமிக்கவும் முடியும்."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android துவங்குகிறது..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"டேப்லெட் தொடங்குகிறது…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"சாதனம் தொடங்குகிறது…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"சேமிப்பகத்தை உகந்ததாக்குகிறது."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"சிஸ்டம் புதுப்பிப்பை நிறைவுசெய்கிறது…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g>ஐ மேம்படுத்துகிறது…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> ஆப்ஸை ஒருங்கிணைக்கிறது."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>ஐத் தயார்செய்கிறது."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ஆப்ஸ் தொடங்கப்படுகின்றன."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"துவக்குதலை முடிக்கிறது."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB மூலமாக PTP பயன்முறை ஆன் செய்யப்பட்டது"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB இணைப்பு முறை ஆன் செய்யப்பட்டது"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB மூலமாக MIDI பயன்முறை ஆன் செய்யப்பட்டது"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB துணைக்கருவி இணைக்கப்பட்டது"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"மேலும் விருப்பங்களுக்கு, தட்டவும்."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"இணைக்கப்பட்ட சாதனத்தைச் சார்ஜ் செய்கிறது. கூடுதல் விருப்பங்களுக்கு, தட்டவும்."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"முடிந்தது"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ஷார்ட்கட்டை முடக்கு"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ஷார்ட்கட்டைப் பயன்படுத்து"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"நிற நேரெதிர் மாற்றம்"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"கலர் கரெக்‌ஷன்"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ஒற்றைக் கைப் பயன்முறை"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"மிகக் குறைவான வெளிச்சம்"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"முழுத் திரையில் காட்டுகிறது"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"வெளியேற, மேலிருந்து கீழே ஸ்வைப் செய்யவும்"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"புரிந்தது"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"சிறந்த காட்சிக்கு சுழற்றுங்கள்"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"சிறந்த காட்சிக்கு திரைப் பிரிப்புப் பயன்முறையில் இருந்து வெளியேறுங்கள்"</string>
     <string name="done_label" msgid="7283767013231718521">"முடிந்தது"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"மணிநேர வட்ட வடிவ ஸ்லைடர்"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"நிமிடங்களுக்கான வட்டவடிவ ஸ்லைடர்"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"பணியிடம் <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"குளோன் <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"அகற்றும் முன் PINஐக் கேள்"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"பின்னணியிலிருந்து முன்புலச் சேவைகளைத் தொடங்க துணைத் தயாரிப்பு ஆப்ஸை அனுமதிக்கும்."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"மைக்ரோஃபோன் இயக்கப்பட்டது"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"மைக்ரோஃபோன் முடக்கப்பட்டுள்ளது"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"இரட்டைத் திரை"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"இரட்டைத் திரை அம்சம் இயக்கத்தில் உள்ளது"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"உள்ளடக்கத்தைக் காட்டுவதற்கு இரண்டு டிஸ்ப்ளேக்களையும் <xliff:g id="APP_NAME">%1$s</xliff:g> பயன்படுத்துகிறது"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"சாதனம் மிகவும் சூடாக உள்ளது"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"உங்கள் மொபைல் மிகவும் சூடாக இருப்பதால் இரட்டைத் திரை அம்சத்தைப் பயன்படுத்த முடியாது"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"முடக்கு"</string>
 </resources>
diff --git a/core/res/res/values-te-watch/strings.xml b/core/res/res/values-te-watch/strings.xml
index e97ee7c..3a487bd 100644
--- a/core/res/res/values-te-watch/strings.xml
+++ b/core/res/res/values-te-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో<xliff:g id="NUMBER_0">%1$d</xliff:g>వ యాప్."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"సెన్సార్‌లు"</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index e0e232f..46ab23c 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"యాప్ ఉపయోగంలో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, ఇంకా రక్తంలోని ఆక్సిజన్ శాతం వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"బ్యాక్‌గ్రౌండ్‌లో గుండె స్పందన రేటు వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయండి"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"యాప్ బ్యాక్‌గ్రౌండ్‌లో ఉన్నప్పుడు గుండె స్పందన రేటు, ఉష్ణోగ్రత, ఇంకా రక్తంలోని ఆక్సిజన్ శాతం వంటి శరీర సెన్సార్ డేటాను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"యాప్ వినియోగంలో ఉన్నప్పుడు, శరీర సెన్సార్ మణికట్టు ఉష్ణోగ్రత డేటాను యాక్సెస్ చేయండి."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"యాప్ వినియోగంలో ఉన్నప్పుడు, శరీర సెన్సార్ మణికట్టు ఉష్ణోగ్రత డేటాను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"యాప్ బ్యాక్‌గ్రౌండ్‌లో ఉన్నప్పుడు, శరీర సెన్సార్ మణికట్టు ఉష్ణోగ్రత డేటాను యాక్సెస్ చేయండి."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"యాప్ బ్యాక్‌గ్రౌండ్‌లో ఉన్నప్పుడు, శరీర సెన్సార్ మణికట్టు ఉష్ణోగ్రత డేటాను యాక్సెస్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"క్యాలెండర్ ఈవెంట్‌లు మరియు వివరాలను చదవడం"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"ఈ యాప్ మీ టాబ్లెట్‌లో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు మరియు మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"ఈ యాప్‌ మీ Android TV పరికరంలో నిల్వ చేసిన క్యాలెండర్ ఈవెంట్‌లన్నీ చదవగలదు, మీ క్యాలెండర్ డేటాను షేర్ చేయగలదు లేదా సేవ్ చేయగలదు."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android ప్రారంభమవుతోంది…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"టాబ్లెట్ ప్రారంభమవుతోంది…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"పరికరం ప్రారంభమవుతోంది…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"నిల్వను అనుకూలపరుస్తోంది."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"సిస్టమ్ అప్‌డేట్‌ని పూర్తి చేస్తోంది…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g>ని అప్‌గ్రేడ్ చేస్తోంది…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g>లో <xliff:g id="NUMBER_0">%1$d</xliff:g> యాప్‌ను అనుకూలీకరిస్తోంది."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g>ని సిద్ధం చేస్తోంది."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"యాప్‌లను ప్రారంభిస్తోంది."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"బూట్‌ను ముగిస్తోంది."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB ద్వారా PTP ఆన్ చేయబడింది"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB టెథెరింగ్ ఆన్ చేయబడింది"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB ద్వారా MIDI ఆన్ చేయబడింది"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ఉపకరణం కనెక్ట్ చేయబడింది"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"కనెక్ట్ చేయబడిన పరికరాన్ని ఛార్జ్ చేస్తోంది. మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"పూర్తయింది"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"షార్ట్‌కట్‌ను ఆఫ్ చేయి"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"షార్ట్‌కట్‌ను ఉపయోగించండి"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"కలర్ మార్పిడి"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"కలర్ కరెక్షన్"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"వన్-హ్యాండెడ్ మోడ్"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ఎక్స్‌ట్రా డిమ్"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"ఫుల్-స్క్రీన్‌లో వీక్షిస్తున్నారు"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"నిష్క్రమించడానికి, పై నుండి క్రిందికి స్వైప్ చేయండి."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"అర్థమైంది"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"మెరుగైన వీక్షణ కోసం తిప్పండి"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"మెరుగైన వీక్షణ కోసం స్ప్లిట్ స్క్రీన్ నుండి నిష్క్రమించండి"</string>
     <string name="done_label" msgid="7283767013231718521">"పూర్తయింది"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"గంటల వృత్తాకార స్లయిడర్"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"నిమిషాల వృత్తాకార స్లయిడర్"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"ఆఫీస్ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2వ కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3వ కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"క్లోన్ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"అన్‌పిన్ చేయడానికి ముందు పిన్‌ కోసం అడుగు"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"అన్‌పిన్ చేయడానికి ముందు అన్‌లాక్ ఆకృతి కోసం అడుగు"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"అన్‌పిన్ చేయడానికి ముందు పాస్‌వర్డ్ కోసం అడుగు"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"బ్యాక్‌గ్రౌండ్ నుండి ఫోర్‌గ్రౌండ్ సర్వీస్‌లను ప్రారంభించడానికి సహాయక యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"మైక్రోఫోన్ అందుబాటులో ఉంది"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"మైక్రోఫోన్ బ్లాక్ చేయబడింది"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"డ్యూయల్ స్క్రీన్"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"డ్యూయల్ స్క్రీన్ ఆన్‌లో ఉంది"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"కంటెంట్‌ను చూపడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> రెండు డిస్‌ప్లేలనూ ఉపయోగిస్తుంది"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"పరికరం చాలా వేడిగా ఉంది"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"మీ ఫోన్ చాలా వేడిగా అవుతున్నందున, డ్యూయల్ స్క్రీన్ అందుబాటులో లేదు"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ఆఫ్ చేయండి"</string>
 </resources>
diff --git a/core/res/res/values-th-watch/strings.xml b/core/res/res/values-th-watch/strings.xml
index 3ffe914..bc4be24 100644
--- a/core/res/res/values-th-watch/strings.xml
+++ b/core/res/res/values-th-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"แอป <xliff:g id="NUMBER_0">%1$d</xliff:g> จาก <xliff:g id="NUMBER_1">%2$d</xliff:g> แอป"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"เซ็นเซอร์"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 6c6b406..39dd58e 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"อนุญาตให้แอปเข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ และเปอร์เซ็นต์ออกซิเจนในเลือด ขณะใช้งานแอป"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"เข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ ขณะแอปทำงานในเบื้องหลัง"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"อนุญาตให้แอปเข้าถึงข้อมูลเซ็นเซอร์ร่างกาย เช่น อัตราการเต้นของหัวใจ อุณหภูมิ และเปอร์เซ็นต์ออกซิเจนในเลือด ขณะที่แอปทำงานในเบื้องหลัง"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"เข้าถึงข้อมูลอุณหภูมิบนข้อมือจากเซ็นเซอร์ร่างกายขณะใช้งานแอป"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"อนุญาตให้แอปเข้าถึงข้อมูลอุณหภูมิบนข้อมือจากเซ็นเซอร์ร่างกายขณะใช้งานแอป"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"เข้าถึงข้อมูลอุณหภูมิบนข้อมือจากเซ็นเซอร์ร่างกายขณะที่แอปทำงานในเบื้องหลัง"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"อนุญาตให้แอปเข้าถึงข้อมูลอุณหภูมิบนข้อมือจากเซ็นเซอร์ร่างกายขณะที่แอปทำงานในเบื้องหลัง"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"อ่านกิจกรรมในปฏิทินและรายละเอียด"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"แอปนี้สามารถอ่านกิจกรรมทั้งหมดในปฏิทินที่เก็บไว้ในแท็บเล็ต รวมถึงแชร์หรือบันทึกข้อมูลในปฏิทินของคุณ"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"แอปนี้อ่านกิจกรรมทั้งหมดในปฏิทินที่จัดเก็บไว้ในอุปกรณ์ Android TV ได้ รวมถึงแชร์หรือบันทึกข้อมูลในปฏิทินของคุณได้ด้วย"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android กำลังเริ่มต้น…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"แท็บเล็ตกำลังเริ่มต้น…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"อุปกรณ์กำลังเริ่มต้น…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"กำลังเพิ่มประสิทธิภาพพื้นที่จัดเก็บข้อมูล"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"กำลังอัปเดตระบบ…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"กำลังอัปเกรด <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"กำลังเพิ่มประสิทธิภาพแอปพลิเคชัน <xliff:g id="NUMBER_0">%1$d</xliff:g> จาก <xliff:g id="NUMBER_1">%2$d</xliff:g> รายการ"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"กำลังเตรียม <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"กำลังเริ่มต้นแอปพลิเคชัน"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"เสร็จสิ้นการบูต"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"เปิดโหมด PTP ผ่าน USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"เปิดการเชื่อมต่ออินเทอร์เน็ตผ่าน USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"เปิดโหมด MIDI ผ่าน USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"เชื่อมต่ออุปกรณ์เสริม USB แล้ว"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"กำลังชาร์จอุปกรณ์ที่เชื่อมต่อ แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"เสร็จ"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"ปิดทางลัด"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ใช้ทางลัด"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"การกลับสี"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"การแก้สี"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"โหมดมือเดียว"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"หรี่แสงเพิ่มเติม"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"กำลังดูแบบเต็มหน้าจอ"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"หากต้องการออก ให้เลื่อนลงจากด้านบน"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"รับทราบ"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"หมุนเพื่อรับมุมมองที่ดียิ่งขึ้น"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"ออกจากโหมดแยกหน้าจอเพื่อรับมุมมองที่ดียิ่งขึ้น"</string>
     <string name="done_label" msgid="7283767013231718521">"เสร็จสิ้น"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"ตัวเลื่อนหมุนระบุชั่วโมง"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"ตัวเลื่อนหมุนระบุนาที"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g>ที่ทำงาน"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> งานที่ 2"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> งานที่ 3"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"โคลน <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ขอ PIN ก่อนเลิกปักหมุด"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ขอรูปแบบการปลดล็อกก่อนเลิกปักหมุด"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ขอรหัสผ่านก่อนเลิกปักหมุด"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"อนุญาตจากเบื้องหลังให้แอปที่ใช้ร่วมกันเริ่มการทำงานของบริการที่ทำงานอยู่เบื้องหน้า"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"ไมโครโฟนพร้อมใช้งาน"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"ไมโครโฟนถูกบล็อก"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"หน้าจอคู่"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"หน้าจอคู่เปิดอยู่"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังใช้จอแสดงผลทั้งสองจอเพื่อแสดงเนื้อหา"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"อุปกรณ์ร้อนเกินไป"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"หน้าจอคู่ไม่พร้อมให้ใช้งานเนื่องจากโทรศัพท์ของคุณร้อนเกินไป"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ปิด"</string>
 </resources>
diff --git a/core/res/res/values-tl-watch/strings.xml b/core/res/res/values-tl-watch/strings.xml
index 619d9f9..961cccf 100644
--- a/core/res/res/values-tl-watch/strings.xml
+++ b/core/res/res/values-tl-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> ng <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Mga Sensor"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 21f8e39..e5b03e0 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Nagpapahintulot sa app na i-access ang data ng sensor ng katawan, gaya ng bilis ng tibok ng puso, temperatura, at porsyento ng oxygen sa dugo, habang ginagamit ang app."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"I-access ang data ng sensor ng katawan gaya ng heart rate habang nasa background"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Nagpapahintulot sa app na i-access ang data ng sensor ng katawan, gaya ng bilis ng tibok ng puso, temperatura, at porsyento ng oxygen sa dugo, habang nasa background ang app."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"I-access ang data ng temperatura ng wrist mula sa sensor ng katawan habang ginagamit ang app."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Nagpapahintulot sa app na i-access ang data ng temperatura ng wrist mula sa sensor ng katawan, habang ginagamit ang app."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"I-access ang data ng temperatura ng wrist mula sa sensor ng katawan habang nasa background ang app."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Nagpapahintulot sa app na i-access ang data ng temperatura ng wrist mula sa sensor ng katawan, habang nasa background ang app."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Magbasa ng mga event sa kalendaryo at detalye"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Mababasa ng app na ito ang lahat ng event sa kalendaryo na naka-store sa iyong tablet at maibabahagi o mase-save nito ang data ng iyong kalendaryo."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Mababasa ng app na ito ang lahat ng event sa kalendaryo na naka-store sa iyong Android TV device at maibabahagi o mase-save nito ang data ng kalendaryo mo."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Nagsisimula ang Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Nagsisimula ang tablet…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Nagsisimula ang device…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Ino-optimize ang storage."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Tinatapos ang pag-update ng system…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Nag-a-upgrade ang <xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Ino-optimize ang app <xliff:g id="NUMBER_0">%1$d</xliff:g> ng <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Ihinahanda ang <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Sinisimulan ang apps."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Pagtatapos ng pag-boot."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Na-on ang PTP sa pamamagitan ng USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Na-on ang pag-tether ng USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Na-on ang MIDI sa pamamagitan ng USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Nakakonekta ang USB accessory"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"I-tap para sa higit pang mga opsyon."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"China-charge ang nakakonektang device. Mag-tap para sa higit pang opsyon."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Tapos na"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"I-off ang Shortcut"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Pagtatama ng kulay"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-Hand mode"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Panonood sa full screen"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Upang lumabas, mag-swipe mula sa itaas pababa."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Nakuha ko"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"I-rotate para sa mas magandang view"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Lumabas sa split screen para sa mas magandang view"</string>
     <string name="done_label" msgid="7283767013231718521">"Tapos na"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Pabilog na slider ng mga oras"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Pabilog na slider ng mga minuto"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Pangalawang <xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Pangatlong <xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"I-clone ang <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Humingi ng PIN bago mag-unpin"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Humingi ng pattern sa pag-unlock bago mag-unpin"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Humingi ng password bago mag-unpin"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Nagbibigay-daan sa kasamang app na magsimula ng mga serbisyo sa foreground mula sa background."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Available ang mikropono"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Naka-block ang mikropono"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Naka-on ang dual screen"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Ginagamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang parehong display para magpakita ng content"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Masyadong mainit ang device"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Hindi available ang Dual Screen dahil masyado nang umiinit ang telepono mo"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"I-off"</string>
 </resources>
diff --git a/core/res/res/values-tr-watch/strings.xml b/core/res/res/values-tr-watch/strings.xml
index e407867..19add08 100644
--- a/core/res/res/values-tr-watch/strings.xml
+++ b/core/res/res/values-tr-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Uygulama <xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensörler"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index f62560e..78dac1d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Kullanımdaki uygulamanın nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörü verilerine erişmesine izin verir."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Arka plandayken nabız gibi vücut sensörü verilerine erişme"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Arka plandaki uygulamanın nabız, vücut ısısı, kandaki oksijen yüzdesi gibi vücut sensörü verilerine erişmesine izin verir."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Uygulama kullanımdayken bilek ısısı gibi vücut sensörü verilerine erişme."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Kullanımdaki uygulamanın bilek ısısı gibi vücut sensörü verilerine erişmesine izin verir."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Uygulama arka plandayken bilek ısısı gibi vücut sensörü verilerine erişme."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Arka plandaki uygulamanın bilek ısısı gibi vücut sensörü verilerine erişmesine izin verir."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Takvim etkinlikleri ve ayrıntılarını okuma"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu uygulama, tabletinizde kayıtlı tüm takvim etkinliklerini okuyabilir ve takvim verilerinizi paylaşabilir ya da kaydedebilir."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu uygulama, Android TV cihazınızda kayıtlı tüm takvim etkinliklerini okuyabilir ve takvim verilerinizi paylaşabilir ya da kaydedebilir."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android başlatılıyor…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Tablet başlatılıyor…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Cihaz başlatılıyor…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Depolama optimize ediliyor."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Sistem güncellemesi tamamlanıyor…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> yeni sürüme geçiriliyor…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g> uygulama optimize ediliyor."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> hazırlanıyor."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Uygulamalar başlatılıyor"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Açılış tamamlanıyor."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB üzerinden PTP açık"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB tethering açık"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB üzerinden MIDI açık"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB aksesuarı bağlandı"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Diğer seçenekler için dokunun."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Bağlı cihaz şarj ediliyor. Diğer seçenekler için dokunun."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Bitti"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Kısayolu Kapat"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Renk düzeltme"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tek El modu"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra loş"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Tam ekran olarak görüntüleme"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Çıkmak için yukarıdan aşağıya doğru hızlıca kaydırın."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Anladım"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Daha iyi bir görünüm elde etmek için ekranı döndürün"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Daha iyi bir görünüm elde etmek için bölünmüş ekrandan çıkın"</string>
     <string name="done_label" msgid="7283767013231718521">"Bitti"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Saat kaydırma çemberi"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Dakika kaydırma çemberi"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> (İş)"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"İş için 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"İş için 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> klonu"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sabitlemeyi kaldırmadan önce PIN\'i sor"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Tamamlayıcı uygulamanın arka plandan ön plan hizmetlerini başlatmasına izin verir."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon kullanılabilir"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon engellenmiş"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Çift ekran"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Çift Ekran açık"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>, içeriği göstermek için her iki ekranı da kullanıyor"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Cihaz çok ısındı"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Telefonunuz çok ısındığı için Çift Ekran kullanılamıyor"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Kapat"</string>
 </resources>
diff --git a/core/res/res/values-uk-watch/strings.xml b/core/res/res/values-uk-watch/strings.xml
index 1d1fb60..b8416c3 100644
--- a/core/res/res/values-uk-watch/strings.xml
+++ b/core/res/res/values-uk-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Додаток <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Датчики"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 322929f..bae0934 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -460,14 +460,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Під час використання додатка він матиме доступ до даних датчиків на тілі, наприклад пульсу, температури та відсотка кисню в крові."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Доступ до показників датчиків на тілі, наприклад пульсу, у фоновому режимі"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Коли додаток працюватиме у фоновому режимі, він матиме доступ до показників датчиків на тілі, наприклад пульсу, температури та відсотка кисню в крові."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Отримувати доступ до даних датчика на тілі про температуру в зоні зап’ястя, коли додаток використовується."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Під час використання додатка він матиме доступ до даних датчика на тілі про температуру в зоні зап’ястя."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Отримувати доступ до даних датчика на тілі про температуру в зоні зап’ястя, коли додаток працює у фоновому режимі."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Коли додаток працюватиме у фоновому режимі, він матиме доступ до даних датчика на тілі про температуру в зоні зап’ястя."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Переглядати події календаря й додаткову інформацію"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Цей додаток може переглядати всі події календаря, збережені на вашому планшеті, а також надсилати та зберігати дані календаря."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Додаток може переглядати всі події календаря, збережені на вашому пристрої Android TV, а також надсилати та зберігати дані календаря."</string>
@@ -1251,10 +1247,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Запуск ОС Android…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Планшет запускається…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Пристрій запускається…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Оптимізація пам’яті."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Завершується оновлення системи…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Додаток <xliff:g id="APPLICATION">%1$s</xliff:g> оновлюється…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Оптимізація програми <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Підготовка додатка <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск програм."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Завершення завантаження."</string>
@@ -1366,6 +1360,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP через USB ввімкнено"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Режим USB-модема ввімкнено"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Режим MIDI через USB ввімкнено"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Під’єднано USB-аксесуар"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Торкніться, щоб переглянути більше опцій."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Під’єднаний пристрій заряджається. Торкніться, щоб побачити більше опцій."</string>
@@ -1714,7 +1710,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Готово"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Вимкнути ярлик"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Використовувати ярлик"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія кольорів"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Корекція кольору"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим керування однією рукою"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додаткове зменшення яскравості"</string>
@@ -1852,6 +1849,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Перегляд на весь екран"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Щоб вийти, проведіть пальцем зверху вниз."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Оберніть для кращого огляду"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Для кращого огляду вийдіть із режиму розділення екрана"</string>
     <string name="done_label" msgid="7283767013231718521">"Готово"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Вибір годин на циферблаті"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Вибір хвилин на циферблаті"</string>
@@ -1863,6 +1862,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Робоча <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-а робота: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-я робота: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Копія додатка <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-код для відкріплення"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитувати ключ розблокування перед відкріпленням"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитувати пароль перед відкріпленням"</string>
@@ -2317,4 +2317,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Дозволяє супутньому додатку запускати активні сервіси у фоновому режимі."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Мікрофон доступний"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Мікрофон заблоковано"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Подвійний екран"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Подвійний екран увімкнено"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> використовує обидва екрани для показу контенту"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Пристрій сильно нагрівається"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Подвійний екран недоступний, оскільки телефон сильно нагрівається"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Вимкнути"</string>
 </resources>
diff --git a/core/res/res/values-ur-watch/strings.xml b/core/res/res/values-ur-watch/strings.xml
index 073022d..ec1089c 100644
--- a/core/res/res/values-ur-watch/strings.xml
+++ b/core/res/res/values-ur-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"ایپ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>۔"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"سینسرز"</string>
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 50e79a1..62f1c2b 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"ایپ کے استعمال میں ہونے کے دوران ایپ کو حرکت قلب کی شرح، درجہ حرارت اور خون میں آکسیجن کا فیصد جیسے باڈی سینسر ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"پس منظر میں ہونے کے دوران حرکت قلب کی شرح جیسے باڈی سینسر ڈیٹا تک رسائی پائیں"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"ایپ کے پس منظر میں ہونے کے دوران ایپ کو حرکت قلب کی شرح، درجہ حرارت اور خون میں آکسیجن کا فیصد جیسے باڈی سینسر ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"ایپ کے استعمال میں ہونے کے دوران، باڈی سینسر کلائی کے درجہ حرارت کے ڈیٹا تک رسائی حاصل کریں۔"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"ایپ کے استعمال میں ہونے کے دوران، ایپ کو باڈی سینسر کلائی کے درجہ حرارت کے ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"ایپ کے پس منظر میں ہونے کے دوران، باڈی سینسر کلائی کے درجہ حرارت کے ڈیٹا تک رسائی حاصل کریں۔"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"ایپ کے پس منظر میں ہونے کے دوران، ایپ کو باڈی سینسر کلائی کے درجہ حرارت کے ڈیٹا تک رسائی کی اجازت دیتا ہے۔"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"کیلنڈر ایونٹس اور تفاصیل پڑھیں"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"یہ ایپ آپ کے ٹیبلیٹ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھ سکتی ہے اور آپ کے  کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کر سکتی ہے۔"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"‏یہ ایپ آپ کے Android TV آلہ پر اسٹور کردہ سبھی کیلنڈر ایونٹس کو پڑھ سکتی ہے اور آپ کے کیلنڈر ڈیٹا کا اشتراک یا اسے محفوظ کر سکتی ہے۔"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"‏Android شروع ہو رہا ہے…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"ٹیبلیٹ شروع ہو رہا ہے…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"آلہ شروع ہو رہا ہے…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"اسٹوریج کو بہترین بنایا جا رہا ہے۔"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"سسٹم اپ ڈیٹ مکمل ہو رہا ہے…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> اپ گریڈ ہو رہی ہے…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"ایپ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g> کو بہتر بنایا جا رہا ہے۔"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> تیار ہو رہی ہے۔"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ایپس شروع ہو رہی ہیں۔"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"بوٹ مکمل ہو رہا ہے۔"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"‏USB کے ذریعے PTP آن ہے"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"‏USB ٹیدرنگ آن ہے"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"‏USB کے ذریعے MIDI آن ہے"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"‏USB کے لوازم منسلک ہیں"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"مزید اختیارات کیلئے تھپتھپائیں۔"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"منسلکہ آلہ کو چارج کیا جا رہا ہے۔ مزید اختیارات کے لئے تھپتھپائيں۔"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"ہو گیا"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"شارٹ کٹ آف کریں"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"شارٹ کٹ استعمال کریں"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"رنگوں کی تقلیب"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"رنگ کی اصلاح"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ایک ہاتھ کی وضع"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"اضافی مدھم"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"پوری اسکرین میں دیکھ رہے ہیں"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"خارج ہونے کیلئے اوپر سے نیچے سوائپ کریں۔"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"سمجھ آ گئی"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"بہتر منظر کے لیے گھمائیں"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"بہتر منظر کے لیے اسپلٹ اسکرین سے باہر نکلیں"</string>
     <string name="done_label" msgid="7283767013231718521">"ہو گیا"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"گھنٹوں کا سرکلر سلائیڈر"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"منٹس سرکلر سلائیڈر"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"دفتر <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"دوسرا کام <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"تیسرا کام <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> کلون"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"‏پن ہٹانے سے پہلے PIN طلب کریں"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"ساتھی ایپ کو پس منظر سے پیش منظر کی سروسز شروع کرنے کی اجازت دیتی ہے۔"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"مائیکروفون دستیاب ہے"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"مائیکروفون مسدود ہے"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"دوہری اسکرین"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"دوہری اسکرین آن ہے"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> مواد دکھانے کیلئے دونوں ڈسپلیز استعمال کر رہی ہے"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"آلہ بہت زیادہ گرم ہے"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"دوہری اسکرین دستیاب نہیں ہے کیونکہ آپ کا فون بہت زیادہ گرم ہو رہا ہے"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"آف کریں"</string>
 </resources>
diff --git a/core/res/res/values-uz-watch/strings.xml b/core/res/res/values-uz-watch/strings.xml
index fd5b2e9..cf1b7a5 100644
--- a/core/res/res/values-uz-watch/strings.xml
+++ b/core/res/res/values-uz-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"<xliff:g id="NUMBER_1">%2$d</xliff:g>dan <xliff:g id="NUMBER_0">%1$d</xliff:g> ilova."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Sensorlar"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index ddcb6e1..055a3b5 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ilovaga yurak urishi, harorat, qondagi kislorod foizi kabi tanadagi sensor maʼlumotlaridan foydalanishga ruxsat beradi."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Fonda ishlaganda yurak urishi kabi tanadagi sensor maʼlumotlariga ruxsat"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ilovaga yurak urishi, harorat, qondagi kislorod foizi kabi tanadagi sensor maʼlumotlaridan ilova fonda ishlaganda foydalanishga ruxsat beradi."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Ilova ishlayotgan vaqtda tana sensori bilak harorati maʼlumotlariga kirish."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Ilovaga tana sensori bilak harorati maʼlumotlaridan ilova ishlayotganda foydalanishga ruxsat beradi."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Ilova fonda ishlayotgan vaqtda tana sensori bilak harorati maʼlumotlariga kirish."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Ilovaga tana sensori bilan harorati maʼlumotlaridan ilova fonda ishlayotganda foydalanishga ruxsat beradi."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Taqvim tadbirlari va tafsilotlarini o‘qish"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Bu ilova planshetdagi barcha taqvim tadbirlarini o‘qiy olishi hamda taqvim ma’lumotlarini ulashishi yoki saqlashi mumkin."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Bu ilova Android TV qurilmangizda barcha taqvim tadbirlarini oʻqiy olishi hamda taqvim maʼlumotlarini ulashishi yoki saqlashi mumkin."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android ishga tushmoqda…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Planshet ishga tushirilmoqda…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Qurilma ishga tushirilmoqda…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Xotira optimallashtirilmoqda."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Tizimni yangilash tugay deb qoldi…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasi yangilanmoqda…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Ilovalar optimallashtirilmoqda (<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>)."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> tayyorlanmoqda."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Ilovalar ishga tushirilmoqda."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Tizimni yuklashni tugatish."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB orqali PTP rejimi yoqildi"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB modem rejimi yoqildi"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB orqali MIDI rejimi yoqildi"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB qurilma ulandi"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Boshqa parametrlarini ko‘rish uchun bosing."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Ulangan qurilma quvvatlanmoqda. Boshqa parametrlar uchun bosing."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"OK"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Tezkor ishga tushirishni o‘chirib qo‘yish"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tezkor ishga tushirishdan foydalanish"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Ranglarni akslantirish"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Ranglarni tuzatish"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Ixcham rejim"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Juda xira"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Butun ekranli rejim"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Chiqish uchun tepadan pastga torting."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Yaxshiroq koʻrish uchun kamerani buring"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Yaxshiroq koʻrish uchun ajratilgan ekran rejimidan chiqing"</string>
     <string name="done_label" msgid="7283767013231718521">"Tayyor"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Doiradan soatni tanlang"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Doiradan daqiqani tanlang"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Ish <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ishxona <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-ishxona <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> nusxasini yaratish"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Yechishda PIN kod talab qilinsin"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Yechishdan oldin grafik kalit so‘ralsin"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bo‘shatishdan oldin parol so‘ralsin"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Hamroh ilovaga faol xizmatlarni fonda ishga tushirishga ruxsat beradi."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Mikrofon yoqildi"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon bloklandi"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Ikki ekranli rejim"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Ikki ekranli rejim yoniq"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> kontentni ikkala ekranda chiqarmoqda"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Qurilma qizib ketdi"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Telefon qizib ketgani uchun hozir ikki ekranli rejim ishlamaydi"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Faolsizlantirish"</string>
 </resources>
diff --git a/core/res/res/values-vi-watch/strings.xml b/core/res/res/values-vi-watch/strings.xml
index e81211e..162a223 100644
--- a/core/res/res/values-vi-watch/strings.xml
+++ b/core/res/res/values-vi-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Ứng dụng <xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Cảm biến"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 9ae3290..cd7a7fa 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi đang dùng, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Cho phép ứng dụng truy cập vào dữ liệu cảm biến cơ thể khi ở chế độ nền, chẳng hạn như nhịp tim, thân nhiệt và tỷ lệ phần trăm oxy trong máu."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Quyền truy cập vào dữ liệu nhiệt độ cổ tay đo bằng cảm biến cơ thể khi ứng dụng đang được sử dụng."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Cho phép ứng dụng truy cập vào dữ liệu nhiệt độ cổ tay đo bằng cảm biến cơ thể khi ứng dụng đang được sử dụng."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Quyền truy cập vào dữ liệu nhiệt độ cổ tay đo bằng cảm biến cơ thể khi ứng dụng ở chế độ nền."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Cho phép ứng dụng truy cập vào dữ liệu nhiệt độ cổ tay đo bằng cảm biến cơ thể khi ứng dụng ở chế độ nền."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Đọc chi tiết và sự kiện lịch"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ứng dụng này có thể đọc tất cả các sự kiện lịch được lưu trữ trên máy tính bảng của bạn và chia sẻ hoặc lưu dữ liệu lịch của bạn."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ứng dụng này có thể đọc tất cả sự kiện trên lịch mà bạn lưu vào thiết bị Android TV cũng như chia sẻ hoặc lưu dữ liệu lịch của bạn."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android đang khởi động..."</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Máy tính bảng đang khởi động…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Thiết bị đang khởi động…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Tối ưu hóa lưu trữ."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Đang hoàn tất cập nhật hệ thống…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> đang nâng cấp…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Đang tối ưu hóa ứng dụng <xliff:g id="NUMBER_0">%1$d</xliff:g> trong tổng số <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Đang chuẩn bị <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Khởi động ứng dụng."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Hoàn tất khởi động."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"Đã bật chế độ PTP qua USB"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Đã bật tính năng chia sẻ Internet qua USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"Đã bật chế độ MIDI qua USB"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Đã kết nối phụ kiện USB"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Nhấn để biết thêm tùy chọn."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Đang sạc thiết bị được kết nối. Hãy nhấn để biết thêm các tùy chọn."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Xong"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Tắt phím tắt"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sử dụng phím tắt"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Đảo màu"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Chỉnh màu"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Chế độ một tay"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Siêu tối"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Xem toàn màn hình"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Để thoát, hãy vuốt từ trên cùng xuống dưới."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"OK"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Xoay để xem dễ hơn"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Thoát chế độ chia đôi màn hình để xem dễ hơn"</string>
     <string name="done_label" msgid="7283767013231718521">"Xong"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Thanh trượt giờ hình tròn"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Thanh trượt phút hình tròn"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"<xliff:g id="LABEL">%1$s</xliff:g> làm việc"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Công việc thứ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Công việc thứ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"Sao chép <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Hỏi mã PIN trước khi bỏ ghim"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Hỏi hình mở khóa trước khi bỏ ghim"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Hỏi mật khẩu trước khi bỏ ghim"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Cho phép một ứng dụng đồng hành bắt đầu các dịch vụ trên nền trước từ nền."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Micrô đang hoạt động"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Micrô đang bị chặn"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Màn hình đôi"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Chế độ Màn hình đôi đang bật"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang dùng cả hai màn hình để thể hiện nội dung"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Thiết bị quá nóng"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Không bật được chế độ Màn hình đôi vì điện thoại của bạn quá nóng"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Tắt"</string>
 </resources>
diff --git a/core/res/res/values-watch/strings.xml b/core/res/res/values-watch/strings.xml
index 4d4ce1e..e44eda3 100644
--- a/core/res/res/values-watch/strings.xml
+++ b/core/res/res/values-watch/strings.xml
@@ -18,12 +18,6 @@
 */
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- [CHAR LIMIT=16] Message shown in upgrading dialog for each .apk that is optimized. -->
-    <!-- Each word has an 8 character limit due to screen width limitation. -->
-    <string name="android_upgrading_apk">App
-        <xliff:g id="number" example="123">%1$d</xliff:g> of
-        <xliff:g id="number" example="123">%2$d</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. Override from base which says "Body Sensors". [CHAR_LIMIT=25] -->
     <string name="permgrouplab_sensors">Sensors</string>
 
diff --git a/core/res/res/values-zh-rCN-watch/strings.xml b/core/res/res/values-zh-rCN-watch/strings.xml
index 0cbe677..d047d8e 100644
--- a/core/res/res/values-zh-rCN-watch/strings.xml
+++ b/core/res/res/values-zh-rCN-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"应用:<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g>。"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"传感器"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 118c520..238d54c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允许应用在使用期间访问身体传感器数据,如心率、体温和血氧浓度。"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在后台运行时可访问身体传感器数据,如心率"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允许应用在后台运行时访问身体传感器数据,如心率、体温和血氧浓度。"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"在应用使用期间访问身体传感器的手腕温度数据。"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"允许应用在使用期间访问身体传感器的手腕温度数据。"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"在应用于后台运行时访问身体传感器的手腕温度数据。"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"允许应用在后台运行时访问身体传感器的手腕温度数据。"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"读取日历活动和详情"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此应用可读取您平板电脑上存储的所有日历活动,并分享或保存您的日历数据。"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此应用可读取您的 Android TV 设备上存储的所有日历活动,以及分享或保存您的日历数据。"</string>
@@ -636,7 +632,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>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android 正在启动…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"平板电脑正在启动…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"设备正在启动…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"正在优化存储空间。"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"正在完成系统更新…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"正在升级<xliff:g id="APPLICATION">%1$s</xliff:g>…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"正在优化第<xliff:g id="NUMBER_0">%1$d</xliff:g>个应用(共<xliff:g id="NUMBER_1">%2$d</xliff:g>个)。"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"正在准备升级<xliff:g id="APPNAME">%1$s</xliff:g>。"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在启动应用。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"即将完成启动。"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"已开启 USB PTP 模式"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"已开启 USB 网络共享模式"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"已开启 USB MIDI 模式"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB 配件已连接"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"点按即可查看更多选项。"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"正在为连接的设备充电。点按即可查看更多选项。"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"完成"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"关闭快捷方式"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快捷方式"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"颜色反转"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"色彩校正"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"单手模式"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"极暗"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"目前处于全屏模式"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"要退出,请从顶部向下滑动。"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋转可改善预览效果"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"退出分屏可改善预览效果"</string>
     <string name="done_label" msgid="7283767013231718521">"完成"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"小时转盘"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"分钟转盘"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第二个工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第三个工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>克隆"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消时要求输入PIN码"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消时要求绘制解锁图案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消时要求输入密码"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"允许配套应用从后台启动前台服务。"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"麦克风可用"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"麦克风已被屏蔽"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"双屏幕"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"双屏幕功能已开启"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在使用双屏幕显示内容"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"设备过热"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"手机过热,因此无法使用双屏幕功能"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"关闭"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK-watch/strings.xml b/core/res/res/values-zh-rHK-watch/strings.xml
index 101b4e5..668061e 100644
--- a/core/res/res/values-zh-rHK-watch/strings.xml
+++ b/core/res/res/values-zh-rHK-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"應用程式 (<xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>)"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"感應器"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 2e44412..ca49433 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時存取人體感應器資料,例如心率"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心率、體溫、血氧百分比等。"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"應用程式在使用期間存取人體感應器手腕溫度資料。"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"允許應用程式在使用期間存取人體感應器手腕溫度資料。"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"應用程式在背景執行時存取人體感應器手腕溫度資料。"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"允許應用程式在背景執行時存取人體感應器手腕溫度資料。"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳情"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"此應用程式可以讀取所有儲存在您的平板電腦的日曆活動,並分享或儲存您的日曆資料。"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"此應用程式可以讀取所有儲存在 Android TV 裝置上的日曆活動,並分享或儲存您的日曆資料。"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android 正在啟動…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"平板電腦正在啟動…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"裝置正在啟動…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"正在優化儲存空間。"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"正在完成系統更新…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」正在升級…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"正在優化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"正在準備 <xliff:g id="APPNAME">%1$s</xliff:g>。"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"啟動完成。"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"已開啟 USB PTP 模式"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"已開啟 USB 的網絡共享模式"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"已開啟 USB MIDI 模式"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"已連接 USB 配件"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"輕按即可查看更多選項。"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"正在為連接的裝置充電。輕按即可查看更多選項。"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"完成"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"關閉快速鍵"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快速鍵"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"色彩校正"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"開啟全螢幕"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"由頂部向下滑動即可退出。"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋轉以改善預覽效果"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"退出分割螢幕,以改善預覽效果"</string>
     <string name="done_label" msgid="7283767013231718521">"完成"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"小時環形滑桿"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"分鐘環形滑桿"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"公司<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第二個工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第三個工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"複製 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消固定時必須輸入 PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"允許隨附應用程式從背景啟動前景服務。"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"可以使用麥克風"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"已封鎖麥克風"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"雙螢幕"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"已開啟雙螢幕功能"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用雙螢幕顯示內容"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"裝置過熱"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"由於手機過熱,雙螢幕功能無法使用"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"關閉"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW-watch/strings.xml b/core/res/res/values-zh-rTW-watch/strings.xml
index 122ac0a..668061e 100644
--- a/core/res/res/values-zh-rTW-watch/strings.xml
+++ b/core/res/res/values-zh-rTW-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"應用程式 <xliff:g id="NUMBER_0">%1$d</xliff:g>/<xliff:g id="NUMBER_1">%2$d</xliff:g>。"</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"感應器"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2155790..f282ba3 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"允許應用程式在使用期間存取人體感應器資料,例如心跳速率、體溫和血氧比例。"</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"在背景執行時可存取人體感應器資料,例如心跳速率"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"允許應用程式在背景執行時存取人體感應器資料,例如心跳速率、體溫和血氧比例。"</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"在應用程式使用期間存取手錶人體感應器上的溫度資料。"</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"允許應用程式在使用期間存取手錶人體感應器上的溫度資料。"</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"在背景執行應用程式時存取手錶人體感應器上的溫度資料。"</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"允許應用程式在背景執行時存取手錶人體感應器上的溫度資料。"</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"讀取日曆活動和詳細資訊"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"這個應用程式可讀取所有儲存在平板電腦上的日曆活動資訊,以及共用或儲存日曆資料。"</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"這個應用程式可讀取所有儲存在 Android TV 裝置上的日曆活動,以及共用或儲存日曆資料。"</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"Android 正在啟動…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"平板電腦正在啟動…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"裝置正在啟動…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"正在對儲存空間進行最佳化處理。"</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"正在完成系統更新…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"正在升級「<xliff:g id="APPLICATION">%1$s</xliff:g>」…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"正在最佳化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 個)。"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"正在準備升級「<xliff:g id="APPNAME">%1$s</xliff:g>」。"</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在啟動應用程式。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"啟動完成。"</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"已開啟 USB PTP 模式"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"已開啟 USB 網路共用模式"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"已開啟 USB MIDI 模式"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"已連接 USB 配件"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"輕觸即可查看更多選項。"</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"正在為連接的裝置充電。輕觸即可查看更多選項。"</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"完成"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"停用捷徑"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用捷徑"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"色彩校正"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"以全螢幕檢視"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"如要退出,請從畫面頂端向下滑動。"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"知道了"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"旋轉螢幕以瀏覽完整的檢視畫面"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"結束分割畫面以全螢幕瀏覽"</string>
     <string name="done_label" msgid="7283767013231718521">"完成"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"小時數環狀滑桿"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"分鐘數環狀滑桿"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第 2 項工作:<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第 3 項工作:<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"複製<xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消固定時必須輸入 PIN"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須畫出解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"允許隨附應用程式從背景啟動前景服務。"</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"麥克風已可使用"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"麥克風已封鎖"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"雙螢幕"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"雙螢幕功能已啟用"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用雙螢幕顯示內容"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"裝置過熱"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"手機過熱,因此無法使用雙螢幕功能"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"停用"</string>
 </resources>
diff --git a/core/res/res/values-zu-watch/strings.xml b/core/res/res/values-zu-watch/strings.xml
index 36acb14..a19d77f 100644
--- a/core/res/res/values-zu-watch/strings.xml
+++ b/core/res/res/values-zu-watch/strings.xml
@@ -20,6 +20,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="android_upgrading_apk" msgid="5356436701512342265">"Uhlelo lokusebenza olungu-<xliff:g id="NUMBER_0">%1$d</xliff:g> kokungu-<xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="permgrouplab_sensors" msgid="2439544173324807471">"Izinzwa"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c81ab5e..72180d4 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -458,14 +458,10 @@
     <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ivumela i-app ukuthi ifinyelele idatha yenzwa yomzimba, efana nokushaya kwenhliziyo, izinga lokushisa, namaphesenti komoyampilo wegazi, kuyilapho i-app isetshenziswa."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Finyelela kudatha yenzwa yomzimba, njengokushaya kwenhliziyo, ngenkathi ungemuva"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ivumela i-app ukuthi ifinyelele idatha yenzwa yomzimba, efana nokushaya kwenhliziyo, izinga lokushisa, namaphesenti komoyampilo wegazi, kuyilapho i-app ingemuva."</string>
-    <!-- no translation found for permlab_bodySensorsWristTemperature (5007987988922337657) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensorsWristTemperature (4978345709781045181) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors_wristTemperature_background (7692772783509074356) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors_wristTemperature_background (3170369705518699219) -->
-    <skip />
+    <string name="permlab_bodySensorsWristTemperature" msgid="5007987988922337657">"Finyelela kudatha yezinga lokushisa lenzwa yomzimba ngenkathi i-app isetshenziswa."</string>
+    <string name="permdesc_bodySensorsWristTemperature" product="default" msgid="4978345709781045181">"Ivumela i-app ukuthi ifinyelele idatha yezinga lokushisa kwengalo yenzwa yomzimba, kuyilapho i-app isetshenziswa."</string>
+    <string name="permlab_bodySensors_wristTemperature_background" msgid="7692772783509074356">"Finyelela kudatha yezinga lokushisa lenzwa yomzimba ngenkathi i-app ingemuva."</string>
+    <string name="permdesc_bodySensors_wristTemperature_background" product="default" msgid="3170369705518699219">"Ivumela i-app ifinyelele idatha yezinga lokushisa lengalo yenzwa yomzimba, kuyilapho i-app ingemuva."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Funda imicimbi yekhalenda nemininingwane"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Lolu hlelo lokusebenza lungafunda yonke imicimbi yekhalenda elondolozwe kuthebhulethi yakho nokwabelana noma ukulondoloza idatha yakho yekhalenda."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Lolu hlelo lokusebenza lungafunda yonke imicimbi yekhalenda elondolozwe kudivayisi yakho ye-Android TV nokwabelana noma ukulondoloza idatha yakho yekhalenda."</string>
@@ -1249,10 +1245,8 @@
     <string name="android_start_title" product="automotive" msgid="7917984412828168079">"I-Android iyaqala…"</string>
     <string name="android_start_title" product="tablet" msgid="4429767260263190344">"Ithebulethi iyaqala…"</string>
     <string name="android_start_title" product="device" msgid="6967413819673299309">"Idivayisi iyaqala…"</string>
-    <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Ikhulisa isitoreji."</string>
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Iqedela ukubuyekezwa kwesistimu…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> iyathuthukisa…"</string>
-    <string name="android_upgrading_apk" msgid="1339564803894466737">"Ukubeka ezingeni eliphezulu <xliff:g id="NUMBER_0">%1$d</xliff:g> uhlelo lokusebenza <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Ukulungisela i-<xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Qalisa izinhlelo zokusebenza."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Qedela ukuqala kabusha."</string>
@@ -1364,6 +1358,8 @@
     <string name="usb_ptp_notification_title" msgid="5043437571863443281">"I-PTP nge-USB ivuliwe"</string>
     <string name="usb_tether_notification_title" msgid="8828527870612663771">"Kuvulwe ukusebenzisa ifoni njengemodemu kwe-USB"</string>
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"I-MIDI nge-USB ivuliwe"</string>
+    <!-- no translation found for usb_uvc_notification_title (2030032862673400008) -->
+    <skip />
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"Insiza ye-USB ixhunyiwe"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"Thepha ngezinketho eziningi."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"Ishaja idivayisi exhunyiwe. Thepha ukuze uthole okunye okungakhethwa."</string>
@@ -1712,7 +1708,8 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Kwenziwe"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Vala isinqamuleli"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sebenzisa isinqamuleli"</string>
-    <string name="color_inversion_feature_name" msgid="326050048927789012">"Ukuguqulwa kombala"</string>
+    <!-- no translation found for color_inversion_feature_name (2672824491933264951) -->
+    <skip />
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Ukulungiswa kombala"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Imodi yesandla esisodwa"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ukufiphaza okwengeziwe"</string>
@@ -1850,6 +1847,8 @@
     <string name="immersive_cling_title" msgid="2307034298721541791">"Ukubuka isikrini esigcwele"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Ukuze uphume, swayiphela phansi kusuka phezulu."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Ngiyitholile"</string>
+    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Zungezisa ukuze uthole ukubuka okungcono"</string>
+    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Phuma ekuhlukaniseni isikrini ukuze ubuke kangcono"</string>
     <string name="done_label" msgid="7283767013231718521">"Kwenziwe"</string>
     <string name="hour_picker_description" msgid="5153757582093524635">"Amahora weslayidi esiyindingilizi"</string>
     <string name="minute_picker_description" msgid="9029797023621927294">"Amaminithi weslayidi esiyindingilizi"</string>
@@ -1861,6 +1860,7 @@
     <string name="managed_profile_label_badge" msgid="6762559569999499495">"Umsebenzi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Umsebenzi wesibili <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Umsebenzi wesithathu <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="clone_profile_label_badge" msgid="1871997694718793964">"I-Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Cela iphinikhodi ngaphambi kokuphina"</string>
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string>
@@ -2315,4 +2315,10 @@
     <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Ivumela i-app ehambisanayo ukuthi iqale amasevisi angaphambili kusukela ngemuva."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Imakrofoni iyatholakala"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Imakrofoni ivinjiwe"</string>
+    <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Isikrini esikabili"</string>
+    <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Isikrini esikabili sivuliwe"</string>
+    <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> isebenzisa zombili izibonisi ukukhombisa okuqukethwe"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Idivayisi ifudumele kakhulu"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"I-Dual Screen ayitholakali ngoba ifoni yakho iqala ukufudumala kakhulu"</string>
+    <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Vala"</string>
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index c3366cf..4468ebe 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -210,8 +210,7 @@
     <!-- Device state identifiers and strings for system notifications. The string arrays must have
          the same length and order as the identifier array. -->
     <integer-array name="device_state_notification_state_identifiers">
-        <!-- TODO(b/267231269) change to concurrent display identifier when ready -->
-        <item>-1</item>
+        <item>@integer/config_deviceStateConcurrentRearDisplay</item>
     </integer-array>
     <string-array name="device_state_notification_names">
         <item>@string/concurrent_display_notification_name</item>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index e242e20..0c2fc1d 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -150,6 +150,8 @@
     <color name="notification_default_color">#757575</color> <!-- Gray 600 -->
 
     <color name="notification_action_button_text_color">@color/notification_default_color</color>
+    <item  name="notification_action_disabled_content_alpha" format="float" type="dimen">0.38</item>
+    <item  name="notification_action_disabled_container_alpha" format="float" type="dimen">0.12</item>
 
     <color name="notification_progress_background_color">@color/notification_secondary_text_color_current</color>
 
@@ -523,15 +525,15 @@
     <color name="system_error_container_dark">#930001</color>
     <color name="system_on_error_container_dark">#FFDAD5</color>
     <color name="system_primary_fixed_dark">#D8E2FF</color>
-    <color name="system_primary_fixeder_dark">#ADC6FF</color>
+    <color name="system_primary_fixed_darker_dark">#ADC6FF</color>
     <color name="system_on_primary_fixed_dark">#001A41</color>
     <color name="system_on_primary_fixed_variant_dark">#2B4678</color>
     <color name="system_secondary_fixed_dark">#DBE2F9</color>
-    <color name="system_secondary_fixeder_dark">#BFC6DC</color>
+    <color name="system_secondary_fixed_darker_dark">#BFC6DC</color>
     <color name="system_on_secondary_fixed_dark">#141B2C</color>
     <color name="system_on_secondary_fixed_variant_dark">#3F4759</color>
     <color name="system_tertiary_fixed_dark">#FBD7FC</color>
-    <color name="system_tertiary_fixeder_dark">#DEBCDF</color>
+    <color name="system_tertiary_fixed_darker_dark">#DEBCDF</color>
     <color name="system_on_tertiary_fixed_dark">#29132D</color>
     <color name="system_on_tertiary_fixed_variant_dark">#583E5B</color>
     <color name="system_control_activated_dark">#2B4678</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1e3074c..c75ee93 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -465,12 +465,6 @@
     <string-array translatable="false" name="config_cdma_dun_supported_types">
     </string-array>
 
-    <!-- Package name of the system app that implements the shared connectivity service -->
-    <string translatable="false" name="sharedconnectivity_service_package"></string>
-
-     <!-- Class name in the system app that implements the shared connectivity service -->
-    <string translatable="false" name="sharedconnectivity_service_class"></string>
-
     <!-- Flag indicating whether we should enable the automatic brightness.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
@@ -983,6 +977,13 @@
     <integer-array name="config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis">
     </integer-array>
 
+    <!-- Boolean indicating whether secondary built-in displays should have their orientation
+         match the active default display. This config assumes that the secondary display only
+         requires swapping ROTATION_90 and ROTATION_270.
+         TODO(b/265991392): This should eventually be configured and parsed in
+          display_settings.xml -->
+    <bool name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay">true</bool>
+
     <!-- Indicate available ColorDisplayManager.COLOR_MODE_xxx. -->
     <integer-array name="config_availableColorModes">
         <!-- Example:
@@ -1309,7 +1310,7 @@
     <!-- Default value for led color when battery is medium charged -->
     <integer name="config_notificationsBatteryMediumARGB">0xFFFFFF00</integer>
 
-    <!-- Default value for led color when battery is fully charged -->
+    <!-- Default value for led color when battery is fully or nearly fully charged -->
     <integer name="config_notificationsBatteryFullARGB">0xFF00FF00</integer>
 
     <!-- Default value for LED on time when the battery is low on charge in miliseconds -->
@@ -1324,6 +1325,9 @@
     <!-- Default value for LED off time when the battery is low on charge in miliseconds -->
     <integer name="config_notificationsBatteryLedOff">2875</integer>
 
+    <!-- Battery level percent that is treated as nearly full. -->
+    <integer name="config_notificationsBatteryNearlyFullLevel">90</integer>
+
     <!-- If true, only colorized CallStyle notifications will apply custom colors -->
     <bool name="config_callNotificationActionColorsRequireColorized">true</bool>
 
@@ -2186,6 +2190,9 @@
     <!-- The name of the package that will hold the system financed device controller role. -->
     <string name="config_systemFinancedDeviceController" translatable="false">com.android.devicelockcontroller</string>
 
+    <!-- The component name of the wear service class that will be started by the system server. -->
+    <string name="config_wearServiceComponent" translatable="false"></string>
+
     <!-- The name of the package that will handle updating the device management role. -->
     <string name="config_devicePolicyManagementUpdater" translatable="false"></string>
 
@@ -2774,6 +2781,10 @@
      it can't be deleted or downgraded to non-admin status. -->
     <bool name="config_isMainUserPermanentAdmin">false</bool>
 
+    <!-- Whether switch to headless system user is allowed. If allowed,
+    headless system user can run in the foreground even though it is not a full user. -->
+    <bool name="config_canSwitchToHeadlessSystemUser">false</bool>
+
     <!-- Whether UI for multi user should be shown -->
     <bool name="config_enableMultiUserUI">false</bool>
 
@@ -3233,6 +3244,12 @@
     <string name="config_somnambulatorComponent" translatable="false"
             >com.android.systemui/com.android.systemui.Somnambulator</string>
 
+    <!-- The component name of the screenshot App Clips service that communicates with SystemUI to
+         evaluate certain aspects of App Clips flow such as whether a calling activity can launch
+         capture content for note activity. -->
+    <string name="config_screenshotAppClipsServiceComponent" translatable="false"
+            >com.android.systemui/com.android.systemui.screenshot.appclips.AppClipsService</string>
+
     <!-- The component name of a special dock app that merely launches a dream.
          We don't want to launch this app when docked because it causes an unnecessary
          activity transition.  We just want to start the dream.. -->
@@ -4104,16 +4121,6 @@
     -->
     <string-array translatable="false" name="config_convert_to_emergency_number_map" />
 
-    <!-- An array of packages for which notifications cannot be blocked.
-         Should only be used for core device functionality that must not be
-         rendered inoperative for safety reasons, like the phone dialer and
-         SMS handler. -->
-    <string-array translatable="false" name="config_nonBlockableNotificationPackages">
-        <item>com.android.dialer</item>
-        <item>com.android.messaging</item>
-        <item>com.android.cellbroadcastreceiver.module</item>
-    </string-array>
-
     <!-- An array of packages that can make sound on the ringer stream in priority-only DND
      mode -->
     <string-array translatable="false" name="config_priorityOnlyDndExemptPackages">
@@ -4170,12 +4177,19 @@
     <bool name="config_quickSettingsSupported">true</bool>
 
     <!-- The component name, flattened to a string, for the default autofill service
-         to  enabled for an user. This service must be trusted, as it can be activated
+         to  enabled for a user. This service must be trusted, as it can be activated
          without explicit consent of the user. If no autofill service with the
           specified name exists on the device, autofill will be disabled by default.
     -->
     <string name="config_defaultAutofillService" translatable="false"></string>
 
+    <!-- The component name, flattened to a string, for the default field classification service
+         to  enabled for a user. This service must be trusted, as it can be activated
+         without explicit consent of the user. If no field classification service with the
+         specified name exists on the device, field classification will be disabled by default.
+    -->
+    <string name="config_defaultFieldClassificationService" translatable="false"></string>
+
     <!-- The package name for the OEM custom system textclassifier service.
          This service must be trusted, as it can be activated without explicit consent of the user.
          Example: "com.android.textclassifier"
@@ -4365,6 +4379,18 @@
     -->
     <string name="config_defaultCredentialManagerHybridService" translatable="false"></string>
 
+    <!-- The component name, flattened to a string, for the system's credential manager
+      provider service. This service allows credential retrieval and storage od credentials.
+
+     This service must be trusted, as it can be activated without explicit consent of the user.
+     If no service with the specified name exists on the device, there will be no user configurable
+     provider to service credential manager requests. However, credential manager system
+     services that do not require user consent, will still work.
+
+     See android.credentials.CredentialManager
+    -->
+    <string name="config_defaultCredentialProviderService" translatable="false"></string>
+
     <!-- The package name for the system's smartspace service.
      This service returns smartspace results.
 
@@ -6197,6 +6223,18 @@
          different from the home screen wallpaper. -->
     <bool name="config_independentLockscreenLiveWallpaper">false</bool>
 
+    <!-- Device state that corresponds to concurrent display mode where the default display
+         is the internal display. Public API for the feature is provided through Jetpack
+         WindowManager.
+         TODO(b/236022708) Move concurrent display state to device state config file
+    -->
+    <integer name="config_deviceStateConcurrentRearDisplay">-1</integer>
+
+    <!-- Physical display address that corresponds to the rear display in rear display mode
+         and concurrent display mode. Used to get information about the display before
+         entering the corresponding modes -->
+    <string name="config_rearDisplayPhysicalAddress" translatable="false"></string>
+
     <!-- List of certificate to be used for font fs-verity integrity verification -->
     <string-array translatable="false" name="config_fontManagerServiceCerts">
     </string-array>
@@ -6244,6 +6282,9 @@
     <string-array name="config_healthConnectMigrationKnownSigners">
     </string-array>
 
+    <!-- Package name of Health Connect data migrator application.  -->
+    <string name="config_healthConnectMigratorPackageName"></string>
+
     <!-- The Universal Stylus Initiative (USI) protocol version supported by each display.
          (@see https://universalstylus.org/).
 
@@ -6266,4 +6307,7 @@
         "stopped" during initial boot of a device, or after an OTA update. Stopped state of
         an app is not changed during subsequent reboots.  -->
     <bool name="config_stopSystemPackagesByDefault">false</bool>
+
+    <!-- Whether to show weather on the lock screen by default. -->
+    <bool name="config_lockscreenWeatherEnabledByDefault">false</bool>
 </resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 0ec3ef7..7d41f76 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -242,15 +242,15 @@
     <public name="system_error_container_dark"/>
     <public name="system_on_error_container_dark"/>
     <public name="system_primary_fixed_dark"/>
-    <public name="system_primary_fixeder_dark"/>
+    <public name="system_primary_fixed_darker_dark"/>
     <public name="system_on_primary_fixed_dark"/>
     <public name="system_on_primary_fixed_variant_dark"/>
     <public name="system_secondary_fixed_dark"/>
-    <public name="system_secondary_fixeder_dark"/>
+    <public name="system_secondary_fixed_darker_dark"/>
     <public name="system_on_secondary_fixed_dark"/>
     <public name="system_on_secondary_fixed_variant_dark"/>
     <public name="system_tertiary_fixed_dark"/>
-    <public name="system_tertiary_fixeder_dark"/>
+    <public name="system_tertiary_fixed_darker_dark"/>
     <public name="system_on_tertiary_fixed_dark"/>
     <public name="system_on_tertiary_fixed_variant_dark"/>
     <public name="system_control_activated_dark"/>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index da44c2e..26927f8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -965,6 +965,11 @@
     <!-- Description for the capability of an accessibility service to take screenshot. [CHAR LIMIT=NONE] -->
     <string name="capability_desc_canTakeScreenshot">Can take a screenshot of the display.</string>
 
+    <!-- Dream -->
+
+    <!-- The title to use when a dream is opened in preview mode. [CHAR LIMIT=NONE] -->
+    <string name="dream_preview_title">Preview, <xliff:g id="dream_name" example="Clock">%1$s</xliff:g></string>
+
     <!--  Permissions -->
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -3396,7 +3401,6 @@
     <string name="android_start_title" product="device">Device is starting\u2026</string>
 
     <!-- [CHAR LIMIT=NONE] Message shown in upgrading dialog when doing an fstrim. -->
-    <string name="android_upgrading_fstrim">Optimizing storage.</string>
 
     <!-- [CHAR LIMIT=40] Title of notification that is shown when finishing a system update. -->
     <string name="android_upgrading_notification_title" product="default">Finishing system update\u2026</string>
@@ -3404,11 +3408,6 @@
     <!-- [CHAR LIMIT=40] Toast that is shown when an app is still upgrading. -->
     <string name="app_upgrading_toast"><xliff:g id="application">%1$s</xliff:g> is upgrading\u2026</string>
 
-    <!-- [CHAR LIMIT=NONE] Message shown in upgrading dialog for each .apk that is optimized. -->
-    <string name="android_upgrading_apk">Optimizing app
-        <xliff:g id="number" example="123">%1$d</xliff:g> of
-        <xliff:g id="number" example="123">%2$d</xliff:g>.</string>
-
     <!-- [CHAR LIMIT=NONE] Message shown in upgrading dialog for each .apk pre boot broadcast -->
     <string name="android_preparing_apk">Preparing <xliff:g id="appname">%1$s</xliff:g>.</string>
 
@@ -3699,6 +3698,8 @@
     <string name="usb_tether_notification_title">USB tethering turned on</string>
     <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MIDI mode.  This is the title -->
     <string name="usb_midi_notification_title">MIDI via USB turned on</string>
+    <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in UVC mode.  This is the title -->
+    <string name="usb_uvc_notification_title">Device connected as Webcam</string>
     <!-- USB_PREFERENCES: Notification for when a USB accessory is attached.  This is the title -->
     <string name="usb_accessory_notification_title">USB accessory connected</string>
     <!-- See USB_PREFERENCES. This is the message. -->
@@ -4713,7 +4714,7 @@
 
     <!-- Title of Color Inversion feature shown in the warning dialog about the accessibility
     shortcut. -->
-    <string name="color_inversion_feature_name">Color Inversion</string>
+    <string name="color_inversion_feature_name">Color inversion</string>
 
     <!-- Title of Color Correction feature, which is mostly used to help users who are colorblind,
      shown in the warning dialog about the accessibility shortcut. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 11aac16..d7cdf73 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -355,6 +355,7 @@
   <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
   <java-symbol type="bool" name="config_useFixedVolume" />
   <java-symbol type="bool" name="config_isMainUserPermanentAdmin"/>
+  <java-symbol type="bool" name="config_canSwitchToHeadlessSystemUser"/>
   <java-symbol type="bool" name="config_enableMultiUserUI"/>
   <java-symbol type="bool" name="config_enableMultipleAdmins"/>
   <java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
@@ -370,6 +371,7 @@
   <java-symbol type="string" name="config_controlsPackage" />
   <java-symbol type="string" name="config_screenRecorderComponent" />
   <java-symbol type="string" name="config_somnambulatorComponent" />
+  <java-symbol type="string" name="config_screenshotAppClipsServiceComponent" />
   <java-symbol type="string" name="config_screenshotServiceComponent" />
   <java-symbol type="string" name="config_screenshotErrorReceiverComponent" />
   <java-symbol type="string" name="config_slicePermissionComponent" />
@@ -1440,6 +1442,8 @@
   <java-symbol type="drawable" name="ic_feedback_downrank" />
 
   <java-symbol type="drawable" name="ic_account_circle" />
+  <java-symbol type="drawable" name="ic_dual_screen" />
+  <java-symbol type="drawable" name="ic_thermostat" />
   <java-symbol type="color" name="user_icon_1" />
   <java-symbol type="color" name="user_icon_2" />
   <java-symbol type="color" name="user_icon_3" />
@@ -1998,6 +2002,7 @@
   <java-symbol type="integer" name="config_notificationsBatteryLedOn" />
   <java-symbol type="integer" name="config_notificationsBatteryLowARGB" />
   <java-symbol type="integer" name="config_notificationsBatteryMediumARGB" />
+  <java-symbol type="integer" name="config_notificationsBatteryNearlyFullLevel" />
   <java-symbol type="integer" name="config_notificationServiceArchiveSize" />
   <java-symbol type="integer" name="config_previousVibrationsDumpLimit" />
   <java-symbol type="integer" name="config_defaultVibrationAmplitude" />
@@ -2051,8 +2056,6 @@
   <java-symbol type="string" name="aerr_process" />
   <java-symbol type="string" name="aerr_application_repeated" />
   <java-symbol type="string" name="aerr_process_repeated" />
-  <java-symbol type="string" name="android_upgrading_fstrim" />
-  <java-symbol type="string" name="android_upgrading_apk" />
   <java-symbol type="string" name="android_upgrading_complete" />
   <java-symbol type="string" name="android_upgrading_starting_apps" />
   <java-symbol type="string" name="anr_activity_application" />
@@ -2140,6 +2143,7 @@
   <java-symbol type="string" name="usb_power_notification_message" />
   <java-symbol type="string" name="usb_ptp_notification_title" />
   <java-symbol type="string" name="usb_midi_notification_title" />
+  <java-symbol type="string" name="usb_uvc_notification_title" />
   <java-symbol type="string" name="usb_tether_notification_title" />
   <java-symbol type="string" name="usb_supplying_notification_title" />
   <java-symbol type="string" name="usb_unsupported_audio_accessory_title" />
@@ -3261,7 +3265,10 @@
   <java-symbol type="id" name="notification_action_list_margin_target" />
   <java-symbol type="dimen" name="notification_actions_padding_start"/>
   <java-symbol type="dimen" name="notification_actions_collapsed_priority_width"/>
+  <!--prefer to use disabled content and surface alpha values for disabled actions-->
   <java-symbol type="dimen" name="notification_action_disabled_alpha" />
+  <java-symbol type="dimen" name="notification_action_disabled_content_alpha" />
+  <java-symbol type="dimen" name="notification_action_disabled_container_alpha" />
   <java-symbol type="id" name="tag_margin_end_when_icon_visible" />
   <java-symbol type="id" name="tag_margin_end_when_icon_gone" />
   <java-symbol type="id" name="tag_uses_right_icon_drawable" />
@@ -3313,6 +3320,7 @@
   <java-symbol type="string" name="unsupported_display_size_message" />
 
   <java-symbol type="layout" name="notification_material_action_emphasized" />
+  <java-symbol type="layout" name="notification_material_action_emphasized_tombstone" />
 
   <!-- Package name for the device provisioning package -->
   <java-symbol type="string" name="config_deviceProvisioningPackage" />
@@ -3401,6 +3409,13 @@
        TODO(b/265312193): Remove this workaround when this bug is fixed.-->
   <java-symbol type="array" name="config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis" />
 
+  <!-- Boolean indicating whether secondary built-in displays should have their orientation
+       match the active default display. This config assumes that the secondary display only
+       requires swapping ROTATION_90 and ROTATION_270.
+       TODO(b/265991392): This should eventually be configured and parsed in
+        display_settings.xml -->
+  <java-symbol type="bool" name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay" />
+
   <!-- Default user restrictions for the SYSTEM user -->
   <java-symbol type="array" name="config_defaultFirstUserRestrictions" />
 
@@ -3416,7 +3431,6 @@
 
   <java-symbol type="array" name="config_convert_to_emergency_number_map" />
 
-  <java-symbol type="array" name="config_nonBlockableNotificationPackages" />
   <java-symbol type="array" name="config_priorityOnlyDndExemptPackages" />
 
   <!-- Screen-size-dependent modes for picker dialogs. -->
@@ -3710,6 +3724,7 @@
   <java-symbol type="string" name="notification_channel_accessibility_magnification" />
   <java-symbol type="string" name="notification_channel_accessibility_security_policy" />
   <java-symbol type="string" name="config_defaultAutofillService" />
+  <java-symbol type="string" name="config_defaultFieldClassificationService" />
   <java-symbol type="string" name="config_defaultOnDeviceSpeechRecognitionService" />
   <java-symbol type="string" name="config_defaultTextClassifierPackage" />
   <java-symbol type="string" name="config_defaultWellbeingPackage" />
@@ -3719,6 +3734,7 @@
   <java-symbol type="string" name="config_defaultAppPredictionService" />
   <java-symbol type="string" name="config_defaultContentSuggestionsService" />
   <java-symbol type="string" name="config_defaultCredentialManagerHybridService" />
+  <java-symbol type="string" name="config_defaultCredentialProviderService" />
   <java-symbol type="string" name="config_defaultSearchUiService" />
   <java-symbol type="string" name="config_defaultSmartspaceService" />
   <java-symbol type="string" name="config_defaultWallpaperEffectsGenerationService" />
@@ -4235,6 +4251,8 @@
   <java-symbol type="string" name="capability_desc_canTakeScreenshot" />
   <java-symbol type="string" name="capability_title_canTakeScreenshot" />
 
+  <java-symbol type="string" name="dream_preview_title" />
+
   <java-symbol type="string" name="config_servicesExtensionPackage" />
 
   <!-- For app process exit info tracking -->
@@ -4897,6 +4915,8 @@
   <java-symbol type="string" name="concurrent_display_notification_thermal_content"/>
   <java-symbol type="string" name="device_state_notification_turn_off_button"/>
   <java-symbol type="bool" name="config_independentLockscreenLiveWallpaper"/>
+  <java-symbol type="integer" name="config_deviceStateConcurrentRearDisplay" />
+  <java-symbol type="string" name="config_rearDisplayPhysicalAddress" />
 
   <!-- For app language picker -->
   <java-symbol type="string" name="system_locale_title" />
@@ -4916,4 +4936,8 @@
   <java-symbol type="array" name="config_displayShapeArray" />
 
   <java-symbol type="bool" name="config_stopSystemPackagesByDefault"/>
+  <java-symbol type="string" name="config_wearServiceComponent" />
+
+  <!-- Whether to show weather on the lockscreen by default. -->
+  <java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" />
 </resources>
diff --git a/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java
index b1991c2..b3c7f88 100644
--- a/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/ParcelableBenchmark.java
@@ -60,8 +60,8 @@
 
     public void timeReadWriteInsetsState(int reps) {
         final InsetsState insetsState = new InsetsState();
-        for (int i = 0; i < InsetsState.SIZE; i++) {
-            insetsState.addSource(new InsetsSource(i, InsetsState.toPublicType(i)));
+        for (int i = 0; i < 10; i++) {
+            insetsState.addSource(new InsetsSource(i, 1 << i));
         }
         for (int i = 0; i < reps; i++) {
             insetsState.writeToParcel(mParcel, 0);
diff --git a/core/tests/coretests/src/android/app/admin/PackagePolicyTest.java b/core/tests/coretests/src/android/app/admin/PackagePolicyTest.java
new file mode 100644
index 0000000..d8298fd
--- /dev/null
+++ b/core/tests/coretests/src/android/app/admin/PackagePolicyTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin;
+
+import static android.app.admin.PackagePolicy.PACKAGE_POLICY_ALLOWLIST;
+import static android.app.admin.PackagePolicy.PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM;
+import static android.app.admin.PackagePolicy.PACKAGE_POLICY_BLOCKLIST;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class PackagePolicyTest {
+
+    private static final String TEST_PACKAGE_NAME = "com.example";
+
+    private static final String TEST_PACKAGE_NAME_2 = "com.example.2";
+
+    private static final String TEST_SYSTEM_PACKAGE_NAME = "com.system";
+
+
+    @Test
+    public void testParceling() {
+        final int policyType = PACKAGE_POLICY_BLOCKLIST;
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+
+        final Parcel parcel = Parcel.obtain();
+        PackagePolicy packagePolicy = new PackagePolicy(policyType, packageNames);
+        try {
+            packagePolicy.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            packagePolicy = PackagePolicy.CREATOR.createFromParcel(parcel);
+        } finally {
+            parcel.recycle();
+        }
+
+        assertEquals(policyType, packagePolicy.getPolicyType());
+        assertNotNull(packagePolicy.getPackageNames());
+        assertEquals(1, packagePolicy.getPackageNames().size());
+        assertTrue(packagePolicy.getPackageNames().contains(TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    public void testEmptyBlocklistCreation() {
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_BLOCKLIST);
+        assertEquals(PACKAGE_POLICY_BLOCKLIST, policy.getPolicyType());
+        assertNotNull(policy.getPackageNames());
+        assertTrue(policy.getPackageNames().isEmpty());
+    }
+
+    @Test
+    public void testEmptyAllowlistCreation() {
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_ALLOWLIST);
+        assertEquals(PACKAGE_POLICY_ALLOWLIST, policy.getPolicyType());
+        assertNotNull(policy.getPackageNames());
+        assertTrue(policy.getPackageNames().isEmpty());
+    }
+
+    @Test
+    public void testEmptyAllowlistAndSystemCreation() {
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM);
+        assertEquals(PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM, policy.getPolicyType());
+        assertNotNull(policy.getPackageNames());
+        assertTrue(policy.getPackageNames().isEmpty());
+    }
+
+    @Test
+    public void testSuppliedBlocklistCreation() {
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_BLOCKLIST, packageNames);
+        assertEquals(PACKAGE_POLICY_BLOCKLIST, policy.getPolicyType());
+        assertNotNull(policy.getPackageNames());
+        assertEquals(1, policy.getPackageNames().size());
+        assertTrue(policy.getPackageNames().contains(TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    public void testSuppliedAllowlistCreation() {
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_ALLOWLIST, packageNames);
+        assertEquals(PACKAGE_POLICY_ALLOWLIST, policy.getPolicyType());
+        assertNotNull(policy.getPackageNames());
+        assertEquals(1, policy.getPackageNames().size());
+        assertTrue(policy.getPackageNames().contains(TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    public void testSuppliedAllowlistAndSystemCreation() {
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM, packageNames);
+        assertEquals(PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM, policy.getPolicyType());
+        assertNotNull(policy.getPackageNames());
+        assertEquals(1, policy.getPackageNames().size());
+        assertTrue(policy.getPackageNames().contains(TEST_PACKAGE_NAME));
+    }
+
+    @Test
+    public void testBlocklist_isPackageAllowed() {
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+        final Set<String> systemPackages = new ArraySet<>();
+        systemPackages.add(TEST_SYSTEM_PACKAGE_NAME);
+
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_BLOCKLIST, packageNames);
+
+        assertFalse(policy.isPackageAllowed(TEST_PACKAGE_NAME, Collections.emptySet()));
+        assertFalse(policy.isPackageAllowed(TEST_PACKAGE_NAME, systemPackages));
+        assertTrue(policy.isPackageAllowed(TEST_PACKAGE_NAME_2, Collections.emptySet()));
+        assertTrue(policy.isPackageAllowed(TEST_PACKAGE_NAME_2, systemPackages));
+        assertTrue(policy.isPackageAllowed(TEST_SYSTEM_PACKAGE_NAME, Collections.emptySet()));
+        assertTrue(policy.isPackageAllowed(TEST_SYSTEM_PACKAGE_NAME, systemPackages));
+    }
+
+    @Test
+    public void testAllowlist_isPackageAllowed() {
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+        final Set<String> systemPackages = new ArraySet<>();
+        systemPackages.add(TEST_SYSTEM_PACKAGE_NAME);
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_ALLOWLIST, packageNames);
+
+        assertTrue(policy.isPackageAllowed(TEST_PACKAGE_NAME, Collections.emptySet()));
+        assertTrue(policy.isPackageAllowed(TEST_PACKAGE_NAME, systemPackages));
+        assertFalse(policy.isPackageAllowed(TEST_PACKAGE_NAME_2, Collections.emptySet()));
+        assertFalse(policy.isPackageAllowed(TEST_PACKAGE_NAME_2, systemPackages));
+        assertFalse(policy.isPackageAllowed(TEST_SYSTEM_PACKAGE_NAME, Collections.emptySet()));
+        assertFalse(policy.isPackageAllowed(TEST_SYSTEM_PACKAGE_NAME, systemPackages));
+    }
+
+    @Test
+    public void testAllowlistAndSystem_isPackageAllowed() {
+        final Set<String> packageNames = new ArraySet<>();
+        packageNames.add(TEST_PACKAGE_NAME);
+        final Set<String> systemPackages = new ArraySet<>();
+        systemPackages.add(TEST_SYSTEM_PACKAGE_NAME);
+        PackagePolicy policy = new PackagePolicy(PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM, packageNames);
+
+        assertTrue(policy.isPackageAllowed(TEST_PACKAGE_NAME, Collections.emptySet()));
+        assertTrue(policy.isPackageAllowed(TEST_PACKAGE_NAME, systemPackages));
+        assertFalse(policy.isPackageAllowed(TEST_PACKAGE_NAME_2, Collections.emptySet()));
+        assertFalse(policy.isPackageAllowed(TEST_PACKAGE_NAME_2, systemPackages));
+        assertFalse(policy.isPackageAllowed(TEST_SYSTEM_PACKAGE_NAME, Collections.emptySet()));
+        assertTrue(policy.isPackageAllowed(TEST_SYSTEM_PACKAGE_NAME, systemPackages));
+    }
+
+}
diff --git a/core/tests/coretests/src/android/credentials/OWNERS b/core/tests/coretests/src/android/credentials/OWNERS
new file mode 100644
index 0000000..00b5e06
--- /dev/null
+++ b/core/tests/coretests/src/android/credentials/OWNERS
@@ -0,0 +1,2 @@
+include /core/java/android/credentials/OWNERS
+
diff --git a/core/tests/coretests/src/android/os/BundleMergerTest.java b/core/tests/coretests/src/android/os/BundleMergerTest.java
index b7012ba..43ed821 100644
--- a/core/tests/coretests/src/android/os/BundleMergerTest.java
+++ b/core/tests/coretests/src/android/os/BundleMergerTest.java
@@ -26,6 +26,7 @@
 import static android.os.BundleMerger.STRATEGY_LAST;
 import static android.os.BundleMerger.STRATEGY_NUMBER_ADD;
 import static android.os.BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST;
+import static android.os.BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD;
 import static android.os.BundleMerger.STRATEGY_REJECT;
 import static android.os.BundleMerger.merge;
 
@@ -151,6 +152,14 @@
     }
 
     @Test
+    public void testStrategyNumberIncrementFirstAndAdd() throws Exception {
+        assertEquals(31, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 10, 20));
+        assertEquals(31, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 20, 10));
+        assertEquals(31L, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 10L, 20L));
+        assertEquals(31L, merge(STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD, 20L, 10L));
+    }
+
+    @Test
     public void testStrategyBooleanAnd() throws Exception {
         assertEquals(false, merge(STRATEGY_BOOLEAN_AND, false, false));
         assertEquals(false, merge(STRATEGY_BOOLEAN_AND, true, false));
@@ -215,6 +224,29 @@
     }
 
     @Test
+    public void testSetDefaultMergeStrategy() throws Exception {
+        final BundleMerger merger = new BundleMerger();
+        merger.setDefaultMergeStrategy(STRATEGY_FIRST);
+        merger.setMergeStrategy(Intent.EXTRA_INDEX, STRATEGY_COMPARABLE_MAX);
+
+        Bundle a = new Bundle();
+        a.putString(Intent.EXTRA_SUBJECT, "SubjectA");
+        a.putInt(Intent.EXTRA_INDEX, 10);
+
+        Bundle b = new Bundle();
+        b.putString(Intent.EXTRA_SUBJECT, "SubjectB");
+        b.putInt(Intent.EXTRA_INDEX, 20);
+
+        Bundle ab = merger.merge(a, b);
+        assertEquals("SubjectA", ab.getString(Intent.EXTRA_SUBJECT));
+        assertEquals(20, ab.getInt(Intent.EXTRA_INDEX));
+
+        Bundle ba = merger.merge(b, a);
+        assertEquals("SubjectB", ba.getString(Intent.EXTRA_SUBJECT));
+        assertEquals(20, ba.getInt(Intent.EXTRA_INDEX));
+    }
+
+    @Test
     public void testMerge_Simple() throws Exception {
         final BundleMerger merger = new BundleMerger();
         final Bundle probe = new Bundle();
@@ -323,7 +355,7 @@
         merger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
                 STRATEGY_COMPARABLE_MAX);
         merger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
-                STRATEGY_NUMBER_INCREMENT_FIRST);
+                STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);
 
         final long now = System.currentTimeMillis();
         final Bundle a = new Bundle();
@@ -341,6 +373,11 @@
         c.putLong(DropBoxManager.EXTRA_TIME, now + 2000);
         c.putInt(DropBoxManager.EXTRA_DROPPED_COUNT, 0);
 
+        final Bundle d = new Bundle();
+        d.putString(DropBoxManager.EXTRA_TAG, "system_server_strictmode");
+        d.putLong(DropBoxManager.EXTRA_TIME, now + 3000);
+        d.putInt(DropBoxManager.EXTRA_DROPPED_COUNT, 5);
+
         final Bundle ab = merger.merge(a, b);
         assertEquals("system_server_strictmode", ab.getString(DropBoxManager.EXTRA_TAG));
         assertEquals(now + 1000, ab.getLong(DropBoxManager.EXTRA_TIME));
@@ -350,6 +387,11 @@
         assertEquals("system_server_strictmode", abc.getString(DropBoxManager.EXTRA_TAG));
         assertEquals(now + 2000, abc.getLong(DropBoxManager.EXTRA_TIME));
         assertEquals(2, abc.getInt(DropBoxManager.EXTRA_DROPPED_COUNT));
+
+        final Bundle abcd = merger.merge(abc, d);
+        assertEquals("system_server_strictmode", abcd.getString(DropBoxManager.EXTRA_TAG));
+        assertEquals(now + 3000, abcd.getLong(DropBoxManager.EXTRA_TIME));
+        assertEquals(8, abcd.getInt(DropBoxManager.EXTRA_DROPPED_COUNT));
     }
 
     private static ArrayList<Object> arrayListOf(Object... values) {
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 958fdc6..a3eda8d 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -17,7 +17,7 @@
 package android.view;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
@@ -92,7 +92,7 @@
 
     @Test
     public void testImeVisibility() {
-        final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, WindowInsets.Type.ime(),
+        final InsetsSourceControl ime = new InsetsSourceControl(ID_IME, WindowInsets.Type.ime(),
                 mLeash, false, new Point(), Insets.NONE);
         mController.onControlsChanged(new InsetsSourceControl[] { ime });
 
@@ -121,7 +121,7 @@
             mController.show(WindowInsets.Type.ime(), true /* fromIme */, null /* statsToken */);
 
             // set control and verify visibility is applied.
-            InsetsSourceControl control = new InsetsSourceControl(ITYPE_IME,
+            InsetsSourceControl control = new InsetsSourceControl(ID_IME,
                     WindowInsets.Type.ime(), mLeash, false, new Point(), Insets.NONE);
             mController.onControlsChanged(new InsetsSourceControl[] { control });
             // IME show animation should be triggered when control becomes available.
@@ -161,7 +161,7 @@
             }
 
             // set control and verify visibility is applied.
-            InsetsSourceControl control = Mockito.spy(new InsetsSourceControl(ITYPE_IME,
+            InsetsSourceControl control = Mockito.spy(new InsetsSourceControl(ID_IME,
                     WindowInsets.Type.ime(), mLeash, false, new Point(), Insets.NONE));
             // Simulate IME source control set this flag when the target has starting window.
             control.setSkipAnimationOnce(true);
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index cc5f7f8..1682135 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -16,8 +16,8 @@
 
 package android.view;
 
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowInsets.Type.systemBars;
 
 import static org.junit.Assert.assertEquals;
@@ -66,6 +66,11 @@
 @RunWith(AndroidJUnit4.class)
 public class InsetsAnimationControlImplTest {
 
+    private static final int ID_STATUS_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, statusBars());
+    private static final int ID_NAVIGATION_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, navigationBars());
+
     private InsetsAnimationControlImpl mController;
 
     private SurfaceSession mSession = new SurfaceSession();
@@ -87,29 +92,31 @@
                 .setName("testSurface")
                 .build();
         mInsetsState = new InsetsState();
-        mInsetsState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 500, 100));
-        mInsetsState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
-        InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR,
+        mInsetsState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 500, 100));
+        mInsetsState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(400, 0, 500, 500));
+        InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ID_STATUS_BAR,
                 WindowInsets.Type.statusBars(), mInsetsState,
                 () -> mMockTransaction, mMockController);
         topConsumer.setControl(
-                new InsetsSourceControl(ITYPE_STATUS_BAR, WindowInsets.Type.statusBars(),
+                new InsetsSourceControl(ID_STATUS_BAR, WindowInsets.Type.statusBars(),
                         mStatusLeash, true, new Point(0, 0), Insets.of(0, 100, 0, 0)),
                 new int[1], new int[1]);
 
-        InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ITYPE_NAVIGATION_BAR,
+        InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ID_NAVIGATION_BAR,
                 WindowInsets.Type.navigationBars(), mInsetsState,
                 () -> mMockTransaction, mMockController);
         navConsumer.setControl(
-                new InsetsSourceControl(ITYPE_NAVIGATION_BAR, WindowInsets.Type.navigationBars(),
+                new InsetsSourceControl(ID_NAVIGATION_BAR, WindowInsets.Type.navigationBars(),
                         mNavLeash, true, new Point(400, 0), Insets.of(0, 0, 100, 0)),
                 new int[1], new int[1]);
         mMockController.setRequestedVisibleTypes(0, WindowInsets.Type.navigationBars());
         navConsumer.applyLocalVisibilityOverride();
 
         SparseArray<InsetsSourceControl> controls = new SparseArray<>();
-        controls.put(ITYPE_STATUS_BAR, topConsumer.getControl());
-        controls.put(ITYPE_NAVIGATION_BAR, navConsumer.getControl());
+        controls.put(ID_STATUS_BAR, topConsumer.getControl());
+        controls.put(ID_NAVIGATION_BAR, navConsumer.getControl());
         mController = new InsetsAnimationControlImpl(controls,
                 new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
                 mMockController, 10 /* durationMs */, new LinearInterpolator(),
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 5ec93e5..ca1367a 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -22,16 +22,13 @@
 import static android.view.InsetsController.ANIMATION_TYPE_RESIZE;
 import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
 import static android.view.InsetsController.AnimationType;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsSourceConsumer.ShowResult.IME_SHOW_DELAYED;
 import static android.view.InsetsSourceConsumer.ShowResult.SHOW_IMMEDIATELY;
-import static android.view.InsetsState.FIRST_TYPE;
-import static android.view.InsetsState.ITYPE_CAPTION_BAR;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.LAST_TYPE;
 import static android.view.ViewRootImpl.CAPTION_ON_SHELL;
+import static android.view.WindowInsets.Type.SIZE;
 import static android.view.WindowInsets.Type.all;
+import static android.view.WindowInsets.Type.captionBar;
 import static android.view.WindowInsets.Type.defaultVisible;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
@@ -64,7 +61,6 @@
 import android.graphics.Rect;
 import android.os.CancellationSignal;
 import android.platform.test.annotations.Presubmit;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.SurfaceControl.Transaction;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.OnControllableInsetsChangedListener;
@@ -101,6 +97,12 @@
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class InsetsControllerTest {
+
+    private static final int ID_STATUS_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, statusBars());
+    private static final int ID_NAVIGATION_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, navigationBars());
+
     private InsetsSource mStatusSource;
     private InsetsSource mNavSource;
     private InsetsSource mImeSource;
@@ -153,11 +155,11 @@
                 }
             }, mTestHandler);
             final Rect rect = new Rect(5, 5, 5, 5);
-            mStatusSource = new InsetsSource(ITYPE_STATUS_BAR, statusBars());
+            mStatusSource = new InsetsSource(ID_STATUS_BAR, statusBars());
             mStatusSource.setFrame(new Rect(0, 0, 100, 10));
-            mNavSource = new InsetsSource(ITYPE_NAVIGATION_BAR, navigationBars());
+            mNavSource = new InsetsSource(ID_NAVIGATION_BAR, navigationBars());
             mNavSource.setFrame(new Rect(0, 90, 100, 100));
-            mImeSource = new InsetsSource(ITYPE_IME, ime());
+            mImeSource = new InsetsSource(ID_IME, ime());
             mImeSource.setFrame(new Rect(0, 0, 100, 10));
             InsetsState state = new InsetsState();
             state.addSource(mStatusSource);
@@ -179,7 +181,7 @@
 
     @Test
     public void testControlsChanged() {
-        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+        mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
         assertNotNull(mController.getSourceConsumer(mStatusSource).getControl().getLeash());
         mController.addOnControllableInsetsChangedListener(
                 ((controller, typeMask) -> assertEquals(statusBars(), typeMask)));
@@ -190,7 +192,7 @@
         OnControllableInsetsChangedListener listener
                 = mock(OnControllableInsetsChangedListener.class);
         mController.addOnControllableInsetsChangedListener(listener);
-        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+        mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
         mController.onControlsChanged(new InsetsSourceControl[0]);
         assertNull(mController.getSourceConsumer(mStatusSource).getControl());
         InOrder inOrder = Mockito.inOrder(listener);
@@ -202,7 +204,7 @@
     @Test
     public void testControlsRevoked_duringAnim() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+            mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
 
             ArgumentCaptor<WindowInsetsAnimationController> animationController =
                     ArgumentCaptor.forClass(WindowInsetsAnimationController.class);
@@ -231,7 +233,7 @@
 
             InsetsSourceControl control =
                     new InsetsSourceControl(
-                            ITYPE_STATUS_BAR, statusBars(), mLeash, true, new Point(),
+                            ID_STATUS_BAR, statusBars(), mLeash, true, new Point(),
                             Insets.of(0, 10, 0, 0));
             mController.onControlsChanged(new InsetsSourceControl[]{control});
             mController.controlWindowInsetsAnimation(0, 0 /* durationMs */,
@@ -284,7 +286,7 @@
 
     @Test
     public void testApplyImeVisibility() {
-        InsetsSourceControl ime = createControl(ITYPE_IME, ime());
+        InsetsSourceControl ime = createControl(ID_IME, ime());
         mController.onControlsChanged(new InsetsSourceControl[] { ime });
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mController.getSourceConsumer(mImeSource).onWindowFocusGained(true);
@@ -423,28 +425,28 @@
 
     @Test
     public void testRestoreStartsAnimation() {
-        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+        mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mController.hide(statusBars());
             mController.cancelExistingAnimations();
             assertFalse(isRequestedVisible(mController, statusBars()));
-            assertFalse(mController.getState().getSource(ITYPE_STATUS_BAR).isVisible());
+            assertFalse(mController.getState().peekSource(ID_STATUS_BAR).isVisible());
 
             // Loosing control
             InsetsState state = new InsetsState(mController.getState());
-            state.setSourceVisible(ITYPE_STATUS_BAR, true);
+            state.setSourceVisible(ID_STATUS_BAR, true);
             mController.onStateChanged(state);
             mController.onControlsChanged(new InsetsSourceControl[0]);
             assertFalse(isRequestedVisible(mController, statusBars()));
-            assertTrue(mController.getState().getSource(ITYPE_STATUS_BAR).isVisible());
+            assertTrue(mController.getState().peekSource(ID_STATUS_BAR).isVisible());
 
             // Gaining control
-            mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+            mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
             assertEquals(ANIMATION_TYPE_HIDE, mController.getAnimationType(statusBars()));
             mController.cancelExistingAnimations();
             assertFalse(isRequestedVisible(mController, statusBars()));
-            assertFalse(mController.getState().getSource(ITYPE_STATUS_BAR).isVisible());
+            assertFalse(mController.getState().peekSource(ID_STATUS_BAR).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -455,18 +457,18 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
 
             mController.show(ime());
-            assertFalse(mController.getState().getSource(ITYPE_IME).isVisible());
+            assertFalse(mController.getState().peekSource(ID_IME).isVisible());
 
             // Pretend IME is calling
             mController.show(ime(), true /* fromIme */, null /* statsToken */);
 
             // Gaining control shortly after
-            mController.onControlsChanged(createSingletonControl(ITYPE_IME, ime()));
+            mController.onControlsChanged(createSingletonControl(ID_IME, ime()));
 
             assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ime()));
             mController.cancelExistingAnimations();
             assertTrue(isRequestedVisible(mController, ime()));
-            assertTrue(mController.getState().getSource(ITYPE_IME).isVisible());
+            assertTrue(mController.getState().peekSource(ID_IME).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -476,10 +478,10 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
 
             mController.show(ime());
-            assertFalse(mController.getState().getSource(ITYPE_IME).isVisible());
+            assertFalse(mController.getState().peekSource(ID_IME).isVisible());
 
             // Gaining control shortly after
-            mController.onControlsChanged(createSingletonControl(ITYPE_IME, ime()));
+            mController.onControlsChanged(createSingletonControl(ID_IME, ime()));
 
             // Pretend IME is calling
             mController.show(ime(), true /* fromIme */, null /* statsToken */);
@@ -487,14 +489,14 @@
             assertEquals(ANIMATION_TYPE_SHOW, mController.getAnimationType(ime()));
             mController.cancelExistingAnimations();
             assertTrue(isRequestedVisible(mController, ime()));
-            assertTrue(mController.getState().getSource(ITYPE_IME).isVisible());
+            assertTrue(mController.getState().peekSource(ID_IME).isVisible());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     @Test
     public void testAnimationEndState_controller() throws Exception {
-        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+        mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             WindowInsetsAnimationControlListener mockListener =
@@ -520,7 +522,7 @@
 
     @Test
     public void testCancellation_afterGainingControl() throws Exception {
-        mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR, statusBars()));
+        mController.onControlsChanged(createSingletonControl(ID_STATUS_BAR, statusBars()));
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             WindowInsetsAnimationControlListener mockListener =
@@ -641,61 +643,60 @@
     public void testFrameUpdateDuringAnimation() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
 
-            mController.onControlsChanged(createSingletonControl(ITYPE_IME, ime()));
+            mController.onControlsChanged(createSingletonControl(ID_IME, ime()));
 
             // Pretend IME is calling
             mController.show(ime(), true /* fromIme */, null /* statsToken */);
 
             InsetsState copy = new InsetsState(mController.getState(), true /* copySources */);
-            copy.getSource(ITYPE_IME).setFrame(0, 1, 2, 3);
-            copy.getSource(ITYPE_IME).setVisibleFrame(new Rect(4, 5, 6, 7));
+            copy.peekSource(ID_IME).setFrame(0, 1, 2, 3);
+            copy.peekSource(ID_IME).setVisibleFrame(new Rect(4, 5, 6, 7));
             mController.onStateChanged(copy);
             assertNotEquals(new Rect(0, 1, 2, 3),
-                    mController.getState().getSource(ITYPE_IME).getFrame());
+                    mController.getState().peekSource(ID_IME).getFrame());
             assertNotEquals(new Rect(4, 5, 6, 7),
-                    mController.getState().getSource(ITYPE_IME).getVisibleFrame());
+                    mController.getState().peekSource(ID_IME).getVisibleFrame());
             mController.cancelExistingAnimations();
             assertEquals(new Rect(0, 1, 2, 3),
-                    mController.getState().getSource(ITYPE_IME).getFrame());
+                    mController.getState().peekSource(ID_IME).getFrame());
             assertEquals(new Rect(4, 5, 6, 7),
-                    mController.getState().getSource(ITYPE_IME).getVisibleFrame());
+                    mController.getState().peekSource(ID_IME).getVisibleFrame());
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
     @Test
     public void testResizeAnimation_insetsTypes() {
-        for (@InternalInsetsType int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
-            final @AnimationType int expectedAnimationType =
-                    (InsetsState.toPublicType(type) & systemBars()) != 0
+        for (int i = 0; i < SIZE; i++) {
+            final @InsetsType int type = 1 << i;
+            final @AnimationType int expectedAnimationType = (type & systemBars()) != 0
                             ? ANIMATION_TYPE_RESIZE
                             : ANIMATION_TYPE_NONE;
             doTestResizeAnimation_insetsTypes(type, expectedAnimationType);
         }
     }
 
-    private void doTestResizeAnimation_insetsTypes(@InternalInsetsType int type,
+    private void doTestResizeAnimation_insetsTypes(@InsetsType int type,
             @AnimationType int expectedAnimationType) {
-        final @InsetsType int publicType = InsetsState.toPublicType(type);
+        final int id = type;
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             final InsetsState state1 = new InsetsState();
-            state1.getSource(type).setVisible(true);
-            state1.getSource(type).setFrame(0, 0, 500, 50);
+            state1.getOrCreateSource(id, type).setVisible(true).setFrame(0, 0, 500, 50);
             final InsetsState state2 = new InsetsState(state1, true /* copySources */);
-            state2.getSource(type).setFrame(0, 0, 500, 60);
-            final String message = "Animation type of " + InsetsState.typeToString(type) + ":";
+            state2.peekSource(id).setFrame(0, 0, 500, 60);
+            final String message = "Animation type of " + WindowInsets.Type.toString(type) + ":";
 
             // New insets source won't cause the resize animation.
             mController.onStateChanged(state1);
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
 
             // Changing frame might cause the resize animation. This depends on the insets type.
             mController.onStateChanged(state2);
-            assertEquals(message, expectedAnimationType, mController.getAnimationType(publicType));
+            assertEquals(message, expectedAnimationType, mController.getAnimationType(type));
 
             // Cancel the existing animations for the next iteration.
             mController.cancelExistingAnimations();
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -703,23 +704,23 @@
     @Test
     public void testResizeAnimation_displayFrame() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            final @InternalInsetsType int type = ITYPE_STATUS_BAR;
-            final @InsetsType int publicType = statusBars();
+            final int id = ID_STATUS_BAR;
+            final @InsetsType int type = statusBars();
             final InsetsState state1 = new InsetsState();
             state1.setDisplayFrame(new Rect(0, 0, 500, 1000));
-            state1.getSource(type).setFrame(0, 0, 500, 50);
+            state1.getOrCreateSource(id, type).setFrame(0, 0, 500, 50);
             final InsetsState state2 = new InsetsState(state1, true /* copySources */);
             state2.setDisplayFrame(new Rect(0, 0, 500, 1010));
-            state2.getSource(type).setFrame(0, 0, 500, 60);
+            state2.peekSource(id).setFrame(0, 0, 500, 60);
             final String message = "There must not be resize animation.";
 
             // New insets source won't cause the resize animation.
             mController.onStateChanged(state1);
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
 
             // Changing frame won't cause the resize animation if the display frame is also changed.
             mController.onStateChanged(state2);
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -727,32 +728,29 @@
     @Test
     public void testResizeAnimation_visibility() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            final @InternalInsetsType int type = ITYPE_STATUS_BAR;
-            final @InsetsType int publicType = statusBars();
+            final int id = ID_STATUS_BAR;
+            final @InsetsType int type = statusBars();
             final InsetsState state1 = new InsetsState();
-            state1.getSource(type).setVisible(true);
-            state1.getSource(type).setFrame(0, 0, 500, 50);
+            state1.getOrCreateSource(id, type).setVisible(true).setFrame(0, 0, 500, 50);
             final InsetsState state2 = new InsetsState(state1, true /* copySources */);
-            state2.getSource(type).setVisible(false);
-            state2.getSource(type).setFrame(0, 0, 500, 60);
+            state2.peekSource(id).setVisible(false).setFrame(0, 0, 500, 60);
             final InsetsState state3 = new InsetsState(state2, true /* copySources */);
-            state3.getSource(type).setVisible(true);
-            state3.getSource(type).setFrame(0, 0, 500, 70);
+            state3.peekSource(id).setVisible(true).setFrame(0, 0, 500, 70);
             final String message = "There must not be resize animation.";
 
             // New insets source won't cause the resize animation.
             mController.onStateChanged(state1);
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
 
             // Changing source visibility (visible --> invisible) won't cause the resize animation.
             // The previous source and the current one must be both visible.
             mController.onStateChanged(state2);
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
 
             // Changing source visibility (invisible --> visible) won't cause the resize animation.
             // The previous source and the current one must be both visible.
             mController.onStateChanged(state3);
-            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(publicType));
+            assertEquals(message, ANIMATION_TYPE_NONE, mController.getAnimationType(type));
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
@@ -765,22 +763,20 @@
             return;
         }
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mController.onFrameChanged(new Rect(0, 0, 100, 300));
-            final InsetsState state = new InsetsState(mController.getState(), true);
-            final Rect captionFrame = new Rect(0, 0, 100, 100);
-            mController.setCaptionInsetsHeight(100);
-            mController.onStateChanged(state);
-            final InsetsState currentState = new InsetsState(mController.getState());
-            // The caption bar source should be synced with the info in mAttachInfo.
-            assertEquals(captionFrame, currentState.peekSource(ITYPE_CAPTION_BAR).getFrame());
-            assertTrue(currentState.equals(state, true /* excludingCaptionInsets*/,
-                    true /* excludeInvisibleIme */));
+            final Rect frame = new Rect(0, 0, 100, 300);
+            final int captionBarHeight = 100;
+            final InsetsState state = mController.getState();
+            mController.onFrameChanged(frame);
+            mController.setCaptionInsetsHeight(captionBarHeight);
+            // The caption bar insets height should be the same as the caption bar height.
+            assertEquals(captionBarHeight, state.calculateInsets(frame, captionBar(), false).top);
             // Test update to remove the caption bar
             mController.setCaptionInsetsHeight(0);
-            mController.onStateChanged(state);
             // The caption bar source should not be there at all, because we don't add empty
             // caption to the state from the server.
-            assertNull(mController.getState().peekSource(ITYPE_CAPTION_BAR));
+            for (int i = state.sourceSize() - 1; i >= 0; i--) {
+                assertNotEquals(captionBar(), state.sourceAt(i).getType());
+            }
         });
     }
 
@@ -792,7 +788,6 @@
             return;
         }
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            final InsetsState state = new InsetsState(mController.getState(), true);
             reset(mTestHost);
             mController.setCaptionInsetsHeight(100);
             verify(mTestHost).notifyInsetsChanged();
@@ -881,28 +876,28 @@
             // Changing status bar frame should cause notifyInsetsChanged.
             clearInvocations(mTestHost);
             InsetsState newState = new InsetsState(localState, true /* copySources */);
-            newState.getSource(ITYPE_STATUS_BAR).getFrame().bottom++;
+            newState.peekSource(ID_STATUS_BAR).getFrame().bottom++;
             mController.onStateChanged(newState);
             verify(mTestHost, times(1)).notifyInsetsChanged();
 
             // Changing status bar visibility should cause notifyInsetsChanged.
             clearInvocations(mTestHost);
             newState = new InsetsState(localState, true /* copySources */);
-            newState.getSource(ITYPE_STATUS_BAR).setVisible(false);
+            newState.peekSource(ID_STATUS_BAR).setVisible(false);
             mController.onStateChanged(newState);
             verify(mTestHost, times(1)).notifyInsetsChanged();
 
             // Changing invisible IME frame should not cause notifyInsetsChanged.
             clearInvocations(mTestHost);
             newState = new InsetsState(localState, true /* copySources */);
-            newState.getSource(ITYPE_IME).getFrame().top--;
+            newState.peekSource(ID_IME).getFrame().top--;
             mController.onStateChanged(newState);
             verify(mTestHost, never()).notifyInsetsChanged();
 
             // Changing IME visibility should cause notifyInsetsChanged.
             clearInvocations(mTestHost);
             newState = new InsetsState(localState, true /* copySources */);
-            newState.getSource(ITYPE_IME).setVisible(true);
+            newState.peekSource(ID_IME).setVisible(true);
             mController.onStateChanged(newState);
             verify(mTestHost, times(1)).notifyInsetsChanged();
         });
@@ -947,9 +942,9 @@
     }
 
     private InsetsSourceControl[] prepareControls() {
-        final InsetsSourceControl navBar = createControl(ITYPE_NAVIGATION_BAR, navigationBars());
-        final InsetsSourceControl statusBar = createControl(ITYPE_STATUS_BAR, statusBars());
-        final InsetsSourceControl ime = createControl(ITYPE_IME, ime());
+        final InsetsSourceControl navBar = createControl(ID_NAVIGATION_BAR, navigationBars());
+        final InsetsSourceControl statusBar = createControl(ID_STATUS_BAR, statusBars());
+        final InsetsSourceControl ime = createControl(ID_IME, ime());
 
         InsetsSourceControl[] controls = new InsetsSourceControl[3];
         controls[0] = navBar;
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 0486e3c..988e690 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -18,9 +18,8 @@
 
 import static android.view.InsetsController.ANIMATION_TYPE_NONE;
 import static android.view.InsetsController.ANIMATION_TYPE_USER;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsSourceConsumer.ShowResult.SHOW_IMMEDIATELY;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.statusBars;
 
@@ -69,6 +68,9 @@
 @RunWith(AndroidJUnit4.class)
 public class InsetsSourceConsumerTest {
 
+    private static final int ID_STATUS_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, statusBars());
+
     private InsetsSourceConsumer mConsumer;
 
     private SurfaceSession mSession = new SurfaceSession();
@@ -97,11 +99,11 @@
                 // activity isn't running, lets ignore BadTokenException.
             }
             mState = new InsetsState();
-            mSpyInsetsSource = Mockito.spy(new InsetsSource(ITYPE_STATUS_BAR, statusBars()));
+            mSpyInsetsSource = Mockito.spy(new InsetsSource(ID_STATUS_BAR, statusBars()));
             mState.addSource(mSpyInsetsSource);
 
             mController = new InsetsController(new ViewRootInsetsControllerHost(mViewRoot));
-            mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, statusBars(), mState,
+            mConsumer = new InsetsSourceConsumer(ID_STATUS_BAR, statusBars(), mState,
                     () -> mMockTransaction, mController) {
                 @Override
                 public void removeSurface() {
@@ -113,7 +115,7 @@
         instrumentation.waitForIdleSync();
 
         mConsumer.setControl(
-                new InsetsSourceControl(ITYPE_STATUS_BAR, statusBars(), mLeash,
+                new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                         true /* initialVisible */, new Point(), Insets.NONE),
                 new int[1], new int[1]);
     }
@@ -147,25 +149,25 @@
         InsetsController controller = new InsetsController(new ViewRootInsetsControllerHost(
                 mViewRoot));
         InsetsSourceConsumer consumer = new InsetsSourceConsumer(
-                ITYPE_IME, ime(), state, null, controller);
+                ID_IME, ime(), state, null, controller);
 
-        InsetsSource source = new InsetsSource(ITYPE_IME, ime());
+        InsetsSource source = new InsetsSource(ID_IME, ime());
         source.setFrame(0, 1, 2, 3);
         consumer.updateSource(new InsetsSource(source), ANIMATION_TYPE_NONE);
 
         // While we're animating, updates are delayed
         source.setFrame(4, 5, 6, 7);
         consumer.updateSource(new InsetsSource(source), ANIMATION_TYPE_USER);
-        assertEquals(new Rect(0, 1, 2, 3), state.peekSource(ITYPE_IME).getFrame());
+        assertEquals(new Rect(0, 1, 2, 3), state.peekSource(ID_IME).getFrame());
 
         // Finish the animation, now the pending frame should be applied
         assertTrue(consumer.onAnimationStateChanged(false /* running */));
-        assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+        assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ID_IME).getFrame());
 
         // Animating again, updates are delayed
         source.setFrame(8, 9, 10, 11);
         consumer.updateSource(new InsetsSource(source), ANIMATION_TYPE_USER);
-        assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+        assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ID_IME).getFrame());
 
         // Updating with the current frame triggers a different code path, verify this clears
         // the pending 8, 9, 10, 11 frame:
@@ -173,7 +175,7 @@
         consumer.updateSource(new InsetsSource(source), ANIMATION_TYPE_USER);
 
         assertFalse(consumer.onAnimationStateChanged(false /* running */));
-        assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame());
+        assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ID_IME).getFrame());
     }
 
     @Test
@@ -185,7 +187,7 @@
             verifyZeroInteractions(mMockTransaction);
             int[] hideTypes = new int[1];
             mConsumer.setControl(
-                    new InsetsSourceControl(ITYPE_STATUS_BAR, statusBars(), mLeash,
+                    new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                             true /* initialVisible */, new Point(), Insets.NONE),
                     new int[1], hideTypes);
             assertEquals(statusBars(), hideTypes[0]);
@@ -203,7 +205,7 @@
             mRemoveSurfaceCalled = false;
             int[] hideTypes = new int[1];
             mConsumer.setControl(
-                    new InsetsSourceControl(ITYPE_STATUS_BAR, statusBars(), mLeash,
+                    new InsetsSourceControl(ID_STATUS_BAR, statusBars(), mLeash,
                             false /* initialVisible */, new Point(), Insets.NONE),
                     new int[1], hideTypes);
             assertTrue(mRemoveSurfaceCalled);
@@ -219,7 +221,7 @@
             ViewRootInsetsControllerHost host = new ViewRootInsetsControllerHost(mViewRoot);
             InsetsController insetsController = new InsetsController(host, (controller, source) -> {
                 if (source.getType() == ime()) {
-                    return new InsetsSourceConsumer(ITYPE_IME, ime(), state,
+                    return new InsetsSourceConsumer(ID_IME, ime(), state,
                             () -> mMockTransaction, controller) {
                         @Override
                         public int requestShow(boolean fromController,
@@ -231,11 +233,11 @@
                 return new InsetsSourceConsumer(source.getId(), source.getType(),
                         controller.getState(), Transaction::new, controller);
             }, host.getHandler());
-            InsetsSource imeSource = new InsetsSource(ITYPE_IME, ime());
+            InsetsSource imeSource = new InsetsSource(ID_IME, ime());
             InsetsSourceConsumer imeConsumer = insetsController.getSourceConsumer(imeSource);
 
             // Initial IME insets source control with its leash.
-            imeConsumer.setControl(new InsetsSourceControl(ITYPE_IME, ime(), mLeash,
+            imeConsumer.setControl(new InsetsSourceControl(ID_IME, ime(), mLeash,
                     false /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1]);
             reset(mMockTransaction);
 
@@ -244,7 +246,7 @@
             insetsController.controlWindowInsetsAnimation(ime(), 0L,
                     null /* interpolator */, null /* cancellationSignal */, null /* listener */);
             assertEquals(ANIMATION_TYPE_USER, insetsController.getAnimationType(ime()));
-            imeConsumer.setControl(new InsetsSourceControl(ITYPE_IME, ime(), mLeash,
+            imeConsumer.setControl(new InsetsSourceControl(ID_IME, ime(), mLeash,
                     true /* initialVisible */, new Point(), Insets.NONE), new int[1], new int[1]);
             verify(mMockTransaction, never()).show(mLeash);
         });
diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java
index e01440c..1db6587 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -16,15 +16,19 @@
 
 package android.view;
 
-import static android.view.WindowInsets.Type.captionBar;
+import static android.view.WindowInsets.Type.FIRST;
+import static android.view.WindowInsets.Type.LAST;
+import static android.view.WindowInsets.Type.SIZE;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.util.SparseArray;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -47,13 +51,11 @@
 
     private final InsetsSource mSource = new InsetsSource(0 /* id */, navigationBars());
     private final InsetsSource mImeSource = new InsetsSource(1 /* id */, ime());
-    private final InsetsSource mCaptionSource = new InsetsSource(2 /* id */, captionBar());
 
     @Before
     public void setUp() {
         mSource.setVisible(true);
         mImeSource.setVisible(true);
-        mCaptionSource.setVisible(true);
     }
 
     @Test
@@ -105,17 +107,6 @@
     }
 
     @Test
-    public void testCalculateInsets_caption_resizing() {
-        mCaptionSource.setFrame(new Rect(0, 0, 100, 100));
-        Insets insets = mCaptionSource.calculateInsets(new Rect(0, 0, 200, 200), false);
-        assertEquals(Insets.of(0, 100, 0, 0), insets);
-        insets = mCaptionSource.calculateInsets(new Rect(0, 0, 50, 200), false);
-        assertEquals(Insets.of(0, 100, 0, 0), insets);
-        insets = mCaptionSource.calculateInsets(new Rect(100, 100, 200, 500), false);
-        assertEquals(Insets.of(0, 100, 0, 0), insets);
-    }
-
-    @Test
     public void testCalculateInsets_invisible() {
         mSource.setFrame(new Rect(0, 0, 500, 100));
         mSource.setVisible(false);
@@ -206,6 +197,21 @@
         assertEquals(Insets.of(0, 0, 0, 0), insets);
     }
 
+    @Test
+    public void testCreateId() {
+        final int numSourcePerType = 2048;
+        final int numTotalSources = SIZE * numSourcePerType;
+        final SparseArray<InsetsSource> sources = new SparseArray<>(numTotalSources);
+        final Object owner = new Object();
+        for (int index = 0; index < numSourcePerType; index++) {
+            for (int type = FIRST; type <= LAST; type = type << 1) {
+                final int id = InsetsSource.createId(owner, index, type);
+                assertNull("Must not create the same ID.", sources.get(id));
+                sources.append(id, new InsetsSource(id, type));
+            }
+        }
+        assertEquals(numTotalSources, sources.size());
+    }
 
     // Parcel and equals already tested via InsetsStateTest
 }
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index 6a96f28..b035c23 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -18,24 +18,20 @@
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsState.ISIDE_BOTTOM;
 import static android.view.InsetsState.ISIDE_TOP;
-import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
-import static android.view.InsetsState.ITYPE_CAPTION_BAR;
-import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.RoundedCorner.POSITION_BOTTOM_LEFT;
 import static android.view.RoundedCorner.POSITION_BOTTOM_RIGHT;
 import static android.view.RoundedCorner.POSITION_TOP_LEFT;
 import static android.view.RoundedCorner.POSITION_TOP_RIGHT;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+import static android.view.WindowInsets.Type.captionBar;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowInsets.Type.systemGestures;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
@@ -47,8 +43,10 @@
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+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 android.graphics.Insets;
@@ -76,33 +74,50 @@
 @RunWith(AndroidJUnit4.class)
 public class InsetsStateTest {
 
-    private InsetsState mState = new InsetsState();
-    private InsetsState mState2 = new InsetsState();
+    private static final int ID_STATUS_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, statusBars());
+    private static final int ID_NAVIGATION_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, navigationBars());
+    private static final int ID_CAPTION_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, captionBar());
+    private static final int ID_CLIMATE_BAR = InsetsSource.createId(
+            null /* owner */, 1 /* index */, statusBars());
+    private static final int ID_EXTRA_NAVIGATION_BAR = InsetsSource.createId(
+            null /* owner */, 1 /* index */, navigationBars());
+    private static final int ID_BOTTOM_GESTURES = InsetsSource.createId(
+            null /* owner */, 0 /* index */, systemGestures());
+
+    private final InsetsState mState = new InsetsState();
+    private final InsetsState mState2 = new InsetsState();
 
     @Test
     public void testCalculateInsets() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
         SparseIntArray typeSideMap = new SparseIntArray();
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
                 typeSideMap);
         assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets());
         assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all()));
-        assertEquals(ISIDE_TOP, typeSideMap.get(ITYPE_STATUS_BAR));
-        assertEquals(ISIDE_BOTTOM, typeSideMap.get(ITYPE_IME));
+        assertEquals(ISIDE_TOP, typeSideMap.get(ID_STATUS_BAR));
+        assertEquals(ISIDE_BOTTOM, typeSideMap.get(ID_IME));
         assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(statusBars()));
         assertEquals(Insets.of(0, 0, 0, 100), insets.getInsets(ime()));
     }
 
     @Test
     public void testCalculateInsets_imeAndNav() {
-        mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 100, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 100, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
                 null);
@@ -116,10 +131,12 @@
 
     @Test
     public void testCalculateInsets_navRightStatusTop() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(80, 0, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
         assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
@@ -129,14 +146,14 @@
 
     @Test
     public void testCalculateInsets_extraNavRightClimateTop() throws Exception {
-        mState.getSource(ITYPE_CLIMATE_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_CLIMATE_BAR).setVisible(true);
-        mState.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
-        mState.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_CLIMATE_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_EXTRA_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(80, 0, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
-        // ITYPE_CLIMATE_BAR is a type of status bar and ITYPE_EXTRA_NAVIGATION_BAR is a type
-        // of navigation bar.
         assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
         assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars()));
         assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars()));
@@ -144,10 +161,12 @@
 
     @Test
     public void testCalculateInsets_imeIgnoredWithoutAdjustResize() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
                 null);
@@ -158,10 +177,12 @@
 
     @Test
     public void testCalculateInsets_systemUiFlagLayoutStable() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(false);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, SOFT_INPUT_ADJUST_NOTHING, 0, SYSTEM_UI_FLAG_LAYOUT_STABLE, TYPE_APPLICATION,
                 WINDOWING_MODE_UNDEFINED, null);
@@ -174,8 +195,9 @@
 
     @Test
     public void testCalculateInsets_systemUiFlagLayoutStable_windowFlagFullscreen() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(false);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, SOFT_INPUT_ADJUST_NOTHING, FLAG_FULLSCREEN, SYSTEM_UI_FLAG_LAYOUT_STABLE,
                 TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
@@ -188,8 +210,9 @@
 
     @Test
     public void testCalculateInsets_flagLayoutNoLimits() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS,
                 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
@@ -211,10 +234,12 @@
 
     @Test
     public void testCalculateInsets_captionStatusBarOverlap() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(0, 0, 100, 300));
-        mState.getSource(ITYPE_CAPTION_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_CAPTION_BAR, captionBar())
+                .setFrame(new Rect(0, 0, 100, 300))
+                .setVisible(true);
 
         Insets visibleInsets = mState.calculateVisibleInsets(
                 new Rect(0, 0, 100, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
@@ -223,22 +248,13 @@
     }
 
     @Test
-    public void testCalculateInsets_captionBarOffset() {
-        mState.getSource(ITYPE_CAPTION_BAR).setFrame(new Rect(0, 0, 100, 300));
-        mState.getSource(ITYPE_CAPTION_BAR).setVisible(true);
-
-        Insets visibleInsets = mState.calculateVisibleInsets(
-                new Rect(0, 0, 150, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
-                SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */);
-        assertEquals(Insets.of(0, 300, 0, 0), visibleInsets);
-    }
-
-    @Test
     public void testCalculateInsets_extraNavRightStatusTop() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
-        mState.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_EXTRA_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(80, 0, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
         assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
@@ -248,10 +264,12 @@
 
     @Test
     public void testCalculateInsets_navigationRightClimateTop() {
-        mState.getSource(ITYPE_CLIMATE_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_CLIMATE_BAR).setVisible(true);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(80, 0, 100, 300));
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_CLIMATE_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(80, 0, 100, 300))
+                .setVisible(true);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false,
                 false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
         assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets());
@@ -261,11 +279,13 @@
 
     @Test
     public void testStripForDispatch() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
-        mState.removeSource(ITYPE_IME);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
+        mState.removeSource(ID_IME);
         WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false,
                 SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null);
         assertEquals(0, insets.getSystemWindowInsetBottom());
@@ -273,32 +293,42 @@
 
     @Test
     public void testEquals_differentRect() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 10, 10));
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100));
+        mState2.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 10, 10));
         assertNotEqualsAndHashCode();
     }
 
     @Test
     public void testEquals_differentSource() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100));
+        mState2.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100));
         assertNotEqualsAndHashCode();
     }
 
     @Test
     public void testEquals_sameButDifferentInsertOrder() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100));
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100));
+        mState2.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100));
+        mState2.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100));
         assertEqualsAndHashCode();
     }
 
     @Test
     public void testEquals_visibility() {
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_IME).setVisible(true);
-        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState2.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100));
         assertNotEqualsAndHashCode();
     }
 
@@ -363,19 +393,23 @@
 
     @Test
     public void testEquals_excludeInvisibleIme() {
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_IME).setVisible(false);
-        mState2.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 200));
-        mState2.getSource(ITYPE_IME).setVisible(false);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(false);
+        mState2.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 200))
+                .setVisible(false);
         assertTrue(mState2.equals(mState, true, true /* excludeInvisibleIme */));
     }
 
     @Test
     public void testParcelUnparcel() {
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_IME).setVisibleFrame(new Rect(0, 0, 50, 10));
-        mState.getSource(ITYPE_IME).setVisible(true);
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisibleFrame(new Rect(0, 0, 50, 10))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100));
         Parcel p = Parcel.obtain();
         mState.writeToParcel(p, 0 /* flags */);
         p.setDataPosition(0);
@@ -386,35 +420,31 @@
 
     @Test
     public void testCopy() {
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_IME).setVisibleFrame(new Rect(0, 0, 50, 10));
-        mState.getSource(ITYPE_IME).setVisible(true);
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState2.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(0, 0, 100, 100));
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisibleFrame(new Rect(0, 0, 50, 10))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100));
+        mState2.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(0, 0, 100, 100));
         mState2.set(mState, true);
         assertEquals(mState, mState2);
     }
 
     @Test
-    public void testGetDefaultVisibility() {
-        assertTrue(InsetsState.getDefaultVisibility(ITYPE_STATUS_BAR));
-        assertTrue(InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR));
-        assertTrue(InsetsState.getDefaultVisibility(ITYPE_CLIMATE_BAR));
-        assertTrue(InsetsState.getDefaultVisibility(ITYPE_EXTRA_NAVIGATION_BAR));
-        assertTrue(InsetsState.getDefaultVisibility(ITYPE_CAPTION_BAR));
-        assertFalse(InsetsState.getDefaultVisibility(ITYPE_IME));
-    }
-
-    @Test
     public void testCalculateVisibleInsets() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
 
         // Make sure bottom gestures are ignored
-        mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300));
-        mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true);
+        mState.getOrCreateSource(ID_BOTTOM_GESTURES, systemGestures())
+                .setFrame(new Rect(0, 100, 100, 300))
+                .setVisible(true);
         Insets visibleInsets = mState.calculateVisibleInsets(
                 new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
                 SOFT_INPUT_ADJUST_PAN, 0 /* windowFlags */);
@@ -423,14 +453,17 @@
 
     @Test
     public void testCalculateVisibleInsets_adjustNothing() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
 
         // Make sure bottom gestures are ignored
-        mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300));
-        mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true);
+        mState.getOrCreateSource(ID_BOTTOM_GESTURES, systemGestures())
+                .setFrame(new Rect(0, 100, 100, 300))
+                .setVisible(true);
         Insets visibleInsets = mState.calculateVisibleInsets(
                 new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
                 SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */);
@@ -439,14 +472,17 @@
 
     @Test
     public void testCalculateVisibleInsets_layoutNoLimits() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 100, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 100, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 100, 300))
+                .setVisible(true);
 
         // Make sure bottom gestures are ignored
-        mState.getSource(ITYPE_BOTTOM_GESTURES).setFrame(new Rect(0, 100, 100, 300));
-        mState.getSource(ITYPE_BOTTOM_GESTURES).setVisible(true);
+        mState.getOrCreateSource(ID_BOTTOM_GESTURES, systemGestures())
+                .setFrame(new Rect(0, 100, 100, 300))
+                .setVisible(true);
         Insets visibleInsets = mState.calculateVisibleInsets(
                 new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED,
                 SOFT_INPUT_ADJUST_PAN, FLAG_LAYOUT_NO_LIMITS);
@@ -455,12 +491,15 @@
 
     @Test
     public void testCalculateUncontrollableInsets() {
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 200, 100));
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(true);
-        mState.getSource(ITYPE_IME).setFrame(new Rect(0, 200, 200, 300));
-        mState.getSource(ITYPE_IME).setVisible(true);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(new Rect(100, 0, 200, 300));
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(true);
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars())
+                .setFrame(new Rect(0, 0, 200, 100))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setFrame(new Rect(0, 200, 200, 300))
+                .setVisible(true);
+        mState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars())
+                .setFrame(new Rect(100, 0, 200, 300))
+                .setVisible(true);
 
         mState.setDisplayFrame(new Rect(0, 0, 200, 300));
         assertEquals(0,
@@ -539,4 +578,77 @@
         assertNotEquals(mState, mState2);
         assertNotEquals(mState.hashCode(), mState2.hashCode());
     }
+
+    @Test
+    public void testTraverse() {
+        // The type doesn't matter in this test.
+        final int type = statusBars();
+
+        final InsetsState insetsState1 = new InsetsState();
+        insetsState1.getOrCreateSource(2000, type);
+        insetsState1.getOrCreateSource(1000, type);
+        insetsState1.getOrCreateSource(3000, type);
+
+        final InsetsState insetsState2 = new InsetsState();
+        insetsState2.getOrCreateSource(3000, type);
+        insetsState2.getOrCreateSource(4000, type);
+        insetsState2.getOrCreateSource(2000, type);
+        insetsState2.getOrCreateSource(5000, type);
+
+        final int[] onStartCalled = {0};
+        final int[] onIdMatchCalled = {0};
+        final int[] onIdNotFoundInState1Called = {0};
+        final int[] onIdNotFoundInState2Called = {0};
+        final int[] onFinishCalled = {0};
+
+        InsetsState.traverse(insetsState1, insetsState2, new InsetsState.OnTraverseCallbacks() {
+            @Override
+            public void onStart(InsetsState state1, InsetsState state2) {
+                assertSame("state1 must be the same as insetsState1", state1, insetsState1);
+                assertSame("state2 must be the same as insetsState2", state2, insetsState2);
+                onStartCalled[0]++;
+            }
+
+            @Override
+            public void onIdMatch(InsetsSource source1, InsetsSource source2) {
+                assertNotNull("source1 must not be null.", source1);
+                assertNotNull("source2 must not be null.", source2);
+                assertEquals("Source IDs must match.", source1.getId(), source2.getId());
+                onIdMatchCalled[0]++;
+            }
+
+            @Override
+            public void onIdNotFoundInState1(int index2, InsetsSource source2) {
+                assertNotNull("source2 must not be null.", source2);
+                assertSame(source2 + " must be placed at " + index2 + " of insetsState2",
+                        source2, insetsState2.sourceAt(index2));
+                assertNull("state1 must not have " + source2,
+                        insetsState1.peekSource(source2.getId()));
+                onIdNotFoundInState1Called[0]++;
+            }
+
+            @Override
+            public void onIdNotFoundInState2(int index1, InsetsSource source1) {
+                assertNotNull("source1 must not be null.", source1);
+                assertSame(source1 + " must be placed at " + index1 + " of insetsState1",
+                        source1, insetsState1.sourceAt(index1));
+                assertNull("state2 must not have " + source1,
+                        insetsState2.peekSource(source1.getId()));
+                onIdNotFoundInState2Called[0]++;
+            }
+
+            @Override
+            public void onFinish(InsetsState state1, InsetsState state2) {
+                assertSame("state1 must be the same as insetsState1", state1, insetsState1);
+                assertSame("state2 must be the same as insetsState2", state2, insetsState2);
+                onFinishCalled[0]++;
+            }
+        });
+
+        assertEquals(1, onStartCalled[0]);
+        assertEquals(2, onIdMatchCalled[0]); // 2000 and 3000.
+        assertEquals(2, onIdNotFoundInState1Called[0]); // 4000 and 5000.
+        assertEquals(1, onIdNotFoundInState2Called[0]); // 1000.
+        assertEquals(1, onFinishCalled[0]);
+    }
 }
diff --git a/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java b/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java
index 4731e81..a65830f 100644
--- a/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java
+++ b/core/tests/coretests/src/android/view/SurfaceControlViewHostInsetsTest.java
@@ -16,35 +16,26 @@
 
 package android.view;
 
+import static android.view.WindowInsets.Type.statusBars;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-
 import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Insets;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
-import android.view.InsetsState.InternalInsetsType;
-import android.view.SurfaceControlViewHost;
-import android.view.View;
-import android.view.WindowInsets;
-import android.view.WindowInsets.Type;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class SurfaceControlViewHostInsetsTest {
@@ -79,8 +70,10 @@
     private InsetsState statusBarState(boolean visible) {
         final InsetsState insetsState = new InsetsState();
         insetsState.setDisplayFrame(new Rect(0, 0, 1000, 1000));
-        insetsState.getSource(ITYPE_STATUS_BAR).setVisible(visible);
-        insetsState.getSource(ITYPE_STATUS_BAR).setFrame(new Rect(0, 0, 100, 10));
+        insetsState.getOrCreateSource(
+                InsetsSource.createId(null /* owner */, 0 /* index */, statusBars()), statusBars())
+                        .setVisible(visible)
+                        .setFrame(new Rect(0, 0, 100, 10));
         return insetsState;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java b/core/tests/coretests/src/android/view/WindowLayoutTests.java
similarity index 83%
rename from services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
rename to core/tests/coretests/src/android/view/WindowLayoutTests.java
index 56c59cc..5cac98d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
+++ b/core/tests/coretests/src/android/view/WindowLayoutTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.server.wm;
+package android.view;
 
-import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
-import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_RIGHT_DISPLAY_CUTOUT;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.ITYPE_TOP_DISPLAY_CUTOUT;
+import static android.view.InsetsSource.ID_IME;
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
@@ -38,12 +37,6 @@
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
-import android.view.DisplayCutout;
-import android.view.Gravity;
-import android.view.InsetsState;
-import android.view.WindowInsets;
-import android.view.WindowLayout;
-import android.view.WindowManager;
 import android.window.ClientWindowFrames;
 
 import androidx.test.filters.SmallTest;
@@ -70,6 +63,11 @@
             new Rect(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT);
     private static final Insets WATERFALL_INSETS = Insets.of(6, 0, 12, 0);
 
+    private static final int ID_STATUS_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, statusBars());
+    private static final int ID_NAVIGATION_BAR = InsetsSource.createId(
+            null /* owner */, 0 /* index */, navigationBars());
+
     private final WindowLayout mWindowLayout = new WindowLayout();
     private final ClientWindowFrames mFrames = new ClientWindowFrames();
 
@@ -88,9 +86,9 @@
         mAttrs = new WindowManager.LayoutParams();
         mState = new InsetsState();
         mState.setDisplayFrame(new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
-        mState.getSource(ITYPE_STATUS_BAR).setFrame(
+        mState.getOrCreateSource(ID_STATUS_BAR, statusBars()).setFrame(
                 0, 0, DISPLAY_WIDTH, STATUS_BAR_HEIGHT);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setFrame(
+        mState.getOrCreateSource(ID_NAVIGATION_BAR, navigationBars()).setFrame(
                 0, DISPLAY_HEIGHT - NAVIGATION_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
         mState.getDisplayCutoutSafe(mDisplayCutoutSafe);
         mWindowBounds = new Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
@@ -117,14 +115,14 @@
                 new Rect(),
                 WATERFALL_INSETS));
         mState.getDisplayCutoutSafe(mDisplayCutoutSafe);
-        mState.getSource(ITYPE_LEFT_DISPLAY_CUTOUT).setFrame(
-                0, 0, mDisplayCutoutSafe.left, DISPLAY_HEIGHT);
-        mState.getSource(ITYPE_TOP_DISPLAY_CUTOUT).setFrame(
-                0, 0, DISPLAY_WIDTH, mDisplayCutoutSafe.top);
-        mState.getSource(ITYPE_RIGHT_DISPLAY_CUTOUT).setFrame(
-                mDisplayCutoutSafe.right, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
-        mState.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame(
-                0, mDisplayCutoutSafe.bottom, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+        mState.getOrCreateSource(InsetsSource.createId(null, 0, displayCutout()), displayCutout())
+                .setFrame(0, 0, mDisplayCutoutSafe.left, DISPLAY_HEIGHT);
+        mState.getOrCreateSource(InsetsSource.createId(null, 1, displayCutout()), displayCutout())
+                .setFrame(0, 0, DISPLAY_WIDTH, mDisplayCutoutSafe.top);
+        mState.getOrCreateSource(InsetsSource.createId(null, 2, displayCutout()), displayCutout())
+                .setFrame(mDisplayCutoutSafe.right, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+        mState.getOrCreateSource(InsetsSource.createId(null, 3, displayCutout()), displayCutout())
+                .setFrame(0, mDisplayCutoutSafe.bottom, DISPLAY_WIDTH, DISPLAY_HEIGHT);
     }
 
     private static void assertInsetByTopBottom(int top, int bottom, Rect actual) {
@@ -266,8 +264,8 @@
 
     @Test
     public void fitInvisibleInsets() {
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
+        mState.setSourceVisible(ID_STATUS_BAR, false);
+        mState.setSourceVisible(ID_NAVIGATION_BAR, false);
         computeFrames();
 
         assertInsetByTopBottom(0, 0, mFrames.displayFrame);
@@ -277,8 +275,8 @@
 
     @Test
     public void fitInvisibleInsetsIgnoringVisibility() {
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
+        mState.setSourceVisible(ID_STATUS_BAR, false);
+        mState.setSourceVisible(ID_NAVIGATION_BAR, false);
         mAttrs.setFitInsetsIgnoringVisibility(true);
         computeFrames();
 
@@ -289,9 +287,9 @@
 
     @Test
     public void insetParentFrameByIme() {
-        mState.getSource(InsetsState.ITYPE_IME).setVisible(true);
-        mState.getSource(InsetsState.ITYPE_IME).setFrame(
-                0, DISPLAY_HEIGHT - IME_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
+        mState.getOrCreateSource(ID_IME, ime())
+                .setVisible(true)
+                .setFrame(0, DISPLAY_HEIGHT - IME_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
         mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
         computeFrames();
 
@@ -322,11 +320,11 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.displayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.parentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.frame);
     }
 
@@ -363,17 +361,17 @@
     @Test
     public void layoutInDisplayCutoutModeDefaultWithInvisibleSystemBars() {
         addDisplayCutout();
-        mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
-        mState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false);
+        mState.setSourceVisible(ID_STATUS_BAR, false);
+        mState.setSourceVisible(ID_NAVIGATION_BAR, false);
         mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.displayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.parentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.frame);
     }
 
@@ -396,11 +394,11 @@
         mAttrs.setFitInsetsTypes(0);
         computeFrames();
 
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.displayFrame);
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.parentFrame);
-        assertInsetBy(WATERFALL_INSETS.left, STATUS_BAR_HEIGHT, WATERFALL_INSETS.right, 0,
+        assertInsetBy(WATERFALL_INSETS.left, DISPLAY_CUTOUT_HEIGHT, WATERFALL_INSETS.right, 0,
                 mFrames.frame);
     }
 
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
index eb58c63..27d58b8 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
@@ -20,13 +20,19 @@
 
 import static org.testng.Assert.assertThrows;
 
+import android.compat.testing.PlatformCompatChangeRule;
 import android.graphics.Insets;
 import android.view.View;
 import android.view.ViewStructure;
 import android.view.autofill.AutofillId;
 import android.view.contentcapture.ViewNode.ViewStructureImpl;
 
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
@@ -39,6 +45,8 @@
  */
 @RunWith(MockitoJUnitRunner.class)
 public class ContentCaptureSessionTest {
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
 
     private ContentCaptureSession mSession1 = new MyContentCaptureSession(111);
 
@@ -47,6 +55,7 @@
     @Mock
     private View mMockView;
 
+    @DisableCompatChanges({ContentCaptureSession.NOTIFY_NODES_DISAPPEAR_NOW_SENDS_TREE_EVENTS})
     @Test
     public void testNewAutofillId_invalid() {
         assertThrows(NullPointerException.class, () -> mSession1.newAutofillId(null, 42L));
@@ -79,6 +88,8 @@
         assertThrows(NullPointerException.class, () -> mSession1.notifyViewAppeared(null));
         assertThrows(NullPointerException.class, () -> mSession1.notifyViewDisappeared(null));
         assertThrows(NullPointerException.class,
+                () -> mSession1.notifyViewsAppeared(null));
+        assertThrows(NullPointerException.class,
                 () -> mSession1.notifyViewTextChanged(null, "whatever"));
     }
 
@@ -115,8 +126,29 @@
                 () -> mSession1.notifyViewsDisappeared(new AutofillId(42, 108), new long[] {666}));
     }
 
+    @Test
+    public void testNotifyViewsDisappeared_noSendTreeEventBeforeU() {
+        MyContentCaptureSession session = new MyContentCaptureSession(121);
+        session.notifyViewsDisappeared(new AutofillId(42), new long[] {42});
+
+        assertThat(session.mInternalNotifyViewTreeEventStartedCount).isEqualTo(0);
+        assertThat(session.mInternalNotifyViewTreeEventFinishedCount).isEqualTo(0);
+    }
+
+    @EnableCompatChanges({ContentCaptureSession.NOTIFY_NODES_DISAPPEAR_NOW_SENDS_TREE_EVENTS})
+    @Test
+    public void testNotifyViewsDisappeared_sendTreeEventSinceU() {
+        MyContentCaptureSession session = new MyContentCaptureSession(122);
+        session.notifyViewsDisappeared(new AutofillId(42), new long[] {42});
+
+        assertThat(session.mInternalNotifyViewTreeEventStartedCount).isEqualTo(1);
+        assertThat(session.mInternalNotifyViewTreeEventFinishedCount).isEqualTo(1);
+    }
+
     // Cannot use @Spy because we need to pass the session id on constructor
     private class MyContentCaptureSession extends ContentCaptureSession {
+        int mInternalNotifyViewTreeEventStartedCount = 0;
+        int mInternalNotifyViewTreeEventFinishedCount = 0;
 
         private MyContentCaptureSession(int id) {
             super(id);
@@ -148,9 +180,7 @@
         }
 
         @Override
-        void internalNotifyViewDisappeared(AutofillId id) {
-            throw new UnsupportedOperationException("should not have been called");
-        }
+        void internalNotifyViewDisappeared(AutofillId id) {}
 
         @Override
         void internalNotifyViewTextChanged(AutofillId id, CharSequence text) {
@@ -159,7 +189,11 @@
 
         @Override
         public void internalNotifyViewTreeEvent(boolean started) {
-            throw new UnsupportedOperationException("should not have been called");
+            if (started) {
+                mInternalNotifyViewTreeEventStartedCount += 1;
+            } else {
+                mInternalNotifyViewTreeEventFinishedCount += 1;
+            }
         }
 
         @Override
diff --git a/core/tests/coretests/src/android/widget/EditTextCursorAnchorInfoTest.java b/core/tests/coretests/src/android/widget/EditTextCursorAnchorInfoTest.java
new file mode 100644
index 0000000..1a01987
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/EditTextCursorAnchorInfoTest.java
@@ -0,0 +1,576 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.inputmethod.CursorAnchorInfo;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class EditTextCursorAnchorInfoTest {
+    private static final CursorAnchorInfo.Builder sCursorAnchorInfoBuilder =
+            new CursorAnchorInfo.Builder();
+    private static final Matrix sMatrix = new Matrix();
+    private static final int[] sLocationOnScreen = new int[2];
+    private static Typeface sTypeface;
+    private static final float TEXT_SIZE = 1f;
+    // The line height of the test font font is 1.2 * textSize.
+    private static final int LINE_HEIGHT = 12;
+    private static final CharSequence DEFAULT_TEXT = "X\nXX\nXXX\nXXXX\nXXXXX";
+    private static final ImmutableList<RectF> DEFAULT_LINE_BOUNDS = ImmutableList.of(
+            new RectF(0f, 0f, 10f, LINE_HEIGHT),
+            new RectF(0f, LINE_HEIGHT, 20f, 2 * LINE_HEIGHT),
+            new RectF(0f, 2 * LINE_HEIGHT, 30f, 3 * LINE_HEIGHT),
+            new RectF(0f, 3 * LINE_HEIGHT, 40f, 4 * LINE_HEIGHT),
+            new RectF(0f, 4 * LINE_HEIGHT, 50f, 5 * LINE_HEIGHT));
+
+    @Rule
+    public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
+            TextViewActivity.class);
+    private Activity mActivity;
+    private TextView mEditText;
+
+    @BeforeClass
+    public static void setupClass() {
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        // The test font has following coverage and width.
+        // U+0020: 10em
+        // U+002E (.): 10em
+        // U+0043 (C): 100em
+        // U+0049 (I): 1em
+        // U+004C (L): 50em
+        // U+0056 (V): 5em
+        // U+0058 (X): 10em
+        // U+005F (_): 0em
+        // U+05D0    : 1em  // HEBREW LETTER ALEF
+        // U+05D1    : 5em  // HEBREW LETTER BET
+        // U+FFFD (invalid surrogate will be replaced to this): 7em
+        // U+10331 (\uD800\uDF31): 10em
+        // Undefined : 0.5em
+        sTypeface = Typeface.createFromAsset(instrumentation.getTargetContext().getAssets(),
+                "fonts/StaticLayoutLineBreakingTestFont.ttf");
+    }
+
+    @Before
+    public void setup() {
+        mActivity = mActivityRule.getActivity();
+    }
+
+    @Test
+    public void testMatrix() {
+        setupEditText("", /* height= */ 100);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        Matrix actualMatrix = cursorAnchorInfo.getMatrix();
+        Matrix expectedMatrix = new Matrix();
+        expectedMatrix.setTranslate(sLocationOnScreen[0], sLocationOnScreen[1]);
+
+        assertThat(actualMatrix).isEqualTo(expectedMatrix);
+    }
+
+    @Test
+    public void testMatrix_withTranslation() {
+        float translationX = 10f;
+        float translationY = 20f;
+        createEditText("");
+        mEditText.setTranslationX(translationX);
+        mEditText.setTranslationY(translationY);
+        measureEditText(100);
+
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        Matrix actualMatrix = cursorAnchorInfo.getMatrix();
+        Matrix expectedMatrix = new Matrix();
+        expectedMatrix.setTranslate(sLocationOnScreen[0] + translationX,
+                sLocationOnScreen[1] + translationY);
+
+        assertThat(actualMatrix).isEqualTo(expectedMatrix);
+    }
+
+    @Test
+    public void testVisibleLineBounds_allVisible() {
+        setupEditText(DEFAULT_TEXT, /* height= */ 100);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        assertThat(lineBounds).isEqualTo(DEFAULT_LINE_BOUNDS);
+    }
+
+    @Test
+    public void testVisibleLineBounds_allVisible_withLineSpacing() {
+        float lineSpacing = 10f;
+        setupEditText("X\nXX\nXXX", /* height= */ 100, lineSpacing,
+                /* lineMultiplier=*/ 1f);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        assertThat(lineBounds.size()).isEqualTo(3);
+        assertThat(lineBounds.get(0)).isEqualTo(new RectF(0f, 0f, 10f, LINE_HEIGHT));
+
+        float line1Top = LINE_HEIGHT + lineSpacing;
+        float line1Bottom = line1Top + LINE_HEIGHT;
+        assertThat(lineBounds.get(1)).isEqualTo(new RectF(0f, line1Top, 20f, line1Bottom));
+
+        float line2Top = 2 * (LINE_HEIGHT + lineSpacing);
+        float line2Bottom = line2Top + LINE_HEIGHT;
+        assertThat(lineBounds.get(2)).isEqualTo(new RectF(0f, line2Top, 30f, line2Bottom));
+    }
+
+    @Test
+    public void testVisibleLineBounds_allVisible_withLineMultiplier() {
+        float lineMultiplier = 2f;
+        setupEditText("X\nXX\nXXX", /* height= */ 100, /* lineSpacing= */ 0f,
+                /* lineMultiplier=*/ lineMultiplier);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        assertThat(lineBounds.size()).isEqualTo(3);
+        assertThat(lineBounds.get(0)).isEqualTo(new RectF(0f, 0f, 10f, LINE_HEIGHT));
+
+        float line1Top = LINE_HEIGHT * lineMultiplier;
+        float line1Bottom = line1Top + LINE_HEIGHT;
+        assertThat(lineBounds.get(1)).isEqualTo(new RectF(0f, line1Top, 20f, line1Bottom));
+
+        float line2Top = 2 * LINE_HEIGHT * lineMultiplier;
+        float line2Bottom = line2Top + LINE_HEIGHT;
+        assertThat(lineBounds.get(2)).isEqualTo(new RectF(0f, line2Top, 30f, line2Bottom));
+    }
+
+    @Test
+    public void testVisibleLineBounds_cutBottomLines() {
+        // Line top is inclusive and line bottom is exclusive. And if the visible area's
+        // bottom equals to the line top, this line is still visible. So the line height is
+        // 3 * LINE_HEIGHT - 1 to avoid including the line 3.
+        setupEditText(DEFAULT_TEXT, /* height= */ 3 * LINE_HEIGHT - 1);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        assertThat(lineBounds).isEqualTo(DEFAULT_LINE_BOUNDS.subList(0, 3));
+    }
+
+    @Test
+    public void testVisibleLineBounds_scrolled_cutTopLines() {
+        // First 2 lines are cut.
+        int scrollY = 2 * LINE_HEIGHT;
+        setupEditText(/* height= */ 3 * LINE_HEIGHT,
+                /* scrollY= */ scrollY);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 2, 5);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0, -scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_scrolled_cutTopAndBottomLines() {
+        // Line top is inclusive and line bottom is exclusive. And if the visible area's
+        // bottom equals to the line top, this line is still visible. So the line height is
+        // 2 * LINE_HEIGHT - 1 which only shows 2 lines.
+        int scrollY = 2 * LINE_HEIGHT;
+        setupEditText(/* height= */ 2 * LINE_HEIGHT - 1,
+                /* scrollY= */ scrollY);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 2, 4);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0, -scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_scrolled_partiallyVisibleLines() {
+        // The first 2 lines are completely cut, line 2 and 3 are partially visible.
+        int scrollY = 2 * LINE_HEIGHT + LINE_HEIGHT / 2;
+        setupEditText(/* height= */ LINE_HEIGHT,
+                /* scrollY= */ scrollY);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 2, 4);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, -scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withCompoundDrawable_allVisible() {
+        int topDrawableHeight = LINE_HEIGHT;
+        Drawable topDrawable = createDrawable(topDrawableHeight);
+        Drawable bottomDrawable = createDrawable(2 * LINE_HEIGHT);
+        setupEditText(/* height= */ 100,
+                /* scrollY= */ 0, topDrawable, bottomDrawable);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = copy(DEFAULT_LINE_BOUNDS);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topDrawableHeight));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withCompoundDrawable_cutBottomLines() {
+        // The view's totally height is 5 * LINE_HEIGHT, and drawables take 3 * LINE_HEIGHT.
+        // Only first 2 lines are visible.
+        int topDrawableHeight = LINE_HEIGHT;
+        Drawable topDrawable = createDrawable(topDrawableHeight);
+        Drawable bottomDrawable = createDrawable(2 * LINE_HEIGHT + 1);
+        setupEditText(/* height= */ 5 * LINE_HEIGHT,
+                /* scrollY= */ 0, topDrawable, bottomDrawable);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 0, 2);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topDrawableHeight));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withCompoundDrawable_scrolled() {
+        // The view's totally height is 5 * LINE_HEIGHT, and drawables take 3 * LINE_HEIGHT.
+        // So 2 lines are visible. Because the view is scrolled vertically by LINE_HEIGHT,
+        // the line 1 and 2 are visible.
+        int topDrawableHeight = LINE_HEIGHT;
+        Drawable topDrawable = createDrawable(topDrawableHeight);
+        Drawable bottomDrawable = createDrawable(2 * LINE_HEIGHT + 1);
+        int scrollY = LINE_HEIGHT;
+        setupEditText(/* height= */ 5 * LINE_HEIGHT, scrollY,
+                topDrawable, bottomDrawable);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 1, 3);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topDrawableHeight - scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withCompoundDrawable_partiallyVisible() {
+        // The view's totally height is 5 * LINE_HEIGHT, and drawables take 3 * LINE_HEIGHT.
+        // And because the view is scrolled vertically by 0.5 * LINE_HEIGHT,
+        // the line 0, 1 and 2 are visible.
+        int topDrawableHeight = LINE_HEIGHT;
+        Drawable topDrawable = createDrawable(topDrawableHeight);
+        Drawable bottomDrawable = createDrawable(2 * LINE_HEIGHT + 1);
+        int scrollY = LINE_HEIGHT / 2;
+        setupEditText(/* height= */ 5 * LINE_HEIGHT, scrollY,
+                topDrawable, bottomDrawable);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 0, 3);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topDrawableHeight - scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withPaddings_allVisible() {
+        int topPadding = LINE_HEIGHT;
+        int bottomPadding = LINE_HEIGHT;
+        setupEditText(/* height= */ 100, /* scrollY= */ 0, topPadding, bottomPadding);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = copy(DEFAULT_LINE_BOUNDS);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topPadding));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withPaddings_cutBottomLines() {
+        // The view's totally height is 5 * LINE_HEIGHT, and paddings take 3 * LINE_HEIGHT.
+        // So 2 lines are visible.
+        int topPadding = LINE_HEIGHT;
+        int bottomPadding = 2 * LINE_HEIGHT + 1;
+        setupEditText(/* height= */ 5 * LINE_HEIGHT, /* scrollY= */ 0, topPadding, bottomPadding);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 0, 2);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topPadding));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withPaddings_scrolled() {
+        // The view's totally height is 5 * LINE_HEIGHT, and paddings take 3 * LINE_HEIGHT.
+        // So 2 lines are visible. Because the view is scrolled vertically by LINE_HEIGHT,
+        // the line 1 and 2 are visible.
+        int topPadding = LINE_HEIGHT;
+        int bottomPadding = 2 * LINE_HEIGHT + 1;
+        int scrollY = LINE_HEIGHT;
+        setupEditText(/* height= */ 5 * LINE_HEIGHT, scrollY,
+                topPadding, bottomPadding);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 1, 3);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topPadding - scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_withPadding_partiallyVisible() {
+        // The view's totally height is 5 * LINE_HEIGHT, and paddings take 3 * LINE_HEIGHT.
+        // And because the view is scrolled vertically by 0.5 * LINE_HEIGHT, the line 0, 1 and 2
+        // are visible.
+        int topPadding = LINE_HEIGHT;
+        int bottomPadding = 2 * LINE_HEIGHT + 1;
+        int scrollY = LINE_HEIGHT / 2;
+        setupEditText(/* height= */ 5 * LINE_HEIGHT, scrollY,
+                topPadding, bottomPadding);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 0, 3);
+        expectedLineBounds.forEach(rectF -> rectF.offset(0f, topPadding - scrollY));
+
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_clippedTop() {
+        // The first line is clipped off.
+        setupVerticalClippedEditText(LINE_HEIGHT, 5 * LINE_HEIGHT);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 1, 5);
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_clippedBottom() {
+        // The last line is clipped off.
+        setupVerticalClippedEditText(0, 4 * LINE_HEIGHT - 1);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 0, 4);
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    @Test
+    public void testVisibleLineBounds_clippedTopAndBottom() {
+        // The first and last line are clipped off.
+        setupVerticalClippedEditText(LINE_HEIGHT, 4 * LINE_HEIGHT - 1);
+        CursorAnchorInfo cursorAnchorInfo =
+                mEditText.getCursorAnchorInfo(0, sCursorAnchorInfoBuilder, sMatrix);
+
+        List<RectF> lineBounds = cursorAnchorInfo.getVisibleLineBounds();
+
+        List<RectF> expectedLineBounds = subList(DEFAULT_LINE_BOUNDS, 1, 4);
+        assertThat(lineBounds).isEqualTo(expectedLineBounds);
+    }
+
+    private List<RectF> copy(List<RectF> rectFList) {
+        List<RectF> result = new ArrayList<>();
+        for (RectF rectF : rectFList) {
+            result.add(new RectF(rectF));
+        }
+        return result;
+    }
+    private List<RectF> subList(List<RectF> rectFList, int start, int end) {
+        List<RectF> result = new ArrayList<>();
+        for (int index = start; index < end; ++index) {
+            result.add(new RectF(rectFList.get(index)));
+        }
+        return result;
+    }
+
+    private void setupVerticalClippedEditText(int visibleTop, int visibleBottom) {
+        ScrollView scrollView = new ScrollView(mActivity);
+        mEditText = new EditText(mActivity);
+        mEditText.setTypeface(sTypeface);
+        mEditText.setText(DEFAULT_TEXT);
+        mEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, TEXT_SIZE);
+
+        mEditText.setPadding(0, 0, 0, 0);
+        mEditText.setCompoundDrawables(null, null, null, null);
+        mEditText.setCompoundDrawablePadding(0);
+
+        mEditText.scrollTo(0, 0);
+        mEditText.setLineSpacing(0f, 1f);
+
+        // Place the text layout top to the view's top.
+        mEditText.setGravity(Gravity.TOP);
+        int width = 1000;
+        int height = visibleBottom - visibleTop;
+
+        scrollView.addView(mEditText, new FrameLayout.LayoutParams(
+                View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(5 * LINE_HEIGHT, View.MeasureSpec.EXACTLY)));
+        scrollView.measure(
+                View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
+        scrollView.layout(0, 0, width, height);
+
+        scrollView.scrollTo(0, visibleTop);
+    }
+
+    private void setupEditText(CharSequence text, int height) {
+        createEditText(text);
+        measureEditText(height);
+    }
+
+    private void setupEditText(CharSequence text, int height, float lineSpacing,
+            float lineMultiplier) {
+        createEditText(text);
+        mEditText.setLineSpacing(lineSpacing, lineMultiplier);
+        measureEditText(height);
+    }
+
+    private void setupEditText(int height, int scrollY) {
+        createEditText();
+        mEditText.scrollTo(0, scrollY);
+        measureEditText(height);
+    }
+
+    private void setupEditText(int height, int scrollY, Drawable drawableTop,
+            Drawable drawableBottom) {
+        createEditText();
+        mEditText.scrollTo(0, scrollY);
+        mEditText.setCompoundDrawables(null, drawableTop, null, drawableBottom);
+        measureEditText(height);
+    }
+
+    private void setupEditText(int height, int scrollY, int paddingTop,
+            int paddingBottom) {
+        createEditText();
+        mEditText.scrollTo(0, scrollY);
+        mEditText.setPadding(0, paddingTop, 0, paddingBottom);
+        measureEditText(height);
+    }
+
+    private void createEditText() {
+        createEditText(DEFAULT_TEXT);
+    }
+
+    private void createEditText(CharSequence text) {
+        mEditText = new EditText(mActivity);
+        mEditText.setTypeface(sTypeface);
+        mEditText.setText(text);
+        mEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, TEXT_SIZE);
+
+        mEditText.setPadding(0, 0, 0, 0);
+        mEditText.setCompoundDrawables(null, null, null, null);
+        mEditText.setCompoundDrawablePadding(0);
+
+        mEditText.scrollTo(0, 0);
+        mEditText.setLineSpacing(0f, 1f);
+
+        // Place the text layout top to the view's top.
+        mEditText.setGravity(Gravity.TOP);
+    }
+
+    private void measureEditText(int height) {
+        // width equals to 1000 is enough to avoid line break for all test cases.
+        measureEditText(1000, height);
+    }
+
+    private void measureEditText(int width, int height) {
+        mEditText.measure(
+                View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
+        mEditText.layout(0, 0, width, height);
+
+        mEditText.getLocationOnScreen(sLocationOnScreen);
+    }
+
+    private Drawable createDrawable(int height) {
+        // width is not important for this drawable, make it 1 pixel.
+        return createDrawable(1, height);
+    }
+
+    private Drawable createDrawable(int width, int height) {
+        ShapeDrawable drawable = new ShapeDrawable();
+        drawable.setBounds(new Rect(0, 0, width, height));
+        return drawable;
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java
index 045b3a2..3ea7f47 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java
@@ -16,8 +16,19 @@
 
 package com.android.internal.accessibility;
 
-import static junit.framework.Assert.assertEquals;
+import static com.android.internal.accessibility.util.AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM;
+import static com.android.internal.accessibility.util.AccessibilityUtils.MENU_SERVICE_RELATIVE_CLASS_NAME;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.text.ParcelableSpan;
 import android.text.SpannableString;
 import android.text.style.LocaleSpan;
@@ -26,9 +37,13 @@
 
 import com.android.internal.accessibility.util.AccessibilityUtils;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -36,6 +51,15 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityUtilsTest {
+    private static final int USER_ID = 123;
+    @Mock
+    private PackageManager mMockPackageManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
     @Test
     public void textOrSpanChanged_stringChange_returnTextChange() {
         final CharSequence beforeText = "a";
@@ -44,7 +68,7 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.TEXT, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.TEXT);
     }
 
     @Test
@@ -55,7 +79,7 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.NONE, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.NONE);
     }
 
     @Test
@@ -68,7 +92,7 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.NONE, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.NONE);
     }
 
     @Test
@@ -81,7 +105,7 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.PARCELABLE_SPAN, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.PARCELABLE_SPAN);
     }
 
     @Test
@@ -96,7 +120,7 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.PARCELABLE_SPAN, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.PARCELABLE_SPAN);
     }
 
     @Test
@@ -110,7 +134,7 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.NONE, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.NONE);
     }
 
     @Test
@@ -124,6 +148,72 @@
 
         @AccessibilityUtils.A11yTextChangeType int type = AccessibilityUtils.textOrSpanChanged(
                 beforeText, afterText);
-        assertEquals(AccessibilityUtils.PARCELABLE_SPAN, type);
+        assertThat(type).isEqualTo(AccessibilityUtils.PARCELABLE_SPAN);
+    }
+
+    @Test
+    public void getAccessibilityMenuComponentToMigrate_isNull_whenNoMenuComponents() {
+        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
+                eq(USER_ID))).thenReturn(List.of());
+
+        final ComponentName result = AccessibilityUtils.getAccessibilityMenuComponentToMigrate(
+                mMockPackageManager, USER_ID);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void getAccessibilityMenuComponentToMigrate_isNull_whenTooManyMenuComponents() {
+        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
+                eq(USER_ID))).thenReturn(List.of(
+                createResolveInfo(ComponentName.createRelative("external1",
+                        MENU_SERVICE_RELATIVE_CLASS_NAME)),
+                createResolveInfo(ComponentName.createRelative("external2",
+                        MENU_SERVICE_RELATIVE_CLASS_NAME)),
+                createResolveInfo(ComponentName.createRelative("external3",
+                        MENU_SERVICE_RELATIVE_CLASS_NAME))));
+
+        final ComponentName result = AccessibilityUtils.getAccessibilityMenuComponentToMigrate(
+                mMockPackageManager, USER_ID);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void getAccessibilityMenuComponentToMigrate_isNull_whenMenuInSystemNotFound() {
+        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
+                eq(USER_ID))).thenReturn(List.of(
+                createResolveInfo(ComponentName.createRelative("external1",
+                        MENU_SERVICE_RELATIVE_CLASS_NAME)),
+                createResolveInfo(ComponentName.createRelative("external2",
+                        MENU_SERVICE_RELATIVE_CLASS_NAME))));
+
+        final ComponentName result = AccessibilityUtils.getAccessibilityMenuComponentToMigrate(
+                mMockPackageManager, USER_ID);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void getAccessibilityMenuComponentToMigrate_returnsMenuOutsideSystem() {
+        ComponentName menuOutsideSystem = ComponentName.createRelative("external1",
+                MENU_SERVICE_RELATIVE_CLASS_NAME);
+        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
+                eq(USER_ID))).thenReturn(List.of(
+                createResolveInfo(menuOutsideSystem),
+                createResolveInfo(ACCESSIBILITY_MENU_IN_SYSTEM)));
+
+        final ComponentName result = AccessibilityUtils.getAccessibilityMenuComponentToMigrate(
+                mMockPackageManager, USER_ID);
+
+        assertThat(result).isEqualTo(menuOutsideSystem);
+    }
+
+    private static ResolveInfo createResolveInfo(ComponentName componentName) {
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.serviceInfo = new ServiceInfo();
+        resolveInfo.serviceInfo.packageName = componentName.getPackageName();
+        resolveInfo.serviceInfo.name = componentName.getClassName();
+        return resolveInfo;
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/config/sysui/OWNERS b/core/tests/coretests/src/com/android/internal/config/sysui/OWNERS
new file mode 100644
index 0000000..2e96c97
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/config/sysui/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/config/sysui/SystemUiSystemPropertiesFlagsTest.java b/core/tests/coretests/src/com/android/internal/config/sysui/SystemUiSystemPropertiesFlagsTest.java
new file mode 100644
index 0000000..6b9d39c
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/config/sysui/SystemUiSystemPropertiesFlagsTest.java
@@ -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.internal.config.sysui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.Flag;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.FlagResolver;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@SmallTest
+public class SystemUiSystemPropertiesFlagsTest extends TestCase {
+
+    public class TestableDebugResolver extends SystemUiSystemPropertiesFlags.DebugResolver {
+        final Map<String, Boolean> mTestData = new HashMap<>();
+
+        @Override
+        public boolean getBoolean(String key, boolean defaultValue) {
+            Boolean testValue = mTestData.get(key);
+            return testValue == null ? defaultValue : testValue;
+        }
+
+        public void set(Flag flag, Boolean value) {
+            mTestData.put(flag.mSysPropKey, value);
+        }
+    }
+
+    private FlagResolver mProdResolver;
+    private TestableDebugResolver mDebugResolver;
+
+    private Flag mReleasedFlag;
+    private Flag mTeamfoodFlag;
+    private Flag mDevFlag;
+
+    public void setUp() {
+        mProdResolver = new SystemUiSystemPropertiesFlags.ProdResolver();
+        mDebugResolver = new TestableDebugResolver();
+        mReleasedFlag = SystemUiSystemPropertiesFlags.releasedFlag("mReleasedFlag");
+        mTeamfoodFlag = SystemUiSystemPropertiesFlags.teamfoodFlag("mTeamfoodFlag");
+        mDevFlag = SystemUiSystemPropertiesFlags.devFlag("mDevFlag");
+    }
+
+    public void tearDown() {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = null;
+    }
+
+    public void testProdResolverReturnsDefault() {
+        assertThat(mProdResolver.isEnabled(mReleasedFlag)).isTrue();
+        assertThat(mProdResolver.isEnabled(mTeamfoodFlag)).isFalse();
+        assertThat(mProdResolver.isEnabled(mDevFlag)).isFalse();
+    }
+
+    public void testDebugResolverAndReleasedFlag() {
+        assertThat(mDebugResolver.isEnabled(mReleasedFlag)).isTrue();
+
+        mDebugResolver.set(mReleasedFlag, false);
+        assertThat(mDebugResolver.isEnabled(mReleasedFlag)).isFalse();
+
+        mDebugResolver.set(mReleasedFlag, true);
+        assertThat(mDebugResolver.isEnabled(mReleasedFlag)).isTrue();
+    }
+
+    private void assertTeamfoodFlag(Boolean flagValue, Boolean teamfood, boolean expected) {
+        mDebugResolver.set(mTeamfoodFlag, flagValue);
+        mDebugResolver.set(SystemUiSystemPropertiesFlags.TEAMFOOD, teamfood);
+        assertThat(mDebugResolver.isEnabled(mTeamfoodFlag)).isEqualTo(expected);
+    }
+
+    public void testDebugResolverAndTeamfoodFlag() {
+        assertTeamfoodFlag(null, null, false);
+        assertTeamfoodFlag(true, null, true);
+        assertTeamfoodFlag(false, null, false);
+        assertTeamfoodFlag(null, true, true);
+        assertTeamfoodFlag(true, true, true);
+        assertTeamfoodFlag(false, true, false);
+        assertTeamfoodFlag(null, false, false);
+        assertTeamfoodFlag(true, false, true);
+        assertTeamfoodFlag(false, false, false);
+    }
+
+    public void testDebugResolverAndDevFlag() {
+        assertThat(mDebugResolver.isEnabled(mDevFlag)).isFalse();
+
+        mDebugResolver.set(mDevFlag, true);
+        assertThat(mDebugResolver.isEnabled(mDevFlag)).isTrue();
+
+        mDebugResolver.set(mDevFlag, false);
+        assertThat(mDebugResolver.isEnabled(mDevFlag)).isFalse();
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
index 048c48b..f79ba28 100644
--- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
+++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
@@ -67,7 +67,7 @@
                 BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
                 WindowInsets.Type.defaultVisible(),
                 "test" /* packageName */,
-                new int[0] /* transientBarTypes */,
+                0 /* transientBarTypes */,
                 new LetterboxDetails[] {letterboxDetails});
 
         final RegisterStatusBarResult copy = clone(original);
diff --git a/core/tests/expresslog/Android.bp b/core/tests/expresslog/Android.bp
new file mode 100644
index 0000000..cab49a7
--- /dev/null
+++ b/core/tests/expresslog/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+    name: "ExpressLogTests",
+
+    srcs: [
+        "src/**/*.java",
+    ],
+
+    static_libs: [
+        "androidx.test.rules",
+        "modules-utils-build",
+    ],
+
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+
+    platform_apis: true,
+    test_suites: [
+        "general-tests",
+    ],
+
+    certificate: "platform",
+}
diff --git a/core/tests/expresslog/AndroidManifest.xml b/core/tests/expresslog/AndroidManifest.xml
new file mode 100644
index 0000000..94a39e0
--- /dev/null
+++ b/core/tests/expresslog/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          android:installLocation="internalOnly"
+          package="com.android.internal.expresslog" >
+
+    <application >
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.internal.expresslog"
+            android:label="Telemetry Express Logging Helper Tests" />
+
+</manifest>
diff --git a/core/tests/expresslog/OWNERS b/core/tests/expresslog/OWNERS
new file mode 100644
index 0000000..3dc958b
--- /dev/null
+++ b/core/tests/expresslog/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 719316
+# Stats/expresslog
+file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/tests/expresslog/TEST_MAPPING b/core/tests/expresslog/TEST_MAPPING
new file mode 100644
index 0000000..c9b0cf8
--- /dev/null
+++ b/core/tests/expresslog/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "ExpressLogTests",
+      "options": [
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java b/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java
new file mode 100644
index 0000000..9fa6d06
--- /dev/null
+++ b/core/tests/expresslog/src/com/android/internal/expresslog/UniformOptionsTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.expresslog;
+
+import androidx.test.filters.SmallTest;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class UniformOptionsTest {
+    private static final String TAG = UniformOptionsTest.class.getSimpleName();
+
+    @Test
+    @SmallTest
+    public void testGetBinsCount() {
+        Histogram.UniformOptions options1 = new Histogram.UniformOptions(1, 100, 1000);
+        assertEquals(3, options1.getBinsCount());
+
+        Histogram.UniformOptions options10 = new Histogram.UniformOptions(10, 100, 1000);
+        assertEquals(12, options10.getBinsCount());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    @SmallTest
+    public void testConstructZeroBinsCount() {
+        new Histogram.UniformOptions(0, 100, 1000);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    @SmallTest
+    public void testConstructNegativeBinsCount() {
+        new Histogram.UniformOptions(-1, 100, 1000);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    @SmallTest
+    public void testConstructMaxValueLessThanMinValue() {
+        new Histogram.UniformOptions(10, 1000, 100);
+    }
+
+    @Test
+    @SmallTest
+    public void testBinIndexForRangeEqual1() {
+        Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 11);
+        for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
+            assertEquals(i, options.getBinForSample(i));
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testBinIndexForRangeEqual2() {
+        Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 21);
+        for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
+            assertEquals(i, options.getBinForSample(i * 2));
+            assertEquals(i, options.getBinForSample(i * 2 - 1));
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testBinIndexForRangeEqual5() {
+        Histogram.UniformOptions options = new Histogram.UniformOptions(2, 0, 10);
+        assertEquals(4, options.getBinsCount());
+        for (int i = 0; i < 2; i++) {
+            for (int sample = 0; sample < 5; sample++) {
+                assertEquals(i + 1, options.getBinForSample(i * 5 + sample));
+            }
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testBinIndexForRangeEqual10() {
+        Histogram.UniformOptions options = new Histogram.UniformOptions(10, 1, 101);
+        assertEquals(0, options.getBinForSample(0));
+        assertEquals(options.getBinsCount() - 2, options.getBinForSample(100));
+        assertEquals(options.getBinsCount() - 1, options.getBinForSample(101));
+
+        final float binSize = (101 - 1) / 10f;
+        for (int i = 1, bins = options.getBinsCount() - 1; i < bins; i++) {
+            assertEquals(i, options.getBinForSample(i * binSize));
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testBinIndexForRangeEqual90() {
+        final int binCount = 10;
+        final int minValue = 100;
+        final int maxValue = 100000;
+
+        Histogram.UniformOptions options = new Histogram.UniformOptions(binCount, minValue,
+                maxValue);
+
+        // logging underflow sample
+        assertEquals(0, options.getBinForSample(minValue - 1));
+
+        // logging overflow sample
+        assertEquals(binCount + 1, options.getBinForSample(maxValue));
+        assertEquals(binCount + 1, options.getBinForSample(maxValue + 1));
+
+        // logging min edge sample
+        assertEquals(1, options.getBinForSample(minValue));
+
+        // logging max edge sample
+        assertEquals(binCount, options.getBinForSample(maxValue - 1));
+
+        // logging single valid sample per bin
+        final int binSize = (maxValue - minValue) / binCount;
+
+        for (int i = 0; i < binCount; i++) {
+            assertEquals(i + 1, options.getBinForSample(minValue + binSize * i));
+        }
+    }
+}
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 0aad0a8..116aa489 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -50,6 +50,7 @@
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+        <permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
         <permission name="android.permission.REAL_GET_TASKS"/>
         <permission name="android.permission.REQUEST_NETWORK_SCORES"/>
         <permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index bccf283..0d74e12 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -61,6 +61,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/WindowToken.java"
     },
+    "-2088209279": {
+      "message": "Notified TransitionController that the display is ready.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+    },
     "-2072089308": {
       "message": "Attempted to add window with token that is a sub-window: %s.  Aborting.",
       "level": "WARN",
@@ -1771,6 +1777,12 @@
       "group": "WM_DEBUG_KEEP_SCREEN_ON",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "-464564167": {
+      "message": "Current transition prevents automatic focus change",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_FOCUS",
+      "at": "com\/android\/server\/wm\/DisplayContent.java"
+    },
     "-463348344": {
       "message": "Removing and adding activity %s to root task at top callers=%s",
       "level": "INFO",
@@ -2065,12 +2077,6 @@
       "group": "WM_DEBUG_ANIM",
       "at": "com\/android\/server\/wm\/SurfaceAnimator.java"
     },
-    "-206549078": {
-      "message": "Not moving display (displayId=%d) to top. Top focused displayId=%d. Reason: config_perDisplayFocusEnabled",
-      "level": "INFO",
-      "group": "WM_DEBUG_FOCUS_LIGHT",
-      "at": "com\/android\/server\/wm\/WindowManagerService.java"
-    },
     "-203358733": {
       "message": "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW %s",
       "level": "INFO",
@@ -2767,6 +2773,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/TaskFragment.java"
     },
+    "378890013": {
+      "message": "Apply and finish immediately because player is disabled for transition #%d .",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/Transition.java"
+    },
     "385237117": {
       "message": "moveFocusableActivityToTop: already on top and focused, activity=%s",
       "level": "DEBUG",
@@ -3649,6 +3661,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "1282992082": {
+      "message": "Disabling player for transition #%d because display isn't enabled yet",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+      "at": "com\/android\/server\/wm\/TransitionController.java"
+    },
     "1284122013": {
       "message": "TaskFragment appeared name=%s",
       "level": "VERBOSE",
@@ -4399,6 +4417,12 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "2043434284": {
+      "message": "setWallpaperShowWhenLocked: non-existent wallpaper token: %s",
+      "level": "WARN",
+      "group": "WM_ERROR",
+      "at": "com\/android\/server\/wm\/WindowManagerService.java"
+    },
     "2045641491": {
       "message": "Checking %d opening apps (frozen=%b timeout=%b)...",
       "level": "VERBOSE",
diff --git a/data/keyboards/Vendor_18d1_Product_9451.idc b/data/keyboards/Vendor_18d1_Product_9451.idc
new file mode 100644
index 0000000..e13fcb2
--- /dev/null
+++ b/data/keyboards/Vendor_18d1_Product_9451.idc
@@ -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.
+
+#
+# Input Device Configuration file for a flavor of the Google Reference RCU Remote.
+#
+#
+
+# Basic Parameters
+keyboard.layout = Vendor_0957_Product_0001
+keyboard.doNotWakeByDefault = 1
+audio.mic = 1
\ No newline at end of file
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java
index c1a2048..abef78e 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java
@@ -68,6 +68,8 @@
                     .named("myUserId"),
             instanceMethod().onExactClass("android.content.pm.ShortcutManager")
                     .named("injectMyUserId"),
+            instanceMethod().onExactClass("android.os.UserManager")
+                    .named("getContextUserIfAppropriate"),
             instanceMethod().onDescendantOf("android.content.Context")
                     .named("getUserId")));
 
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
index fa173072..d39d4b4 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
@@ -412,11 +412,11 @@
 
     private static ParsedRequiresPermission parseRequiresPermissionRecursively(
             MethodInvocationTree tree, VisitorState state) {
-        if (ENFORCE_VIA_CONTEXT.matches(tree, state)) {
+        if (ENFORCE_VIA_CONTEXT.matches(tree, state) && tree.getArguments().size() > 0) {
             final ParsedRequiresPermission res = new ParsedRequiresPermission();
             res.allOf.add(String.valueOf(ASTHelpers.constValue(tree.getArguments().get(0))));
             return res;
-        } else if (ENFORCE_VIA_CHECKER.matches(tree, state)) {
+        } else if (ENFORCE_VIA_CHECKER.matches(tree, state) && tree.getArguments().size() > 1) {
             final ParsedRequiresPermission res = new ParsedRequiresPermission();
             res.allOf.add(String.valueOf(ASTHelpers.constValue(tree.getArguments().get(1))));
             return res;
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java
index 1679bb6..854016f 100644
--- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java
@@ -148,4 +148,31 @@
                         "}")
                 .doTest();
     }
+
+    @Test
+    public void testUserManager() {
+        compilationHelper
+                .addSourceFile("/android/annotation/SystemService.java")
+                .addSourceFile("/android/content/Context.java")
+                .addSourceFile("/android/content/Intent.java")
+                .addSourceFile("/android/foo/IFooService.java")
+                .addSourceFile("/android/os/IInterface.java")
+                .addSourceFile("/android/os/UserHandle.java")
+                .addSourceFile("/android/os/RemoteException.java")
+                .addSourceLines("UserManager.java",
+                        "package android.os;",
+                        "import android.annotation.SystemService;",
+                        "import android.content.Context;",
+                        "import android.foo.IFooService;",
+                        "import android.os.UserHandle;",
+                        "import android.os.RemoteException;",
+                        "@SystemService(\"user\") public class UserManager {",
+                        "  IFooService mService;",
+                        "  int getContextUserIfAppropriate() { return 0; }",
+                        "  void bar() throws RemoteException {",
+                        "    mService.baz(null, getContextUserIfAppropriate());",
+                        "  }",
+                        "}")
+                .doTest();
+    }
 }
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java
index 388988e..38831b1 100644
--- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java
@@ -415,4 +415,27 @@
                         "}")
                 .doTest();
     }
+
+    @Test
+    public void testInvalidFunctions() {
+        compilationHelper
+                .addSourceFile("/android/annotation/RequiresPermission.java")
+                .addSourceFile("/android/annotation/SuppressLint.java")
+                .addSourceFile("/android/content/Context.java")
+                .addSourceLines("Example.java",
+                        "import android.annotation.RequiresPermission;",
+                        "import android.annotation.SuppressLint;",
+                        "import android.content.Context;",
+                        "class Foo extends Context {",
+                        "  private static final String RED = \"red\";",
+                        "  public void checkPermission() {",
+                        "  }",
+                        "  @RequiresPermission(RED)",
+                        "  // BUG: Diagnostic contains:",
+                        "  public void exampleScoped(Context context) {",
+                        "    checkPermission();",
+                        "  }",
+                        "}")
+                .doTest();
+    }
 }
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index 8cd8ddf..a7acaf9 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -675,10 +675,11 @@
      *
      * @param mesh {@link Mesh} object that will be drawn to the screen
      * @param blendMode {@link BlendMode} used to blend mesh primitives as the destination color
-     *            with the Paint color/shader as the source color.
+     *            with the Paint color/shader as the source color. This defaults to
+     *            {@link BlendMode#MODULATE} if null.
      * @param paint {@link Paint} used to provide a color/shader/blend mode.
      */
-    public void drawMesh(@NonNull Mesh mesh, BlendMode blendMode, @NonNull Paint paint) {
+    public void drawMesh(@NonNull Mesh mesh, @Nullable BlendMode blendMode, @NonNull Paint paint) {
         if (!isHardwareAccelerated() && onHwFeatureInSwMode()) {
             throw new RuntimeException("software rendering doesn't support meshes");
         }
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 43cb5ee..2f6dd46 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -17,6 +17,7 @@
 package android.graphics;
 
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 
 import java.lang.annotation.Retention;
@@ -102,6 +103,8 @@
 
     private boolean mRequestDirectSampling;
 
+    private int mMaxAniso = 0;
+
     /**
      * Call this to create a new shader that will draw with a bitmap.
      *
@@ -135,15 +138,47 @@
     }
 
     /**
-     * Set the filter mode to be used when sampling from this shader
+     * Set the filter mode to be used when sampling from this shader. If this is configured
+     * then the anisotropic filtering value specified in any previous call to
+     * {@link #setMaxAnisotropy(int)} is ignored.
      */
     public void setFilterMode(@FilterMode int mode) {
         if (mode != mFilterMode) {
             mFilterMode = mode;
+            mMaxAniso = 0;
             discardNativeInstance();
         }
     }
 
+    /**
+     * Enables and configures the max anisotropy sampling value. If this value is configured,
+     * {@link #setFilterMode(int)} is ignored.
+     *
+     * Anisotropic filtering can enhance visual quality by removing aliasing effects of images
+     * that are at oblique viewing angles. This value is typically consumed as a power of 2 and
+     * anisotropic values of the next power of 2 typically provide twice the quality improvement
+     * as the previous value. For example, a sampling value of 4 would provide twice the improvement
+     * of a sampling value of 2. It is important to note that higher sampling values reach
+     * diminishing returns as the improvements between 8 and 16 can be slight.
+     *
+     * @param maxAnisotropy The Anisotropy value to use for filtering. Must be greater than 0.
+     */
+    public void setMaxAnisotropy(@IntRange(from = 1) int maxAnisotropy) {
+        if (mMaxAniso != maxAnisotropy && maxAnisotropy > 0) {
+            mMaxAniso = maxAnisotropy;
+            mFilterMode = FILTER_MODE_DEFAULT;
+            discardNativeInstance();
+        }
+    }
+
+    /**
+     * Returns the current max anisotropic filtering value configured by
+     * {@link #setFilterMode(int)}. If {@link #setFilterMode(int)} is invoked this returns zero.
+     */
+    public int getMaxAnisotropy() {
+        return mMaxAniso;
+    }
+
     /** @hide */
     /* package */ synchronized long getNativeInstanceWithDirectSampling() {
         mRequestDirectSampling = true;
@@ -162,8 +197,13 @@
         mIsDirectSampled = mRequestDirectSampling;
         mRequestDirectSampling = false;
 
-        return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY,
-                            enableLinearFilter, mIsDirectSampled);
+        if (mMaxAniso > 0) {
+            return nativeCreateWithMaxAniso(nativeMatrix, mBitmap.getNativeInstance(), mTileX,
+                    mTileY, mMaxAniso, mIsDirectSampled);
+        } else {
+            return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY,
+                    enableLinearFilter, mIsDirectSampled);
+        }
     }
 
     /** @hide */
@@ -175,5 +215,8 @@
 
     private static native long nativeCreate(long nativeMatrix, long bitmapHandle,
             int shaderTileModeX, int shaderTileModeY, boolean filter, boolean isDirectSampled);
+
+    private static native long nativeCreateWithMaxAniso(long nativeMatrix, long bitmapHandle,
+            int shaderTileModeX, int shaderTileModeY, int maxAniso, boolean isDirectSampled);
 }
 
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 42c892a..e7814cb 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -241,7 +241,7 @@
 
     /**
      * Return true if the device that the current layer draws into is opaque
-     * (i.e. does not support per-pixel alpha).
+     * (that is, it does not support per-pixel alpha).
      *
      * @return true if the device that the current layer draws into is opaque
      */
diff --git a/graphics/java/android/graphics/Mesh.java b/graphics/java/android/graphics/Mesh.java
index a599b2c..6a1313e 100644
--- a/graphics/java/android/graphics/Mesh.java
+++ b/graphics/java/android/graphics/Mesh.java
@@ -16,6 +16,8 @@
 
 package android.graphics;
 
+import android.annotation.ColorInt;
+import android.annotation.ColorLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 
@@ -27,10 +29,8 @@
 /**
  * Class representing a mesh object.
  *
- * This class generates Mesh objects via the
- * {@link #make(MeshSpecification, int, Buffer, int, Rect)} and
- * {@link #makeIndexed(MeshSpecification, int, Buffer, int, ShortBuffer, Rect)} methods,
- * where a {@link MeshSpecification} is required along with various attributes for
+ * This class represents a Mesh object that can optionally be indexed.
+ * A {@link MeshSpecification} is required along with various attributes for
  * detailing the mesh object, including a mode, vertex buffer, optional index buffer, and bounds
  * for the mesh. Once generated, a mesh object can be drawn through
  * {@link Canvas#drawMesh(Mesh, BlendMode, Paint)}
@@ -62,7 +62,7 @@
     }
 
     /**
-     * Generates a {@link Mesh} object.
+     * Constructor for a non-indexed Mesh.
      *
      * @param meshSpec     {@link MeshSpecification} used when generating the mesh.
      * @param mode         Determines what mode to draw the mesh in. Must be one of
@@ -74,11 +74,9 @@
      *                     backed buffer generated.
      * @param vertexCount  the number of vertices represented in the vertexBuffer and mesh.
      * @param bounds       bounds of the mesh object.
-     * @return a new Mesh object.
      */
-    @NonNull
-    public static Mesh make(@NonNull MeshSpecification meshSpec, @Mode int mode,
-            @NonNull Buffer vertexBuffer, int vertexCount, @NonNull Rect bounds) {
+    public Mesh(@NonNull MeshSpecification meshSpec, @Mode int mode,
+            @NonNull Buffer vertexBuffer, int vertexCount, @NonNull RectF bounds) {
         if (mode != TRIANGLES && mode != TRIANGLE_STRIP) {
             throw new IllegalArgumentException("Invalid value passed in for mode parameter");
         }
@@ -88,11 +86,12 @@
         if (nativeMesh == 0) {
             throw new IllegalArgumentException("Mesh construction failed.");
         }
-        return new Mesh(nativeMesh, false);
+
+        meshSetup(nativeMesh, false);
     }
 
     /**
-     * Generates a {@link Mesh} object.
+     * Constructor for an indexed Mesh.
      *
      * @param meshSpec     {@link MeshSpecification} used when generating the mesh.
      * @param mode         Determines what mode to draw the mesh in. Must be one of
@@ -108,12 +107,10 @@
      *                     currently implementation will have a CPU
      *                     backed buffer generated.
      * @param bounds       bounds of the mesh object.
-     * @return a new Mesh object.
      */
-    @NonNull
-    public static Mesh makeIndexed(@NonNull MeshSpecification meshSpec, @Mode int mode,
+    public Mesh(@NonNull MeshSpecification meshSpec, @Mode int mode,
             @NonNull Buffer vertexBuffer, int vertexCount, @NonNull ShortBuffer indexBuffer,
-            @NonNull Rect bounds) {
+            @NonNull RectF bounds) {
         if (mode != TRIANGLES && mode != TRIANGLE_STRIP) {
             throw new IllegalArgumentException("Invalid value passed in for mode parameter");
         }
@@ -124,7 +121,8 @@
         if (nativeMesh == 0) {
             throw new IllegalArgumentException("Mesh construction failed.");
         }
-        return new Mesh(nativeMesh, true);
+
+        meshSetup(nativeMesh, true);
     }
 
     /**
@@ -137,7 +135,7 @@
      * @param color       the provided sRGB color will be converted into the shader program's output
      *                    colorspace and be available as a vec4 uniform in the program.
      */
-    public void setColorUniform(@NonNull String uniformName, int color) {
+    public void setColorUniform(@NonNull String uniformName, @ColorInt int color) {
         setUniform(uniformName, Color.valueOf(color).getComponents(), true);
     }
 
@@ -151,7 +149,7 @@
      * @param color       the provided sRGB color will be converted into the shader program's output
      *                    colorspace and be available as a vec4 uniform in the program.
      */
-    public void setColorUniform(@NonNull String uniformName, long color) {
+    public void setColorUniform(@NonNull String uniformName, @ColorLong long color) {
         Color exSRGB = Color.valueOf(color).convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
         setUniform(uniformName, exSRGB.getComponents(), true);
     }
@@ -357,7 +355,7 @@
                 mNativeMeshWrapper, uniformName, value1, value2, value3, value4, count);
     }
 
-    private Mesh(long nativeMeshWrapper, boolean isIndexed) {
+    private void meshSetup(long nativeMeshWrapper, boolean isIndexed) {
         mNativeMeshWrapper = nativeMeshWrapper;
         this.mIsIndexed = isIndexed;
         MeshHolder.MESH_SPECIFICATION_REGISTRY.registerNativeAllocation(this, mNativeMeshWrapper);
@@ -366,13 +364,13 @@
     private static native long nativeGetFinalizer();
 
     private static native long nativeMake(long meshSpec, int mode, Buffer vertexBuffer,
-            boolean isDirect, int vertexCount, int vertexOffset, int left, int top, int right,
-            int bottom);
+            boolean isDirect, int vertexCount, int vertexOffset, float left, float top, float right,
+            float bottom);
 
     private static native long nativeMakeIndexed(long meshSpec, int mode, Buffer vertexBuffer,
             boolean isVertexDirect, int vertexCount, int vertexOffset, ShortBuffer indexBuffer,
-            boolean isIndexDirect, int indexCount, int indexOffset, int left, int top, int right,
-            int bottom);
+            boolean isIndexDirect, int indexCount, int indexOffset, float left, float top,
+            float right, float bottom);
 
     private static native void nativeUpdateUniforms(long builder, String uniformName, float value1,
             float value2, float value3, float value4, int count);
diff --git a/graphics/java/android/graphics/MeshSpecification.java b/graphics/java/android/graphics/MeshSpecification.java
index 52b4002..6b5f1da 100644
--- a/graphics/java/android/graphics/MeshSpecification.java
+++ b/graphics/java/android/graphics/MeshSpecification.java
@@ -17,11 +17,15 @@
 package android.graphics;
 
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
+import android.annotation.Size;
+import android.annotation.SuppressLint;
 
 import libcore.util.NativeAllocationRegistry;
 
-import java.util.List;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Class responsible for holding specifications for {@link Mesh} creations. This class
@@ -43,100 +47,162 @@
     long mNativeMeshSpec;
 
     /**
-     * Constants for {@link #make(List, int, List, String, String)}
+     * Constants for {@link #make(Attribute[], int, Varying[], String, String)}
      * to determine alpha type. Describes how to interpret the alpha component of a pixel.
+     *
+     * @hide
      */
-    @IntDef({UNKNOWN, OPAQUE, PREMUL, UNPREMULT})
+    @IntDef({ALPHA_TYPE_UNKNOWN, ALPHA_TYPE_OPAQUE, ALPHA_TYPE_PREMUL, ALPHA_TYPE_PREMULT})
+    @Retention(RetentionPolicy.SOURCE)
     private @interface AlphaType {}
 
     /**
      * uninitialized.
      */
-    public static final int UNKNOWN = 0;
+    public static final int ALPHA_TYPE_UNKNOWN = 0;
 
     /**
      * Pixel is opaque.
      */
-    public static final int OPAQUE = 1;
+    public static final int ALPHA_TYPE_OPAQUE = 1;
 
     /**
      * Pixel components are premultiplied by alpha.
      */
-    public static final int PREMUL = 2;
+    public static final int ALPHA_TYPE_PREMUL = 2;
 
     /**
      * Pixel components are independent of alpha.
      */
-    public static final int UNPREMULT = 3;
+    public static final int ALPHA_TYPE_PREMULT = 3;
 
     /**
      * Constants for {@link Attribute} and {@link Varying} for determining the data type.
+     *
+     * @hide
      */
-    @IntDef({FLOAT, FLOAT2, FLOAT3, FLOAT4, UBYTE4})
+    @IntDef({TYPE_FLOAT, TYPE_FLOAT2, TYPE_FLOAT3, TYPE_FLOAT4, TYPE_UBYTE4})
+    @Retention(RetentionPolicy.SOURCE)
     private @interface Type {}
 
     /**
      * Represents one float. Its equivalent shader type is float.
      */
-    public static final int FLOAT = 0;
+    public static final int TYPE_FLOAT = 0;
 
     /**
      * Represents two floats. Its equivalent shader type is float2.
      */
-    public static final int FLOAT2 = 1;
+    public static final int TYPE_FLOAT2 = 1;
 
     /**
      * Represents three floats. Its equivalent shader type is float3.
      */
-    public static final int FLOAT3 = 2;
+    public static final int TYPE_FLOAT3 = 2;
 
     /**
      * Represents four floats. Its equivalent shader type is float4.
      */
-    public static final int FLOAT4 = 3;
+    public static final int TYPE_FLOAT4 = 3;
 
     /**
      * Represents four bytes. Its equivalent shader type is half4.
      */
-    public static final int UBYTE4 = 4;
+    public static final int TYPE_UBYTE4 = 4;
 
     /**
-     * Data class to represent a single attribute in a shader. Note that type parameter must be
-     * one of {@link #FLOAT}, {@link #FLOAT2}, {@link #FLOAT3}, {@link #FLOAT4}, or {@link #UBYTE4}.
+     * Data class to represent a single attribute in a shader.
      *
      * Note that offset is the offset in number of bytes. For example, if we had two attributes
      *
+     * <pre>
      * Float3 att1
      * Float att2
+     * </pre>
      *
      * att1 would have an offset of 0, while att2 would have an offset of 12 bytes.
      */
     public static class Attribute {
         @Type
-        private int mType;
-        private int mOffset;
-        private String mName;
+        private final int mType;
+        private final int mOffset;
+        private final String mName;
 
         public Attribute(@Type int type, int offset, @NonNull String name) {
             mType = type;
             mOffset = offset;
             mName = name;
         }
+
+        /**
+         * Return the corresponding data type for this {@link Attribute}.
+         */
+        @Type
+        public int getType() {
+            return mType;
+        }
+
+        /**
+         * Return the offset of the attribute in bytes
+         */
+        public int getOffset() {
+            return mOffset;
+        }
+
+        /**
+         * Return the name of this {@link Attribute}
+         */
+        @NonNull
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public String toString() {
+            return "Attribute{"
+                    + "mType=" + mType
+                    + ", mOffset=" + mOffset
+                    + ", mName='" + mName + '\''
+                    + '}';
+        }
     }
 
     /**
-     * Data class to represent a single varying variable. Note that type parameter must be
-     * one of {@link #FLOAT}, {@link #FLOAT2}, {@link #FLOAT3}, {@link #FLOAT4}, or {@link #UBYTE4}.
+     * Data class to represent a single varying variable.
      */
     public static class Varying {
         @Type
-        private int mType;
-        private String mName;
+        private final int mType;
+        private final String mName;
 
         public Varying(@Type int type, @NonNull String name) {
             mType = type;
             mName = name;
         }
+
+        /**
+         * Return the corresponding data type for this {@link Varying}.
+         */
+        @Type
+        public int getType() {
+            return mType;
+        }
+
+        /**
+         * Return the name of this {@link Varying}
+         */
+        @NonNull
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public String toString() {
+            return "Varying{"
+                    + "mType=" + mType
+                    + ", mName='" + mName + '\''
+                    + '}';
+        }
     }
 
     private static class MeshSpecificationHolder {
@@ -146,7 +212,9 @@
     }
 
     /**
-     * Creates a {@link MeshSpecification} object for use within {@link Mesh}.
+     * Creates a {@link MeshSpecification} object for use within {@link Mesh}. This uses a default
+     * color space of {@link ColorSpace.Named#SRGB} and {@link AlphaType} of
+     * {@link #ALPHA_TYPE_PREMUL}.
      *
      * @param attributes     list of attributes represented by {@link Attribute}. Can hold a max of
      *                       8.
@@ -162,11 +230,14 @@
      * @return {@link MeshSpecification} object for use when creating {@link Mesh}
      */
     @NonNull
-    public static MeshSpecification make(@NonNull List<Attribute> attributes, int vertexStride,
-            @NonNull List<Varying> varyings, @NonNull String vertexShader,
+    public static MeshSpecification make(
+            @SuppressLint("ArrayReturn") @NonNull @Size(max = 8) Attribute[] attributes,
+            @IntRange(from = 1, to = 1024) int vertexStride,
+            @SuppressLint("ArrayReturn") @NonNull @Size(max = 6) Varying[] varyings,
+            @NonNull String vertexShader,
             @NonNull String fragmentShader) {
-        long nativeMeshSpec = nativeMake(attributes.toArray(new Attribute[attributes.size()]),
-                vertexStride, varyings.toArray(new Varying[varyings.size()]), vertexShader,
+        long nativeMeshSpec = nativeMake(attributes,
+                vertexStride, varyings, vertexShader,
                 fragmentShader);
         if (nativeMeshSpec == 0) {
             throw new IllegalArgumentException("MeshSpecification construction failed");
@@ -175,7 +246,8 @@
     }
 
     /**
-     * Creates a {@link MeshSpecification} object.
+     * Creates a {@link MeshSpecification} object.  This uses a default {@link AlphaType} of
+     * {@link #ALPHA_TYPE_PREMUL}.
      *
      * @param attributes     list of attributes represented by {@link Attribute}. Can hold a max of
      *                       8.
@@ -192,11 +264,16 @@
      * @return {@link MeshSpecification} object for use when creating {@link Mesh}
      */
     @NonNull
-    public static MeshSpecification make(@NonNull List<Attribute> attributes, int vertexStride,
-            @NonNull List<Varying> varyings, @NonNull String vertexShader,
-            @NonNull String fragmentShader, @NonNull ColorSpace colorSpace) {
-        long nativeMeshSpec = nativeMakeWithCS(attributes.toArray(new Attribute[attributes.size()]),
-                vertexStride, varyings.toArray(new Varying[varyings.size()]), vertexShader,
+    public static MeshSpecification make(
+            @SuppressLint("ArrayReturn") @NonNull @Size(max = 8) Attribute[] attributes,
+            @IntRange(from = 1, to = 1024) int vertexStride,
+            @SuppressLint("ArrayReturn") @NonNull @Size(max = 6) Varying[] varyings,
+            @NonNull String vertexShader,
+            @NonNull String fragmentShader,
+            @NonNull ColorSpace colorSpace
+    ) {
+        long nativeMeshSpec = nativeMakeWithCS(attributes,
+                vertexStride, varyings, vertexShader,
                 fragmentShader, colorSpace.getNativeInstance());
         if (nativeMeshSpec == 0) {
             throw new IllegalArgumentException("MeshSpecification construction failed");
@@ -221,20 +298,23 @@
      * @param colorSpace     {@link ColorSpace} to tell what color space to work in.
      * @param alphaType      Describes how to interpret the alpha component for a pixel. Must be
      *                       one of
-     *                       {@link MeshSpecification#UNKNOWN},
-     *                       {@link MeshSpecification#OPAQUE},
-     *                       {@link MeshSpecification#PREMUL}, or
-     *                       {@link MeshSpecification#UNPREMULT}
+     *                       {@link MeshSpecification#ALPHA_TYPE_UNKNOWN},
+     *                       {@link MeshSpecification#ALPHA_TYPE_OPAQUE},
+     *                       {@link MeshSpecification#ALPHA_TYPE_PREMUL}, or
+     *                       {@link MeshSpecification#ALPHA_TYPE_PREMULT}
      * @return {@link MeshSpecification} object for use when creating {@link Mesh}
      */
     @NonNull
-    public static MeshSpecification make(@NonNull List<Attribute> attributes, int vertexStride,
-            @NonNull List<Varying> varyings, @NonNull String vertexShader,
-            @NonNull String fragmentShader, @NonNull ColorSpace colorSpace,
+    public static MeshSpecification make(
+            @SuppressLint("ArrayReturn") @NonNull @Size(max = 8) Attribute[] attributes,
+            @IntRange(from = 1, to = 1024) int vertexStride,
+            @SuppressLint("ArrayReturn") @NonNull @Size(max = 6) Varying[] varyings,
+            @NonNull String vertexShader,
+            @NonNull String fragmentShader,
+            @NonNull ColorSpace colorSpace,
             @AlphaType int alphaType) {
         long nativeMeshSpec =
-                nativeMakeWithAlpha(attributes.toArray(new Attribute[attributes.size()]),
-                        vertexStride, varyings.toArray(new Varying[varyings.size()]), vertexShader,
+                nativeMakeWithAlpha(attributes, vertexStride, varyings, vertexShader,
                         fragmentShader, colorSpace.getNativeInstance(), alphaType);
         if (nativeMeshSpec == 0) {
             throw new IllegalArgumentException("MeshSpecification construction failed");
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 4715045..c1f6c29 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -801,7 +801,8 @@
             ));
 
             if (mSpec.isDevicePropertiesAttestationIncluded()) {
-                final String platformReportedBrand = TextUtils.isEmpty(Build.BRAND_FOR_ATTESTATION)
+                final String platformReportedBrand =
+                        isPropertyEmptyOrUnknown(Build.BRAND_FOR_ATTESTATION)
                         ? Build.BRAND : Build.BRAND_FOR_ATTESTATION;
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND,
@@ -812,8 +813,8 @@
                         Build.DEVICE.getBytes(StandardCharsets.UTF_8)
                 ));
                 final String platformReportedProduct =
-                        TextUtils.isEmpty(Build.PRODUCT_FOR_ATTESTATION) ? Build.PRODUCT :
-                                Build.PRODUCT_FOR_ATTESTATION;
+                        isPropertyEmptyOrUnknown(Build.PRODUCT_FOR_ATTESTATION)
+                        ? Build.PRODUCT : Build.PRODUCT_FOR_ATTESTATION;
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT,
                         platformReportedProduct.getBytes(StandardCharsets.UTF_8)
@@ -822,7 +823,8 @@
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER,
                         Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8)
                 ));
-                final String platformReportedModel = TextUtils.isEmpty(Build.MODEL_FOR_ATTESTATION)
+                final String platformReportedModel =
+                        isPropertyEmptyOrUnknown(Build.MODEL_FOR_ATTESTATION)
                         ? Build.MODEL : Build.MODEL_FOR_ATTESTATION;
                 params.add(KeyStore2ParameterUtils.makeBytes(
                         KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL,
@@ -1227,4 +1229,8 @@
         result.retainAll(authorizedKeymasterKeyDigests);
         return result;
     }
+
+    private boolean isPropertyEmptyOrUnknown(String property) {
+        return TextUtils.isEmpty(property) || property.equals(Build.UNKNOWN);
+    }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index 666b472..76e0e1e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -48,7 +48,7 @@
     // TODO(b/241126279) Introduce constants to better version functionality
     @Override
     public int getVendorApiLevel() {
-        return 2;
+        return 3;
     }
 
     @NonNull
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentation.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentation.java
new file mode 100644
index 0000000..1ff1694
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentation.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.extensions.area;
+
+import android.app.Presentation;
+import android.content.Context;
+import android.view.Display;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.window.extensions.core.util.function.Consumer;
+
+/**
+ * {@link Presentation} object that is used to present extra content
+ * on the rear facing display when in a rear display presentation feature.
+ */
+class RearDisplayPresentation extends Presentation implements ExtensionWindowAreaPresentation {
+
+    @NonNull
+    private final Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> mStateConsumer;
+
+    RearDisplayPresentation(@NonNull Context outerContext, @NonNull Display display,
+            @NonNull Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> stateConsumer) {
+        super(outerContext, display);
+        mStateConsumer = stateConsumer;
+    }
+
+    /**
+     * {@code mStateConsumer} is notified that their content is now visible when the
+     * {@link Presentation} object is started. There is no comparable callback for
+     * {@link WindowAreaComponent#SESSION_STATE_INVISIBLE} in {@link #onStop()} due to the
+     * timing of when a {@link android.hardware.devicestate.DeviceStateRequest} is cancelled
+     * ending rear display presentation mode happening before the {@link Presentation} is stopped.
+     */
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mStateConsumer.accept(WindowAreaComponent.SESSION_STATE_VISIBLE);
+    }
+
+    @NonNull
+    @Override
+    public Context getPresentationContext() {
+        return getContext();
+    }
+
+    @Override
+    public void setPresentationView(View view) {
+        setContentView(view);
+        if (!isShowing()) {
+            show();
+        }
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationController.java
new file mode 100644
index 0000000..141a6ad
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationController.java
@@ -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 androidx.window.extensions.area;
+
+import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_ACTIVE;
+import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_INACTIVE;
+
+import android.content.Context;
+import android.hardware.devicestate.DeviceStateRequest;
+import android.hardware.display.DisplayManager;
+import android.util.Log;
+import android.view.Display;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.window.extensions.core.util.function.Consumer;
+
+import java.util.Objects;
+
+/**
+ * Controller class that keeps track of the status of the device state request
+ * to enable the rear display presentation feature. This controller notifies the session callback
+ * when the state request is active, and notifies the callback when the request is canceled.
+ *
+ * Clients are notified via {@link Consumer} provided with
+ * {@link androidx.window.extensions.area.WindowAreaComponent.WindowAreaStatus} values to signify
+ * when the request becomes active and cancelled.
+ */
+class RearDisplayPresentationController implements DeviceStateRequest.Callback {
+
+    private static final String TAG = "RearDisplayPresentationController";
+
+    // Original context that requested to enable rear display presentation mode
+    @NonNull
+    private final Context mContext;
+    @NonNull
+    private final Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> mStateConsumer;
+    @Nullable
+    private ExtensionWindowAreaPresentation mExtensionWindowAreaPresentation;
+    @NonNull
+    private final DisplayManager mDisplayManager;
+
+    /**
+     * Creates the RearDisplayPresentationController
+     * @param context Originating {@link android.content.Context} that is initiating the rear
+     *                display presentation session.
+     * @param stateConsumer {@link Consumer} that will be notified that the session is active when
+     *        the device state request is active and the session has been created. If the device
+     *        state request is cancelled, the callback will be notified that the session has been
+     *        ended. This could occur through a call to cancel the feature or if the device is
+     *        manipulated in a way that cancels any device state override.
+     */
+    RearDisplayPresentationController(@NonNull Context context,
+            @NonNull Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> stateConsumer) {
+        Objects.requireNonNull(context);
+        Objects.requireNonNull(stateConsumer);
+
+        mContext = context;
+        mStateConsumer = stateConsumer;
+        mDisplayManager = context.getSystemService(DisplayManager.class);
+    }
+
+    @Override
+    public void onRequestActivated(@NonNull DeviceStateRequest request) {
+        Display[] rearDisplays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_REAR);
+        if (rearDisplays.length == 0) {
+            mStateConsumer.accept(SESSION_STATE_INACTIVE);
+            Log.e(TAG, "Rear display list should not be empty");
+            return;
+        }
+
+        mExtensionWindowAreaPresentation =
+                new RearDisplayPresentation(mContext, rearDisplays[0], mStateConsumer);
+        mStateConsumer.accept(SESSION_STATE_ACTIVE);
+    }
+
+    @Override
+    public void onRequestCanceled(@NonNull DeviceStateRequest request) {
+        mStateConsumer.accept(SESSION_STATE_INACTIVE);
+    }
+
+    @Nullable
+    public ExtensionWindowAreaPresentation getWindowAreaPresentation() {
+        return mExtensionWindowAreaPresentation;
+    }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationStatus.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationStatus.java
new file mode 100644
index 0000000..0b1423a
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/RearDisplayPresentationStatus.java
@@ -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 androidx.window.extensions.area;
+
+import android.util.DisplayMetrics;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Class that provides information around the current status of a window area feature. Contains
+ * the current {@link WindowAreaComponent.WindowAreaStatus} value corresponding to the
+ * rear display presentation feature, as well as the {@link DisplayMetrics} for the rear facing
+ * display.
+ */
+class RearDisplayPresentationStatus implements ExtensionWindowAreaStatus {
+
+    @WindowAreaComponent.WindowAreaStatus
+    private final int mWindowAreaStatus;
+
+    @NonNull
+    private final DisplayMetrics mDisplayMetrics;
+
+    RearDisplayPresentationStatus(@WindowAreaComponent.WindowAreaStatus int status,
+            @NonNull DisplayMetrics displayMetrics) {
+        mWindowAreaStatus = status;
+        mDisplayMetrics = displayMetrics;
+    }
+
+    /**
+     * Returns the {@link androidx.window.extensions.area.WindowAreaComponent.WindowAreaStatus}
+     * value that relates to the current status of a feature.
+     */
+    @Override
+    @WindowAreaComponent.WindowAreaStatus
+    public int getWindowAreaStatus() {
+        return mWindowAreaStatus;
+    }
+
+    /**
+     * Returns the {@link DisplayMetrics} that corresponds to the window area that a feature
+     * interacts with. This is converted to size class information provided to developers.
+     */
+    @Override
+    @NonNull
+    public DisplayMetrics getWindowAreaDisplayMetrics() {
+        return mDisplayMetrics;
+    }
+}
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 87c2822..274dcae 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java
@@ -22,13 +22,20 @@
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.devicestate.DeviceStateRequest;
+import android.hardware.display.DisplayManager;
 import android.util.ArraySet;
+import android.util.DisplayMetrics;
+import android.util.Pair;
+import android.view.Display;
+import android.view.DisplayAddress;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 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.concurrent.Executor;
 
@@ -46,61 +53,102 @@
 
     private final Object mLock = new Object();
 
+    @NonNull
     private final DeviceStateManager mDeviceStateManager;
+    @NonNull
+    private final DisplayManager mDisplayManager;
+    @NonNull
     private final Executor mExecutor;
 
     @GuardedBy("mLock")
     private final ArraySet<Consumer<Integer>> mRearDisplayStatusListeners = new ArraySet<>();
+    @GuardedBy("mLock")
+    private final ArraySet<Consumer<ExtensionWindowAreaStatus>>
+            mRearDisplayPresentationStatusListeners = new ArraySet<>();
     private final int mRearDisplayState;
+    private final int mConcurrentDisplayState;
+    @NonNull
+    private final int[] mFoldedDeviceStates;
+    @NonNull
+    private long mRearDisplayAddress = 0;
     @WindowAreaSessionState
     private int mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_INACTIVE;
 
     @GuardedBy("mLock")
     private int mCurrentDeviceState = INVALID_DEVICE_STATE;
     @GuardedBy("mLock")
-    private int mCurrentDeviceBaseState = INVALID_DEVICE_STATE;
+    private int[] mCurrentSupportedDeviceStates;
+
     @GuardedBy("mLock")
-    private DeviceStateRequest mDeviceStateRequest;
+    private DeviceStateRequest mRearDisplayStateRequest;
+    @GuardedBy("mLock")
+    private RearDisplayPresentationController mRearDisplayPresentationController;
+
+    @Nullable
+    @GuardedBy("mLock")
+    private DisplayMetrics mRearDisplayMetrics;
+
+    @WindowAreaSessionState
+    @GuardedBy("mLock")
+    private int mLastReportedRearDisplayPresentationStatus;
 
     public WindowAreaComponentImpl(@NonNull Context context) {
         mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
+        mDisplayManager = context.getSystemService(DisplayManager.class);
         mExecutor = context.getMainExecutor();
 
+        mCurrentSupportedDeviceStates = mDeviceStateManager.getSupportedStates();
+        mFoldedDeviceStates = context.getResources().getIntArray(
+                R.array.config_foldedDeviceStates);
+
         // TODO(b/236022708) Move rear display state to device state config file
         mRearDisplayState = context.getResources().getInteger(
                 R.integer.config_deviceStateRearDisplay);
 
+        mConcurrentDisplayState = context.getResources().getInteger(
+                R.integer.config_deviceStateConcurrentRearDisplay);
+
         mDeviceStateManager.registerCallback(mExecutor, this);
+        if (mConcurrentDisplayState != INVALID_DEVICE_STATE) {
+            mRearDisplayAddress = Long.parseLong(context.getResources().getString(
+                    R.string.config_rearDisplayPhysicalAddress));
+        }
     }
 
     /**
      * Adds a listener interested in receiving updates on the RearDisplayStatus
      * of the device. Because this is being called from the OEM provided
-     * extensions, we will post the result of the listener on the executor
+     * extensions, the result of the listener will be posted on the executor
      * provided by the developer at the initial call site.
      *
-     * Depending on the initial state of the device, we will return either
+     * Rear display mode moves the calling application to the display on the device that is
+     * facing the same direction as the rear cameras. This would be the cover display on a fold-in
+     * style device when the device is opened.
+     *
+     * Depending on the initial state of the device, the {@link Consumer} will receive either
      * {@link WindowAreaComponent#STATUS_AVAILABLE} or
      * {@link WindowAreaComponent#STATUS_UNAVAILABLE} if the feature is supported or not in that
-     * state respectively. When the rear display feature is triggered, we update the status to be
-     * {@link WindowAreaComponent#STATUS_UNAVAILABLE}. TODO(b/240727590) Prefix with AREA_
+     * state respectively. When the rear display feature is triggered, the status is updated to be
+     * {@link WindowAreaComponent#STATUS_UNAVAILABLE}.
+     * TODO(b/240727590): Prefix with AREA_
      *
-     * TODO(b/239833099) Add a STATUS_ACTIVE option to let apps know if a feature is currently
-     * enabled.
+     * TODO(b/239833099): Add a STATUS_ACTIVE option to let apps know if a feature is currently
+     *  enabled.
      *
      * @param consumer {@link Consumer} interested in receiving updates to the status of
      * rear display mode.
      */
+    @Override
     public void addRearDisplayStatusListener(
             @NonNull Consumer<@WindowAreaStatus Integer> consumer) {
         synchronized (mLock) {
             mRearDisplayStatusListeners.add(consumer);
 
-            // If current device state is still invalid, we haven't gotten our initial value yet
+            // If current device state is still invalid, the initial value has not been provided.
             if (mCurrentDeviceState == INVALID_DEVICE_STATE) {
                 return;
             }
-            consumer.accept(getCurrentStatus());
+            consumer.accept(getCurrentRearDisplayModeStatus());
         }
     }
 
@@ -108,6 +156,7 @@
      * Removes a listener no longer interested in receiving updates.
      * @param consumer no longer interested in receiving updates to RearDisplayStatus
      */
+    @Override
     public void removeRearDisplayStatusListener(
             @NonNull Consumer<@WindowAreaStatus Integer> consumer) {
         synchronized (mLock) {
@@ -118,13 +167,17 @@
     /**
      * Creates and starts a rear display session and provides updates to the
      * callback provided. Because this is being called from the OEM provided
-     * extensions, we will post the result of the listener on the executor
+     * extensions, the result of the listener will be posted on the executor
      * provided by the developer at the initial call site.
      *
-     * When we enable rear display mode, we submit a request to {@link DeviceStateManager}
+     * Rear display mode moves the calling application to the display on the device that is
+     * facing the same direction as the rear cameras. This would be the cover display on a fold-in
+     * style device when the device is opened.
+     *
+     * When rear display mode is enabled, a request is made to {@link DeviceStateManager}
      * to override the device state to the state that corresponds to RearDisplay
-     * mode. When the {@link DeviceStateRequest} is activated, we let the
-     * consumer know that the session is active by sending
+     * mode. When the {@link DeviceStateRequest} is activated, the provided {@link Consumer} is
+     * notified that the session is active by receiving
      * {@link WindowAreaComponent#SESSION_STATE_ACTIVE}.
      *
      * @param activity to provide updates to the client on
@@ -132,19 +185,20 @@
      * @param rearDisplaySessionCallback to provide updates to the client on
      * the status of the Session
      */
+    @Override
     public void startRearDisplaySession(@NonNull Activity activity,
             @NonNull Consumer<@WindowAreaSessionState Integer> rearDisplaySessionCallback) {
         synchronized (mLock) {
-            if (mDeviceStateRequest != null) {
+            if (mRearDisplayStateRequest != null) {
                 // Rear display session is already active
                 throw new IllegalStateException(
                         "Unable to start new rear display session as one is already active");
             }
-            mDeviceStateRequest = DeviceStateRequest.newBuilder(mRearDisplayState).build();
+            mRearDisplayStateRequest = DeviceStateRequest.newBuilder(mRearDisplayState).build();
             mDeviceStateManager.requestState(
-                    mDeviceStateRequest,
+                    mRearDisplayStateRequest,
                     mExecutor,
-                    new DeviceStateRequestCallbackAdapter(rearDisplaySessionCallback)
+                    new RearDisplayStateRequestCallbackAdapter(rearDisplaySessionCallback)
             );
         }
     }
@@ -152,13 +206,14 @@
     /**
      * Ends the current rear display session and provides updates to the
      * callback provided. Because this is being called from the OEM provided
-     * extensions, we will post the result of the listener on the executor
-     * provided by the developer.
+     * extensions, the result of the listener will be posted on the executor
+     * provided by the developer at the initial call site.
      */
+    @Override
     public void endRearDisplaySession() {
         synchronized (mLock) {
-            if (mDeviceStateRequest != null || isRearDisplayActive()) {
-                mDeviceStateRequest = null;
+            if (mRearDisplayStateRequest != null || isRearDisplayActive()) {
+                mRearDisplayStateRequest = null;
                 mDeviceStateManager.cancelStateRequest();
             } else {
                 throw new IllegalStateException(
@@ -167,13 +222,176 @@
         }
     }
 
+    /**
+     * 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
+     * provided by the developer at the initial call site.
+     *
+     * Rear display presentation mode is a feature where an {@link Activity} can present
+     * additional content on a device with a second display that is facing the same direction
+     * as the rear camera (i.e. the cover display on a fold-in style device). The calling
+     * {@link Activity} does not move, whereas in rear display mode it does.
+     *
+     * This listener receives a {@link Pair} with the first item being the
+     * {@link WindowAreaComponent.WindowAreaStatus} that corresponds to the current status of the
+     * feature, and the second being the {@link DisplayMetrics} of the display that would be
+     * presented to when the feature is active.
+     *
+     * Depending on the initial state of the device, the {@link Consumer} will receive either
+     * {@link WindowAreaComponent#STATUS_AVAILABLE} or
+     * {@link WindowAreaComponent#STATUS_UNAVAILABLE} for the status value of the {@link Pair} if
+     * the feature is supported or not in that state respectively. Rear display presentation mode is
+     * currently not supported when the device is folded. When the rear display presentation feature
+     * is triggered, the status is updated to be {@link WindowAreaComponent#STATUS_UNAVAILABLE}.
+     * TODO(b/240727590): Prefix with AREA_
+     *
+     * TODO(b/239833099): Add a STATUS_ACTIVE option to let apps know if a feature is currently
+     *  enabled.
+     *
+     * @param consumer {@link Consumer} interested in receiving updates to the status of
+     * rear display presentation mode.
+     */
     @Override
-    public void onBaseStateChanged(int state) {
+    public void addRearDisplayPresentationStatusListener(
+            @NonNull Consumer<ExtensionWindowAreaStatus> consumer) {
         synchronized (mLock) {
-            mCurrentDeviceBaseState = state;
-            if (state == mCurrentDeviceState) {
-                updateStatusConsumers(getCurrentStatus());
+            mRearDisplayPresentationStatusListeners.add(consumer);
+
+            // If current device state is still invalid, the initial value has not been provided
+            if (mCurrentDeviceState == INVALID_DEVICE_STATE) {
+                return;
             }
+            @WindowAreaStatus int currentStatus = getCurrentRearDisplayPresentationModeStatus();
+            consumer.accept(
+                    new RearDisplayPresentationStatus(currentStatus, getRearDisplayMetrics()));
+        }
+    }
+
+    /**
+     * Removes a listener no longer interested in receiving updates.
+     * @param consumer no longer interested in receiving updates to RearDisplayPresentationStatus
+     */
+    @Override
+    public void removeRearDisplayPresentationStatusListener(
+            @NonNull Consumer<ExtensionWindowAreaStatus> consumer) {
+        synchronized (mLock) {
+            mRearDisplayPresentationStatusListeners.remove(consumer);
+        }
+    }
+
+    /**
+     * Creates and starts a rear display presentation session and sends state updates to the
+     * consumer provided. This consumer will receive a constant represented by
+     * {@link WindowAreaSessionState} to represent the state of the current rear display
+     * session. It will be translated to a more friendly interface in the library.
+     *
+     * Because this is being called from the OEM provided extensions, the library
+     * will post the result of the listener on the executor provided by the developer.
+     *
+     * Rear display presentation mode refers to a feature where an {@link Activity} can present
+     * additional content on a device with a second display that is facing the same direction
+     * as the rear camera (i.e. the cover display on a fold-in style device). The calling
+     * {@link Activity} stays on the user-facing display.
+     *
+     * @param activity that the OEM implementation will use as a base
+     * context and to identify the source display area of the request.
+     * The reference to the activity instance must not be stored in the OEM
+     * implementation to prevent memory leaks.
+     * @param consumer to provide updates to the client on the status of the session
+     * @throws UnsupportedOperationException if this method is called when rear display presentation
+     * mode is not available. This could be to an incompatible device state or when
+     * another process is currently in this mode.
+     */
+    @Override
+    public void startRearDisplayPresentationSession(@NonNull Activity activity,
+            @NonNull Consumer<@WindowAreaSessionState Integer> consumer) {
+        synchronized (mLock) {
+            if (mRearDisplayPresentationController != null) {
+                // Rear display presentation session is already active
+                throw new IllegalStateException(
+                        "Unable to start new rear display presentation session as one is already "
+                                + "active");
+            }
+            if (getCurrentRearDisplayPresentationModeStatus()
+                    != WindowAreaComponent.STATUS_AVAILABLE) {
+                throw new IllegalStateException(
+                        "Unable to start new rear display presentation session as the feature is "
+                                + "is not currently available");
+            }
+
+            mRearDisplayPresentationController = new RearDisplayPresentationController(activity,
+                    stateStatus -> {
+                        synchronized (mLock) {
+                            if (stateStatus == SESSION_STATE_INACTIVE) {
+                                // If the last reported session status was VISIBLE
+                                // then the INVISIBLE state should be dispatched before INACTIVE
+                                // due to not having a good mechanism to know when
+                                // the content is no longer visible before it's fully removed
+                                if (getLastReportedRearDisplayPresentationStatus()
+                                        == SESSION_STATE_VISIBLE) {
+                                    consumer.accept(SESSION_STATE_INVISIBLE);
+                                }
+                                mRearDisplayPresentationController = null;
+                            }
+                            mLastReportedRearDisplayPresentationStatus = stateStatus;
+                            consumer.accept(stateStatus);
+                        }
+                    });
+
+            DeviceStateRequest concurrentDisplayStateRequest = DeviceStateRequest.newBuilder(
+                    mConcurrentDisplayState).build();
+            mDeviceStateManager.requestState(
+                    concurrentDisplayStateRequest,
+                    mExecutor,
+                    mRearDisplayPresentationController
+            );
+        }
+    }
+
+    /**
+     * Ends the current rear display presentation session and provides updates to the
+     * callback provided. When this is ended, the presented content from the calling
+     * {@link Activity} will also be removed from the rear facing display.
+     * Because this is being called from the OEM provided extensions, the result of the listener
+     * will be posted on the executor provided by the developer at the initial call site.
+     *
+     * Cancelling the {@link DeviceStateRequest} and exiting the rear display presentation state,
+     * will remove the presentation window from the cover display as the cover display is no longer
+     * enabled.
+     */
+    @Override
+    public void endRearDisplayPresentationSession() {
+        synchronized (mLock) {
+            if (mRearDisplayPresentationController != null) {
+                mDeviceStateManager.cancelStateRequest();
+            } else {
+                throw new IllegalStateException(
+                        "Unable to cancel a rear display presentation session as there is no "
+                                + "active session");
+            }
+        }
+    }
+
+    @Nullable
+    @Override
+    public ExtensionWindowAreaPresentation getRearDisplayPresentation() {
+        synchronized (mLock) {
+            ExtensionWindowAreaPresentation presentation = null;
+            if (mRearDisplayPresentationController != null) {
+                presentation = mRearDisplayPresentationController.getWindowAreaPresentation();
+            }
+            return presentation;
+        }
+    }
+
+    @Override
+    public void onSupportedStatesChanged(int[] supportedStates) {
+        synchronized (mLock) {
+            mCurrentSupportedDeviceStates = supportedStates;
+            updateRearDisplayStatusListeners(getCurrentRearDisplayModeStatus());
+            updateRearDisplayPresentationStatusListeners(
+                    getCurrentRearDisplayPresentationModeStatus());
         }
     }
 
@@ -181,13 +399,17 @@
     public void onStateChanged(int state) {
         synchronized (mLock) {
             mCurrentDeviceState = state;
-            updateStatusConsumers(getCurrentStatus());
+            updateRearDisplayStatusListeners(getCurrentRearDisplayModeStatus());
+            updateRearDisplayPresentationStatusListeners(
+                    getCurrentRearDisplayPresentationModeStatus());
         }
     }
 
+
     @GuardedBy("mLock")
-    private int getCurrentStatus() {
+    private int getCurrentRearDisplayModeStatus() {
         if (mRearDisplaySessionStatus == WindowAreaComponent.SESSION_STATE_ACTIVE
+                || !ArrayUtils.contains(mCurrentSupportedDeviceStates, mRearDisplayState)
                 || isRearDisplayActive()) {
             return WindowAreaComponent.STATUS_UNAVAILABLE;
         }
@@ -196,19 +418,20 @@
 
     /**
      * Helper method to determine if a rear display session is currently active by checking
-     * if the current device configuration matches that of rear display. This would be true
-     * if there is a device override currently active (base state != current state) and the current
-     * state is that which corresponds to {@code mRearDisplayState}
-     * @return {@code true} if the device is in rear display mode and {@code false} if not
+     * if the current device state is that which corresponds to {@code mRearDisplayState}.
+     *
+     * @return {@code true} if the device is in rear display state {@code false} if not
      */
     @GuardedBy("mLock")
     private boolean isRearDisplayActive() {
-        return (mCurrentDeviceState != mCurrentDeviceBaseState) && (mCurrentDeviceState
-                == mRearDisplayState);
+        return mCurrentDeviceState == mRearDisplayState;
     }
 
     @GuardedBy("mLock")
-    private void updateStatusConsumers(@WindowAreaStatus int windowAreaStatus) {
+    private void updateRearDisplayStatusListeners(@WindowAreaStatus int windowAreaStatus) {
+        if (mRearDisplayState == INVALID_DEVICE_STATE) {
+            return;
+        }
         synchronized (mLock) {
             for (int i = 0; i < mRearDisplayStatusListeners.size(); i++) {
                 mRearDisplayStatusListeners.valueAt(i).accept(windowAreaStatus);
@@ -216,26 +439,95 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private int getCurrentRearDisplayPresentationModeStatus() {
+        if (mCurrentDeviceState == mConcurrentDisplayState
+                || !ArrayUtils.contains(mCurrentSupportedDeviceStates, mConcurrentDisplayState)
+                || isDeviceFolded()) {
+            return WindowAreaComponent.STATUS_UNAVAILABLE;
+        }
+        return WindowAreaComponent.STATUS_AVAILABLE;
+    }
+
+    @GuardedBy("mLock")
+    private boolean isDeviceFolded() {
+        return ArrayUtils.contains(mFoldedDeviceStates, mCurrentDeviceState);
+    }
+
+    @GuardedBy("mLock")
+    private void updateRearDisplayPresentationStatusListeners(
+            @WindowAreaStatus int windowAreaStatus) {
+        if (mConcurrentDisplayState == INVALID_DEVICE_STATE) {
+            return;
+        }
+        RearDisplayPresentationStatus consumerValue = new RearDisplayPresentationStatus(
+                windowAreaStatus, getRearDisplayMetrics());
+        synchronized (mLock) {
+            for (int i = 0; i < mRearDisplayPresentationStatusListeners.size(); i++) {
+                mRearDisplayPresentationStatusListeners.valueAt(i).accept(consumerValue);
+            }
+        }
+    }
+
+    /**
+     * 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");
+        }
+    }
+
+    @GuardedBy("mLock")
+    @WindowAreaSessionState
+    private int getLastReportedRearDisplayPresentationStatus() {
+        return mLastReportedRearDisplayPresentationStatus;
+    }
+
     /**
      * Callback for the {@link DeviceStateRequest} to be notified of when the request has been
      * activated or cancelled. This callback provides information to the client library
      * on the status of the RearDisplay session through {@code mRearDisplaySessionCallback}
      */
-    private class DeviceStateRequestCallbackAdapter implements DeviceStateRequest.Callback {
+    private class RearDisplayStateRequestCallbackAdapter implements DeviceStateRequest.Callback {
 
         private final Consumer<Integer> mRearDisplaySessionCallback;
 
-        DeviceStateRequestCallbackAdapter(@NonNull Consumer<Integer> callback) {
+        RearDisplayStateRequestCallbackAdapter(@NonNull Consumer<Integer> callback) {
             mRearDisplaySessionCallback = callback;
         }
 
         @Override
         public void onRequestActivated(@NonNull DeviceStateRequest request) {
             synchronized (mLock) {
-                if (request.equals(mDeviceStateRequest)) {
+                if (request.equals(mRearDisplayStateRequest)) {
                     mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_ACTIVE;
                     mRearDisplaySessionCallback.accept(mRearDisplaySessionStatus);
-                    updateStatusConsumers(getCurrentStatus());
+                    updateRearDisplayStatusListeners(getCurrentRearDisplayModeStatus());
                 }
             }
         }
@@ -243,12 +535,12 @@
         @Override
         public void onRequestCanceled(DeviceStateRequest request) {
             synchronized (mLock) {
-                if (request.equals(mDeviceStateRequest)) {
-                    mDeviceStateRequest = null;
+                if (request.equals(mRearDisplayStateRequest)) {
+                    mRearDisplayStateRequest = null;
                 }
                 mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_INACTIVE;
                 mRearDisplaySessionCallback.accept(mRearDisplaySessionStatus);
-                updateStatusConsumers(getCurrentStatus());
+                updateRearDisplayStatusListeners(getCurrentRearDisplayModeStatus());
             }
         }
     }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
index 67963a3..d94e8e4 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -154,7 +154,7 @@
                 activityOptions);
 
         // Set adjacent to each other so that the containers below will be invisible.
-        setAdjacentTaskFragments(wct, launchingFragmentToken, secondaryFragmentToken, rule);
+        setAdjacentTaskFragmentsWithRule(wct, launchingFragmentToken, secondaryFragmentToken, rule);
         setCompanionTaskFragment(wct, launchingFragmentToken, secondaryFragmentToken, rule,
                 false /* isStacked */);
     }
@@ -167,7 +167,7 @@
     void expandTaskFragment(@NonNull WindowContainerTransaction wct,
             @NonNull IBinder fragmentToken) {
         resizeTaskFragment(wct, fragmentToken, new Rect());
-        setAdjacentTaskFragments(wct, fragmentToken, null /* secondary */, null /* splitRule */);
+        clearAdjacentTaskFragments(wct, fragmentToken);
         updateWindowingMode(wct, fragmentToken, WINDOWING_MODE_UNDEFINED);
         updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
     }
@@ -238,26 +238,37 @@
         wct.reparentActivityToTaskFragment(fragmentToken, reparentActivityToken);
     }
 
-    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
-            @NonNull IBinder primary, @Nullable IBinder secondary, @Nullable SplitRule splitRule) {
-        if (secondary == null) {
-            wct.clearAdjacentTaskFragments(primary);
-            return;
-        }
-
+    /**
+     * Sets the two given TaskFragments as adjacent to each other with respecting the given
+     * {@link SplitRule} for {@link WindowContainerTransaction.TaskFragmentAdjacentParams}.
+     */
+    void setAdjacentTaskFragmentsWithRule(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder primary, @NonNull IBinder secondary, @NonNull SplitRule splitRule) {
         WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams = null;
         final boolean finishSecondaryWithPrimary =
-                splitRule != null && SplitContainer.shouldFinishSecondaryWithPrimary(splitRule);
+                SplitContainer.shouldFinishSecondaryWithPrimary(splitRule);
         final boolean finishPrimaryWithSecondary =
-                splitRule != null && SplitContainer.shouldFinishPrimaryWithSecondary(splitRule);
+                SplitContainer.shouldFinishPrimaryWithSecondary(splitRule);
         if (finishSecondaryWithPrimary || finishPrimaryWithSecondary) {
             adjacentParams = new WindowContainerTransaction.TaskFragmentAdjacentParams();
             adjacentParams.setShouldDelayPrimaryLastActivityRemoval(finishSecondaryWithPrimary);
             adjacentParams.setShouldDelaySecondaryLastActivityRemoval(finishPrimaryWithSecondary);
         }
+        setAdjacentTaskFragments(wct, primary, secondary, adjacentParams);
+    }
+
+    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder primary, @NonNull IBinder secondary,
+            @Nullable WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams) {
         wct.setAdjacentTaskFragments(primary, secondary, adjacentParams);
     }
 
+    void clearAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder fragmentToken) {
+        // Clear primary will also clear secondary.
+        wct.clearAdjacentTaskFragments(fragmentToken);
+    }
+
     void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct,
             @NonNull IBinder primary, @NonNull IBinder secondary, @NonNull SplitRule splitRule,
             boolean isStacked) {
@@ -268,7 +279,7 @@
         } else {
             finishPrimaryWithSecondary = shouldFinishPrimaryWithSecondary(splitRule);
         }
-        wct.setCompanionTaskFragment(primary, finishPrimaryWithSecondary ? secondary : null);
+        setCompanionTaskFragment(wct, primary, finishPrimaryWithSecondary ? secondary : null);
 
         final boolean finishSecondaryWithPrimary;
         if (isStacked) {
@@ -277,7 +288,12 @@
         } else {
             finishSecondaryWithPrimary = shouldFinishSecondaryWithPrimary(splitRule);
         }
-        wct.setCompanionTaskFragment(secondary, finishSecondaryWithPrimary ? primary : null);
+        setCompanionTaskFragment(wct, secondary, finishSecondaryWithPrimary ? primary : null);
+    }
+
+    void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder primary,
+            @Nullable IBinder secondary) {
+        wct.setCompanionTaskFragment(primary, secondary);
     }
 
     void resizeTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder fragmentToken,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java
index 77284c41..18497ad 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java
@@ -17,12 +17,15 @@
 package androidx.window.extensions.embedding;
 
 import android.app.Activity;
-import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.IBinder;
 import android.util.Pair;
 import android.util.Size;
+import android.window.TaskFragmentParentInfo;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.NonNull;
+import androidx.window.extensions.core.util.function.Function;
 
 /**
  * Client-side descriptor of a split that holds two containers.
@@ -34,8 +37,14 @@
     private final TaskFragmentContainer mSecondaryContainer;
     @NonNull
     private final SplitRule mSplitRule;
+    /** @see SplitContainer#getCurrentSplitAttributes() */
     @NonNull
-    private SplitAttributes mSplitAttributes;
+    private SplitAttributes mCurrentSplitAttributes;
+    /** @see SplitContainer#getDefaultSplitAttributes() */
+    @NonNull
+    private SplitAttributes mDefaultSplitAttributes;
+    @NonNull
+    private final IBinder mToken;
 
     SplitContainer(@NonNull TaskFragmentContainer primaryContainer,
             @NonNull Activity primaryActivity,
@@ -45,7 +54,9 @@
         mPrimaryContainer = primaryContainer;
         mSecondaryContainer = secondaryContainer;
         mSplitRule = splitRule;
-        mSplitAttributes = splitAttributes;
+        mDefaultSplitAttributes = splitRule.getDefaultSplitAttributes();
+        mCurrentSplitAttributes = splitAttributes;
+        mToken = new Binder("SplitContainer");
 
         if (shouldFinishPrimaryWithSecondary(splitRule)) {
             if (mPrimaryContainer.getRunningActivityCount() == 1
@@ -78,19 +89,60 @@
         return mSplitRule;
     }
 
+    /**
+     * Returns the current {@link SplitAttributes} this {@code SplitContainer} is showing.
+     * <p>
+     * If the {@code SplitAttributes} calculator function is not set by
+     * {@link SplitController#setSplitAttributesCalculator(Function)}, the current
+     * {@code SplitAttributes} is either to expand the containers if the size constraints of
+     * {@link #getSplitRule()} are not satisfied,
+     * or the {@link #getDefaultSplitAttributes()}, otherwise.
+     * </p><p>
+     * If the {@code SplitAttributes} calculator function is set, the current
+     * {@code SplitAttributes} will be customized by the function, which can be any
+     * {@code SplitAttributes}.
+     * </p>
+     *
+     * @see SplitAttributes.SplitType.ExpandContainersSplitType
+     */
     @NonNull
-    SplitAttributes getSplitAttributes() {
-        return mSplitAttributes;
+    SplitAttributes getCurrentSplitAttributes() {
+        return mCurrentSplitAttributes;
+    }
+
+    /**
+     * Returns the default {@link SplitAttributes} when the parent task container bounds satisfy
+     * {@link #getSplitRule()} constraints.
+     * <p>
+     * The value is usually from {@link SplitRule#getDefaultSplitAttributes} unless it is overridden
+     * by {@link SplitController#updateSplitAttributes(IBinder, SplitAttributes)}.
+     */
+    @NonNull
+    SplitAttributes getDefaultSplitAttributes() {
+        return mDefaultSplitAttributes;
+    }
+
+    @NonNull
+    IBinder getToken() {
+        return mToken;
     }
 
     /**
      * Updates the {@link SplitAttributes} to this container.
      * It is usually used when there's a folding state change or
-     * {@link SplitController#onTaskFragmentParentInfoChanged(WindowContainerTransaction, int,
-     * Configuration)}.
+     * {@link SplitController#onTaskFragmentParentInfoChanged(WindowContainerTransaction,
+     * int, TaskFragmentParentInfo)}.
      */
-    void setSplitAttributes(@NonNull SplitAttributes splitAttributes) {
-        mSplitAttributes = splitAttributes;
+    void updateCurrentSplitAttributes(@NonNull SplitAttributes splitAttributes) {
+        mCurrentSplitAttributes = splitAttributes;
+    }
+
+    /**
+     * Overrides the default {@link SplitAttributes} to this container, which may be different
+     * from {@link SplitRule#getDefaultSplitAttributes}.
+     */
+    void updateDefaultSplitAttributes(@NonNull SplitAttributes splitAttributes) {
+        mDefaultSplitAttributes = splitAttributes;
     }
 
     @NonNull
@@ -112,7 +164,7 @@
     @NonNull
     SplitInfo toSplitInfo() {
         return new SplitInfo(mPrimaryContainer.toActivityStack(),
-                mSecondaryContainer.toActivityStack(), mSplitAttributes);
+                mSecondaryContainer.toActivityStack(), mCurrentSplitAttributes, mToken);
     }
 
     static boolean shouldFinishPrimaryWithSecondary(@NonNull SplitRule splitRule) {
@@ -171,9 +223,10 @@
     public String toString() {
         return "SplitContainer{"
                 + " primaryContainer=" + mPrimaryContainer
-                + " secondaryContainer=" + mSecondaryContainer
-                + " splitRule=" + mSplitRule
-                + " splitAttributes" + mSplitAttributes
+                + ", secondaryContainer=" + mSecondaryContainer
+                + ", splitRule=" + mSplitRule
+                + ", currentSplitAttributes" + mCurrentSplitAttributes
+                + ", defaultSplitAttributes" + mDefaultSplitAttributes
                 + "}";
     }
 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 57ba6bb..2c1ddf7 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -87,6 +87,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -230,6 +231,14 @@
         return mSplitAttributesCalculator;
     }
 
+    @Override
+    @NonNull
+    public ActivityOptions setLaunchingActivityStack(@NonNull ActivityOptions options,
+            @NonNull IBinder token) {
+        options.setLaunchTaskFragmentToken(token);
+        return options;
+    }
+
     @NonNull
     @GuardedBy("mLock")
     @VisibleForTesting
@@ -271,6 +280,98 @@
         }
     }
 
+    @Override
+    public void finishActivityStacks(@NonNull Set<IBinder> activityStackTokens) {
+        if (activityStackTokens.isEmpty()) {
+            return;
+        }
+        synchronized (mLock) {
+            // Translate ActivityStack to TaskFragmentContainer.
+            final List<TaskFragmentContainer> pendingFinishingContainers =
+                    activityStackTokens.stream()
+                    .map(token -> {
+                        synchronized (mLock) {
+                            return getContainer(token);
+                        }
+                    }).filter(Objects::nonNull)
+                    .toList();
+
+            if (pendingFinishingContainers.isEmpty()) {
+                return;
+            }
+            // Start transaction with close transit type.
+            final TransactionRecord transactionRecord = mTransactionManager.startNewTransaction();
+            transactionRecord.setOriginType(TASK_FRAGMENT_TRANSIT_CLOSE);
+            final WindowContainerTransaction wct = transactionRecord.getTransaction();
+
+            forAllTaskContainers(taskContainer -> {
+                synchronized (mLock) {
+                    final List<TaskFragmentContainer> containers = taskContainer.mContainers;
+                    // Clean up the TaskFragmentContainers by the z-order from the lowest.
+                    for (int i = 0; i < containers.size() - 1; i++) {
+                        final TaskFragmentContainer container = containers.get(i);
+                        if (pendingFinishingContainers.contains(container)) {
+                            // Don't update records here to prevent double invocation.
+                            container.finish(false /* shouldFinishDependant */, mPresenter,
+                                    wct, this, false /* shouldRemoveRecord */);
+                        }
+                    }
+                    // Remove container records.
+                    removeContainers(taskContainer, pendingFinishingContainers);
+                    // Update the change to the client side.
+                    updateContainersInTaskIfVisible(wct, taskContainer.getTaskId());
+                }
+            });
+
+            // Apply the transaction.
+            transactionRecord.apply(false /* shouldApplyIndependently */);
+        }
+    }
+
+    @Override
+    public void invalidateTopVisibleSplitAttributes() {
+        synchronized (mLock) {
+            WindowContainerTransaction wct = mTransactionManager.startNewTransaction()
+                    .getTransaction();
+            forAllTaskContainers(taskContainer -> {
+                synchronized (mLock) {
+                    updateContainersInTaskIfVisible(wct, taskContainer.getTaskId());
+                }
+            });
+            mTransactionManager.getCurrentTransactionRecord()
+                    .apply(false /* shouldApplyIndependently */);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void forAllTaskContainers(@NonNull Consumer<TaskContainer> callback) {
+        for (int i = mTaskContainers.size() - 1; i >= 0; --i) {
+            callback.accept(mTaskContainers.valueAt(i));
+        }
+    }
+
+    @Override
+    public void updateSplitAttributes(@NonNull IBinder splitInfoToken,
+            @NonNull SplitAttributes splitAttributes) {
+        synchronized (mLock) {
+            final SplitContainer splitContainer = getSplitContainer(splitInfoToken);
+            if (splitContainer == null) {
+                Log.w(TAG, "Cannot find SplitContainer for token:" + splitInfoToken);
+                return;
+            }
+            WindowContainerTransaction wct = mTransactionManager.startNewTransaction()
+                    .getTransaction();
+            if (updateSplitContainerIfNeeded(splitContainer, wct, splitAttributes)) {
+                splitContainer.updateDefaultSplitAttributes(splitAttributes);
+                mTransactionManager.getCurrentTransactionRecord()
+                        .apply(false /* shouldApplyIndependently */);
+            } else {
+                // Abort if the SplitContainer wasn't updated.
+                mTransactionManager.getCurrentTransactionRecord().abort();
+            }
+        }
+    }
+
     /**
      * Called when the transaction is ready so that the organizer can update the TaskFragments based
      * on the changes in transaction.
@@ -424,6 +525,9 @@
             // All overrides will be cleanup.
             container.setLastRequestedBounds(null /* bounds */);
             container.setLastRequestedWindowingMode(WINDOWING_MODE_UNDEFINED);
+            container.clearLastAdjacentTaskFragment();
+            container.setLastCompanionTaskFragment(null /* fragmentToken */);
+            container.setLastRequestAnimationParams(TaskFragmentAnimationParams.DEFAULT);
             cleanupForEnterPip(wct, container);
         } else if (wasInPip) {
             // Exit PIP.
@@ -640,35 +744,6 @@
         }
     }
 
-    /** Returns whether the given {@link TaskContainer} may show in split. */
-    // Suppress GuardedBy warning because lint asks to mark this method as
-    // @GuardedBy(mPresenter.mController.mLock), which is mLock itself
-    @SuppressWarnings("GuardedBy")
-    @GuardedBy("mLock")
-    private boolean mayShowSplit(@NonNull TaskContainer taskContainer) {
-        // No split inside PIP.
-        if (taskContainer.isInPictureInPicture()) {
-            return false;
-        }
-        // Always assume the TaskContainer if SplitAttributesCalculator is set
-        if (mSplitAttributesCalculator != null) {
-            return true;
-        }
-        // Check if the parent container bounds can support any split rule.
-        for (EmbeddingRule rule : mSplitRules) {
-            if (!(rule instanceof SplitRule)) {
-                continue;
-            }
-            final SplitRule splitRule = (SplitRule) rule;
-            final SplitAttributes splitAttributes = mPresenter.computeSplitAttributes(
-                    taskContainer.getTaskProperties(), splitRule, null /* minDimensionsPair */);
-            if (shouldShowSplit(splitAttributes)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     @VisibleForTesting
     @GuardedBy("mLock")
     void onActivityCreated(@NonNull WindowContainerTransaction wct,
@@ -1352,20 +1427,33 @@
      * Removes the container from bookkeeping records.
      */
     void removeContainer(@NonNull TaskFragmentContainer container) {
+        removeContainers(container.getTaskContainer(), Collections.singletonList(container));
+    }
+
+    /**
+     * Removes containers from bookkeeping records.
+     */
+    void removeContainers(@NonNull TaskContainer taskContainer,
+            @NonNull List<TaskFragmentContainer> containers) {
         // Remove all split containers that included this one
-        final TaskContainer taskContainer = container.getTaskContainer();
-        taskContainer.mContainers.remove(container);
+        taskContainer.mContainers.removeAll(containers);
         // Marked as a pending removal which will be removed after it is actually removed on the
         // server side (#onTaskFragmentVanished).
         // In this way, we can keep track of the Task bounds until we no longer have any
         // TaskFragment there.
-        taskContainer.mFinishedContainer.add(container.getTaskFragmentToken());
+        taskContainer.mFinishedContainer.addAll(containers.stream().map(
+                TaskFragmentContainer::getTaskFragmentToken).toList());
 
         // Cleanup any split references.
         final List<SplitContainer> containersToRemove = new ArrayList<>();
         for (SplitContainer splitContainer : taskContainer.mSplitContainers) {
-            if (container.equals(splitContainer.getSecondaryContainer())
-                    || container.equals(splitContainer.getPrimaryContainer())) {
+            if (containersToRemove.contains(splitContainer)) {
+                // Don't need to check because it has been in the remove list.
+                continue;
+            }
+            if (containers.stream().anyMatch(container ->
+                    splitContainer.getPrimaryContainer().equals(container)
+                            || splitContainer.getSecondaryContainer().equals(container))) {
                 containersToRemove.add(splitContainer);
             }
         }
@@ -1373,7 +1461,7 @@
 
         // Cleanup any dependent references.
         for (TaskFragmentContainer containerToUpdate : taskContainer.mContainers) {
-            containerToUpdate.removeContainerToFinishOnExit(container);
+            containerToUpdate.removeContainersToFinishOnExit(containers);
         }
     }
 
@@ -1453,26 +1541,53 @@
         if (splitContainer == null) {
             return;
         }
+
+        updateSplitContainerIfNeeded(splitContainer, wct, null /* splitAttributes */);
+    }
+
+    /**
+     * Updates {@link SplitContainer} with the given {@link SplitAttributes} if the
+     * {@link SplitContainer} is the top most and not finished. If passed {@link SplitAttributes}
+     * are {@code null}, the {@link SplitAttributes} will be calculated with
+     * {@link SplitPresenter#computeSplitAttributes(TaskContainer.TaskProperties, SplitRule, Pair)}.
+     *
+     * @param splitContainer The {@link SplitContainer} to update
+     * @param splitAttributes Update with this {@code splitAttributes} if it is not {@code null}.
+     *                        Otherwise, use the value calculated by
+     *                        {@link SplitPresenter#computeSplitAttributes(
+     *                        TaskContainer.TaskProperties, SplitRule, Pair)}
+     *
+     * @return {@code true} if the update succeed. Otherwise, returns {@code false}.
+     */
+    @GuardedBy("mLock")
+    private boolean updateSplitContainerIfNeeded(@NonNull SplitContainer splitContainer,
+            @NonNull WindowContainerTransaction wct, @Nullable SplitAttributes splitAttributes) {
         if (!isTopMostSplit(splitContainer)) {
             // Skip position update - it isn't the topmost split.
-            return;
+            return false;
         }
         if (splitContainer.getPrimaryContainer().isFinished()
                 || splitContainer.getSecondaryContainer().isFinished()) {
             // Skip position update - one or both containers are finished.
-            return;
+            return false;
         }
-        final TaskContainer taskContainer = splitContainer.getTaskContainer();
-        final SplitRule splitRule = splitContainer.getSplitRule();
-        final Pair<Size, Size> minDimensionsPair = splitContainer.getMinDimensionsPair();
-        final SplitAttributes splitAttributes = mPresenter.computeSplitAttributes(
-                taskContainer.getTaskProperties(), splitRule, minDimensionsPair);
-        splitContainer.setSplitAttributes(splitAttributes);
+        if (splitAttributes == null) {
+            final TaskContainer.TaskProperties taskProperties = splitContainer.getTaskContainer()
+                    .getTaskProperties();
+            final SplitRule splitRule = splitContainer.getSplitRule();
+            final SplitAttributes defaultSplitAttributes = splitContainer
+                    .getDefaultSplitAttributes();
+            final Pair<Size, Size> minDimensionsPair = splitContainer.getMinDimensionsPair();
+            splitAttributes = mPresenter.computeSplitAttributes(taskProperties, splitRule,
+                    defaultSplitAttributes, minDimensionsPair);
+        }
+        splitContainer.updateCurrentSplitAttributes(splitAttributes);
         if (dismissPlaceholderIfNecessary(wct, splitContainer)) {
             // Placeholder was finished, the positions will be updated when its container is emptied
-            return;
+            return true;
         }
-        mPresenter.updateSplitContainer(splitContainer, container, wct);
+        mPresenter.updateSplitContainer(splitContainer, wct);
+        return true;
     }
 
     /** Whether the given split is the topmost split in the Task. */
@@ -1568,7 +1683,7 @@
         final Pair<Size, Size> minDimensionsPair = getActivityIntentMinDimensionsPair(activity,
                 placeholderRule.getPlaceholderIntent());
         final SplitAttributes splitAttributes = mPresenter.computeSplitAttributes(taskProperties,
-                placeholderRule, minDimensionsPair);
+                placeholderRule, placeholderRule.getDefaultSplitAttributes(), minDimensionsPair);
         if (!SplitPresenter.shouldShowSplit(splitAttributes)) {
             return false;
         }
@@ -1647,7 +1762,7 @@
             // The placeholder should remain after it was first shown.
             return false;
         }
-        final SplitAttributes splitAttributes = splitContainer.getSplitAttributes();
+        final SplitAttributes splitAttributes = splitContainer.getCurrentSplitAttributes();
         if (SplitPresenter.shouldShowSplit(splitAttributes)) {
             return false;
         }
@@ -1791,6 +1906,20 @@
 
     @Nullable
     @GuardedBy("mLock")
+    SplitContainer getSplitContainer(@NonNull IBinder token) {
+        for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+            final List<SplitContainer> containers = mTaskContainers.valueAt(i).mSplitContainers;
+            for (SplitContainer container : containers) {
+                if (container.getToken().equals(token)) {
+                    return container;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Nullable
+    @GuardedBy("mLock")
     TaskContainer getTaskContainer(int taskId) {
         return mTaskContainers.get(taskId);
     }
@@ -2064,6 +2193,7 @@
                     transactionRecord.apply(false /* shouldApplyIndependently */);
                     // Amend the request to let the WM know that the activity should be placed in
                     // the dedicated container.
+                    // TODO(b/229680885): skip override launching TaskFragment token by split-rule
                     options.putBinder(ActivityOptions.KEY_LAUNCH_TASK_FRAGMENT_TOKEN,
                             launchedInTaskFragment.getTaskFragmentToken());
                     mCurrentIntent = intent;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 2b93682..0408511 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -179,7 +179,7 @@
         final Pair<Size, Size> minDimensionsPair = getActivityIntentMinDimensionsPair(
                 primaryActivity, secondaryIntent);
         final SplitAttributes splitAttributes = computeSplitAttributes(taskProperties, rule,
-                minDimensionsPair);
+                rule.getDefaultSplitAttributes(), minDimensionsPair);
         final Rect primaryRelBounds = getRelBoundsForPosition(POSITION_START, taskProperties,
                 splitAttributes);
         final TaskFragmentContainer primaryContainer = prepareContainerForActivity(wct,
@@ -225,7 +225,7 @@
         final Pair<Size, Size> minDimensionsPair = getActivitiesMinDimensionsPair(primaryActivity,
                 secondaryActivity);
         final SplitAttributes splitAttributes = computeSplitAttributes(taskProperties, rule,
-                minDimensionsPair);
+                rule.getDefaultSplitAttributes(), minDimensionsPair);
         final Rect primaryRelBounds = getRelBoundsForPosition(POSITION_START, taskProperties,
                 splitAttributes);
         final TaskFragmentContainer primaryContainer = prepareContainerForActivity(wct,
@@ -334,11 +334,9 @@
     /**
      * Updates the positions of containers in an existing split.
      * @param splitContainer The split container to be updated.
-     * @param updatedContainer The task fragment that was updated and caused this split update.
      * @param wct WindowContainerTransaction that this update should be performed with.
      */
     void updateSplitContainer(@NonNull SplitContainer splitContainer,
-            @NonNull TaskFragmentContainer updatedContainer,
             @NonNull WindowContainerTransaction wct) {
         // Getting the parent configuration using the updated container - it will have the recent
         // value.
@@ -348,8 +346,9 @@
         if (activity == null) {
             return;
         }
-        final TaskProperties taskProperties = getTaskProperties(updatedContainer);
-        final SplitAttributes splitAttributes = splitContainer.getSplitAttributes();
+        final TaskContainer taskContainer = splitContainer.getTaskContainer();
+        final TaskProperties taskProperties = taskContainer.getTaskProperties();
+        final SplitAttributes splitAttributes = splitContainer.getCurrentSplitAttributes();
         final Rect primaryRelBounds = getRelBoundsForPosition(POSITION_START, taskProperties,
                 splitAttributes);
         final Rect secondaryRelBounds = getRelBoundsForPosition(POSITION_END, taskProperties,
@@ -370,7 +369,6 @@
             // When placeholder is shown in split, we should keep the focus on the primary.
             wct.requestFocusOnTaskFragment(primaryContainer.getTaskFragmentToken());
         }
-        final TaskContainer taskContainer = updatedContainer.getTaskContainer();
         final int windowingMode = taskContainer.getWindowingModeForSplitTaskFragment(
                 primaryRelBounds);
         updateTaskFragmentWindowingModeIfRegistered(wct, primaryContainer, windowingMode);
@@ -387,10 +385,9 @@
         // secondaryContainer could not be finished.
         boolean isStacked = !shouldShowSplit(splitAttributes);
         if (isStacked) {
-            setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
-                    null /* secondary */, null /* splitRule */);
+            clearAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken());
         } else {
-            setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(),
+            setAdjacentTaskFragmentsWithRule(wct, primaryContainer.getTaskFragmentToken(),
                     secondaryContainer.getTaskFragmentToken(), splitRule);
         }
         setCompanionTaskFragment(wct, primaryContainer.getTaskFragmentToken(),
@@ -427,7 +424,7 @@
                 fragmentOptions.getFragmentToken());
         if (container == null) {
             throw new IllegalStateException(
-                    "Creating a task fragment that is not registered with controller.");
+                    "Creating a TaskFragment that is not registered with controller.");
         }
 
         container.setLastRequestedBounds(fragmentOptions.getInitialRelativeBounds());
@@ -441,7 +438,7 @@
         TaskFragmentContainer container = mController.getContainer(fragmentToken);
         if (container == null) {
             throw new IllegalStateException(
-                    "Resizing a task fragment that is not registered with controller.");
+                    "Resizing a TaskFragment that is not registered with controller.");
         }
 
         if (container.areLastRequestedBoundsEqual(relBounds)) {
@@ -458,7 +455,7 @@
             @NonNull IBinder fragmentToken, @WindowingMode int windowingMode) {
         final TaskFragmentContainer container = mController.getContainer(fragmentToken);
         if (container == null) {
-            throw new IllegalStateException("Setting windowing mode for a task fragment that is"
+            throw new IllegalStateException("Setting windowing mode for a TaskFragment that is"
                     + " not registered with controller.");
         }
 
@@ -476,7 +473,7 @@
             @NonNull IBinder fragmentToken, @NonNull TaskFragmentAnimationParams animationParams) {
         final TaskFragmentContainer container = mController.getContainer(fragmentToken);
         if (container == null) {
-            throw new IllegalStateException("Setting animation params for a task fragment that is"
+            throw new IllegalStateException("Setting animation params for a TaskFragment that is"
                     + " not registered with controller.");
         }
 
@@ -489,6 +486,64 @@
         super.updateAnimationParams(wct, fragmentToken, animationParams);
     }
 
+    @Override
+    void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder primary, @NonNull IBinder secondary,
+            @Nullable WindowContainerTransaction.TaskFragmentAdjacentParams adjacentParams) {
+        final TaskFragmentContainer primaryContainer = mController.getContainer(primary);
+        final TaskFragmentContainer secondaryContainer = mController.getContainer(secondary);
+        if (primaryContainer == null || secondaryContainer == null) {
+            throw new IllegalStateException("setAdjacentTaskFragments on TaskFragment that is"
+                    + " not registered with controller.");
+        }
+
+        if (primaryContainer.isLastAdjacentTaskFragmentEqual(secondary, adjacentParams)
+                && secondaryContainer.isLastAdjacentTaskFragmentEqual(primary, adjacentParams)) {
+            // Return early if the same adjacent TaskFragments were already requested
+            return;
+        }
+
+        primaryContainer.setLastAdjacentTaskFragment(secondary, adjacentParams);
+        secondaryContainer.setLastAdjacentTaskFragment(primary, adjacentParams);
+        super.setAdjacentTaskFragments(wct, primary, secondary, adjacentParams);
+    }
+
+    @Override
+    void clearAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
+            @NonNull IBinder fragmentToken) {
+        final TaskFragmentContainer container = mController.getContainer(fragmentToken);
+        if (container == null) {
+            throw new IllegalStateException("clearAdjacentTaskFragments on TaskFragment that is"
+                    + " not registered with controller.");
+        }
+
+        if (container.isLastAdjacentTaskFragmentEqual(null /* fragmentToken*/, null /* params */)) {
+            // Return early if no adjacent TaskFragment was yet requested
+            return;
+        }
+
+        container.clearLastAdjacentTaskFragment();
+        super.clearAdjacentTaskFragments(wct, fragmentToken);
+    }
+
+    @Override
+    void setCompanionTaskFragment(@NonNull WindowContainerTransaction wct, @NonNull IBinder primary,
+            @Nullable IBinder secondary) {
+        final TaskFragmentContainer container = mController.getContainer(primary);
+        if (container == null) {
+            throw new IllegalStateException("setCompanionTaskFragment on TaskFragment that is"
+                    + " not registered with controller.");
+        }
+
+        if (container.isLastCompanionTaskFragmentEqual(secondary)) {
+            // Return early if the same companion TaskFragment was already requested
+            return;
+        }
+
+        container.setLastCompanionTaskFragment(secondary);
+        super.setCompanionTaskFragment(wct, primary, secondary);
+    }
+
     /**
      * Expands the split container if the current split bounds are smaller than the Activity or
      * Intent that is added to the container.
@@ -515,9 +570,9 @@
         // Expand the splitContainer if minimum dimensions are not satisfied.
         final TaskContainer taskContainer = splitContainer.getTaskContainer();
         final SplitAttributes splitAttributes = sanitizeSplitAttributes(
-                taskContainer.getTaskProperties(), splitContainer.getSplitAttributes(),
+                taskContainer.getTaskProperties(), splitContainer.getCurrentSplitAttributes(),
                 minDimensionsPair);
-        splitContainer.setSplitAttributes(splitAttributes);
+        splitContainer.updateCurrentSplitAttributes(splitAttributes);
         if (!shouldShowSplit(splitAttributes)) {
             // If the client side hasn't received TaskFragmentInfo yet, we can't change TaskFragment
             // bounds. Return failure to create a new SplitContainer which fills task bounds.
@@ -540,7 +595,7 @@
     }
 
     static boolean shouldShowSplit(@NonNull SplitContainer splitContainer) {
-        return shouldShowSplit(splitContainer.getSplitAttributes());
+        return shouldShowSplit(splitContainer.getCurrentSplitAttributes());
     }
 
     static boolean shouldShowSplit(@NonNull SplitAttributes splitAttributes) {
@@ -549,12 +604,12 @@
 
     @NonNull
     SplitAttributes computeSplitAttributes(@NonNull TaskProperties taskProperties,
-            @NonNull SplitRule rule, @Nullable Pair<Size, Size> minDimensionsPair) {
+            @NonNull SplitRule rule, @NonNull SplitAttributes defaultSplitAttributes,
+            @Nullable Pair<Size, Size> minDimensionsPair) {
         final Configuration taskConfiguration = taskProperties.getConfiguration();
         final WindowMetrics taskWindowMetrics = getTaskWindowMetrics(taskConfiguration);
         final Function<SplitAttributesCalculatorParams, SplitAttributes> calculator =
                 mController.getSplitAttributesCalculator();
-        final SplitAttributes defaultSplitAttributes = rule.getDefaultSplitAttributes();
         final boolean areDefaultConstraintsSatisfied = rule.checkParentMetrics(taskWindowMetrics);
         if (calculator == null) {
             if (!areDefaultConstraintsSatisfied) {
@@ -957,11 +1012,6 @@
     }
 
     @NonNull
-    static TaskProperties getTaskProperties(@NonNull TaskFragmentContainer container) {
-        return container.getTaskContainer().getTaskProperties();
-    }
-
-    @NonNull
     TaskProperties getTaskProperties(@NonNull Activity activity) {
         final TaskContainer taskContainer = mController.getTaskContainer(
                 mController.getTaskId(activity));
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index f41295b..4b15bb1 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -108,12 +108,6 @@
     }
 
     @NonNull
-    Configuration getConfiguration() {
-        // Make a copy in case the config is updated unexpectedly.
-        return new Configuration(mConfiguration);
-    }
-
-    @NonNull
     TaskProperties getTaskProperties() {
         return new TaskProperties(mDisplayId, mConfiguration);
     }
@@ -157,7 +151,7 @@
 
     @WindowingMode
     private int getWindowingMode() {
-        return getConfiguration().windowConfiguration.getWindowingMode();
+        return mConfiguration.windowConfiguration.getWindowingMode();
     }
 
     /** Whether there is any {@link TaskFragmentContainer} below this Task. */
@@ -220,10 +214,7 @@
         }
     }
 
-    /**
-     * A wrapper class which contains the display ID and {@link Configuration} of a
-     * {@link TaskContainer}
-     */
+    /** A wrapper class which contains the information of {@link TaskContainer} */
     static final class TaskProperties {
         private final int mDisplayId;
         @NonNull
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 861cb49..b38f824 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -37,8 +37,10 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Client-side container for a stack of activities. Corresponds to an instance of TaskFragment
@@ -116,6 +118,27 @@
     private TaskFragmentAnimationParams mLastAnimationParams = TaskFragmentAnimationParams.DEFAULT;
 
     /**
+     * TaskFragment token that was requested last via
+     * {@link android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS}.
+     */
+    @Nullable
+    private IBinder mLastAdjacentTaskFragment;
+
+    /**
+     * {@link WindowContainerTransaction.TaskFragmentAdjacentParams} token that was requested last
+     * via {@link android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS}.
+     */
+    @Nullable
+    private WindowContainerTransaction.TaskFragmentAdjacentParams mLastAdjacentParams;
+
+    /**
+     * TaskFragment token that was requested last via
+     * {@link android.window.TaskFragmentOperation#OP_TYPE_SET_COMPANION_TASK_FRAGMENT}.
+     */
+    @Nullable
+    private IBinder mLastCompanionTaskFragment;
+
+    /**
      * When the TaskFragment has appeared in server, but is empty, we should remove the TaskFragment
      * if it is still empty after the timeout.
      */
@@ -243,7 +266,7 @@
 
     @NonNull
     ActivityStack toActivityStack() {
-        return new ActivityStack(collectNonFinishingActivities(), isEmpty());
+        return new ActivityStack(collectNonFinishingActivities(), isEmpty(), mToken);
     }
 
     /** Adds the activity that will be reparented to this container. */
@@ -436,10 +459,17 @@
      * Removes a container that should be finished when this container is finished.
      */
     void removeContainerToFinishOnExit(@NonNull TaskFragmentContainer containerToRemove) {
+        removeContainersToFinishOnExit(Collections.singletonList(containerToRemove));
+    }
+
+    /**
+     * Removes container list that should be finished when this container is finished.
+     */
+    void removeContainersToFinishOnExit(@NonNull List<TaskFragmentContainer> containersToRemove) {
         if (mIsFinished) {
             return;
         }
-        mContainersToFinishOnExit.remove(containerToRemove);
+        mContainersToFinishOnExit.removeAll(containersToRemove);
     }
 
     /**
@@ -478,6 +508,16 @@
     @GuardedBy("mController.mLock")
     void finish(boolean shouldFinishDependent, @NonNull SplitPresenter presenter,
             @NonNull WindowContainerTransaction wct, @NonNull SplitController controller) {
+        finish(shouldFinishDependent, presenter, wct, controller, true /* shouldRemoveRecord */);
+    }
+
+    /**
+     * Removes all activities that belong to this process and finishes other containers/activities
+     * configured to finish together.
+     */
+    void finish(boolean shouldFinishDependent, @NonNull SplitPresenter presenter,
+            @NonNull WindowContainerTransaction wct, @NonNull SplitController controller,
+            boolean shouldRemoveRecord) {
         if (!mIsFinished) {
             mIsFinished = true;
             if (mAppearEmptyTimeout != null) {
@@ -494,8 +534,10 @@
 
         // Cleanup the visuals
         presenter.deleteTaskFragment(wct, getTaskFragmentToken());
-        // Cleanup the records
-        controller.removeContainer(this);
+        if (shouldRemoveRecord) {
+            // Cleanup the records
+            controller.removeContainer(this);
+        }
         // Clean up task fragment information
         mInfo = null;
     }
@@ -571,6 +613,7 @@
     /**
      * Checks if last requested bounds are equal to the provided value.
      * The requested bounds are relative bounds in parent coordinate.
+     * @see WindowContainerTransaction#setRelativeBounds
      */
     boolean areLastRequestedBoundsEqual(@Nullable Rect relBounds) {
         return (relBounds == null && mLastRequestedBounds.isEmpty())
@@ -580,6 +623,7 @@
     /**
      * Updates the last requested bounds.
      * The requested bounds are relative bounds in parent coordinate.
+     * @see WindowContainerTransaction#setRelativeBounds
      */
     void setLastRequestedBounds(@Nullable Rect relBounds) {
         if (relBounds == null) {
@@ -589,13 +633,9 @@
         }
     }
 
-    @NonNull
-    Rect getLastRequestedBounds() {
-        return mLastRequestedBounds;
-    }
-
     /**
      * Checks if last requested windowing mode is equal to the provided value.
+     * @see WindowContainerTransaction#setWindowingMode
      */
     boolean isLastRequestedWindowingModeEqual(@WindowingMode int windowingMode) {
         return mLastRequestedWindowingMode == windowingMode;
@@ -603,6 +643,7 @@
 
     /**
      * Updates the last requested windowing mode.
+     * @see WindowContainerTransaction#setWindowingMode
      */
     void setLastRequestedWindowingMode(@WindowingMode int windowingModes) {
         mLastRequestedWindowingMode = windowingModes;
@@ -610,6 +651,7 @@
 
     /**
      * Checks if last requested {@link TaskFragmentAnimationParams} are equal to the provided value.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ANIMATION_PARAMS
      */
     boolean areLastRequestedAnimationParamsEqual(
             @NonNull TaskFragmentAnimationParams animationParams) {
@@ -618,11 +660,66 @@
 
     /**
      * Updates the last requested {@link TaskFragmentAnimationParams}.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ANIMATION_PARAMS
      */
     void setLastRequestAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
         mLastAnimationParams = animationParams;
     }
 
+    /**
+     * Checks if last requested adjacent TaskFragment token and params are equal to the provided
+     * values.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS
+     * @see android.window.TaskFragmentOperation#OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS
+     */
+    boolean isLastAdjacentTaskFragmentEqual(@Nullable IBinder fragmentToken,
+            @Nullable WindowContainerTransaction.TaskFragmentAdjacentParams params) {
+        return Objects.equals(mLastAdjacentTaskFragment, fragmentToken)
+                && Objects.equals(mLastAdjacentParams, params);
+    }
+
+    /**
+     * Updates the last requested adjacent TaskFragment token and params.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS
+     */
+    void setLastAdjacentTaskFragment(@NonNull IBinder fragmentToken,
+            @NonNull WindowContainerTransaction.TaskFragmentAdjacentParams params) {
+        mLastAdjacentTaskFragment = fragmentToken;
+        mLastAdjacentParams = params;
+    }
+
+    /**
+     * Clears the last requested adjacent TaskFragment token and params.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS
+     */
+    void clearLastAdjacentTaskFragment() {
+        final TaskFragmentContainer lastAdjacentTaskFragment = mLastAdjacentTaskFragment != null
+                ? mController.getContainer(mLastAdjacentTaskFragment)
+                : null;
+        mLastAdjacentTaskFragment = null;
+        mLastAdjacentParams = null;
+        if (lastAdjacentTaskFragment != null) {
+            // Clear the previous adjacent TaskFragment as well.
+            lastAdjacentTaskFragment.clearLastAdjacentTaskFragment();
+        }
+    }
+
+    /**
+     * Checks if last requested companion TaskFragment token is equal to the provided value.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_COMPANION_TASK_FRAGMENT
+     */
+    boolean isLastCompanionTaskFragmentEqual(@Nullable IBinder fragmentToken) {
+        return Objects.equals(mLastCompanionTaskFragment, fragmentToken);
+    }
+
+    /**
+     * Updates the last requested companion TaskFragment token.
+     * @see android.window.TaskFragmentOperation#OP_TYPE_SET_COMPANION_TASK_FRAGMENT
+     */
+    void setLastCompanionTaskFragment(@Nullable IBinder fragmentToken) {
+        mLastCompanionTaskFragment = fragmentToken;
+    }
+
     /** Gets the parent leaf Task id. */
     int getTaskId() {
         return mTaskContainer.getTaskId();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index a26311e..17909d4 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -275,7 +275,8 @@
 
         assertNotNull(tf);
         assertNotNull(taskContainer);
-        assertEquals(TASK_BOUNDS, taskContainer.getConfiguration().windowConfiguration.getBounds());
+        assertEquals(TASK_BOUNDS, taskContainer.getTaskProperties().getConfiguration()
+                .windowConfiguration.getBounds());
     }
 
     @Test
@@ -288,7 +289,7 @@
         doReturn(true).when(tf).isEmpty();
         doReturn(true).when(mSplitController).launchPlaceholderIfNecessary(mTransaction,
                 mActivity, false /* isOnCreated */);
-        doNothing().when(mSplitPresenter).updateSplitContainer(any(), any(), any());
+        doNothing().when(mSplitPresenter).updateSplitContainer(any(), any());
 
         mSplitController.updateContainer(mTransaction, tf);
 
@@ -341,7 +342,7 @@
 
         mSplitController.updateContainer(mTransaction, tf);
 
-        verify(mSplitPresenter, never()).updateSplitContainer(any(), any(), any());
+        verify(mSplitPresenter, never()).updateSplitContainer(any(), any());
 
         // Verify if the top active split is updated if both of its containers are not finished.
         doReturn(false).when(mSplitController)
@@ -349,7 +350,7 @@
 
         mSplitController.updateContainer(mTransaction, tf);
 
-        verify(mSplitPresenter).updateSplitContainer(splitContainer, tf, mTransaction);
+        verify(mSplitPresenter).updateSplitContainer(splitContainer, mTransaction);
     }
 
     @Test
@@ -366,14 +367,14 @@
         doReturn(false).when(taskContainer).isVisible();
         mSplitController.updateContainer(mTransaction, taskFragmentContainer);
 
-        verify(mSplitPresenter, never()).updateSplitContainer(any(), any(), any());
+        verify(mSplitPresenter, never()).updateSplitContainer(any(), any());
 
         // Update the split when the Task is visible.
         doReturn(true).when(taskContainer).isVisible();
         mSplitController.updateContainer(mTransaction, taskFragmentContainer);
 
         verify(mSplitPresenter).updateSplitContainer(taskContainer.mSplitContainers.get(0),
-                taskFragmentContainer, mTransaction);
+                mTransaction);
     }
 
     @Test
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
index a41e63f..8330156 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
@@ -177,6 +177,64 @@
     }
 
     @Test
+    public void testSetAdjacentTaskFragments() {
+        final TaskFragmentContainer container0 = mController.newContainer(mActivity, TASK_ID);
+        final TaskFragmentContainer container1 = mController.newContainer(mActivity, TASK_ID);
+
+        mPresenter.setAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken(), null /* adjacentParams */);
+        verify(mTransaction).setAdjacentTaskFragments(container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken(), null /* adjacentParams */);
+
+        // No request to set the same adjacent TaskFragments.
+        clearInvocations(mTransaction);
+        mPresenter.setAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken(), null /* adjacentParams */);
+
+        verify(mTransaction, never()).setAdjacentTaskFragments(any(), any(), any());
+    }
+
+    @Test
+    public void testClearAdjacentTaskFragments() {
+        final TaskFragmentContainer container0 = mController.newContainer(mActivity, TASK_ID);
+        final TaskFragmentContainer container1 = mController.newContainer(mActivity, TASK_ID);
+
+        // No request to clear as it is not set by default.
+        mPresenter.clearAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken());
+        verify(mTransaction, never()).clearAdjacentTaskFragments(any());
+
+        mPresenter.setAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken(), null /* adjacentParams */);
+        mPresenter.clearAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken());
+        verify(mTransaction).clearAdjacentTaskFragments(container0.getTaskFragmentToken());
+
+        // No request to clear on either of the previous cleared TasKFragments.
+        clearInvocations(mTransaction);
+        mPresenter.clearAdjacentTaskFragments(mTransaction, container0.getTaskFragmentToken());
+        mPresenter.clearAdjacentTaskFragments(mTransaction, container1.getTaskFragmentToken());
+
+        verify(mTransaction, never()).clearAdjacentTaskFragments(any());
+    }
+
+    @Test
+    public void testSetCompanionTaskFragment() {
+        final TaskFragmentContainer container0 = mController.newContainer(mActivity, TASK_ID);
+        final TaskFragmentContainer container1 = mController.newContainer(mActivity, TASK_ID);
+
+        mPresenter.setCompanionTaskFragment(mTransaction, container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken());
+        verify(mTransaction).setCompanionTaskFragment(container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken());
+
+        // No request to set the same adjacent TaskFragments.
+        clearInvocations(mTransaction);
+        mPresenter.setCompanionTaskFragment(mTransaction, container0.getTaskFragmentToken(),
+                container1.getTaskFragmentToken());
+
+        verify(mTransaction, never()).setCompanionTaskFragment(any(), any());
+    }
+
+    @Test
     public void testUpdateAnimationParams() {
         final TaskFragmentContainer container = mController.newContainer(mActivity, TASK_ID);
 
@@ -228,7 +286,7 @@
 
     @Test
     public void testGetRelBoundsForPosition_expandContainers() {
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
         final SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.ExpandContainersSplitType())
                 .build();
@@ -248,7 +306,7 @@
 
     @Test
     public void testGetRelBoundsForPosition_expandContainers_isRelativeToParent() {
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty(
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties(
                 new Rect(100, 100, 500, 1000));
         final SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.ExpandContainersSplitType())
@@ -273,7 +331,7 @@
                 false /* splitHorizontally */);
         final Rect secondaryBounds = getSplitBounds(false /* isPrimary */,
                 false /* splitHorizontally */);
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
         SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(SplitAttributes.SplitType.RatioSplitType.splitEqually())
                 .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
@@ -339,7 +397,7 @@
         // Offset TaskBounds to 100, 100. The returned rel bounds shouldn't be affected.
         final Rect taskBounds = new Rect(TASK_BOUNDS);
         taskBounds.offset(100, 100);
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty(taskBounds);
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties(taskBounds);
         SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(SplitAttributes.SplitType.RatioSplitType.splitEqually())
                 .setLayoutDirection(SplitAttributes.LayoutDirection.LEFT_TO_RIGHT)
@@ -400,7 +458,7 @@
                 true /* splitHorizontally */);
         final Rect secondaryBounds = getSplitBounds(false /* isPrimary */,
                 true /* splitHorizontally */);
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
         SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(SplitAttributes.SplitType.RatioSplitType.splitEqually())
                 .setLayoutDirection(SplitAttributes.LayoutDirection.TOP_TO_BOTTOM)
@@ -442,7 +500,7 @@
                 false /* splitHorizontally */);
         final Rect secondaryBounds = getSplitBounds(false /* isPrimary */,
                 false /* splitHorizontally */);
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
         final SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.HingeSplitType(
                         SplitAttributes.SplitType.RatioSplitType.splitEqually()
@@ -506,7 +564,7 @@
 
     @Test
     public void testGetRelBoundsForPosition_fallbackToExpandContainers() {
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
         final SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.HingeSplitType(
                         new SplitAttributes.SplitType.ExpandContainersSplitType()
@@ -528,7 +586,7 @@
 
     @Test
     public void testGetRelBoundsForPosition_useHingeSplitType() {
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
         final SplitAttributes splitAttributes = new SplitAttributes.Builder()
                 .setSplitType(new SplitAttributes.SplitType.HingeSplitType(
                         new SplitAttributes.SplitType.ExpandContainersSplitType()
@@ -581,13 +639,13 @@
                 splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */));
         verify(mPresenter, never()).expandTaskFragment(any(), any());
 
-        splitContainer.setSplitAttributes(SPLIT_ATTRIBUTES);
+        splitContainer.updateCurrentSplitAttributes(SPLIT_ATTRIBUTES);
         doReturn(createActivityInfoWithMinDimensions()).when(secondaryActivity).getActivityInfo();
         assertEquals(RESULT_EXPAND_FAILED_NO_TF_INFO, mPresenter.expandSplitContainerIfNeeded(
                 mTransaction, splitContainer, mActivity, secondaryActivity,
                 null /* secondaryIntent */));
 
-        splitContainer.setSplitAttributes(SPLIT_ATTRIBUTES);
+        splitContainer.updateCurrentSplitAttributes(SPLIT_ATTRIBUTES);
         primaryTf.setInfo(mTransaction, createMockTaskFragmentInfo(primaryTf, mActivity));
         secondaryTf.setInfo(mTransaction,
                 createMockTaskFragmentInfo(secondaryTf, secondaryActivity));
@@ -597,7 +655,7 @@
         verify(mPresenter).expandTaskFragment(mTransaction, primaryTf.getTaskFragmentToken());
         verify(mPresenter).expandTaskFragment(mTransaction, secondaryTf.getTaskFragmentToken());
 
-        splitContainer.setSplitAttributes(SPLIT_ATTRIBUTES);
+        splitContainer.updateCurrentSplitAttributes(SPLIT_ATTRIBUTES);
         clearInvocations(mPresenter);
 
         assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction,
@@ -639,37 +697,35 @@
                 .setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY)
                 .setDefaultSplitAttributes(SPLIT_ATTRIBUTES)
                 .build();
-        final TaskContainer.TaskProperties taskProperties = getTaskProperty();
+        final TaskContainer.TaskProperties taskProperties = getTaskProperties();
 
         assertEquals(SPLIT_ATTRIBUTES, mPresenter.computeSplitAttributes(taskProperties,
-                splitPairRule, null /* minDimensionsPair */));
+                splitPairRule, SPLIT_ATTRIBUTES,  null /* minDimensionsPair */));
 
         final Pair<Size, Size> minDimensionsPair = new Pair<>(
                 new Size(TASK_BOUNDS.width(), TASK_BOUNDS.height()), null);
 
         assertEquals(EXPAND_CONTAINERS_ATTRIBUTES, mPresenter.computeSplitAttributes(taskProperties,
-                splitPairRule, minDimensionsPair));
+                splitPairRule, SPLIT_ATTRIBUTES, minDimensionsPair));
 
         taskProperties.getConfiguration().windowConfiguration.setBounds(new Rect(
                 TASK_BOUNDS.left + 1, TASK_BOUNDS.top + 1, TASK_BOUNDS.right + 1,
                 TASK_BOUNDS.bottom + 1));
 
         assertEquals(EXPAND_CONTAINERS_ATTRIBUTES, mPresenter.computeSplitAttributes(taskProperties,
-                splitPairRule, null /* minDimensionsPair */));
+                splitPairRule, SPLIT_ATTRIBUTES, null /* minDimensionsPair */));
 
         final SplitAttributes splitAttributes = new SplitAttributes.Builder()
-                .setSplitType(
-                        new SplitAttributes.SplitType.HingeSplitType(
-                                SplitAttributes.SplitType.RatioSplitType.splitEqually()
-                        )
-                ).build();
+                .setSplitType(new SplitAttributes.SplitType.HingeSplitType(
+                        SplitAttributes.SplitType.RatioSplitType.splitEqually()))
+                .build();
         final Function<SplitAttributesCalculatorParams, SplitAttributes> calculator =
                 params -> splitAttributes;
 
         mController.setSplitAttributesCalculator(calculator);
 
         assertEquals(splitAttributes, mPresenter.computeSplitAttributes(taskProperties,
-                splitPairRule, null /* minDimensionsPair */));
+                splitPairRule, SPLIT_ATTRIBUTES, null /* minDimensionsPair */));
     }
 
     @Test
@@ -696,14 +752,15 @@
         doReturn(activityConfig).when(mActivityResources).getConfiguration();
         doReturn(new ActivityInfo()).when(activity).getActivityInfo();
         doReturn(mock(IBinder.class)).when(activity).getActivityToken();
+        doReturn(TASK_ID).when(activity).getTaskId();
         return activity;
     }
 
-    private static TaskContainer.TaskProperties getTaskProperty() {
-        return getTaskProperty(TASK_BOUNDS);
+    private static TaskContainer.TaskProperties getTaskProperties() {
+        return getTaskProperties(TASK_BOUNDS);
     }
 
-    private static TaskContainer.TaskProperties getTaskProperty(@NonNull Rect taskBounds) {
+    private static TaskContainer.TaskProperties getTaskProperties(@NonNull Rect taskBounds) {
         final Configuration configuration = new Configuration();
         configuration.windowConfiguration.setBounds(taskBounds);
         return new TaskContainer.TaskProperties(DEFAULT_DISPLAY, configuration);
diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar
index 7eee6da..c3b6916 100644
--- a/libs/WindowManager/Jetpack/window-extensions-release.aar
+++ b/libs/WindowManager/Jetpack/window-extensions-release.aar
Binary files differ
diff --git a/libs/WindowManager/Shell/res/drawable/caption_close_button.xml b/libs/WindowManager/Shell/res/drawable/caption_close_button.xml
new file mode 100644
index 0000000..e258564
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/caption_close_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="32.0dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0"
+>
+    <group android:scaleX="0.5"
+           android:scaleY="0.5"
+           android:translateY="4.0">
+        <path
+            android:fillColor="#FFFF0000"
+            android:pathData="M12.45,38.35 L9.65,35.55 21.2,24 9.65,12.45 12.45,9.65 24,21.2 35.55,9.65 38.35,12.45 26.8,24 38.35,35.55 35.55,38.35 24,26.8Z"/>
+    </group>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml b/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
new file mode 100644
index 0000000..166552d
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/caption_collapse_menu_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+>
+    <group android:scaleX="1.25"
+           android:scaleY="1.75"
+           android:translateY="6.0">
+        <path
+            android:fillColor="@android:color/black"
+            android:pathData="M10.3937 6.93935L11.3337 5.99935L6.00033 0.666016L0.666992 5.99935L1.60699 6.93935L6.00033 2.55268"/>
+    </group>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_screenshot_button.xml b/libs/WindowManager/Shell/res/drawable/caption_screenshot_button.xml
new file mode 100644
index 0000000..7c86888
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/caption_screenshot_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="32.0dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0"
+>
+    <group android:scaleX="0.5"
+           android:scaleY="0.5"
+           android:translateY="4.0">
+        <path
+            android:fillColor="@android:color/black"
+            android:pathData="M10,38V28.35H13V35H19.65V38ZM10,19.65V10H19.65V13H13V19.65ZM28.35,38V35H35V28.35H38V38ZM35,19.65V13H28.35V10H38V19.65Z"/>
+    </group>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/caption_select_button.xml b/libs/WindowManager/Shell/res/drawable/caption_select_button.xml
new file mode 100644
index 0000000..8c60c84
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/caption_select_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32.0dp"
+        android:height="32.0dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0"
+>
+    <group
+           android:translateX="4.0"
+           android:translateY="6.0">
+        <path
+            android:fillColor="@android:color/black"
+            android:pathData="M13.7021 12.5833L16.5676 15.5L15.426 16.7333L12.526 13.8333L10.4426 15.9167V10.5H15.9176L13.7021 12.5833ZM13.8343 3.83333H15.501V5.5H13.8343V3.83333ZM15.501 2.16667H13.8343V0.566667C14.751 0.566667 15.501 1.33333 15.501 2.16667ZM10.501 0.5H12.1676V2.16667H10.501V0.5ZM13.8343 7.16667H15.501V8.83333H13.8343V7.16667ZM5.50098 15.5H3.83431V13.8333H5.50098V15.5ZM2.16764 5.5H0.500977V3.83333H2.16764V5.5ZM2.16764 0.566667V2.16667H0.500977C0.500977 1.33333 1.33431 0.566667 2.16764 0.566667ZM2.16764 12.1667H0.500977V10.5H2.16764V12.1667ZM5.50098 2.16667H3.83431V0.5H5.50098V2.16667ZM8.83431 2.16667H7.16764V0.5H8.83431V2.16667ZM8.83431 15.5H7.16764V13.8333H8.83431V15.5ZM2.16764 8.83333H0.500977V7.16667H2.16764V8.83333ZM2.16764 15.5667C1.25098 15.5667 0.500977 14.6667 0.500977 13.8333H2.16764V15.5667Z"/>
+    </group>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
index c9f2623..27e0b18 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
@@ -17,9 +17,10 @@
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="24"
-        android:viewportHeight="24">
+        android:viewportHeight="24"
+        android:tint="@color/decor_button_dark_color">
     <group android:translateY="8.0">
         <path
-            android:fillColor="@android:color/black" android:pathData="M3,5V3H21V5Z"/>
+            android:fillColor="@android:color/white" android:pathData="M3,5V3H21V5Z"/>
     </group>
 </vector>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
index 416287d..9167382 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_menu_background.xml
@@ -18,4 +18,5 @@
        xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="@android:color/white" />
     <corners android:radius="20dp" />
+    <stroke android:width="1dp" android:color="#b3b3b3"/>
 </shape>
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_title.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_title.xml
index 53a8bb1..ef30060 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_title.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_decor_title.xml
@@ -15,6 +15,8 @@
   ~ limitations under the License.
   -->
 <shape android:shape="rectangle"
+       android:tintMode="multiply"
+       android:tint="@color/decor_title_color"
        xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="@android:color/white" />
 </shape>
diff --git a/libs/WindowManager/Shell/res/drawable/size_compat_restart_button.xml b/libs/WindowManager/Shell/res/drawable/size_compat_restart_button.xml
index 2994593..b3f8e801 100644
--- a/libs/WindowManager/Shell/res/drawable/size_compat_restart_button.xml
+++ b/libs/WindowManager/Shell/res/drawable/size_compat_restart_button.xml
@@ -25,12 +25,10 @@
         android:fillAlpha="0.8"
         android:pathData="M0,24 a24,24 0 1,0 48,0 a24,24 0 1,0 -48,0"/>
     <group
-        android:scaleX="0.8"
-        android:scaleY="0.8"
-        android:translateX="10"
-        android:translateY="10">
+        android:translateX="12"
+        android:translateY="12">
         <path
-            android:pathData="M0,36V24.5H3V30.85L10.4,23.45L12.55,25.6L5.15,33H11.5V36H0ZM24.5,36V33H30.85L23.5,25.65L25.65,23.5L33,30.85V24.5H36V36H24.5ZM10.35,12.5L3,5.15V11.5H0V0H11.5V3H5.15L12.5,10.35L10.35,12.5ZM25.65,12.5L23.5,10.35L30.85,3H24.5V0H36V11.5H33V5.15L25.65,12.5Z"
-            android:fillColor="@color/compat_controls_text"/>
+            android:fillColor="@color/compat_controls_text"
+            android:pathData="M3,21V15H5V17.6L8.1,14.5L9.5,15.9L6.4,19H9V21ZM15,21V19H17.6L14.5,15.9L15.9,14.5L19,17.6V15H21V21ZM8.1,9.5 L5,6.4V9H3V3H9V5H6.4L9.5,8.1ZM15.9,9.5 L14.5,8.1 17.6,5H15V3H21V9H19V6.4Z"/>
     </group>
 </vector>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
index 8b4792a..f6e3f2e 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
@@ -1,49 +1,129 @@
 <?xml version="1.0" encoding="utf-8"?>
-    <!--
-      ~ Copyright (C) 2022 The Android Open Source Project
-      ~
-      ~ Licensed under the Apache License, Version 2.0 (the "License");
-      ~ you may not use this file except in compliance with the License.
-      ~ You may obtain a copy of the License at
-      ~
-      ~      http://www.apache.org/licenses/LICENSE-2.0
-      ~
-      ~ Unless required by applicable law or agreed to in writing, software
-      ~ distributed under the License is distributed on an "AS IS" BASIS,
-      ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-      ~ See the License for the specific language governing permissions and
-      ~ limitations under the License.
-      -->
+<!--
+  ~ 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.
+  -->
 <com.android.wm.shell.windowdecor.WindowDecorLinearLayout
-xmlns:android="http://schemas.android.com/apk/res/android"
-android:id="@+id/handle_menu"
-android:layout_width="wrap_content"
-android:layout_height="wrap_content"
-android:gravity="center_horizontal"
-android:background="@drawable/desktop_mode_decor_menu_background">
-    <Button
-        style="@style/CaptionButtonStyle"
-        android:id="@+id/fullscreen_button"
-        android:contentDescription="@string/fullscreen_text"
-        android:background="@drawable/caption_fullscreen_button"/>
-    <Button
-        style="@style/CaptionButtonStyle"
-        android:id="@+id/split_screen_button"
-        android:contentDescription="@string/split_screen_text"
-        android:background="@drawable/caption_split_screen_button"/>
-    <Button
-        style="@style/CaptionButtonStyle"
-        android:id="@+id/floating_button"
-        android:contentDescription="@string/float_button_text"
-        android:background="@drawable/caption_floating_button"/>
-    <Button
-        style="@style/CaptionButtonStyle"
-        android:id="@+id/desktop_button"
-        android:contentDescription="@string/desktop_text"
-        android:background="@drawable/caption_desktop_button"/>
-    <Button
-        style="@style/CaptionButtonStyle"
-        android:id="@+id/more_button"
-        android:contentDescription="@string/more_button_text"
-        android:background="@drawable/caption_more_button"/>
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/handle_menu"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@drawable/desktop_mode_decor_menu_background"
+    android:elevation="@dimen/caption_menu_elevation"
+    android:divider="?android:attr/dividerHorizontal"
+    android:showDividers="middle"
+    android:dividerPadding="18dip">
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <ImageView
+            android:id="@+id/application_icon"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:layout_margin="12dp"
+            android:contentDescription="@string/app_icon_text"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"/>
+        <TextView
+            android:id="@+id/application_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toEndOf="@+id/application_icon"
+            android:layout_toStartOf="@+id/collapse_menu_button"
+            android:textColor="#FF000000"
+            android:layout_centerVertical="true"/>
+        <Button
+            android:id="@+id/collapse_menu_button"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:layout_marginEnd="10dp"
+            android:contentDescription="@string/collapse_menu_text"
+            android:layout_alignParentEnd="true"
+            android:background="@drawable/caption_collapse_menu_button"
+            android:layout_centerVertical="true"/>
+    </RelativeLayout>
+    <LinearLayout
+        android:id="@+id/windowing_mode_buttons"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_horizontal">
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="0.5" />
+        <Button
+            style="@style/CaptionWindowingButtonStyle"
+            android:id="@+id/fullscreen_button"
+            android:contentDescription="@string/fullscreen_text"
+            android:background="@drawable/caption_fullscreen_button"/>
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+        <Button
+            style="@style/CaptionWindowingButtonStyle"
+            android:id="@+id/split_screen_button"
+            android:contentDescription="@string/split_screen_text"
+            android:background="@drawable/caption_split_screen_button"/>
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+        <Button
+            style="@style/CaptionWindowingButtonStyle"
+            android:id="@+id/floating_button"
+            android:contentDescription="@string/float_button_text"
+            android:background="@drawable/caption_floating_button"/>
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1" />
+        <Button
+            style="@style/CaptionWindowingButtonStyle"
+            android:id="@+id/desktop_button"
+            android:contentDescription="@string/desktop_text"
+            android:background="@drawable/caption_desktop_button"/>
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="0.5" />
+
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/menu_buttons_misc"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+        <Button
+            style="@style/CaptionMenuButtonStyle"
+            android:id="@+id/screenshot_button"
+            android:contentDescription="@string/screenshot_text"
+            android:text="@string/screenshot_text"
+            android:drawableStart="@drawable/caption_screenshot_button"/>
+        <Button
+            style="@style/CaptionMenuButtonStyle"
+            android:id="@+id/select_button"
+            android:contentDescription="@string/select_text"
+            android:text="@string/select_text"
+            android:drawableStart="@drawable/caption_select_button"/>
+        <Button
+            style="@style/CaptionMenuButtonStyle"
+            android:id="@+id/close_button"
+            android:contentDescription="@string/close_text"
+            android:text="@string/close_text"
+            android:drawableStart="@drawable/caption_close_button"
+            android:textColor="#FFFF0000"/>
+    </LinearLayout>
 </com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
index da31a46..29cf151 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
@@ -22,9 +22,20 @@
     android:gravity="center_horizontal"
     android:background="@drawable/desktop_mode_decor_title">
     <Button
+        style="@style/CaptionButtonStyle"
+        android:id="@+id/back_button"
+        android:contentDescription="@string/back_button_text"
+        android:background="@drawable/decor_back_button_dark"/>
+    <Button
         android:id="@+id/caption_handle"
         android:layout_width="128dp"
         android:layout_height="32dp"
+        android:layout_margin="5dp"
         android:contentDescription="@string/handle_text"
         android:background="@drawable/decor_handle_dark"/>
+    <Button
+        style="@style/CaptionButtonStyle"
+        android:id="@+id/close_window"
+        android:contentDescription="@string/close_button_text"
+        android:background="@drawable/decor_close_button_dark"/>
 </com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index a93f090..ee00e26 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bo 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bo 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Volskerm onder"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Gebruik eenhandmodus"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Swiep van die onderkant van die skerm af op of tik enige plek bo die program om uit te gaan"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Begin eenhandmodus"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dubbeltik buite ’n program om dit te herposisioneer"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Het dit"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vou uit vir meer inligting."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Herbegin vir ’n beter aansig?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Jy kan die app herbegin sodat dit beter op jou skerm lyk, maar jy sal dalk jou vordering of enige ongestoorde veranderinge verloor"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Kanselleer"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Herbegin"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Moenie weer wys nie"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeer"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Maak klein"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Maak toe"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 032767e..781038f 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ከላይ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገጽ"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ባለአንድ እጅ ሁነታን በመጠቀም ላይ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ለመውጣት ከማያው ግርጌ ወደ ላይ ይጥረጉ ወይም ከመተግበሪያው በላይ ማንኛውም ቦታ ላይ መታ ያድርጉ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ባለአንድ እጅ ሁነታ ጀምር"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ቦታውን ለመቀየር ከመተግበሪያው ውጪ ሁለቴ መታ ያድርጉ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ለተጨማሪ መረጃ ይዘርጉ።"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ለተሻለ ዕይታ እንደገና ይጀመር?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"በማያ ገጽዎ ላይ የተሻለ ሆኖ እንዲታይ መተግበሪያውን እንደገና ማስጀመር ይችላሉ ነገር ግን የደረሱበትን የሂደት ደረጃ ወይም ማናቸውንም ያልተቀመጡ ለውጦች ሊያጡ ይችላሉ"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ይቅር"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"እንደገና ያስጀምሩ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ዳግም አታሳይ"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"አስፋ"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"አሳንስ"</string>
     <string name="close_button_text" msgid="2913281996024033299">"ዝጋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 9bbee53..7325da1 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ضبط حجم النافذة العلوية ليكون ٥٠%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ضبط حجم النافذة العلوية ليكون ٣٠%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"عرض النافذة السفلية بملء الشاشة"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استخدام وضع \"التصفح بيد واحدة\""</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"للخروج، مرِّر سريعًا من أسفل الشاشة إلى أعلاها أو انقر في أي مكان فوق التطبيق."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"بدء وضع \"التصفح بيد واحدة\""</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"انقر مرّتين خارج تطبيق لتغيير موضعه."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"حسنًا"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"التوسيع للحصول على مزيد من المعلومات"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"هل تريد إعادة تشغيل التطبيق لعرضه بشكل أفضل؟"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"يمكنك إعادة تشغيل التطبيق حتى يظهر بشكل أفضل على شاشتك، ولكن قد تفقد تقدمك أو أي تغييرات غير محفوظة."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"إلغاء"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"إعادة التشغيل"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"عدم عرض مربّع حوار التأكيد مجددًا"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"تكبير"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"تصغير"</string>
     <string name="close_button_text" msgid="2913281996024033299">"إغلاق"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index f7ea139..3fd705e 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ স্ক্ৰীনখন ৫০% কৰক"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"শীর্ষ স্ক্ৰীনখন ৩০% কৰক"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"তলৰ স্ক্ৰীনখন সম্পূৰ্ণ স্ক্ৰীন কৰক"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"এখন হাতেৰে ব্যৱহাৰ কৰা ম’ড ব্যৱহাৰ কৰা"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"বাহিৰ হ’বলৈ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ছোৱাইপ কৰক অথবা এপ্‌টোৰ ওপৰত যিকোনো ঠাইত টিপক"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"এখন হাতেৰে ব্যৱহাৰ কৰা ম\'ডটো আৰম্ভ কৰক"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"এপ্‌টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ বাহিৰত দুবাৰ টিপক"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুজি পালোঁ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"অধিক তথ্যৰ বাবে বিস্তাৰ কৰক।"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"উন্নতভাৱে দেখা পাবলৈ ৰিষ্টাৰ্ট কৰিবনে?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"আপোনাৰ স্ক্ৰীনত উন্নতভাৱে দেখা পাবলৈ আপুনি এপ্‌টো ৰিষ্টাৰ্ট কৰিব পাৰে, কিন্তু আপুনি আপোনাৰ অগ্ৰগতি অথবা ছেভ নকৰা যিকোনো সালসলনি হেৰুৱাব পাৰে"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"বাতিল কৰক"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ৰিষ্টাৰ্ট কৰক"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"পুনৰাই নেদেখুৱাব"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"মিনিমাইজ কৰক"</string>
     <string name="close_button_text" msgid="2913281996024033299">"বন্ধ কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 86b7714..a31b1e7 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yuxarı 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Yuxarı 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Aşağı tam ekran"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Birəlli rejim istifadəsi"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Çıxmaq üçün ekranın aşağısından yuxarıya doğru sürüşdürün və ya tətbiqin yuxarısında istənilən yerə toxunun"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Birəlli rejim başlasın"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tətbiqin yerini dəyişmək üçün kənarına iki dəfə toxunun"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ətraflı məlumat üçün genişləndirin."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Daha yaxşı görünüş üçün yenidən başladılsın?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Tətbiqi yenidən başlada bilərsiniz ki, ekranınızda daha yaxşı görünsün, lakin irəliləyişi və ya yadda saxlanmamış dəyişiklikləri itirə bilərsiniz"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Ləğv edin"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Yenidən başladın"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Yenidən göstərməyin"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Böyüdün"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Kiçildin"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Bağlayın"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 4a1ee7a..c0e4789 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji ekran 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji ekran 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Režim celog ekrana za donji ekran"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korišćenje režima jednom rukom"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da biste izašli, prevucite nagore od dna ekrana ili dodirnite bilo gde iznad aplikacije"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokrenite režim jednom rukom"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste promenili njenu poziciju"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za još informacija."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Želite li da restartujete radi boljeg prikaza?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Možete da restartujete aplikaciju da bi izgledala bolje na ekranu, s tim što možete da izgubite ono što ste uradili ili nesačuvane promene, ako ih ima"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Otkaži"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartuj"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovo"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Uvećajte"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Umanjite"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zatvorite"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 1986699..b67e2cd 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхні экран – 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхні экран – 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ніжні экран – поўнаэкранны рэжым"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Выкарыстоўваецца рэжым кіравання адной рукой"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Каб выйсці, правядзіце па экране пальцам знізу ўверх або націсніце ў любым месцы над праграмай"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Запусціць рэжым кіравання адной рукой"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двойчы націсніце экран па-за праграмай, каб перамясціць яе"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Зразумела"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгарнуць для дадатковай інфармацыі"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Перазапусціць?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Вы можаце перазапусціць праграму, каб яна выглядала лепш на вашым экране, але пры гэтым могуць знікнуць даныя пра ваш прагрэс або незахаваныя змяненні"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Скасаваць"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Перазапусціць"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Больш не паказваць"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Разгарнуць"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Згарнуць"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Закрыць"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index b8a0316..9bf396d 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горен екран: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горен екран: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Долен екран: Показване на цял екран"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Използване на режима за работа с една ръка"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"За изход прекарайте пръст нагоре от долната част на екрана или докоснете произволно място над приложението"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Стартиране на режима за работа с една ръка"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Докоснете два пъти извън дадено приложение, за да промените позицията му"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Разбрах"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Разгъване за още информация."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Да се рестартира ли с цел подобряване на изгледа?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Можете да рестартирате приложението, за да изглежда по-добре на екрана. Възможно е обаче да загубите напредъка си или незапазените промени"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Отказ"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартиране"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Да не се показва отново"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Увеличаване"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Намаляване"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Затваряне"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 40395fa..affb62e 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"শীর্ষ ৫০%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"শীর্ষ ৩০%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"নীচের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"\'এক হাতে ব্যবহার করার মোড\'-এর ব্যবহার"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"বেরিয়ে আসার জন্য, স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন অথবা অ্যাপ আইকনের উপরে যেকোনও জায়গায় ট্যাপ করুন"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"\'এক হাতে ব্যবহার করার মোড\' শুরু করুন"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"কোনও অ্যাপের স্থান পরিবর্তন করতে তার বাইরে ডবল ট্যাপ করুন"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুঝেছি"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"আরও তথ্যের জন্য বড় করুন।"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"আরও ভালভাবে দেখার জন্য রিস্টার্ট করবেন?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"স্ক্রিনে আরও ভালভাবে দেখার জন্য আপনি অ্যাপ রিস্টার্ট করতে পারবেন, এর ফলে চলতে থাকা কোনও প্রক্রিয়া বা সেভ না করা পরিবর্তন হারিয়ে যেতে পারে"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"বাতিল করুন"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"রিস্টার্ট করুন"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"আর দেখতে চাই না"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"বড় করুন"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ছোট করুন"</string>
     <string name="close_button_text" msgid="2913281996024033299">"বন্ধ করুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index daef1a0..dd2f871 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gore 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gore 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Donji ekran kao cijeli ekran"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korištenje načina rada jednom rukom"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Da izađete, prevucite s dna ekrana prema gore ili dodirnite bilo gdje iznad aplikacije"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Započinjanje načina rada jednom rukom"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da promijenite njen položaj"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Razumijem"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za više informacija."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Ponovo pokrenuti za bolji prikaz?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Možete ponovo pokrenuti aplikaciju da bolje izgleda na ekranu, ali možete izgubiti napredak ili izmjene koje nisu sačuvane"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Otkaži"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Ponovo pokreni"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovo"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziranje"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimiziranje"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zatvaranje"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 85edc20..937e0d9 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -22,8 +22,8 @@
     <string name="pip_phone_settings" msgid="5468987116750491918">"Configuració"</string>
     <string name="pip_phone_enter_split" msgid="7042877263880641911">"Entra al mode de pantalla dividida"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"Menú"</string>
-    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú de pantalla en pantalla"</string>
-    <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> està en pantalla en pantalla"</string>
+    <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menú d\'imatge sobre imatge"</string>
+    <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> està en mode d\'imatge sobre imatge"</string>
     <string name="pip_notification_message" msgid="8854051911700302620">"Si no vols que <xliff:g id="NAME">%s</xliff:g> utilitzi aquesta funció, toca per obrir la configuració i desactiva-la."</string>
     <string name="pip_play" msgid="3496151081459417097">"Reprodueix"</string>
     <string name="pip_pause" msgid="690688849510295232">"Posa en pausa"</string>
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Pantalla superior al 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Pantalla superior al 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"S\'està utilitzant el mode d\'una mà"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Per sortir, llisca cap amunt des de la part inferior de la pantalla o toca qualsevol lloc a sobre de l\'aplicació"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Inicia el mode d\'una mà"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Fes doble toc fora d\'una aplicació per canviar-ne la posició"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entesos"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Desplega per obtenir més informació."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vols reiniciar per a una millor visualització?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Pots reiniciar l\'aplicació perquè es vegi millor en pantalla, però és possible que perdis el teu progrés o qualsevol canvi que no hagis desat"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancel·la"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reinicia"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No ho tornis a mostrar"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximitza"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimitza"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Tanca"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
index e261db9..d51a78b 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
@@ -17,7 +17,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Pantalla en pantalla"</string>
+    <string name="notification_channel_tv_pip" msgid="2576686079160402435">"Imatge sobre imatge"</string>
     <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(Programa sense títol)"</string>
     <string name="pip_close" msgid="2955969519031223530">"Tanca"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
@@ -25,7 +25,7 @@
     <string name="pip_expand" msgid="1051966011679297308">"Desplega"</string>
     <string name="pip_collapse" msgid="3903295106641385962">"Replega"</string>
     <string name="pip_edu_text" msgid="7930546669915337998">"Prem dos cops "<annotation icon="home_icon">"INICI"</annotation>" per accedir als controls"</string>
-    <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú de pantalla en pantalla."</string>
+    <string name="a11y_pip_menu_entered" msgid="5106343214776801614">"Menú d\'imatge sobre imatge."</string>
     <string name="a11y_action_pip_move_left" msgid="6612980937817141583">"Mou cap a l\'esquerra"</string>
     <string name="a11y_action_pip_move_right" msgid="1119409122645529936">"Mou cap a la dreta"</string>
     <string name="a11y_action_pip_move_up" msgid="98502616918621959">"Mou cap amunt"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index ce11197..a358895 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % nahoře"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % nahoře"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolní část na celou obrazovku"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Používání režimu jedné ruky"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Režim ukončíte, když přejedete prstem z dolní části obrazovky nahoru nebo klepnete kamkoli nad aplikaci"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Spustit režim jedné ruky"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikaci změníte její umístění"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozbalením zobrazíte další informace."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Restartovat pro lepší zobrazení?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Aplikaci můžete restartovat, aby na obrazovce vypadala lépe, ale můžete přijít o svůj postup nebo o neuložené změny"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Zrušit"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartovat"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Tuto zprávu příště nezobrazovat"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovat"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovat"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zavřít"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 38acf45..7a40efd 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Øverste 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Øverste 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Vis nederste del i fuld skærm"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Brug af enhåndstilstand"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Du kan afslutte ved at stryge opad fra bunden af skærmen eller trykke et vilkårligt sted over appen"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start enhåndstilstand"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryk to gange uden for en app for at justere dens placering"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Udvid for at få flere oplysninger."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vil du genstarte for at få en bedre visning?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kan genstarte appen, så den ser bedre ud på din skærm, men du mister muligvis dine fremskridt og de ændringer, der ikke gemt"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuller"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Genstart"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Vis ikke igen"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimér"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Luk"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index d455fc6..8f62752 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % oben"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % oben"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Vollbild unten"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Einhandmodus wird verwendet"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Wenn du die App schließen möchtest, wische vom unteren Rand des Displays nach oben oder tippe auf eine beliebige Stelle oberhalb der App"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Einhandmodus starten"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Außerhalb einer App doppeltippen, um die Position zu ändern"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Für weitere Informationen maximieren."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Für bessere Darstellung neu starten?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kannst die App neu starten, damit sie an die Bildschirmabmessungen deines Geräts angepasst dargestellt wird – jedoch können dadurch dein Fortschritt oder nicht gespeicherte Änderungen verloren gehen."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Abbrechen"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Neu starten"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nicht mehr anzeigen"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximieren"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimieren"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Schließen"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 051a20d..8d0faeb 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Πάνω 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Πάνω 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Κάτω πλήρης οθόνη"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Χρήση λειτουργίας ενός χεριού"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Για έξοδο, σύρετε προς τα πάνω από το κάτω μέρος της οθόνης ή πατήστε οπουδήποτε πάνω από την εφαρμογή."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Έναρξη λειτουργίας ενός χεριού"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Πατήστε δύο φορές έξω από μια εφαρμογή για να αλλάξετε τη θέση της"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Το κατάλαβα"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ανάπτυξη για περισσότερες πληροφορίες."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Επανεκκίνηση για καλύτερη προβολή;"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Μπορείτε να επανεκκινήσετε την εφαρμογή για να προβάλλεται καλύτερα στην οθόνη σας, αλλά η πρόοδός σας και τυχόν μη αποθηκευμένες αλλαγές ενδέχεται να χαθούν."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Ακύρωση"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Επανεκκίνηση"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Να μην εμφανιστεί ξανά"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Μεγιστοποίηση"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Ελαχιστοποίηση"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Κλείσιμο"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 68f5de9..a108e89 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -49,6 +49,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Top 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Bottom full screen"</string>
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Split left"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Split right"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Split top"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Split bottom"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Using one-handed mode"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"To exit, swipe up from the bottom of the screen or tap anywhere above the app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start one-handed mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 204a24f..cfa9abc 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -49,6 +49,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Top 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Bottom full screen"</string>
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Split left"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Split right"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Split top"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Split bottom"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Using one-handed mode"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"To exit, swipe up from the bottom of the screen or tap anywhere above the app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start one-handed mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 68f5de9..a108e89 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -49,6 +49,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Top 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Bottom full screen"</string>
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Split left"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Split right"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Split top"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Split bottom"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Using one-handed mode"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"To exit, swipe up from the bottom of the screen or tap anywhere above the app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start one-handed mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 68f5de9..a108e89 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -49,6 +49,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Top 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Top 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Bottom full screen"</string>
+    <string name="accessibility_split_left" msgid="1713683765575562458">"Split left"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"Split right"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"Split top"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"Split bottom"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Using one-handed mode"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"To exit, swipe up from the bottom of the screen or tap anywhere above the app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start one-handed mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 81e6e05..65af778 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -49,6 +49,10 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎Top 50%‎‏‎‎‏‎"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎Top 30%‎‏‎‎‏‎"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎Bottom full screen‎‏‎‎‏‎"</string>
+    <string name="accessibility_split_left" msgid="1713683765575562458">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎Split left‎‏‎‎‏‎"</string>
+    <string name="accessibility_split_right" msgid="8441001008181296837">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎Split right‎‏‎‎‏‎"</string>
+    <string name="accessibility_split_top" msgid="2789329702027147146">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎Split top‎‏‎‎‏‎"</string>
+    <string name="accessibility_split_bottom" msgid="8694551025220868191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎Split bottom‎‏‎‎‏‎"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‎Using one-handed mode‎‏‎‎‏‎"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎To exit, swipe up from the bottom of the screen or tap anywhere above the app‎‏‎‎‏‎"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎Start one-handed mode‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 7b569f2..c26532e 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Cómo usar el modo de una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o presiona cualquier parte arriba de la app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar el modo de una mano"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Presiona dos veces fuera de una app para cambiar su ubicación"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expande para obtener más información."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"¿Quieres reiniciar para que se vea mejor?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Puedes reiniciar la app para que se vea mejor en la pantalla, pero podrías perder tu progreso o cualquier cambio que no hayas guardado"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No volver a mostrar"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index b9ee866..58deed5 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Superior 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Superior 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla inferior completa"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usar modo Una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para salir, desliza el dedo hacia arriba desde la parte inferior de la pantalla o toca cualquier zona que haya encima de la aplicación"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo Una mano"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dos veces fuera de una aplicación para cambiarla de posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mostrar más información"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"¿Reiniciar para que se vea mejor?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Puedes reiniciar la aplicación para que se vea mejor en la pantalla, pero puedes perder tu progreso o cualquier cambio que no hayas guardado"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"No volver a mostrar"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Cerrar"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index de569e6..c0d0588 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ülemine: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Ülemine: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alumine täisekraan"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ühekäerežiimi kasutamine"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Väljumiseks pühkige ekraani alaosast üles või puudutage rakenduse kohal olevat ala"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ühekäerežiimi käivitamine"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Topeltpuudutage rakendusest väljaspool, et selle asendit muuta"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Selge"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Laiendage lisateabe saamiseks."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Kas taaskäivitada parema vaate saavutamiseks?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Saate rakenduse taaskäivitada, et see näeks ekraanikuval parem välja, kuid võite kaotada edenemise või salvestamata muudatused"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Tühista"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Taaskäivita"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ära kuva uuesti"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimeeri"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimeeri"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Sule"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index c05b3c7..6a1f457 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Ezarri goialdea % 50en"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Ezarri goialdea % 30en"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ezarri behealdea pantaila osoan"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Esku bakarreko modua erabiltzea"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Irteteko, pasatu hatza pantailaren behealdetik gora edo sakatu aplikazioaren gainaldea"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Abiarazi esku bakarreko modua"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Aplikazioaren posizioa aldatzeko, sakatu birritan haren kanpoaldea"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ados"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Informazio gehiago lortzeko, zabaldu hau."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Aplikazioa berrabiarazi nahi duzu itxura hobea izan dezan?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Aplikazioa berrabiarazi egin dezakezu itxura hobea izan dezan, baina agian garapena edo gorde gabeko aldaketak galduko dituzu"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Utzi"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Berrabiarazi"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ez erakutsi berriro"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizatu"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizatu"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Itxi"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index f7d52f9..59c119d 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"٪۵۰ بالا"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"٪۳۰ بالا"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"تمام‌صفحه پایین"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از حالت یک‌دستی"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحه‌نمایش تند به‌طرف بالا بکشید یا در هر جایی از بالای برنامه که می‌خواهید ضربه بزنید"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت یک‌دستی»"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابه‌جا کردن برنامه، بیرون از آن دوضربه بزنید"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجه‌ام"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"برای اطلاعات بیشتر، گسترده کنید."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"برای نمایش بهتر بازراه‌اندازی شود؟"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"می‌توانید برنامه را بازراه‌اندازی کنید تا بهتر روی صفحه‌نمایش نشان داده شود، اما ممکن است پیشرفت یا تغییرات ذخیره‌نشده را ازدست بدهید"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"لغو کردن"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"بازراه‌اندازی"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"دوباره نشان داده نشود"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string>
     <string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 91120d4..edb1dae 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Yläosa 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Yläosa 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alaosa koko näytölle"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Yhden käden moodin käyttö"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Poistu pyyhkäisemällä ylös näytön alareunasta tai napauttamalla sovelluksen yllä"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Käynnistä yhden käden moodi"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kaksoisnapauta sovelluksen ulkopuolella, jos haluat siirtää sitä"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Katso lisätietoja laajentamalla."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Käynnistetäänkö sovellus uudelleen, niin saat paremman näkymän?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Voit käynnistää sovelluksen uudelleen, jotta se näyttää paremmalta näytöllä, mutta saatat menettää edistymisesi tai tallentamattomat muutokset"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Peru"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Käynnistä uudelleen"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Älä näytä uudelleen"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Suurenna"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Pienennä"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Sulje"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 59bd339..ee6e7be 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % dans le haut"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % dans le haut"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Plein écran dans le bas"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utiliser le mode Une main"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran du bas vers le haut, ou touchez n\'importe où sur l\'écran en haut de l\'application"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode Une main"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une application pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour un meilleur affichage?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'application pour qu\'elle s\'affiche mieux sur votre écran, mais il se peut que vous perdiez votre progression ou toute modification non enregistrée"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 41de4db..c9fc061 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Écran du haut à 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Écran du haut à 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Écran du bas en plein écran"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utiliser le mode une main"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran de bas en haut ou appuyez n\'importe où au-dessus de l\'application"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode une main"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Appuyez deux fois en dehors d\'une appli pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développez pour obtenir plus d\'informations"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour améliorer l\'affichage ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'appli pour en améliorer son aspect sur votre écran, mais vous risquez de perdre votre progression ou les modifications non enregistrées"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 573e17e..3e1a93f 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50 % arriba"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30 % arriba"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pantalla completa abaixo"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como se usa o modo dunha soa man?"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para saír, pasa o dedo cara arriba desde a parte inferior da pantalla ou toca calquera lugar da zona situada encima da aplicación"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar modo dunha soa man"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toca dúas veces fóra da aplicación para cambiala de posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Despregar para obter máis información."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Queres reiniciar a aplicación para que se vexa mellor?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Podes reiniciar a aplicación para que se vexa mellor na pantalla, pero podes perder o progreso que levas feito ou calquera cambio que non gardases"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Non mostrar outra vez"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Pechar"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 35e9607..24950f7 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"શીર્ષ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"શીર્ષ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"તળિયાની પૂર્ણ સ્ક્રીન"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"એક-હાથે વાપરો મોડનો ઉપયોગ કરી રહ્યાં છીએ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"બહાર નીકળવા માટે, સ્ક્રીનની નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરો અથવા ઍપના આઇકન પર ગમે ત્યાં ટૅપ કરો"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"એક-હાથે વાપરો મોડ શરૂ કરો"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"કોઈ ઍપની જગ્યા બદલવા માટે, તેની બહાર બે વાર ટૅપ કરો"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"સમજાઈ ગયું"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"વધુ માહિતી માટે મોટું કરો."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"બહેતર વ્યૂ માટે ફરીથી શરૂ કરીએ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"તમે ઍપને ફરીથી શરૂ કરી શકો છો, જેથી તે તમારી સ્ક્રીન પર વધુ સારી રીતે દેખાય, પરંતુ આમ કરવાથી તમે તમારી ઍપ પર કરી હોય એવી કોઈ પ્રક્રિયાની પ્રગતિ અથવા સાચવ્યા ન હોય એવો કોઈપણ ફેરફાર ગુમાવી શકો છો"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"રદ કરો"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ફરી શરૂ કરો"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ફરીથી બતાવશો નહીં"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"મોટું કરો"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"નાનું કરો"</string>
     <string name="close_button_text" msgid="2913281996024033299">"બંધ કરો"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 173029a..9f36799 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ऊपर की स्क्रीन को 50% बनाएं"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ऊपर की स्क्रीन को 30% बनाएं"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"नीचे की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"वन-हैंडेड मोड का इस्तेमाल करना"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"इस मोड से बाहर निकलने के लिए, स्क्रीन के सबसे निचले हिस्से से ऊपर की ओर स्वाइप करें या ऐप्लिकेशन के बाहर कहीं भी टैप करें"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"वन-हैंडेड मोड चालू करें"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बाहर दो बार टैप करें"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ठीक है"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ज़्यादा जानकारी के लिए बड़ा करें."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"बेहतर व्यू पाने के लिए ऐप्लिकेशन को रीस्टार्ट करना है?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"स्क्रीन पर ऐप्लिकेशन का बेहतर व्यू पाने के लिए उसे रीस्टार्ट करें. हालांकि, आपने जो बदलाव सेव नहीं किए हैं या अब तक जो काम किए हैं उनका डेटा, ऐप्लिकेशन रीस्टार्ट करने पर मिट सकता है"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"रद्द करें"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"रीस्टार्ट करें"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"फिर से न दिखाएं"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"बड़ा करें"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"विंडो छोटी करें"</string>
     <string name="close_button_text" msgid="2913281996024033299">"बंद करें"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index c45bb56..9459e4c 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gornji zaslon na 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gornji zaslon na 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Donji zaslon u cijeli zaslon"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korištenje načina rada jednom rukom"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Za izlaz prijeđite prstom od dna zaslona prema gore ili dodirnite bio gdje iznad aplikacije"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pokretanje načina rada jednom rukom"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvaput dodirnite izvan aplikacije da biste je premjestili"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Shvaćam"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite da biste saznali više."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Želite li ponovno pokrenuti za bolji pregled?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Možete ponovno pokrenuti aplikaciju tako da bolje izgleda na zaslonu, no mogli biste izgubiti napredak ili sve nespremljene promjene"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Odustani"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Pokreni ponovno"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovno"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiziraj"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimiziraj"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zatvori"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 7c45113..fc9341b 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Felső 50%-ra"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Felső 30%-ra"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Alsó teljes képernyőre"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Egykezes mód használata"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"A kilépéshez csúsztasson felfelé a képernyő aljáról, vagy koppintson az alkalmazás felett a képernyő bármelyik részére"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Egykezes mód indítása"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Koppintson duplán az alkalmazáson kívül az áthelyezéséhez"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Értem"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kibontással további információkhoz juthat."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Újraindítja a jobb megjelenítés érdekében?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Újraindíthatja az alkalmazást a képernyőn való jobb megjelenítés érdekében, de elveszítheti az előrehaladását és az esetleges nem mentett változásokat"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Mégse"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Újraindítás"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne jelenjen meg többé"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Teljes méret"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Kis méret"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Bezárás"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index c26c540..6943532 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Վերևի էկրանը՝ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Վերևի էկրանը՝ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ներքևի էկրանը՝ լիաէկրան"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ինչպես օգտվել մեկ ձեռքի ռեժիմից"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Դուրս գալու համար մատը սահեցրեք էկրանի ներքևից վերև կամ հպեք հավելվածի վերևում որևէ տեղ։"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Գործարկել մեկ ձեռքի ռեժիմը"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Եղավ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Ծավալեք՝ ավելին իմանալու համար։"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Վերագործարկե՞լ հավելվածը"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Դուք կարող եք վերագործարկել հավելվածը, որպեսզի այն ավելի լավ ցուցադրվի ձեր էկրանին, սակայն ձեր առաջընթացը և չպահված փոփոխությունները կկորեն"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Չեղարկել"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Վերագործարկել"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Այլևս ցույց չտալ"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Ծավալել"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Ծալել"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Փակել"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 8247309..4fca32d 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Atas 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Layar penuh di bawah"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Menggunakan mode satu tangan"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Untuk keluar, geser layar dari bawah ke atas atau ketuk di mana saja di atas aplikasi"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Mulai mode satu tangan"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketuk dua kali di luar aplikasi untuk mengubah posisinya"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Oke"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Luaskan untuk melihat informasi selengkapnya."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Mulai ulang untuk tampilan yang lebih baik?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Anda dapat memulai ulang aplikasi agar terlihat lebih baik di layar, tetapi Anda mungkin kehilangan progres atau perubahan yang belum disimpan"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Batal"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulai ulang"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Jangan tampilkan lagi"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimalkan"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimalkan"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index b64f2d5..1bc019e 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Efri 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Efri 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Neðri á öllum skjánum"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Notkun einhentrar stillingar"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Til að loka skaltu strjúka upp frá neðri hluta skjásins eða ýta hvar sem er fyrir ofan forritið"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ræsa einhenta stillingu"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ýttu tvisvar utan við forrit til að færa það"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ég skil"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Stækka til að sjá frekari upplýsingar."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Viltu endurræsa til að fá betri sýn?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Þú getur endurræst forritið svo það falli betur að skjánum en þú gætir tapað framvindunni eða óvistuðum breytingum"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Hætta við"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Endurræsa"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ekki sýna þetta aftur"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Stækka"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minnka"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Loka"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index ffb5f30..8d2715a 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Schermata superiore al 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Schermata superiore al 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Schermata inferiore a schermo intero"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Usare la modalità a una mano"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Per uscire, scorri verso l\'alto dalla parte inferiore dello schermo oppure tocca un punto qualsiasi sopra l\'app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Avvia la modalità a una mano"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 5f204b2..26f3236 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"עליון 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"למעלה 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"מסך תחתון מלא"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"איך להשתמש בתכונה \'מצב שימוש ביד אחת\'"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"כדי לצאת, יש להחליק למעלה מתחתית המסך או להקיש במקום כלשהו במסך מעל האפליקציה"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"הפעלה של מצב שימוש ביד אחת"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"צריך להקיש הקשה כפולה מחוץ לאפליקציה כדי למקם אותה מחדש"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"הבנתי"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"מרחיבים כדי לקבל מידע נוסף."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"להפעיל מחדש לתצוגה טובה יותר?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"אפשר להפעיל מחדש את האפליקציה כדי שהיא תוצג באופן טוב יותר במסך, אבל ייתכן שההתקדמות שלך או כל שינוי שלא נשמר יאבדו"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ביטול"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"הפעלה מחדש"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"אין צורך להציג את זה שוב"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string>
     <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 8c70341..91fd724 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"上 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"上 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"下部全画面"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"片手モードの使用"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの任意の場所をタップします"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"片手モードを開始します"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 82048c9..a711afd 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ზედა ეკრანი — 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ზედა ეკრანი — 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ქვედა ნაწილის სრულ ეკრანზე გაშლა"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ცალი ხელის რეჟიმის გამოყენება"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"გასასვლელად გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ ან შეეხეთ ნებისმიერ ადგილას აპის ზემოთ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ცალი ხელის რეჟიმის დაწყება"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ორმაგად შეეხეთ აპის გარშემო სივრცეს, რათა ის სხვაგან გადაიტანოთ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"გასაგებია"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"დამატებითი ინფორმაციისთვის გააფართოეთ."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"გსურთ გადატვირთვა უკეთესი ხედისთვის?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"შეგიძლიათ გადატვირთოთ აპი იმისათვის, რომ თქვენს ეკრანზე უკეთესად გამოჩნდეს, თუმცა თქვენ მიერ შესრულებული მოქმედებები შეიძლება დაიკარგოს ან ცვლილებების შენახვა ვერ მოხერხდეს"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"გაუქმება"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"გადატვირთვა"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"აღარ გამოჩნდეს"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"მაქსიმალურად გაშლა"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ჩაკეცვა"</string>
     <string name="close_button_text" msgid="2913281996024033299">"დახურვა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index ed4a14b..a2e8688 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% жоғарғы жақта"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% жоғарғы жақта"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Төменгісін толық экранға шығару"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бір қолмен енгізу режимін пайдалану"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Шығу үшін экранның төменгі жағынан жоғары қарай сырғытыңыз немесе қолданбаның үстінен кез келген жерден түртіңіз."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бір қолмен енгізу режимін іске қосу"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Қолданбаның орнын өзгерту үшін одан тыс жерді екі рет түртіңіз."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түсінікті"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толығырақ ақпарат алу үшін терезені жайыңыз."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Көріністі жақсарту үшін өшіріп қосу керек пе?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Экранда жақсырақ көрінуі үшін қолданбаны өшіріп қосуыңызға болады, бірақ мұндайда ағымдағы прогресс өшіп қалуы немесе сақталмаған өзгерістерді жоғалтуыңыз мүмкін."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Бас тарту"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Өшіріп қосу"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Қайта көрсетілмесін"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Жаю"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Кішірейту"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Жабу"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index e705301..7a486b8 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ខាងលើ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ខាងលើ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"អេក្រង់ពេញខាងក្រោម"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"កំពុងប្រើ​មុខងារប្រើដៃម្ខាង"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ដើម្បីចាកចេញ សូមអូសឡើងលើ​ពីផ្នែកខាងក្រោមអេក្រង់ ឬចុចផ្នែកណាមួយ​នៅខាងលើកម្មវិធី"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ចាប់ផ្ដើម​មុខងារប្រើដៃម្ខាង"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ចុចពីរដង​នៅ​ក្រៅ​កម្មវិធី ដើម្បី​ប្ដូរ​ទីតាំង​កម្មវិធី​នោះ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"យល់ហើយ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ពង្រីកដើម្បីទទួលបានព័ត៌មានបន្ថែម។"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ចាប់ផ្ដើម​ឡើងវិញ ដើម្បីទទួលបានទិដ្ឋភាពកាន់តែស្អាតឬ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"អ្នកអាចចាប់ផ្ដើម​កម្មវិធីឡើងវិញ ដើម្បីឱ្យកម្មវិធីនេះមើលទៅស្អាតជាងមុននៅលើអេក្រង់របស់អ្នក ប៉ុន្តែអ្នកអាចនឹងបាត់បង់ដំណើរការរបស់អ្នក ឬការកែប្រែណាមួយដែលអ្នកមិនបានរក្សាទុក"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"បោះបង់"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ចាប់ផ្ដើម​ឡើង​វិញ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"កុំ​បង្ហាញ​ម្ដង​ទៀត"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ពង្រីក"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"បង្រួម"</string>
     <string name="close_button_text" msgid="2913281996024033299">"បិទ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index bebf0c0..5fcdcf2 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% ಮೇಲಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% ಮೇಲಕ್ಕೆ"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ಕೆಳಗಿನ ಪೂರ್ಣ ಪರದೆ"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ಒಂದು ಕೈ ಮೋಡ್ ಬಳಸುವುದರ ಬಗ್ಗೆ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ನಿರ್ಗಮಿಸಲು, ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಅಥವಾ ಆ್ಯಪ್‌ನ ಮೇಲೆ ಎಲ್ಲಿಯಾದರೂ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ಒಂದು ಕೈ ಮೋಡ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ಆ್ಯಪ್ ಒಂದರ ಸ್ಥಾನವನ್ನು ಬದಲಾಯಿಸಲು ಅದರ ಹೊರಗೆ ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ಸರಿ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ವಿಸ್ತೃತಗೊಳಿಸಿ."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ಉತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಬಹುದು, ಇದರಿಂದ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಆ್ಯಪ್ ಉತ್ತಮವಾಗಿ ಕಾಣಿಸುತ್ತದೆ, ಆದರೆ ನಿಮ್ಮ ಪ್ರಗತಿಯನ್ನು ಅಥವಾ ಯಾವುದೇ ಉಳಿಸದ ಬದಲಾವಣೆಗಳನ್ನು ನೀವು ಕಳೆದುಕೊಳ್ಳಬಹುದು"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ರದ್ದುಮಾಡಿ"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ಮತ್ತೊಮ್ಮೆ ತೋರಿಸಬೇಡಿ"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ಹಿಗ್ಗಿಸಿ"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ಕುಗ್ಗಿಸಿ"</string>
     <string name="close_button_text" msgid="2913281996024033299">"ಮುಚ್ಚಿರಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 6c58c31..74cff1f 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"위쪽 화면 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"위쪽 화면 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"아래쪽 화면 전체화면"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"한 손 사용 모드 사용하기"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"화면 하단에서 위로 스와이프하거나 앱 상단을 탭하여 종료합니다."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"한 손 사용 모드 시작"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"앱 위치를 조정하려면 앱 외부를 두 번 탭합니다."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"확인"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"추가 정보는 펼쳐서 확인하세요."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"화면에 맞게 보도록 다시 시작할까요?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"앱을 다시 시작하면 화면에 더 잘 맞게 볼 수는 있지만 진행 상황 또는 저장되지 않은 변경사항을 잃을 수도 있습니다."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"취소"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"다시 시작"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"다시 표시 안함"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"최대화"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"최소화"</string>
     <string name="close_button_text" msgid="2913281996024033299">"닫기"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 9f4dbb5..477c65d 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Үстүнкү экранды 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Үстүнкү экранды 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ылдыйкы экранды толук экран режимине өткөрүү"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бир кол режимин колдонуу"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чыгуу үчүн экранды ылдый жагынан өйдө сүрүңүз же колдонмонун өйдө жагын басыңыз"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бир кол режимин баштоо"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Колдонмону жылдыруу үчүн сырт жагын эки жолу таптаңыз"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түшүндүм"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Толук маалымат алуу үчүн жайып көрүңүз."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Жакшыраак көрүү үчүн өчүрүп күйгүзөсүзбү?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Экранда жакшыраак көрүү үчүн колдонмону өчүрүп күйгүзө аласыз, бирок аткарылган иш же сакталбаган өзгөрүүлөр өчүрүлүшү мүмкүн"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Токтотуу"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Өчүрүп күйгүзүү"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Экинчи көрүнбөсүн"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Чоңойтуу"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Кичирейтүү"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Жабуу"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 97a7344..81b0826 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ເທິງສຸດ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ເທິງສຸດ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ເຕັມໜ້າຈໍລຸ່ມສຸດ"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ກຳລັງໃຊ້ໂໝດມືດຽວ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ເພື່ອອອກ, ໃຫ້ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍ ຫຼື ແຕະບ່ອນໃດກໍໄດ້ຢູ່ເໜືອແອັບ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ເລີ່ມໂໝດມືດຽວ"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ແຕະສອງເທື່ອໃສ່ນອກແອັບໃດໜຶ່ງເພື່ອຈັດຕຳແໜ່ງຂອງມັນຄືນໃໝ່"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ເຂົ້າໃຈແລ້ວ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ຂະຫຍາຍເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ຣີສະຕາດເພື່ອໃຫ້ມີມຸມມອງທີ່ດີຂຶ້ນບໍ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ທ່ານສາມາດຣີສະຕາດແອັບໄດ້ເພື່ອໃຫ້ມັນເບິ່ງດີຂຶ້ນໃນໜ້າຈໍຂອງທ່ານ ແຕ່ທ່ານອາດຈະສູນເສຍຄວາມຄືບໜ້າ ຫຼື ການປ່ຽນແປງທີ່ບໍ່ໄດ້ບັນທຶກໄວ້"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ຍົກເລີກ"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ຣີສະຕາດ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ບໍ່ຕ້ອງສະແດງອີກ"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ຂະຫຍາຍໃຫຍ່ສຸດ"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ຫຍໍ້ລົງ"</string>
     <string name="close_button_text" msgid="2913281996024033299">"ປິດ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 5fc2592..0447ec7 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Viršutinis ekranas 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Viršutinis ekranas 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Apatinis ekranas viso ekrano režimu"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Vienos rankos režimo naudojimas"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Jei norite išeiti, perbraukite aukštyn nuo ekrano apačios arba palieskite bet kur virš programos"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pradėti vienos rankos režimą"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index a89545d..e612ddd 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Augšdaļa 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Augšdaļa 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Apakšdaļu pa visu ekrānu"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Vienas rokas režīma izmantošana"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Lai izietu, velciet augšup no ekrāna apakšdaļas vai pieskarieties jebkurā vietā virs lietotnes"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Pāriet vienas rokas režīmā"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Lai pārvietotu lietotni, veiciet dubultskārienu ārpus lietotnes"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Labi"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Izvērsiet, lai iegūtu plašāku informāciju."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vai restartēt, lai uzlabotu skatu?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Varat restartēt lietotni, lai tā labāk izskatītos ekrānā, taču, iespējams, zaudēsiet paveikto vai nesaglabātas izmaiņas (ja tādas ir)."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Atcelt"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartēt"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Vairs nerādīt"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizēt"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizēt"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Aizvērt"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 1aab9ef..3c5449c 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горниот 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горниот 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Долниот на цел екран"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Користење на режимот со една рака"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"За да излезете, повлечете нагоре од дното на екранот или допрете каде било над апликацијата"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Започни го режимот со една рака"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index f74738b..0df5c3a 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"മുകളിൽ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"മുകളിൽ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"താഴെ പൂർണ്ണ സ്ക്രീൻ"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ഒറ്റക്കൈ മോഡ് എങ്ങനെ ഉപയോഗിക്കാം"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"പുറത്ത് കടക്കാൻ, സ്ക്രീനിന്റെ ചുവടെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക അല്ലെങ്കിൽ ആപ്പിന് മുകളിലായി എവിടെയെങ്കിലും ടാപ്പ് ചെയ്യുക"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ഒറ്റക്കൈ മോഡ് ആരംഭിച്ചു"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ആപ്പിന്റെ സ്ഥാനം മാറ്റാൻ അതിന് പുറത്ത് ഡബിൾ ടാപ്പ് ചെയ്യുക"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"മനസ്സിലായി"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"കൂടുതൽ വിവരങ്ങൾക്ക് വികസിപ്പിക്കുക."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"മെച്ചപ്പെട്ട കാഴ്‌ചയ്‌ക്കായി റീസ്റ്റാർട്ട് ചെയ്യണോ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ആപ്പ് റീസ്റ്റാർട്ട് ചെയ്യുകയാണെങ്കിൽ ഇത് നിങ്ങളുടെ സ്‌ക്രീനിൽ മെച്ചപ്പെട്ടതായി കാണും, എന്നാൽ ഇതുവരെയുള്ള പുരോഗതിയും സംരക്ഷിക്കാത്ത മാറ്റങ്ങളും നിങ്ങൾക്ക് നഷ്‌ടമാകും"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"റദ്ദാക്കുക"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"റീസ്റ്റാർട്ട് ചെയ്യൂ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"വീണ്ടും കാണിക്കരുത്"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"വലുതാക്കുക"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ചെറുതാക്കുക"</string>
     <string name="close_button_text" msgid="2913281996024033299">"അടയ്ക്കുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 51c4584..5f9d3db 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Дээд 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Дээд 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Доод бүтэн дэлгэц"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Нэг гарын горимыг ашиглаж байна"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Гарахын тулд дэлгэцийн доод хэсгээс дээш шударч эсвэл апп дээр хүссэн газраа товшино уу"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Нэг гарын горимыг эхлүүлэх"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Аппыг дахин байрлуулахын тулд гадна талд нь хоёр товшино"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ойлголоо"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Нэмэлт мэдээлэл авах бол дэлгэнэ үү."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Харагдах байдлыг сайжруулахын тулд дахин эхлүүлэх үү?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Та аппыг дахин эхлүүлэх боломжтой бөгөөд ингэснээр энэ нь таны дэлгэцэд илүү сайн харагдах хэдий ч та явцаа эсвэл хадгалаагүй аливаа өөрчлөлтөө алдаж магадгүй"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Цуцлах"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Дахин эхлүүлэх"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Дахиж бүү харуул"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Томруулах"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Багасгах"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Хаах"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index cbde558..4e29c11b 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"शीर्ष 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"शीर्ष 10"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"तळाशी फुल स्क्रीन"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"एकहाती मोड वापरणे"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"बाहेर पडण्यासाठी स्क्रीनच्या खालून वरच्या दिशेने स्वाइप करा किंवा ॲपवर कोठेही टॅप करा"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"एकहाती मोड सुरू करा"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ॲपची स्थिती पुन्हा बदलण्यासाठी, त्याच्या बाहेर दोनदा टॅप करा"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"समजले"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"अधिक माहितीसाठी विस्तार करा."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"आणखी चांगल्या प्रकारे दिसावे यासाठी रीस्टार्ट करायचे आहे का?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"तुम्ही अ‍ॅप रीस्टार्ट करू शकता, जेणेकरून ते तुमच्या स्क्रीनवर आणखी चांगल्या प्रकारे दिसेल, पण तुमची प्रगती किंवा कोणतेही सेव्ह न केलेले बदल तुम्ही गमवाल"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"रद्द करा"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"रीस्टार्ट करा"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"पुन्हा दाखवू नका"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"मोठे करा"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"लहान करा"</string>
     <string name="close_button_text" msgid="2913281996024033299">"बंद करा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 23f7e52..2784472 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Atas 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Atas 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Skrin penuh bawah"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Menggunakan mod sebelah tangan"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Untuk keluar, leret ke atas daripada bahagian bawah skrin atau ketik pada mana-mana di bahagian atas apl"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Mulakan mod sebelah tangan"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketik dua kali di luar apl untuk menempatkan semula apl itu"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Kembangkan untuk mendapatkan maklumat lanjut."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Mulakan semula untuk mendapatkan paparan yang lebih baik?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Anda boleh memulakan semula apl supaya apl kelihatan lebih baik pada skrin anda tetapi anda mungkin akan hilang kemajuan anda atau apa-apa perubahan yang belum disimpan"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Batal"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulakan semula"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Jangan tunjukkan lagi"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimumkan"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimumkan"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Tutup"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 2fae552..2b78106 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"အပေါ်ဘက် မျက်နှာပြင် ၃၀%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"အောက်ခြေ မျက်နှာပြင်အပြည့်"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"လက်တစ်ဖက်သုံးမုဒ် အသုံးပြုခြင်း"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ထွက်ရန် ဖန်သားပြင်၏အောက်ခြေမှ အပေါ်သို့ပွတ်ဆွဲပါ သို့မဟုတ် အက်ပ်အပေါ်ဘက် မည်သည့်နေရာတွင်မဆို တို့ပါ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"လက်တစ်ဖက်သုံးမုဒ်ကို စတင်လိုက်သည်"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"နေရာပြန်ချရန် အက်ပ်အပြင်ဘက်ကို နှစ်ချက်တို့ပါ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"နားလည်ပြီ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"နောက်ထပ်အချက်အလက်များအတွက် ချဲ့နိုင်သည်။"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ပိုကောင်းသောမြင်ကွင်းအတွက် ပြန်စမလား။"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"အက်ပ်ကို ပြန်စပါက ၎င်းသည် စခရင်ပေါ်တွင် ပိုကြည့်ကောင်းသွားသော်လည်း သင်၏ လုပ်ငန်းစဉ် (သို့) မသိမ်းရသေးသော အပြောင်းအလဲများကို ဆုံးရှုံးနိုင်သည်"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"မလုပ်တော့"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ပြန်စရန်"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"နောက်ထပ်မပြပါနှင့်"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ချဲ့ရန်"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ချုံ့ရန်"</string>
     <string name="close_button_text" msgid="2913281996024033299">"ပိတ်ရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index b34e134..3e7c63a 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Sett størrelsen på den øverste delen av skjermen til 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Utvid den nederste delen av skjermen til hele skjermen"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bruk av enhåndsmodus"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"For å avslutte, sveip opp fra bunnen av skjermen eller trykk hvor som helst over appen"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Start enhåndsmodus"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dobbelttrykk utenfor en app for å flytte den"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Greit"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Vis for å få mer informasjon."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vil du starte på nytt for bedre visning?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kan starte appen på nytt, slik at den ser bedre ut på skjermen, men du kan miste fremdrift eller ulagrede endringer"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Avbryt"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Start på nytt"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ikke vis dette igjen"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimer"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimer"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Lukk"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 7bcca1a..1865ee5 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"माथिल्लो भाग ५०%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"माथिल्लो भाग ३०%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"तल्लो भाग फुल स्क्रिन"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"एक हाते मोड प्रयोग गरिँदै छ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"बाहिर निस्कन, स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् वा एपभन्दा माथि जुनसुकै ठाउँमा ट्याप गर्नुहोस्"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"एक हाते मोड सुरु गर्नुहोस्"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"तपाईं जुन एपको स्थिति मिलाउन चाहनुहुन्छ सोही एपको बाहिर डबल ट्याप गर्नुहोस्"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"बुझेँ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"थप जानकारी प्राप्त गर्न चाहनुहुन्छ भने एक्स्पान्ड गर्नुहोस्।"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"अझ राम्रोसँग देखिने बनाउन एप रिस्टार्ट गर्ने हो?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"यो एप तपाईंको स्क्रिनमा अझ राम्रोसँग देखियोस् भन्नाका लागि तपाईं सो एप रिस्टार्ट गर्न सक्नुहुन्छ तर तपाईंले अहिलेसम्म गरेका क्रियाकलाप वा सेभ गर्न बाँकी परिवर्तनहरू हट्न सक्छन्"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"रद्द गर्नुहोस्"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"रिस्टार्ट गर्नुहोस्"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"फेरि नदेखाइयोस्"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ठुलो बनाउनुहोस्"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"मिनिमाइज गर्नुहोस्"</string>
     <string name="close_button_text" msgid="2913281996024033299">"बन्द गर्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 6ec4739..91437ac 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Bovenste scherm 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Bovenste scherm 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Onderste scherm op volledig scherm"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Bediening met 1 hand gebruiken"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Als je wilt afsluiten, swipe je omhoog vanaf de onderkant van het scherm of tik je ergens boven de app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bediening met 1 hand starten"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dubbeltik naast een app om deze opnieuw te positioneren"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Uitvouwen voor meer informatie."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Opnieuw opstarten voor een betere weergave?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Je kunt de app opnieuw opstarten zodat deze er beter uitziet op je scherm, maar je kunt je voortgang of niet-opgeslagen wijzigingen kwijtraken"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuleren"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Opnieuw opstarten"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Niet opnieuw tonen"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximaliseren"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimaliseren"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Sluiten"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index 0f27984..d330749 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ଉପର ଆଡ଼କୁ 30% କରନ୍ତୁ"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ତଳ ଅଂଶର ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ଏକ-ହାତ ମୋଡ୍ ବ୍ୟବହାର କରି"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ବାହାରି ଯିବା ପାଇଁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ କିମ୍ବା ଆପରେ ଯେ କୌଣସି ସ୍ଥାନରେ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ଏକ-ହାତ ମୋଡ୍ ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହାର ବାହାରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ବୁଝିଗଲି"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ଅଧିକ ସୂଚନା ପାଇଁ ବିସ୍ତାର କରନ୍ତୁ।"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ଏକ ଭଲ ଭ୍ୟୁ ପାଇଁ ରିଷ୍ଟାର୍ଟ କରିବେ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ଆପଣ ଆପକୁ ରିଷ୍ଟାର୍ଟ କରିପାରିବେ ଯାହା ଫଳରେ ଏହା ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଆହୁରି ଭଲ ଦେଖାଯିବ, କିନ୍ତୁ ଆପଣ ଆପଣଙ୍କ ପ୍ରଗତି କିମ୍ବା ସେଭ ହୋଇନଥିବା ଯେ କୌଣସି ପରିବର୍ତ୍ତନ ହରାଇପାରନ୍ତି"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ବାତିଲ କରନ୍ତୁ"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ରିଷ୍ଟାର୍ଟ କରନ୍ତୁ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ବଡ଼ କରନ୍ତୁ"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ଛୋଟ କରନ୍ତୁ"</string>
     <string name="close_button_text" msgid="2913281996024033299">"ବନ୍ଦ କରନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 2baec3c..51d491b 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ਉੱਪਰ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ਉੱਪਰ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"ਹੇਠਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ਇੱਕ ਹੱਥ ਮੋਡ ਵਰਤਣਾ"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"ਬਾਹਰ ਜਾਣ ਲਈ, ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ ਜਾਂ ਐਪ \'ਤੇ ਕਿਤੇ ਵੀ ਟੈਪ ਕਰੋ"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ਇੱਕ ਹੱਥ ਮੋਡ ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਬਾਹਰ ਡਬਲ ਟੈਪ ਕਰੋ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ਸਮਝ ਲਿਆ"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਵਿਸਤਾਰ ਕਰੋ।"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"ਕੀ ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਲਈ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ਤੁਸੀਂ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰ ਸਕਦੇ ਹੋ ਤਾਂ ਜੋ ਇਹ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਬਿਹਤਰ ਦਿਸੇ, ਪਰ ਤੁਸੀਂ ਆਪਣੀ ਪ੍ਰਗਤੀ ਜਾਂ ਕਿਸੇ ਅਣਰੱਖਿਅਤ ਤਬਦੀਲੀ ਨੂੰ ਗੁਆ ਸਕਦੇ ਹੋ"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ਰੱਦ ਕਰੋ"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"ਵੱਡਾ ਕਰੋ"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"ਛੋਟਾ ਕਰੋ"</string>
     <string name="close_button_text" msgid="2913281996024033299">"ਬੰਦ ਕਰੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index ecf6b4d..32e9840 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% górnej części ekranu"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% górnej części ekranu"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolna część ekranu na pełnym ekranie"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Korzystanie z trybu jednej ręki"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Aby zamknąć, przesuń palcem z dołu ekranu w górę lub kliknij dowolne miejsce nad aplikacją"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Uruchom tryb jednej ręki"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Kliknij dwukrotnie poza aplikacją, aby ją przenieść"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Rozwiń, aby wyświetlić więcej informacji."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Uruchomić ponownie dla lepszego wyglądu?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Możesz ponownie uruchomić aplikację, aby lepiej wyglądała na ekranie, ale istnieje ryzyko, że utracisz postępy i niezapisane zmiany"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Anuluj"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Uruchom ponownie"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nie pokazuj ponownie"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksymalizuj"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimalizuj"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zamknij"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 847573b..1a29af2 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Parte superior a 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Parte inferior em tela cheia"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de um app para reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Reiniciar para melhorar a visualização?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Você pode reiniciar o app para melhorar a visualização dele, mas talvez perca seu progresso ou mudanças não salvas"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar novamente"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index b684c6c..b2d8e08 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"50% no ecrã superior"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"30% no ecrã superior"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ecrã inferior inteiro"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Utilize o modo para uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize rapidamente para cima a partir da parte inferior do ecrã ou toque em qualquer ponto acima da app."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de uma app para a reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Expandir para obter mais informações"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Reiniciar para uma melhor visualização?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Pode reiniciar a app para ficar com um melhor aspeto no seu ecrã, mas pode perder o seu progresso ou eventuais alterações não guardadas"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar de novo"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 847573b..1a29af2 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Parte superior a 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Parte superior a 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Parte inferior em tela cheia"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Toque duas vezes fora de um app para reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Abra para ver mais informações."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Reiniciar para melhorar a visualização?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Você pode reiniciar o app para melhorar a visualização dele, mas talvez perca seu progresso ou mudanças não salvas"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Cancelar"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reiniciar"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Não mostrar novamente"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizar"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizar"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Fechar"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 5342dfb..8f60979 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Partea de sus: 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Partea de sus: 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Partea de jos pe ecran complet"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Folosirea modului cu o mână"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pentru a ieși, glisează în sus din partea de jos a ecranului sau atinge oriunde deasupra ferestrei aplicației"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Activează modul cu o mână"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Atinge de două ori lângă o aplicație pentru a o repoziționa"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Extinde pentru mai multe informații"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Repornești pentru o vizualizare mai bună?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Poți să repornești aplicația ca să arate mai bine pe ecran, dar este posibil să pierzi progresul sau modificările nesalvate"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Anulează"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Repornește"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Nu mai afișa"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximizează"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizează"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Închide"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 71925a1..0c1e4a9 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхний на 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхний на 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Нижний во весь экран"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Использование режима управления одной рукой"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чтобы выйти, проведите по экрану снизу вверх или коснитесь области за пределами приложения."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Запустить режим управления одной рукой"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Чтобы переместить приложение, дважды нажмите рядом с ним."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОК"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Развернуть, чтобы узнать больше."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Перезапустить приложение?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Вы можете перезапустить приложение, чтобы оно лучше смотрелось на экране. При этом ваш прогресс или несохраненные изменения могут быть утеряны."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Отмена"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Перезапустить"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Больше не показывать"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Развернуть"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Свернуть"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Закрыть"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 188a137..13ac518 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ඉහළම 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ඉහළම 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"පහළ පූර්ණ තිරය"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"තනි-අත් ප්‍රකාරය භාවිත කරමින්"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"පිටවීමට, තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න හෝ යෙදුමට ඉහළින් ඕනෑම තැනක තට්ටු කරන්න"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"තනි අත් ප්‍රකාරය ආරම්භ කරන්න"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"යෙදුමක් නැවත ස්ථානගත කිරීමට පිටතින් දෙවරක් තට්ටු කරන්න"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"තේරුණා"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"වැඩිදුර තොරතුරු සඳහා දිග හරින්න"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"වඩා හොඳ දසුනක් සඳහා යළි අරඹන්න ද?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ඔබට එය ඔබේ තිරයෙහි වඩා හොඳින් පෙනෙන පරිදි යෙදුම යළි ඇරඹිය හැකි නමුත්, ඔබට ඔබේ ප්‍රගතිය හෝ නොසුරකින ලද වෙනස්කම් අහිමි විය හැක"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"අවලංගු කරන්න"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"යළි අරඹන්න"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"නැවත නොපෙන්වන්න"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"විහිදන්න"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"කුඩා කරන්න"</string>
     <string name="close_button_text" msgid="2913281996024033299">"වසන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 0aa4f30..c91856c 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Horná – 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Horná – 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Dolná – na celú obrazovku"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Používanie režimu jednej ruky"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ukončíte potiahnutím z dolnej časti obrazovky nahor alebo klepnutím kdekoľvek nad aplikáciu"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Spustiť režim jednej ruky"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvojitým klepnutím mimo aplikácie zmeníte jej pozíciu"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Dobre"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Po rozbalení sa dozviete viac."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Chcete ju reštartovať, aby mala lepší vzhľad?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Aplikáciu môžete reštartovať, aby mala na obrazovke lepší vzhľad, ale môžete prísť o postup a všetky neuložené zmeny."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Zrušiť"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Reštartovať"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Už nezobrazovať"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maximalizovať"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimalizovať"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zavrieť"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index a4eb3d0..744492c 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Zgornji 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Zgornji 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Spodnji v celozaslonski način"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Uporaba enoročnega načina"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Za izhod povlecite z dna zaslona navzgor ali se dotaknite na poljubnem mestu nad aplikacijo"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Zagon enoročnega načina"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Dvakrat se dotaknite zunaj aplikacije, če jo želite prestaviti."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"V redu"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Razširitev za več informacij"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Želite znova zagnati za boljši pregled?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Če znova zaženete aplikacijo, bo prikaz na zaslonu boljši, vendar lahko izgubite napredek ali neshranjene spremembe."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Prekliči"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Znova zaženi"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikaži več"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimiraj"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimiraj"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Zapri"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index cc4b7a4..9afbbba 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Lart 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Lart 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ekrani i plotë poshtë"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Po përdor modalitetin e përdorimit me një dorë"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Për të dalë, rrëshqit lart nga fundi i ekranit ose trokit diku mbi aplikacion"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Modaliteti i përdorimit me një dorë"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Trokit dy herë jashtë një aplikacioni për ta ripozicionuar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"E kuptova"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Zgjeroje për më shumë informacion."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Rinis për një pamje më të mirë?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Mund të rinisësh aplikacionin në mënyrë që të duket më mirë në ekranin tënd, por mund të humbësh progresin ose çdo ndryshim të paruajtur"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Anulo"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Rinis"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Mos e shfaq përsëri"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Maksimizo"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimizo"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Mbyll"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 80f7aa6..c252fd7 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Горњи екран 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Горњи екран 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Режим целог екрана за доњи екран"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Коришћење режима једном руком"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Да бисте изашли, превуците нагоре од дна екрана или додирните било где изнад апликације"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Покрените режим једном руком"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Двапут додирните изван апликације да бисте променили њену позицију"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширите за још информација."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Желите ли да рестартујете ради бољег приказа?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Можете да рестартујете апликацију да би изгледала боље на екрану, с тим што можете да изгубите оно што сте урадили или несачуване промене, ако их има"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Откажи"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартуј"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Не приказуј поново"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Увећајте"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Умањите"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Затворите"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 4a4b6c9..92622cb 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Övre 50 %"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Övre 30 %"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Helskärm på nedre skärm"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Använda enhandsläge"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Avsluta genom att svepa uppåt från skärmens nederkant eller trycka ovanför appen"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Starta enhandsläge"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Tryck snabbt två gånger utanför en app för att flytta den"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Utöka för mer information."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Vill du starta om för en bättre vy?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Du kan starta om appen så den passar bättre på skärmen men du kan förlora dina framsteg och eventuella osparade ändringar."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Avbryt"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Starta om"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Visa inte igen"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Utöka"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Minimera"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Stäng"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index ad33144..6d92040 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Juu 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Juu 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Skrini nzima ya chini"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Kutumia hali ya kutumia kwa mkono mmoja"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ili ufunge, telezesha kidole juu kutoka sehemu ya chini ya skrini au uguse mahali popote juu ya programu"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Anzisha hali ya kutumia kwa mkono mmoja"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Gusa mara mbili nje ya programu ili uihamishe"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Nimeelewa"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Panua ili upate maelezo zaidi."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Ungependa kuzima kisha uwashe ili upate mwonekano bora zaidi?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Unaweza kuzima kisha uwashe programu yako ili ifanye kazi vizuri zaidi kwenye skrini yako, lakini unaweza kupoteza maendeleo yako au mabadiliko yoyote ambayo hayajahifadhiwa"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Ghairi"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Zima kisha uwashe"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Usionyeshe tena"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Panua"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Punguza"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Funga"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 52f5e22..8cf631b 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"மேலே 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"மேலே 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"கீழ்ப்புறம் முழுத் திரை"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ஒற்றைக் கைப் பயன்முறையைப் பயன்படுத்துதல்"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"வெளியேற, திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்யவும் அல்லது ஆப்ஸுக்கு மேலே ஏதேனும் ஓர் இடத்தில் தட்டவும்"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ஒற்றைக் கைப் பயன்முறையைத் தொடங்கும்"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ஆப்ஸை இடம் மாற்ற அதன் வெளியில் இருமுறை தட்டலாம்"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"சரி"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"கூடுதல் தகவல்களுக்கு விரிவாக்கலாம்."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"சரியான விதத்தில் காட்டப்பட மீண்டும் தொடங்கவா?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"ஆப்ஸை மீண்டும் தொடங்குவதன் மூலம் திரையில் அது சரியான விதத்தில் தோற்றமளிக்கும். ஆனால் செயல்நிலையையோ சேமிக்கப்படாமல் இருக்கும் மாற்றங்களையோ நீங்கள் இழக்கக்கூடும்."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ரத்துசெய்"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"மீண்டும் தொடங்கு"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"மீண்டும் காட்டாதே"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"பெரிதாக்கும்"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"சிறிதாக்கும்"</string>
     <string name="close_button_text" msgid="2913281996024033299">"மூடும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 2eb739d..a4dcd95 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ఎగువ 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ఎగువ 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"దిగువ ఫుల్-స్క్రీన్‌"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"వన్-హ్యాండెడ్ మోడ్‌ను ఉపయోగించడం"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"నిష్క్రమించడానికి, స్క్రీన్ కింది భాగం నుండి పైకి స్వైప్ చేయండి లేదా యాప్ పైన ఎక్కడైనా ట్యాప్ చేయండి"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"వన్-హ్యాండెడ్ మోడ్‌ను ప్రారంభిస్తుంది"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"యాప్ స్థానాన్ని మార్చడానికి దాని వెలుపల డబుల్-ట్యాప్ చేయండి"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"మరింత సమాచారం కోసం విస్తరించండి."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"మెరుగైన వీక్షణ కోసం రీస్టార్ట్ చేయాలా?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"మీరు యాప్‌ని రీస్టార్ట్ చేయవచ్చు, తద్వారా ఇది మీ స్క్రీన్‌పై మెరుగ్గా కనిపిస్తుంది, కానీ మీరు మీ ప్రోగ్రెస్‌ను గానీ లేదా సేవ్ చేయని ఏవైనా మార్పులను గానీ కోల్పోవచ్చు"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"రద్దు చేయండి"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"రీస్టార్ట్ చేయండి"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"మళ్లీ చూపవద్దు"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"గరిష్టీకరించండి"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"కుదించండి"</string>
     <string name="close_button_text" msgid="2913281996024033299">"మూసివేయండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index e0b1bb1..1e900d8 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ด้านบน 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ด้านบน 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"เต็มหน้าจอด้านล่าง"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"การใช้โหมดมือเดียว"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"หากต้องการออก ให้เลื่อนขึ้นจากด้านล่างของหน้าจอหรือแตะที่ใดก็ได้เหนือแอป"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"เริ่มโหมดมือเดียว"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index a49ed27..8d5d0ed 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Gawing 50% ang nasa itaas"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Gawing 30% ang nasa itaas"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"I-full screen ang nasa ibaba"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Paggamit ng one-hand mode"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para lumabas, mag-swipe pataas mula sa ibaba ng screen o mag-tap kahit saan sa itaas ng app"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Simulan ang one-hand mode"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index c19e083..341d8f1 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Üstte %50"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Üstte %30"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Altta tam ekran"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Tek el modunu kullanma"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Çıkmak için ekranın alt kısmından yukarı kaydırın veya uygulamanın üzerinde herhangi bir yere dokunun"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Tek el modunu başlat"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Yeniden konumlandırmak için uygulamanın dışına iki kez dokunun"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Daha fazla bilgi için genişletin."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Daha iyi bir görünüm için yeniden başlatılsın mı?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ekranınızda daha iyi görünmesi için uygulamayı yeniden başlatabilirsiniz, ancak ilerlemenizi ve kaydedilmemiş değişikliklerinizi kaybedebilirsiniz"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"İptal"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Yeniden başlat"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Bir daha gösterme"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Ekranı Kapla"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Küçült"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Kapat"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index 6869401..5b017c6 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Верхнє вікно на 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Верхнє вікно на 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Нижнє вікно на весь екран"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Як користуватися режимом керування однією рукою"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Щоб вийти, проведіть пальцем по екрану знизу вгору або торкніться екрана над додатком"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Увімкнути режим керування однією рукою"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Щоб перемістити додаток, двічі торкніться області поза ним"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Розгорніть, щоб дізнатися більше."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Перезапустити для зручнішого перегляду?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ви можете перезапустити додаток, щоб покращити його вигляд на екрані, але ваші досягнення або незбережені зміни може бути втрачено"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Скасувати"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Перезапустити"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Більше не показувати"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Збільшити"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Згорнути"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Закрити"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index e3a22eb..6493569 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"اوپر %50"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"اوپر %30"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"نچلی فل اسکرین"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"ایک ہاتھ کی وضع کا استعمال کرنا"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"باہر نکلنے کیلئے، اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں یا ایپ کے اوپر کہیں بھی تھپتھپائیں"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"ایک ہاتھ کی وضع شروع کریں"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"کسی ایپ کی پوزیشن تبدیل کرنے کے لیے اس ایپ کے باہر دو بار تھپتھپائیں"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"سمجھ آ گئی"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"مزید معلومات کے لیے پھیلائیں۔"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"بہتر منظر کے لیے ری سٹارٹ کریں؟"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"آپ ایپ کو ری سٹارٹ کر سکتے ہیں تاکہ یہ آپ کی اسکرین پر بہتر نظر آئے، تاہم آپ اپنی پیشرفت سے یا کسی غیر محفوظ شدہ تبدیلیوں سے محروم ہو سکتے ہیں"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"منسوخ کریں"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"ری اسٹارٹ کریں"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"دوبارہ نہ دکھائیں"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"بڑا کریں"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"چھوٹا کریں"</string>
     <string name="close_button_text" msgid="2913281996024033299">"بند کریں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index d12dac3..fdca0d6 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Tepada 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Tepada 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Pastda to‘liq ekran"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ixcham rejimdan foydalanish"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Chiqish uchun ekran pastidan tepaga suring yoki ilovaning tepasidagi istalgan joyga bosing."</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Ixcham rejimni ishga tushirish"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Qayta joylash uchun ilova tashqarisiga ikki marta bosing"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Batafsil axborot olish uchun kengaytiring."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Yaxshi koʻrinishi uchun qayta ishga tushirilsinmi?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ilovani ekranda yaxshiroq koʻrinishi uchun qayta ishga tushirishingiz mumkin. Bunda jarayonlar yoki saqlanmagan oʻzgarishlar yoʻqolishi mumkin."</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Bekor qilish"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Qaytadan"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Boshqa chiqmasin"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Yoyish"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Kichraytirish"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Yopish"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 39de38c..8fd2551 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Trên 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Trên 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Toàn màn hình phía dưới"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Cách dùng chế độ một tay"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Để thoát, hãy vuốt lên từ cuối màn hình hoặc nhấn vào vị trí bất kỳ phía trên ứng dụng"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Bắt đầu chế độ một tay"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Nhấn đúp bên ngoài ứng dụng để đặt lại vị trí"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Mở rộng để xem thêm thông tin."</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Khởi động lại để ứng dụng trông vừa vặn hơn?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Bạn có thể khởi động lại ứng dụng để ứng dụng nhìn đẹp hơn trên màn hình. Tuy nhiên, nếu làm vậy, bạn có thể mất tiến trình hoặc mọi thay đổi chưa lưu"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Huỷ"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Khởi động lại"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Không hiện lại"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Phóng to"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Thu nhỏ"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Đóng"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index c787f61..ba78d1b 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"顶部 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"顶部 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"底部全屏"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用单手模式"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如需退出,请从屏幕底部向上滑动,或点按应用上方的任意位置"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"启动单手模式"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在某个应用外连续点按两次,即可调整它的位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展开即可了解详情。"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"重启以改进外观?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"您可以重启应用,使其在屏幕上的显示效果更好,但您可能会丢失进度或任何未保存的更改"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"取消"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"重启"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不再显示"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
     <string name="close_button_text" msgid="2913281996024033299">"关闭"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 395b2a9..b3bc5b6 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"頂部 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"頂部 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"底部全螢幕"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用單手模式"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如要退出,請從螢幕底部向上滑動,或輕按應用程式上方的任何位置"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"開始單手模式"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在應用程式外輕按兩下即可調整位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳情。"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"要重新啟動改善檢視畫面嗎?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"您可重新啟動應用程式,讓系統更新檢視畫面;但系統可能不會儲存目前進度及您作出的任何變更"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"取消"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"重新啟動"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不要再顯示"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
     <string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 8a84f15..e744461 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"以 50% 的螢幕空間顯示頂端畫面"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"以 30% 的螢幕空間顯示頂端畫面"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"以全螢幕顯示底部畫面"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"使用單手模式"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"如要退出,請從螢幕底部向上滑動,或輕觸應用程式上方的任何位置"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"啟動單手模式"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在應用程式外輕觸兩下即可調整位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"我知道了"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳細資訊。"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"要重新啟動改善檢視畫面嗎?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"你可以重新啟動應用程式,讓系統更新檢視畫面。不過,系統可能不會儲存目前進度及你所做的任何變更"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"取消"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"重新啟動"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不要再顯示"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"最大化"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"最小化"</string>
     <string name="close_button_text" msgid="2913281996024033299">"關閉"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index fca5a7a..913e68f 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -49,6 +49,14 @@
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"Okuphezulu okungu-50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Okuphezulu okungu-30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ngaphansi kwesikrini esigcwele"</string>
+    <!-- no translation found for accessibility_split_left (1713683765575562458) -->
+    <skip />
+    <!-- no translation found for accessibility_split_right (8441001008181296837) -->
+    <skip />
+    <!-- no translation found for accessibility_split_top (2789329702027147146) -->
+    <skip />
+    <!-- no translation found for accessibility_split_bottom (8694551025220868191) -->
+    <skip />
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Ukusebenzisa imodi yesandla esisodwa"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Ukuze uphume, swayipha ngaphezulu kusuka ngezansi kwesikrini noma thepha noma kuphi ngenhla kohlelo lokusebenza"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Qalisa imodi yesandla esisodwa"</string>
@@ -84,16 +92,11 @@
     <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Thepha kabili ngaphandle kwe-app ukuze uyimise kabusha"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ngiyezwa"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Nweba ukuze uthole ulwazi olwengeziwe"</string>
-    <!-- no translation found for letterbox_restart_dialog_title (8543049527871033505) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_description (6096946078246557848) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_cancel (1342209132692537805) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_restart (8529976234412442973) -->
-    <skip />
-    <!-- no translation found for letterbox_restart_dialog_checkbox_title (5252918008140768386) -->
-    <skip />
+    <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Qala kabusha ukuze uthole ukubuka okungcono?"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Ungakwazi ukuqala kabusha i-app ukuze ibukeke kangcono esikrinini sakho, kodwa ungase ulahlekelwe ukuqhubeka kwakho nanoma yiziphi izinguquko ezingalondoloziwe"</string>
+    <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Khansela"</string>
+    <string name="letterbox_restart_restart" msgid="8529976234412442973">"Qala kabusha"</string>
+    <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ungabonisi futhi"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Khulisa"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Nciphisa"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Vala"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 8908959..6f31d06 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -228,7 +228,7 @@
     <dimen name="bubble_user_education_stack_padding">16dp</dimen>
 
     <!-- Bottom and end margin for compat buttons. -->
-    <dimen name="compat_button_margin">16dp</dimen>
+    <dimen name="compat_button_margin">24dp</dimen>
 
     <!-- The radius of the corners of the compat hint bubble. -->
     <dimen name="compat_hint_corner_radius">28dp</dimen>
@@ -367,8 +367,12 @@
     <!-- Width of buttons (32dp each) + padding (128dp total). -->
     <dimen name="freeform_decor_caption_menu_width">256dp</dimen>
 
+    <dimen name="freeform_decor_caption_menu_height">250dp</dimen>
+
     <dimen name="freeform_resize_handle">30dp</dimen>
 
     <dimen name="freeform_resize_corner">44dp</dimen>
 
+    <dimen name="caption_menu_elevation">4dp</dimen>
+
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 3fd97ef..3082962 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -105,6 +105,15 @@
     <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_divider_bottom_full">Bottom full screen</string>
 
+    <!-- Accessibility label for splitting to the left drop zone [CHAR LIMIT=NONE] -->
+    <string name="accessibility_split_left">Split left</string>
+    <!-- Accessibility label for splitting to the right drop zone [CHAR LIMIT=NONE] -->
+    <string name="accessibility_split_right">Split right</string>
+    <!-- Accessibility label for splitting to the top drop zone [CHAR LIMIT=NONE] -->
+    <string name="accessibility_split_top">Split top</string>
+    <!-- Accessibility label for splitting to the bottom drop zone [CHAR LIMIT=NONE] -->
+    <string name="accessibility_split_bottom">Split bottom</string>
+
     <!-- One-Handed Tutorial title [CHAR LIMIT=60] -->
     <string name="one_handed_tutorial_title">Using one-handed mode</string>
     <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] -->
@@ -221,6 +230,8 @@
     <string name="back_button_text">Back</string>
     <!-- Accessibility text for the caption handle [CHAR LIMIT=NONE] -->
     <string name="handle_text">Handle</string>
+    <!-- Accessibility text for the handle menu app icon [CHAR LIMIT=NONE] -->
+    <string name="app_icon_text">App Icon</string>
     <!-- Accessibility text for the handle fullscreen button [CHAR LIMIT=NONE] -->
     <string name="fullscreen_text">Fullscreen</string>
     <!-- Accessibility text for the handle desktop button [CHAR LIMIT=NONE] -->
@@ -231,4 +242,12 @@
     <string name="more_button_text">More</string>
     <!-- Accessibility text for the handle floating window button [CHAR LIMIT=NONE] -->
     <string name="float_button_text">Float</string>
+    <!-- Accessibility text for the handle menu select button [CHAR LIMIT=NONE] -->
+    <string name="select_text">Select</string>
+    <!-- Accessibility text for the handle menu screenshot button [CHAR LIMIT=NONE] -->
+    <string name="screenshot_text">Screenshot</string>
+    <!-- Accessibility text for the handle menu close button [CHAR LIMIT=NONE] -->
+    <string name="close_text">Close</string>
+    <!-- Accessibility text for the handle menu close menu button [CHAR LIMIT=NONE] -->
+    <string name="collapse_menu_text">Close Menu</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index e8f340c..bae009a 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -37,6 +37,22 @@
         <item name="android:padding">4dp</item>
     </style>
 
+    <style name="CaptionWindowingButtonStyle">
+        <item name="android:layout_width">32dp</item>
+        <item name="android:layout_height">32dp</item>
+        <item name="android:padding">4dp</item>
+        <item name="android:layout_marginTop">5dp</item>
+        <item name="android:layout_marginBottom">5dp</item>
+    </style>
+
+    <style name="CaptionMenuButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">52dp</item>
+        <item name="android:layout_marginStart">10dp</item>
+        <item name="android:padding">4dp</item>
+        <item name="android:gravity">start|center_vertical</item>
+    </style>
+
     <style name="DockedDividerBackground">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">@dimen/split_divider_bar_width</item>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
index d276002..88525aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
@@ -84,6 +84,15 @@
                 String[] groups = Arrays.copyOfRange(args, 1, args.length);
                 return mShellProtoLog.stopTextLogging(groups, pw) == 0;
             }
+            case "save-for-bugreport": {
+                if (!mShellProtoLog.isProtoEnabled()) {
+                    pw.println("Logging to proto is not enabled for WMShell.");
+                    return false;
+                }
+                mShellProtoLog.stopProtoLog(pw, true /* writeToFile */);
+                mShellProtoLog.startProtoLog(pw);
+                return true;
+            }
             default: {
                 pw.println("Invalid command: " + args[0]);
                 printShellCommandHelp(pw, "");
@@ -108,5 +117,7 @@
         pw.println(prefix + "  Enable logcat logging for given groups.");
         pw.println(prefix + "disable-text [group...]");
         pw.println(prefix + "  Disable logcat logging for given groups.");
+        pw.println(prefix + "save-for-bugreport");
+        pw.println(prefix + "  Flush proto logging to file, only if it's enabled.");
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
index 5d451a5..7a6aec7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java
@@ -173,7 +173,7 @@
      */
     public void onLocationChanged() {
         getBoundsOnScreen(mTmpRect);
-        mTaskViewTaskController.onLocationChanged(mTmpRect);
+        mTaskViewTaskController.setWindowBounds(mTmpRect);
     }
 
     /**
@@ -198,7 +198,7 @@
     public void surfaceChanged(@androidx.annotation.NonNull SurfaceHolder holder, int format,
             int width, int height) {
         getBoundsOnScreen(mTmpRect);
-        mTaskViewTaskController.surfaceChanged(mTmpRect);
+        mTaskViewTaskController.setWindowBounds(mTmpRect);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java
index 69ce35f..1f223a6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/TaskViewTaskController.java
@@ -183,26 +183,6 @@
     }
 
     /**
-     * Call when view position or size has changed. Do not call when animating.
-     */
-    public void onLocationChanged(Rect newBounds) {
-        if (mTaskToken == null) {
-            return;
-        }
-        // Sync Transactions can't operate simultaneously with shell transition collection.
-        // The transition animation (upon showing) will sync the location itself.
-        if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return;
-
-        WindowContainerTransaction wct = new WindowContainerTransaction();
-        updateWindowBounds(wct);
-        mSyncQueue.queue(wct);
-    }
-
-    private void updateWindowBounds(WindowContainerTransaction wct) {
-        wct.setBounds(mTaskToken, mTaskViewBase.getCurrentBoundsOnScreen());
-    }
-
-    /**
      * Release this container if it is initialized.
      */
     public void release() {
@@ -394,15 +374,24 @@
     }
 
     /**
-     * Should be called when the client surface is changed.
+     * Sets the window bounds to {@code boundsOnScreen}.
+     * Call when view position or size has changed. Can also be called before the animation when
+     * the final bounds are known.
+     * Do not call during the animation.
      *
      * @param boundsOnScreen the on screen bounds of the surface view.
      */
-    public void surfaceChanged(Rect boundsOnScreen) {
+    public void setWindowBounds(Rect boundsOnScreen) {
         if (mTaskToken == null) {
             return;
         }
-        onLocationChanged(boundsOnScreen);
+        // Sync Transactions can't operate simultaneously with shell transition collection.
+        // The transition animation (upon showing) will sync the location itself.
+        if (isUsingShellTransitions() && mTaskViewTransitions.hasPending()) return;
+
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setBounds(mTaskToken, boundsOnScreen);
+        mSyncQueue.queue(wct);
     }
 
     /** Should be called when the client surface is destroyed. */
@@ -493,7 +482,7 @@
                     .setPosition(mTaskLeash, 0, 0)
                     .apply();
 
-            updateWindowBounds(wct);
+            wct.setBounds(mTaskToken, mTaskViewBase.getCurrentBoundsOnScreen());
         } else {
             // The surface has already been destroyed before the task has appeared,
             // so go ahead and hide the task entirely
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
index 00b9fced..579f7aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationAdapter.java
@@ -22,7 +22,6 @@
 import android.annotation.CallSuper;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.view.Choreographer;
 import android.view.SurfaceControl;
 import android.view.animation.Animation;
 import android.view.animation.Transformation;
@@ -71,7 +70,6 @@
     final float[] mVecs = new float[4];
     @NonNull
     final Rect mRect = new Rect();
-    private boolean mIsFirstFrame = true;
     private int mOverrideLayer = LAYER_NO_OVERRIDE;
 
     ActivityEmbeddingAnimationAdapter(@NonNull Animation animation,
@@ -117,20 +115,21 @@
         mOverrideLayer = layer;
     }
 
+    /** Called to prepare for the starting state. */
+    final void prepareForFirstFrame(@NonNull SurfaceControl.Transaction startTransaction) {
+        startTransaction.show(mLeash);
+        if (mOverrideLayer != LAYER_NO_OVERRIDE) {
+            startTransaction.setLayer(mLeash, mOverrideLayer);
+        }
+        mAnimation.getTransformationAt(0, mTransformation);
+        onAnimationUpdateInner(startTransaction);
+    }
+
     /** Called on frame update. */
     final void onAnimationUpdate(@NonNull SurfaceControl.Transaction t, long currentPlayTime) {
-        if (mIsFirstFrame) {
-            t.show(mLeash);
-            if (mOverrideLayer != LAYER_NO_OVERRIDE) {
-                t.setLayer(mLeash, mOverrideLayer);
-            }
-            mIsFirstFrame = false;
-        }
-
         // Extract the transformation to the current time.
         mAnimation.getTransformation(Math.min(currentPlayTime, mAnimation.getDuration()),
                 mTransformation);
-        t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
         onAnimationUpdateInner(t);
     }
 
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 164d2f1..fe3c4ea 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
@@ -32,6 +32,7 @@
 import android.os.IBinder;
 import android.util.ArraySet;
 import android.util.Log;
+import android.view.Choreographer;
 import android.view.SurfaceControl;
 import android.view.animation.Animation;
 import android.window.TransitionInfo;
@@ -130,11 +131,13 @@
             animator.addUpdateListener((anim) -> {
                 // Update all adapters in the same transaction.
                 final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+                t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
                 for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
                     adapter.onAnimationUpdate(t, animator.getCurrentPlayTime());
                 }
                 t.apply();
             });
+            prepareForFirstFrame(startTransaction, adapters);
         }
         animator.setDuration(duration);
         animator.addListener(new Animator.AnimatorListener() {
@@ -248,6 +251,15 @@
         return adapters;
     }
 
+    /** Sets the first frame to the {@code startTransaction} to avoid any flicker on start. */
+    private void prepareForFirstFrame(@NonNull SurfaceControl.Transaction startTransaction,
+            @NonNull List<ActivityEmbeddingAnimationAdapter> adapters) {
+        startTransaction.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
+        for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
+            adapter.prepareForFirstFrame(startTransaction);
+        }
+    }
+
     /** Adds edge extension to the surfaces that have such an animation property. */
     private void addEdgeExtensionIfNeeded(@NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java
index 38f1e28..da113cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java
@@ -370,13 +370,7 @@
 
         @Override
         public void onBackCancelled() {
-            // End the fade in animation.
             mProgressAnimator.onBackCancelled(CrossActivityAnimation.this::finishAnimation);
-            mEnteringProgressSpring.cancel();
-            mLeavingProgressSpring.cancel();
-            // TODO (b259608500): Let BackProgressAnimator could play cancel animation.
-            mProgressAnimator.reset();
-            finishAnimation();
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 360bfe7..36c0cb6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -68,10 +68,14 @@
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.view.IWindowManager;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowInsets;
 import android.view.WindowManager;
+import android.window.ScreenCapture;
+import android.window.ScreenCapture.ScreenCaptureListener;
+import android.window.ScreenCapture.ScreenshotSync;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
@@ -143,6 +147,7 @@
     private final SyncTransactionQueue mSyncQueue;
     private final ShellController mShellController;
     private final ShellCommandHandler mShellCommandHandler;
+    private final IWindowManager mWmService;
 
     // Used to post to main UI thread
     private final ShellExecutor mMainExecutor;
@@ -237,7 +242,8 @@
             @ShellMainThread Handler mainHandler,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             TaskViewTransitions taskViewTransitions,
-            SyncTransactionQueue syncQueue) {
+            SyncTransactionQueue syncQueue,
+            IWindowManager wmService) {
         mContext = context;
         mShellCommandHandler = shellCommandHandler;
         mShellController = shellController;
@@ -269,6 +275,7 @@
         mOneHandedOptional = oneHandedOptional;
         mDragAndDropController = dragAndDropController;
         mSyncQueue = syncQueue;
+        mWmService = wmService;
         shellInit.addInitCallback(this::onInit, this);
     }
 
@@ -1037,6 +1044,26 @@
     }
 
     /**
+     * Performs a screenshot that may exclude the bubble layer, if one is present. The screenshot
+     * can be access via the supplied {@link ScreenshotSync#get()} asynchronously.
+     *
+     * TODO(b/267324693): Implement the exclude layer functionality in screenshot.
+     */
+    public void getScreenshotExcludingBubble(int displayId,
+            Pair<ScreenCaptureListener, ScreenshotSync> screenCaptureListener) {
+        try {
+            mWmService.captureDisplay(displayId, null, screenCaptureListener.first);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to capture screenshot");
+        }
+    }
+
+    /** Sets the app bubble's taskId which is cached for SysUI. */
+    public void setAppBubbleTaskId(int taskId) {
+        mImpl.mCachedState.setAppBubbleTaskId(taskId);
+    }
+
+    /**
      * Fills the overflow bubbles by loading them from disk.
      */
     void loadOverflowBubblesFromDisk() {
@@ -1614,6 +1641,7 @@
             private HashSet<String> mSuppressedBubbleKeys = new HashSet<>();
             private HashMap<String, String> mSuppressedGroupToNotifKeys = new HashMap<>();
             private HashMap<String, Bubble> mShortcutIdToBubble = new HashMap<>();
+            private int mAppBubbleTaskId = INVALID_TASK_ID;
 
             private ArrayList<Bubble> mTmpBubbles = new ArrayList<>();
 
@@ -1645,12 +1673,22 @@
 
                 mSuppressedBubbleKeys.clear();
                 mShortcutIdToBubble.clear();
+                mAppBubbleTaskId = INVALID_TASK_ID;
                 for (Bubble b : mTmpBubbles) {
                     mShortcutIdToBubble.put(b.getShortcutId(), b);
                     updateBubbleSuppressedState(b);
+
+                    if (KEY_APP_BUBBLE.equals(b.getKey())) {
+                        mAppBubbleTaskId = b.getTaskId();
+                    }
                 }
             }
 
+            /** Sets the app bubble's taskId which is cached for SysUI. */
+            synchronized void setAppBubbleTaskId(int taskId) {
+                mAppBubbleTaskId = taskId;
+            }
+
             /**
              * Updates a specific bubble suppressed state.  This is used mainly because notification
              * suppression changes don't go through the same BubbleData update mechanism.
@@ -1700,6 +1738,8 @@
                 for (String key : mSuppressedGroupToNotifKeys.keySet()) {
                     pw.println("   suppressing: " + key);
                 }
+
+                pw.print("mAppBubbleTaskId: " + mAppBubbleTaskId);
             }
         }
 
@@ -1750,6 +1790,24 @@
         }
 
         @Override
+        public boolean isAppBubbleTaskId(int taskId) {
+            return mCachedState.mAppBubbleTaskId == taskId;
+        }
+
+        @Override
+        @Nullable
+        public ScreenshotSync getScreenshotExcludingBubble(int displayId) {
+            Pair<ScreenCaptureListener, ScreenshotSync> screenCaptureListener =
+                    ScreenCapture.createSyncCaptureListener();
+
+            mMainExecutor.execute(
+                    () -> BubbleController.this.getScreenshotExcludingBubble(displayId,
+                            screenCaptureListener));
+
+            return screenCaptureListener.second;
+        }
+
+        @Override
         public boolean handleDismissalInterception(BubbleEntry entry,
                 @Nullable List<BubbleEntry> children, IntConsumer removeCallback,
                 Executor callbackExecutor) {
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 1feff18..57c7731 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
@@ -278,6 +278,11 @@
             // The taskId is saved to use for removeTask, preventing appearance in recent tasks.
             mTaskId = taskId;
 
+            if (Bubble.KEY_APP_BUBBLE.equals(getBubbleKey())) {
+                // Let the controller know sooner what the taskId is.
+                mController.setAppBubbleTaskId(mTaskId);
+            }
+
             // With the task org, the taskAppeared callback will only happen once the task has
             // already drawn
             setContentVisibility(true);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index df43257..1753cda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.bubbles;
 
+import static android.window.ScreenCapture.ScreenshotSync;
+
 import static java.lang.annotation.ElementType.FIELD;
 import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
 import static java.lang.annotation.ElementType.PARAMETER;
@@ -24,11 +26,13 @@
 import android.app.NotificationChannel;
 import android.content.Intent;
 import android.content.pm.UserInfo;
+import android.hardware.HardwareBuffer;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
@@ -132,6 +136,18 @@
      */
     void showOrHideAppBubble(Intent intent);
 
+    /** @return true if the specified {@code taskId} corresponds to app bubble's taskId. */
+    boolean isAppBubbleTaskId(int taskId);
+
+    /**
+     * @return a {@link ScreenshotSync} after performing a screenshot that may exclude the bubble
+     * layer, if one is present. The underlying {@link ScreenshotHardwareBuffer} can be access via
+     * {@link ScreenshotSync#get()} asynchronously and care should be taken to
+     * {@link HardwareBuffer#close()} the associated
+     * {@link ScreenshotHardwareBuffer#getHardwareBuffer()} when no longer required.
+     */
+    ScreenshotSync getScreenshotExcludingBubble(int displayId);
+
     /**
      * @return a bubble that matches the provided shortcutId, if one exists.
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index d0aef20..2ea4316 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -141,7 +141,7 @@
         if (pd == null) {
             return false;
         }
-        final InsetsSource imeSource = pd.mInsetsState.getSource(InsetsState.ITYPE_IME);
+        final InsetsSource imeSource = pd.mInsetsState.peekSource(InsetsSource.ID_IME);
         return imeSource != null && pd.mImeSourceControl != null && imeSource.isVisible();
     }
 
@@ -245,14 +245,17 @@
                 return;
             }
 
-            updateImeVisibility(insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME));
+            updateImeVisibility(insetsState.isSourceOrDefaultVisible(InsetsSource.ID_IME,
+                    WindowInsets.Type.ime()));
 
-            final InsetsSource newSource = insetsState.getSource(InsetsState.ITYPE_IME);
-            final Rect newFrame = newSource.getFrame();
-            final Rect oldFrame = mInsetsState.getSource(InsetsState.ITYPE_IME).getFrame();
+            final InsetsSource newSource = insetsState.peekSource(InsetsSource.ID_IME);
+            final Rect newFrame = newSource != null ? newSource.getFrame() : null;
+            final boolean newSourceVisible = newSource != null && newSource.isVisible();
+            final InsetsSource oldSource = mInsetsState.peekSource(InsetsSource.ID_IME);
+            final Rect oldFrame = oldSource != null ? oldSource.getFrame() : null;
 
             mInsetsState.set(insetsState, true /* copySources */);
-            if (mImeShowing && !newFrame.equals(oldFrame) && newSource.isVisible()) {
+            if (mImeShowing && !Objects.equals(oldFrame, newFrame) && newSourceVisible) {
                 if (DEBUG) Slog.d(TAG, "insetsChanged when IME showing, restart animation");
                 startAnimation(mImeShowing, true /* forceRestart */, null /* statsToken */);
             }
@@ -351,7 +354,7 @@
          * Sends the local visibility state back to window manager. Needed for legacy adjustForIme.
          */
         private void setVisibleDirectly(boolean visible) {
-            mInsetsState.getSource(InsetsState.ITYPE_IME).setVisible(visible);
+            mInsetsState.setSourceVisible(InsetsSource.ID_IME, visible);
             mRequestedVisibleTypes = visible
                     ? mRequestedVisibleTypes | WindowInsets.Type.ime()
                     : mRequestedVisibleTypes & ~WindowInsets.Type.ime();
@@ -382,9 +385,9 @@
 
         private void startAnimation(final boolean show, final boolean forceRestart,
                 @Nullable ImeTracker.Token statsToken) {
-            final InsetsSource imeSource = mInsetsState.getSource(InsetsState.ITYPE_IME);
+            final InsetsSource imeSource = mInsetsState.peekSource(InsetsSource.ID_IME);
             if (imeSource == null || mImeSourceControl == null) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
                 return;
             }
             final Rect newFrame = imeSource.getFrame();
@@ -407,7 +410,8 @@
             }
             if ((!forceRestart && (mAnimationDirection == DIRECTION_SHOW && show))
                     || (mAnimationDirection == DIRECTION_HIDE && !show)) {
-                ImeTracker.get().onCancelled(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
+                ImeTracker.forLogging().onCancelled(
+                        statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
                 return;
             }
             boolean seek = false;
@@ -451,7 +455,7 @@
                 mTransactionPool.release(t);
             });
             mAnimation.setInterpolator(INTERPOLATOR);
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
             mAnimation.addListener(new AnimatorListenerAdapter() {
                 private boolean mCancelled = false;
                 @Nullable
@@ -474,7 +478,7 @@
                             : 1.f;
                     t.setAlpha(mImeSourceControl.getLeash(), alpha);
                     if (mAnimationDirection == DIRECTION_SHOW) {
-                        ImeTracker.get().onProgress(mStatsToken,
+                        ImeTracker.forLogging().onProgress(mStatsToken,
                                 ImeTracker.PHASE_WM_ANIMATION_RUNNING);
                         t.show(mImeSourceControl.getLeash());
                     }
@@ -511,15 +515,15 @@
                     }
                     dispatchEndPositioning(mDisplayId, mCancelled, t);
                     if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
-                        ImeTracker.get().onProgress(mStatsToken,
+                        ImeTracker.forLogging().onProgress(mStatsToken,
                                 ImeTracker.PHASE_WM_ANIMATION_RUNNING);
                         t.hide(mImeSourceControl.getLeash());
                         removeImeSurface();
-                        ImeTracker.get().onHidden(mStatsToken);
+                        ImeTracker.forLogging().onHidden(mStatsToken);
                     } else if (mAnimationDirection == DIRECTION_SHOW && !mCancelled) {
-                        ImeTracker.get().onShown(mStatsToken);
+                        ImeTracker.forLogging().onShown(mStatsToken);
                     } else if (mCancelled) {
-                        ImeTracker.get().onCancelled(mStatsToken,
+                        ImeTracker.forLogging().onCancelled(mStatsToken,
                                 ImeTracker.PHASE_WM_ANIMATION_RUNNING);
                     }
                     if (DEBUG_IME_VISIBILITY) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
index 8759301..9bdda14 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
@@ -162,10 +162,12 @@
                 @Nullable ImeTracker.Token statsToken) {
             CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
             if (listeners == null) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+                ImeTracker.forLogging().onFailed(
+                        statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
                 return;
             }
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+            ImeTracker.forLogging().onProgress(
+                    statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
             for (OnInsetsChangedListener listener : listeners) {
                 listener.showInsets(types, fromIme, statsToken);
             }
@@ -175,10 +177,12 @@
                 @Nullable ImeTracker.Token statsToken) {
             CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
             if (listeners == null) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+                ImeTracker.forLogging().onFailed(
+                        statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
                 return;
             }
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+            ImeTracker.forLogging().onProgress(
+                    statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
             for (OnInsetsChangedListener listener : listeners) {
                 listener.hideInsets(types, fromIme, statsToken);
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index 8484013..b8e8363 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -372,7 +372,7 @@
 
         // Only navigation bar
         if (hasNavigationBar) {
-            final InsetsSource extraNavBar = insetsState.getSource(ITYPE_EXTRA_NAVIGATION_BAR);
+            final InsetsSource extraNavBar = insetsState.peekSource(ITYPE_EXTRA_NAVIGATION_BAR);
             final boolean hasExtraNav = extraNavBar != null && extraNavBar.isVisible();
             int position = navigationBarPosition(res, displayWidth, displayHeight, displayRotation);
             int navBarSize =
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index c634198..5933ac2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -37,6 +37,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -216,13 +217,14 @@
     void onInsetsChanged(InsetsState insetsState, boolean animate) {
         mSplitLayout.getDividerBounds(mTempRect);
         final InsetsSource taskBarInsetsSource =
-                insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+                insetsState.peekSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
         // Only insets the divider bar with task bar when it's expanded so that the rounded corners
         // will be drawn against task bar.
         // But there is no need to do it when IME showing because there are no rounded corners at
         // the bottom. This also avoids the problem of task bar height not changing when IME
         // floating.
-        if (!insetsState.getSourceOrDefaultVisibility(InsetsState.ITYPE_IME)
+        if (!insetsState.isSourceOrDefaultVisible(InsetsSource.ID_IME, WindowInsets.Type.ime())
+                && taskBarInsetsSource != null
                 && taskBarInsetsSource.getFrame().height() >= mExpandedTaskBarHeight) {
             mTempRect.inset(taskBarInsetsSource.calculateVisibleInsets(mTempRect));
         }
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 45b234a..f616e6f 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
@@ -699,19 +699,6 @@
         return bounds.width() > bounds.height();
     }
 
-    /** Reverse the split position. */
-    @SplitPosition
-    public static int reversePosition(@SplitPosition int position) {
-        switch (position) {
-            case SPLIT_POSITION_TOP_OR_LEFT:
-                return SPLIT_POSITION_BOTTOM_OR_RIGHT;
-            case SPLIT_POSITION_BOTTOM_OR_RIGHT:
-                return SPLIT_POSITION_TOP_OR_LEFT;
-            default:
-                return SPLIT_POSITION_UNDEFINED;
-        }
-    }
-
     /**
      * Return if this layout is landscape.
      */
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
new file mode 100644
index 0000000..042721c9
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenUtils.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.common.split;
+
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.wm.shell.ShellTaskOrganizer;
+
+/** Helper utility class for split screen components to use. */
+public class SplitScreenUtils {
+    /** Reverse the split position. */
+    @SplitScreenConstants.SplitPosition
+    public static int reverseSplitPosition(@SplitScreenConstants.SplitPosition int position) {
+        switch (position) {
+            case SPLIT_POSITION_TOP_OR_LEFT:
+                return SPLIT_POSITION_BOTTOM_OR_RIGHT;
+            case SPLIT_POSITION_BOTTOM_OR_RIGHT:
+                return SPLIT_POSITION_TOP_OR_LEFT;
+            case SPLIT_POSITION_UNDEFINED:
+            default:
+                return SPLIT_POSITION_UNDEFINED;
+        }
+    }
+
+    /** Returns true if the task is valid for split screen. */
+    public static boolean isValidToSplit(ActivityManager.RunningTaskInfo taskInfo) {
+        return taskInfo != null && taskInfo.supportsMultiWindow
+                && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
+                && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
+    }
+
+    /** Retrieve package name from an intent */
+    @Nullable
+    public static String getPackageName(Intent intent) {
+        if (intent == null || intent.getComponent() == null) {
+            return null;
+        }
+        return intent.getComponent().getPackageName();
+    }
+
+    /** Retrieve package name from a PendingIntent */
+    @Nullable
+    public static String getPackageName(PendingIntent pendingIntent) {
+        if (pendingIntent == null || pendingIntent.getIntent() == null) {
+            return null;
+        }
+        return getPackageName(pendingIntent.getIntent());
+    }
+
+    /** Retrieve package name from a taskId */
+    @Nullable
+    public static String getPackageName(int taskId, ShellTaskOrganizer taskOrganizer) {
+        final ActivityManager.RunningTaskInfo taskInfo = taskOrganizer.getRunningTaskInfo(taskId);
+        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);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
index be3e0a1..ab96856 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvPipModule.java
@@ -203,6 +203,7 @@
             TvPipMenuController tvPipMenuController,
             SyncTransactionQueue syncTransactionQueue,
             TvPipBoundsState tvPipBoundsState,
+            PipSizeSpecHandler pipSizeSpecHandler,
             PipTransitionState pipTransitionState,
             TvPipBoundsAlgorithm tvPipBoundsAlgorithm,
             PipAnimationController pipAnimationController,
@@ -214,10 +215,11 @@
             PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new TvPipTaskOrganizer(context,
-                syncTransactionQueue, pipTransitionState, tvPipBoundsState, tvPipBoundsAlgorithm,
-                tvPipMenuController, pipAnimationController, pipSurfaceTransactionHelper,
-                pipTransitionController, pipParamsChangedForwarder, splitScreenControllerOptional,
-                displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
+                syncTransactionQueue, pipTransitionState, tvPipBoundsState, pipSizeSpecHandler,
+                tvPipBoundsAlgorithm, tvPipMenuController, pipAnimationController,
+                pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder,
+                splitScreenControllerOptional, displayController, pipUiEventLogger,
+                shellTaskOrganizer, mainExecutor);
     }
 
     @WMSingleton
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 4879d86..2cdd86f 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
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.UserManager;
 import android.view.Choreographer;
+import android.view.IWindowManager;
 import android.view.WindowManager;
 
 import com.android.internal.jank.InteractionJankMonitor;
@@ -170,14 +171,15 @@
             @ShellMainThread Handler mainHandler,
             @ShellBackgroundThread ShellExecutor bgExecutor,
             TaskViewTransitions taskViewTransitions,
-            SyncTransactionQueue syncQueue) {
+            SyncTransactionQueue syncQueue,
+            IWindowManager wmService) {
         return new BubbleController(context, shellInit, shellCommandHandler, shellController, data,
                 null /* synchronizer */, floatingContentCoordinator,
                 new BubbleDataRepository(context, launcherApps, mainExecutor),
                 statusBarService, windowManager, windowManagerShellWrapper, userManager,
                 launcherApps, logger, taskStackListener, organizer, positioner, displayController,
                 oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
-                taskViewTransitions, syncQueue);
+                taskViewTransitions, syncQueue, wmService);
     }
 
     //
@@ -442,6 +444,7 @@
             SyncTransactionQueue syncTransactionQueue,
             PipTransitionState pipTransitionState,
             PipBoundsState pipBoundsState,
+            PipSizeSpecHandler pipSizeSpecHandler,
             PipBoundsAlgorithm pipBoundsAlgorithm,
             PhonePipMenuController menuPhoneController,
             PipAnimationController pipAnimationController,
@@ -453,10 +456,11 @@
             PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new PipTaskOrganizer(context,
-                syncTransactionQueue, pipTransitionState, pipBoundsState, pipBoundsAlgorithm,
-                menuPhoneController, pipAnimationController, pipSurfaceTransactionHelper,
-                pipTransitionController, pipParamsChangedForwarder, splitScreenControllerOptional,
-                displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
+                syncTransactionQueue, pipTransitionState, pipBoundsState, pipSizeSpecHandler,
+                pipBoundsAlgorithm, menuPhoneController, pipAnimationController,
+                pipSurfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder,
+                splitScreenControllerOptional, displayController, pipUiEventLogger,
+                shellTaskOrganizer, mainExecutor);
     }
 
     @WMSingleton
@@ -471,13 +475,14 @@
     static PipTransitionController providePipTransitionController(Context context,
             ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, Transitions transitions,
             PipAnimationController pipAnimationController, PipBoundsAlgorithm pipBoundsAlgorithm,
-            PipBoundsState pipBoundsState, PipTransitionState pipTransitionState,
-            PhonePipMenuController pipMenuController,
+            PipBoundsState pipBoundsState, PipSizeSpecHandler pipSizeSpecHandler,
+            PipTransitionState pipTransitionState, PhonePipMenuController pipMenuController,
             PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
             Optional<SplitScreenController> splitScreenOptional) {
         return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
-                pipBoundsState, pipTransitionState, pipMenuController, pipBoundsAlgorithm,
-                pipAnimationController, pipSurfaceTransactionHelper, splitScreenOptional);
+                pipBoundsState, pipSizeSpecHandler, pipTransitionState, pipMenuController,
+                pipBoundsAlgorithm, pipAnimationController, pipSurfaceTransactionHelper,
+                splitScreenOptional);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index a839a23..bc81710 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -22,6 +22,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 
@@ -253,12 +254,16 @@
      */
     void showDesktopApps() {
         // Bring apps to front, ignoring their visibility status to always ensure they are on top.
-        WindowContainerTransaction wct = bringDesktopAppsToFront(true /* ignoreVisibility */);
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        bringDesktopAppsToFront(wct);
 
-        if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */);
-        } else {
-            mShellTaskOrganizer.applyTransaction(wct);
+        if (!wct.isEmpty()) {
+            if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+                // TODO(b/268662477): add animation for the transition
+                mTransitions.startTransition(TRANSIT_NONE, wct, null /* handler */);
+            } else {
+                mShellTaskOrganizer.applyTransaction(wct);
+            }
         }
     }
 
@@ -267,9 +272,7 @@
         return mDesktopModeTaskRepository.getVisibleTaskCount();
     }
 
-    @NonNull
-    private WindowContainerTransaction bringDesktopAppsToFront(boolean force) {
-        final WindowContainerTransaction wct = new WindowContainerTransaction();
+    private void bringDesktopAppsToFront(WindowContainerTransaction wct) {
         final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
         ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
 
@@ -282,18 +285,11 @@
         }
 
         if (taskInfos.isEmpty()) {
-            return wct;
+            return;
         }
 
-        if (!force) {
-            final boolean allActiveTasksAreVisible = taskInfos.stream()
-                    .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
-            if (allActiveTasksAreVisible) {
-                ProtoLog.d(WM_SHELL_DESKTOP_MODE,
-                        "bringDesktopAppsToFront: active tasks are already in front, skipping.");
-                return wct;
-            }
-        }
+        moveHomeTaskToFront(wct);
+
         ProtoLog.d(WM_SHELL_DESKTOP_MODE,
                 "bringDesktopAppsToFront: reordering all active tasks to the front");
         final List<Integer> allTasksInZOrder =
@@ -304,7 +300,15 @@
         for (RunningTaskInfo task : taskInfos) {
             wct.reorder(task.token, true);
         }
-        return wct;
+    }
+
+    private void moveHomeTaskToFront(WindowContainerTransaction wct) {
+        for (RunningTaskInfo task : mShellTaskOrganizer.getRunningTasks(mContext.getDisplayId())) {
+            if (task.getActivityType() == ACTIVITY_TYPE_HOME) {
+                wct.reorder(task.token, true /* onTop */);
+                return;
+            }
+        }
     }
 
     /**
@@ -363,7 +367,7 @@
         if (wct == null) {
             wct = new WindowContainerTransaction();
         }
-        wct.merge(bringDesktopAppsToFront(false /* ignoreVisibility */), true /* transfer */);
+        bringDesktopAppsToFront(wct);
         wct.reorder(request.getTriggerTask().token, true /* onTop */);
 
         return wct;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 2303325..fce0138 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -27,6 +27,7 @@
 import android.os.IBinder
 import android.view.SurfaceControl
 import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_NONE
 import android.view.WindowManager.TRANSIT_OPEN
 import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.TransitionInfo
@@ -89,7 +90,8 @@
         // Execute transaction if there are pending operations
         if (!wct.isEmpty) {
             if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-                transitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */)
+                // TODO(b/268662477): add animation for the transition
+                transitions.startTransition(TRANSIT_NONE, wct, null /* handler */)
             } else {
                 shellTaskOrganizer.applyTransaction(wct)
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index 55378a8..3ade1ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -22,6 +22,10 @@
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
+import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -315,6 +319,25 @@
                 // Switching between targets
                 mDropZoneView1.animateSwitch();
                 mDropZoneView2.animateSwitch();
+                // Announce for accessibility.
+                switch (target.type) {
+                    case TYPE_SPLIT_LEFT:
+                        mDropZoneView1.announceForAccessibility(
+                                mContext.getString(R.string.accessibility_split_left));
+                        break;
+                    case TYPE_SPLIT_RIGHT:
+                        mDropZoneView2.announceForAccessibility(
+                                mContext.getString(R.string.accessibility_split_right));
+                        break;
+                    case TYPE_SPLIT_TOP:
+                        mDropZoneView1.announceForAccessibility(
+                                mContext.getString(R.string.accessibility_split_top));
+                        break;
+                    case TYPE_SPLIT_BOTTOM:
+                        mDropZoneView2.announceForAccessibility(
+                                mContext.getString(R.string.accessibility_split_bottom));
+                        break;
+                }
             }
             mCurrentTarget = target;
         }
@@ -424,12 +447,10 @@
     }
 
     private void animateHighlight(DragAndDropPolicy.Target target) {
-        if (target.type == DragAndDropPolicy.Target.TYPE_SPLIT_LEFT
-                || target.type == DragAndDropPolicy.Target.TYPE_SPLIT_TOP) {
+        if (target.type == TYPE_SPLIT_LEFT || target.type == TYPE_SPLIT_TOP) {
             mDropZoneView1.setShowingHighlight(true);
             mDropZoneView2.setShowingHighlight(false);
-        } else if (target.type == DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT
-                || target.type == DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM) {
+        } else if (target.type == TYPE_SPLIT_RIGHT || target.type == TYPE_SPLIT_BOTTOM) {
             mDropZoneView1.setShowingHighlight(false);
             mDropZoneView2.setShowingHighlight(true);
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
index e91987d..ac13f96 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.kidsmode;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -68,7 +69,7 @@
     private static final String TAG = "KidsModeTaskOrganizer";
 
     private static final int[] CONTROLLED_ACTIVITY_TYPES =
-            {ACTIVITY_TYPE_UNDEFINED, ACTIVITY_TYPE_STANDARD};
+            {ACTIVITY_TYPE_UNDEFINED, ACTIVITY_TYPE_STANDARD, ACTIVITY_TYPE_HOME};
     private static final int[] CONTROLLED_WINDOWING_MODES =
             {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED};
 
@@ -93,6 +94,8 @@
     private KidsModeSettingsObserver mKidsModeSettingsObserver;
     private boolean mEnabled;
 
+    private ActivityManager.RunningTaskInfo mHomeTask;
+
     private final BroadcastReceiver mUserSwitchIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -219,6 +222,13 @@
         }
         super.onTaskAppeared(taskInfo, leash);
 
+        // Only allow home to draw under system bars.
+        if (taskInfo.getActivityType() == ACTIVITY_TYPE_HOME) {
+            final WindowContainerTransaction wct = getWindowContainerTransaction();
+            wct.setBounds(taskInfo.token, new Rect(0, 0, mDisplayWidth, mDisplayHeight));
+            mSyncQueue.queue(wct);
+            mHomeTask = taskInfo;
+        }
         mSyncQueue.runInSync(t -> {
             // Reset several properties back to fullscreen (PiP, for example, leaves all these
             // properties in a bad state).
@@ -291,6 +301,13 @@
         }
         mLaunchRootTask = null;
         mLaunchRootLeash = null;
+        if (mHomeTask != null && mHomeTask.token != null) {
+            final WindowContainerToken homeToken = mHomeTask.token;
+            final WindowContainerTransaction wct = getWindowContainerTransaction();
+            wct.setBounds(homeToken, null);
+            mSyncQueue.queue(wct);
+        }
+        mHomeTask = null;
         unregisterOrganizer();
     }
 
@@ -320,7 +337,7 @@
             final SurfaceControl rootLeash = mLaunchRootLeash;
             mSyncQueue.runInSync(t -> {
                 t.setPosition(rootLeash, taskBounds.left, taskBounds.top);
-                t.setWindowCrop(rootLeash, taskBounds.width(), taskBounds.height());
+                t.setWindowCrop(rootLeash, mDisplayWidth, mDisplayHeight);
             });
         }
     }
@@ -351,7 +368,7 @@
         final SurfaceControl finalLeash = mLaunchRootLeash;
         mSyncQueue.runInSync(t -> {
             t.setPosition(finalLeash, taskBounds.left, taskBounds.top);
-            t.setWindowCrop(finalLeash, taskBounds.width(), taskBounds.height());
+            t.setWindowCrop(finalLeash, mDisplayWidth, mDisplayHeight);
         });
     }
 
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 6728c00..d9ac76e 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
@@ -28,6 +28,7 @@
 import android.annotation.NonNull;
 import android.app.TaskInfo;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -361,22 +362,26 @@
         }
 
         void setColorContentOverlay(Context context) {
-            final SurfaceControl.Transaction tx =
-                    mSurfaceControlTransactionFactory.getTransaction();
-            if (mContentOverlay != null) {
-                mContentOverlay.detach(tx);
-            }
-            mContentOverlay = new PipContentOverlay.PipColorOverlay(context);
-            mContentOverlay.attach(tx, mLeash);
+            reattachContentOverlay(new PipContentOverlay.PipColorOverlay(context));
         }
 
         void setSnapshotContentOverlay(TaskSnapshot snapshot, Rect sourceRectHint) {
+            reattachContentOverlay(
+                    new PipContentOverlay.PipSnapshotOverlay(snapshot, sourceRectHint));
+        }
+
+        void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo) {
+            reattachContentOverlay(
+                    new PipContentOverlay.PipAppIconOverlay(context, bounds, activityInfo));
+        }
+
+        private void reattachContentOverlay(PipContentOverlay overlay) {
             final SurfaceControl.Transaction tx =
                     mSurfaceControlTransactionFactory.getTransaction();
             if (mContentOverlay != null) {
                 mContentOverlay.detach(tx);
             }
-            mContentOverlay = new PipContentOverlay.PipSnapshotOverlay(snapshot, sourceRectHint);
+            mContentOverlay = overlay;
             mContentOverlay.attach(tx, mLeash);
         }
 
@@ -570,8 +575,9 @@
                     final Rect base = getBaseValue();
                     final Rect start = getStartValue();
                     final Rect end = getEndValue();
+                    Rect bounds = mRectEvaluator.evaluate(fraction, start, end);
                     if (mContentOverlay != null) {
-                        mContentOverlay.onAnimationUpdate(tx, fraction);
+                        mContentOverlay.onAnimationUpdate(tx, bounds, fraction);
                     }
                     if (rotatedEndRect != null) {
                         // Animate the bounds in a different orientation. It only happens when
@@ -579,7 +585,6 @@
                         applyRotation(tx, leash, fraction, start, end);
                         return;
                     }
-                    Rect bounds = mRectEvaluator.evaluate(fraction, start, end);
                     float angle = (1.0f - fraction) * startingAngle;
                     setCurrentValue(bounds);
                     if (inScaleTransition() || sourceHintRect == null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index 61da10b..5be18d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -311,10 +311,10 @@
         mDisplayLayout.set(displayLayout);
     }
 
-    /** Get the display layout. */
+    /** Get a copy of the display layout. */
     @NonNull
     public DisplayLayout getDisplayLayout() {
-        return mDisplayLayout;
+        return new DisplayLayout(mDisplayLayout);
     }
 
     @VisibleForTesting
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 283b1ec..480bf93 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
@@ -16,11 +16,21 @@
 
 package com.android.wm.shell.pip;
 
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Matrix;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.TypedValue;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.window.TaskSnapshot;
@@ -51,9 +61,11 @@
      * Animates the internal {@link #mLeash} by a given fraction.
      * @param atomicTx {@link SurfaceControl.Transaction} to operate, you should not explicitly
      *                 call apply on this transaction, it should be applied on the caller side.
+     * @param currentBounds {@link Rect} of the current animation bounds.
      * @param fraction progress of the animation ranged from 0f to 1f.
      */
-    public abstract void onAnimationUpdate(SurfaceControl.Transaction atomicTx, float fraction);
+    public abstract void onAnimationUpdate(SurfaceControl.Transaction atomicTx,
+            Rect currentBounds, float fraction);
 
     /**
      * Callback when reaches the end of animation on the internal {@link #mLeash}.
@@ -66,13 +78,15 @@
 
     /** A {@link PipContentOverlay} uses solid color. */
     public static final class PipColorOverlay extends PipContentOverlay {
+        private static final String TAG = PipColorOverlay.class.getSimpleName();
+
         private final Context mContext;
 
         public PipColorOverlay(Context context) {
             mContext = context;
             mLeash = new SurfaceControl.Builder(new SurfaceSession())
-                    .setCallsite("PipAnimation")
-                    .setName(PipColorOverlay.class.getSimpleName())
+                    .setCallsite(TAG)
+                    .setName(TAG)
                     .setColorLayer()
                     .build();
         }
@@ -88,7 +102,8 @@
         }
 
         @Override
-        public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, float fraction) {
+        public void onAnimationUpdate(SurfaceControl.Transaction atomicTx,
+                Rect currentBounds, float fraction) {
             atomicTx.setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2);
         }
 
@@ -114,6 +129,8 @@
 
     /** A {@link PipContentOverlay} uses {@link TaskSnapshot}. */
     public static final class PipSnapshotOverlay extends PipContentOverlay {
+        private static final String TAG = PipSnapshotOverlay.class.getSimpleName();
+
         private final TaskSnapshot mSnapshot;
         private final Rect mSourceRectHint;
 
@@ -121,8 +138,8 @@
             mSnapshot = snapshot;
             mSourceRectHint = new Rect(sourceRectHint);
             mLeash = new SurfaceControl.Builder(new SurfaceSession())
-                    .setCallsite("PipAnimation")
-                    .setName(PipSnapshotOverlay.class.getSimpleName())
+                    .setCallsite(TAG)
+                    .setName(TAG)
                     .build();
         }
 
@@ -143,7 +160,8 @@
         }
 
         @Override
-        public void onAnimationUpdate(SurfaceControl.Transaction atomicTx, float fraction) {
+        public void onAnimationUpdate(SurfaceControl.Transaction atomicTx,
+                Rect currentBounds, float fraction) {
             // Do nothing. Keep the snapshot till animation ends.
         }
 
@@ -152,4 +170,113 @@
             atomicTx.remove(mLeash);
         }
     }
+
+    /** A {@link PipContentOverlay} shows app icon on solid color background. */
+    public static final class PipAppIconOverlay extends PipContentOverlay {
+        private static final String TAG = PipAppIconOverlay.class.getSimpleName();
+        private static final int APP_ICON_SIZE_DP = 48;
+
+        private final Context mContext;
+        private final int mAppIconSizePx;
+        private final Rect mAppBounds;
+        private final Matrix mTmpTransform = new Matrix();
+        private final float[] mTmpFloat9 = new float[9];
+
+        private Bitmap mBitmap;
+
+        public PipAppIconOverlay(Context context, Rect appBounds, ActivityInfo activityInfo) {
+            mContext = context;
+            mAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, APP_ICON_SIZE_DP,
+                    context.getResources().getDisplayMetrics());
+            mAppBounds = new Rect(appBounds);
+            mBitmap = Bitmap.createBitmap(appBounds.width(), appBounds.height(),
+                    Bitmap.Config.ARGB_8888);
+            prepareAppIconOverlay(activityInfo);
+            mLeash = new SurfaceControl.Builder(new SurfaceSession())
+                    .setCallsite(TAG)
+                    .setName(TAG)
+                    .build();
+        }
+
+        @Override
+        public void attach(SurfaceControl.Transaction tx, SurfaceControl parentLeash) {
+            tx.show(mLeash);
+            tx.setLayer(mLeash, Integer.MAX_VALUE);
+            tx.setBuffer(mLeash, mBitmap.getHardwareBuffer());
+            tx.reparent(mLeash, parentLeash);
+            tx.apply();
+        }
+
+        @Override
+        public void onAnimationUpdate(SurfaceControl.Transaction atomicTx,
+                Rect currentBounds, float fraction) {
+            mTmpTransform.reset();
+            // Scale back the bitmap with the pivot point at center.
+            mTmpTransform.postScale(
+                    (float) mAppBounds.width() / currentBounds.width(),
+                    (float) mAppBounds.height() / currentBounds.height(),
+                    mAppBounds.centerX(),
+                    mAppBounds.centerY());
+            atomicTx.setMatrix(mLeash, mTmpTransform, mTmpFloat9)
+                    .setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2);
+        }
+
+        @Override
+        public void onAnimationEnd(SurfaceControl.Transaction atomicTx, Rect destinationBounds) {
+            atomicTx.remove(mLeash);
+        }
+
+        @Override
+        public void detach(SurfaceControl.Transaction tx) {
+            super.detach(tx);
+            if (mBitmap != null && !mBitmap.isRecycled()) {
+                mBitmap.recycle();
+            }
+        }
+
+        private void prepareAppIconOverlay(ActivityInfo activityInfo) {
+            final Canvas canvas = new Canvas();
+            canvas.setBitmap(mBitmap);
+            final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
+                    android.R.attr.colorBackground });
+            try {
+                int colorAccent = ta.getColor(0, 0);
+                canvas.drawRGB(
+                        Color.red(colorAccent),
+                        Color.green(colorAccent),
+                        Color.blue(colorAccent));
+            } finally {
+                ta.recycle();
+            }
+            final Drawable appIcon = loadActivityInfoIcon(activityInfo,
+                    mContext.getResources().getConfiguration().densityDpi);
+            final Rect appIconBounds = new Rect(
+                    mAppBounds.centerX() - mAppIconSizePx / 2,
+                    mAppBounds.centerY() - mAppIconSizePx / 2,
+                    mAppBounds.centerX() + mAppIconSizePx / 2,
+                    mAppBounds.centerY() + mAppIconSizePx / 2);
+            appIcon.setBounds(appIconBounds);
+            appIcon.draw(canvas);
+            mBitmap = mBitmap.copy(Bitmap.Config.HARDWARE, false /* mutable */);
+        }
+
+        // Copied from com.android.launcher3.icons.IconProvider#loadActivityInfoIcon
+        private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) {
+            final int iconRes = ai.getIconResource();
+            Drawable icon = null;
+            // Get the preferred density icon from the app's resources
+            if (density != 0 && iconRes != 0) {
+                try {
+                    final Resources resources = mContext.getPackageManager()
+                            .getResourcesForApplication(ai.applicationInfo);
+                    icon = resources.getDrawableForDensity(iconRes, density);
+                } catch (PackageManager.NameNotFoundException | Resources.NotFoundException exc) { }
+            }
+            // Get the default density icon
+            if (icon == null) {
+                icon = ai.loadIcon(mContext.getPackageManager());
+            }
+            return icon;
+        }
+    }
 }
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 8ba2583..ffb2893 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
@@ -62,6 +62,7 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.Display;
@@ -78,11 +79,13 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ScreenshotUtils;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.pip.phone.PipMotionHelper;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.transition.Transitions;
@@ -125,6 +128,7 @@
     private final Context mContext;
     private final SyncTransactionQueue mSyncTransactionQueue;
     private final PipBoundsState mPipBoundsState;
+    private final PipSizeSpecHandler mPipSizeSpecHandler;
     private final PipBoundsAlgorithm mPipBoundsAlgorithm;
     private final @NonNull PipMenuController mPipMenuController;
     private final PipAnimationController mPipAnimationController;
@@ -312,6 +316,7 @@
             @NonNull SyncTransactionQueue syncTransactionQueue,
             @NonNull PipTransitionState pipTransitionState,
             @NonNull PipBoundsState pipBoundsState,
+            @NonNull PipSizeSpecHandler pipSizeSpecHandler,
             @NonNull PipBoundsAlgorithm boundsHandler,
             @NonNull PipMenuController pipMenuController,
             @NonNull PipAnimationController pipAnimationController,
@@ -327,6 +332,7 @@
         mSyncTransactionQueue = syncTransactionQueue;
         mPipTransitionState = pipTransitionState;
         mPipBoundsState = pipBoundsState;
+        mPipSizeSpecHandler = pipSizeSpecHandler;
         mPipBoundsAlgorithm = boundsHandler;
         mPipMenuController = pipMenuController;
         mPipTransitionController = pipTransitionController;
@@ -1568,7 +1574,13 @@
             // Similar to auto-enter-pip transition, we use content overlay when there is no
             // source rect hint to enter PiP use bounds animation.
             if (sourceHintRect == null) {
-                animator.setColorContentOverlay(mContext);
+                if (SystemProperties.getBoolean(
+                        "persist.wm.debug.enable_pip_app_icon_overlay", false)) {
+                    animator.setAppIconContentOverlay(
+                            mContext, currentBounds, mTaskInfo.topActivityInfo);
+                } else {
+                    animator.setColorContentOverlay(mContext);
+                }
             } else {
                 final TaskSnapshot snapshot = PipUtils.getTaskSnapshot(
                         mTaskInfo.launchIntoPipHostTaskId, false /* isLowResolution */);
@@ -1594,7 +1606,12 @@
     private @Nullable Rect computeRotatedBounds(int rotationDelta, int direction,
             Rect outDestinationBounds, Rect sourceHintRect) {
         if (direction == TRANSITION_DIRECTION_TO_PIP) {
-            mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), mNextRotation);
+            DisplayLayout layoutCopy = mPipBoundsState.getDisplayLayout();
+
+            layoutCopy.rotateTo(mContext.getResources(), mNextRotation);
+            mPipBoundsState.setDisplayLayout(layoutCopy);
+            mPipSizeSpecHandler.setDisplayLayout(layoutCopy);
+
             final Rect displayBounds = mPipBoundsState.getDisplayBounds();
             outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds());
             // Transform the destination bounds to current display coordinates.
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 83158ff..e5c0570 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
@@ -50,6 +50,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.os.SystemProperties;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
@@ -64,6 +65,8 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -82,6 +85,7 @@
 
     private final Context mContext;
     private final PipTransitionState mPipTransitionState;
+    private final PipSizeSpecHandler mPipSizeSpecHandler;
     private final int mEnterExitAnimationDuration;
     private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
     private final Optional<SplitScreenController> mSplitScreenOptional;
@@ -112,6 +116,7 @@
             @NonNull ShellTaskOrganizer shellTaskOrganizer,
             @NonNull Transitions transitions,
             PipBoundsState pipBoundsState,
+            PipSizeSpecHandler pipSizeSpecHandler,
             PipTransitionState pipTransitionState,
             PipMenuController pipMenuController,
             PipBoundsAlgorithm pipBoundsAlgorithm,
@@ -122,6 +127,7 @@
                 pipBoundsAlgorithm, pipAnimationController);
         mContext = context;
         mPipTransitionState = pipTransitionState;
+        mPipSizeSpecHandler = pipSizeSpecHandler;
         mEnterExitAnimationDuration = context.getResources()
                 .getInteger(R.integer.config_pipResizeAnimationDuration);
         mSurfaceTransactionHelper = pipSurfaceTransactionHelper;
@@ -307,7 +313,12 @@
             // initial state under the new rotation.
             int rotationDelta = deltaRotation(startRotation, endRotation);
             if (rotationDelta != Surface.ROTATION_0) {
-                mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), endRotation);
+                DisplayLayout layoutCopy = mPipBoundsState.getDisplayLayout();
+
+                layoutCopy.rotateTo(mContext.getResources(), endRotation);
+                mPipBoundsState.setDisplayLayout(layoutCopy);
+                mPipSizeSpecHandler.setDisplayLayout(layoutCopy);
+
                 final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
                 wct.setBounds(mRequestedEnterTask, destinationBounds);
                 return true;
@@ -792,7 +803,13 @@
             if (sourceHintRect == null) {
                 // We use content overlay when there is no source rect hint to enter PiP use bounds
                 // animation.
-                animator.setColorContentOverlay(mContext);
+                if (SystemProperties.getBoolean(
+                        "persist.wm.debug.enable_pip_app_icon_overlay", false)) {
+                    animator.setAppIconContentOverlay(
+                            mContext, currentBounds, taskInfo.topActivityInfo);
+                } else {
+                    animator.setColorContentOverlay(mContext);
+                }
             }
         } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
             animator = mPipAnimationController.getAnimator(taskInfo, leash, destinationBounds,
@@ -817,7 +834,12 @@
     /** Computes destination bounds in old rotation and updates source hint rect if available. */
     private void computeEnterPipRotatedBounds(int rotationDelta, int startRotation, int endRotation,
             TaskInfo taskInfo, Rect outDestinationBounds, @Nullable Rect outSourceHintRect) {
-        mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), endRotation);
+        DisplayLayout layoutCopy = mPipBoundsState.getDisplayLayout();
+
+        layoutCopy.rotateTo(mContext.getResources(), endRotation);
+        mPipBoundsState.setDisplayLayout(layoutCopy);
+        mPipSizeSpecHandler.setDisplayLayout(layoutCopy);
+
         final Rect displayBounds = mPipBoundsState.getDisplayBounds();
         outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds());
         // Transform the destination bounds to current display coordinates.
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 d86468a..4958b25 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
@@ -1032,7 +1032,11 @@
     private void onDisplayRotationChangedNotInPip(Context context, int toRotation) {
         // Update the display layout, note that we have to do this on every rotation even if we
         // aren't in PIP since we need to update the display layout to get the right resources
-        mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
+        DisplayLayout layoutCopy = mPipBoundsState.getDisplayLayout();
+
+        layoutCopy.rotateTo(context.getResources(), toRotation);
+        mPipBoundsState.setDisplayLayout(layoutCopy);
+        mPipSizeSpecHandler.setDisplayLayout(layoutCopy);
     }
 
     /**
@@ -1069,7 +1073,11 @@
                         mPipBoundsState.getStashedState());
 
         // Update the display layout
-        mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
+        DisplayLayout layoutCopy = mPipBoundsState.getDisplayLayout();
+
+        layoutCopy.rotateTo(context.getResources(), toRotation);
+        mPipBoundsState.setDisplayLayout(layoutCopy);
+        mPipSizeSpecHandler.setDisplayLayout(layoutCopy);
 
         // Calculate the stack bounds in the new orientation based on same fraction along the
         // rotated movement bounds.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
index e787ed9..d03d075 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipSizeSpecHandler.java
@@ -409,12 +409,6 @@
         return new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height());
     }
 
-    /** Get the display layout. */
-    @NonNull
-    public DisplayLayout getDisplayLayout() {
-        return mDisplayLayout;
-    }
-
     /** Update the display layout. */
     public void setDisplayLayout(@NonNull DisplayLayout displayLayout) {
         mDisplayLayout.set(displayLayout);
@@ -429,12 +423,11 @@
      */
     public Rect getInsetBounds() {
         Rect insetBounds = new Rect();
-        final DisplayLayout displayLayout = getDisplayLayout();
-        Rect insets = getDisplayLayout().stableInsets();
+        Rect insets = mDisplayLayout.stableInsets();
         insetBounds.set(insets.left + mScreenEdgeInsets.x,
                 insets.top + mScreenEdgeInsets.y,
-                displayLayout.width() - insets.right - mScreenEdgeInsets.x,
-                displayLayout.height() - insets.bottom - mScreenEdgeInsets.y);
+                mDisplayLayout.width() - insets.right - mScreenEdgeInsets.x,
+                mDisplayLayout.height() - insets.bottom - mScreenEdgeInsets.y);
         return insetBounds;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java
index 42fd1aa..be9b936 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTaskOrganizer.java
@@ -36,6 +36,7 @@
 import com.android.wm.shell.pip.PipTransitionState;
 import com.android.wm.shell.pip.PipUiEventLogger;
 import com.android.wm.shell.pip.PipUtils;
+import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 
 import java.util.Objects;
@@ -50,6 +51,7 @@
             @NonNull SyncTransactionQueue syncTransactionQueue,
             @NonNull PipTransitionState pipTransitionState,
             @NonNull PipBoundsState pipBoundsState,
+            @NonNull PipSizeSpecHandler pipSizeSpecHandler,
             @NonNull PipBoundsAlgorithm boundsHandler,
             @NonNull PipMenuController pipMenuController,
             @NonNull PipAnimationController pipAnimationController,
@@ -61,10 +63,11 @@
             @NonNull PipUiEventLogger pipUiEventLogger,
             @NonNull ShellTaskOrganizer shellTaskOrganizer,
             ShellExecutor mainExecutor) {
-        super(context, syncTransactionQueue, pipTransitionState, pipBoundsState, boundsHandler,
-                pipMenuController, pipAnimationController, surfaceTransactionHelper,
-                pipTransitionController, pipParamsChangedForwarder, splitScreenOptional,
-                displayController, pipUiEventLogger, shellTaskOrganizer, mainExecutor);
+        super(context, syncTransactionQueue, pipTransitionState, pipBoundsState, pipSizeSpecHandler,
+                boundsHandler, pipMenuController, pipAnimationController,
+                surfaceTransactionHelper, pipTransitionController, pipParamsChangedForwarder,
+                splitScreenOptional, displayController, pipUiEventLogger, shellTaskOrganizer,
+                mainExecutor);
     }
 
     @Override
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 8490f9f..0d9faa3 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
@@ -308,7 +308,6 @@
             rawMapping.put(taskInfo.taskId, taskInfo);
         }
 
-        boolean desktopModeActive = DesktopModeStatus.isActive(mContext);
         ArrayList<ActivityManager.RecentTaskInfo> freeformTasks = new ArrayList<>();
 
         // Pull out the pairs as we iterate back in the list
@@ -320,7 +319,7 @@
                 continue;
             }
 
-            if (desktopModeActive && mDesktopModeTaskRepository.isPresent()
+            if (DesktopModeStatus.isProto2Enabled() && mDesktopModeTaskRepository.isPresent()
                     && mDesktopModeTaskRepository.get().isActiveTask(taskInfo.taskId)) {
                 // Freeform tasks will be added as a separate entry
                 freeformTasks.add(taskInfo);
@@ -328,7 +327,7 @@
             }
 
             final int pairedTaskId = mSplitTasks.get(taskInfo.taskId);
-            if (!desktopModeActive && pairedTaskId != INVALID_TASK_ID && rawMapping.contains(
+            if (pairedTaskId != INVALID_TASK_ID && rawMapping.contains(
                     pairedTaskId)) {
                 final ActivityManager.RecentTaskInfo pairedTaskInfo = rawMapping.get(pairedTaskId);
                 rawMapping.remove(pairedTaskId);
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 56aa742..81e118a 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
@@ -122,9 +122,9 @@
      * Start a pair of intents using legacy transition system.
      */
     oneway void startIntentsWithLegacyTransition(in PendingIntent pendingIntent1,
-            in Bundle options1, in PendingIntent pendingIntent2, in Bundle options2,
-            int splitPosition, float splitRatio, in RemoteAnimationAdapter adapter,
-            in InstanceId instanceId) = 18;
+            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;
 
     /**
      * Start a pair of intents in one transition.
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 21eeaa2..36da4cf 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
@@ -28,6 +28,9 @@
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit;
+import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
+import static com.android.wm.shell.common.split.SplitScreenUtils.samePackage;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
 import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN;
@@ -39,11 +42,8 @@
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.PendingIntent;
-import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.LauncherApps;
 import android.content.pm.ShortcutInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -82,8 +82,8 @@
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.annotations.ExternalThread;
-import com.android.wm.shell.common.split.SplitLayout;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
+import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.draganddrop.DragAndDropController;
 import com.android.wm.shell.draganddrop.DragAndDropPolicy;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -318,10 +318,6 @@
         return mStageCoordinator;
     }
 
-    public boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
-        return mStageCoordinator.isValidToEnterSplitScreen(taskInfo);
-    }
-
     @Nullable
     public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
         if (!isSplitScreenVisible() || splitPosition == SPLIT_POSITION_UNDEFINED) {
@@ -480,39 +476,54 @@
     @Override
     public void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
             @Nullable Bundle options, UserHandle user) {
-        IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
-            @Override
-            public void onAnimationStart(@WindowManager.TransitionOldType int transit,
-                    RemoteAnimationTarget[] apps,
-                    RemoteAnimationTarget[] wallpapers,
-                    RemoteAnimationTarget[] nonApps,
-                    final IRemoteAnimationFinishedCallback finishedCallback) {
-                try {
-                    finishedCallback.onAnimationFinished();
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Failed to invoke onAnimationFinished", e);
-                }
-                final WindowContainerTransaction evictWct = new WindowContainerTransaction();
-                mStageCoordinator.prepareEvictNonOpeningChildTasks(position, apps, evictWct);
-                mSyncQueue.queue(evictWct);
+        if (options == null) options = new Bundle();
+        final ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
+
+        if (samePackage(packageName, getPackageName(reverseSplitPosition(position)))) {
+            if (supportMultiInstancesSplit(packageName)) {
+                activityOptions.setApplyMultipleTaskFlagForShortcut(true);
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
+            } else if (isSplitScreenVisible()) {
+                mStageCoordinator.switchSplitPosition("startShortcut");
+                return;
+            } else {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+                        "Cancel entering split as not supporting multi-instances");
+                Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
+                        Toast.LENGTH_SHORT).show();
+                return;
             }
-            @Override
-            public void onAnimationCancelled(boolean isKeyguardOccluded) {
-            }
-        };
-        options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
-                null /* wct */);
-        RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper,
-                0 /* duration */, 0 /* statusBarTransitionDelay */);
-        ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
-        activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
-        try {
-            LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
-            launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
-                    activityOptions.toBundle(), user);
-        } catch (ActivityNotFoundException e) {
-            Slog.e(TAG, "Failed to launch shortcut", e);
         }
+
+        mStageCoordinator.startShortcut(packageName, shortcutId, position,
+                activityOptions.toBundle(), user);
+    }
+
+    void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo,
+            @Nullable Bundle options1, int taskId, @Nullable Bundle options2,
+            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
+        if (options1 == null) options1 = new Bundle();
+        final ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
+
+        final String packageName1 = shortcutInfo.getPackage();
+        final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2)) {
+            if (supportMultiInstancesSplit(shortcutInfo.getPackage())) {
+                activityOptions.setApplyMultipleTaskFlagForShortcut(true);
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
+            } else {
+                taskId = INVALID_TASK_ID;
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+                        "Cancel entering split as not supporting multi-instances");
+                Toast.makeText(mContext, R.string.dock_multi_instances_not_supported_text,
+                        Toast.LENGTH_SHORT).show();
+            }
+        }
+
+        mStageCoordinator.startShortcutAndTaskWithLegacyTransition(shortcutInfo,
+                activityOptions.toBundle(), taskId, options2, splitPosition, splitRatio, adapter,
+                instanceId);
     }
 
     /**
@@ -530,8 +541,10 @@
             @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
             InstanceId instanceId) {
         Intent fillInIntent = null;
-        if (launchSameAppAdjacently(pendingIntent, taskId)) {
-            if (supportMultiInstancesSplit(pendingIntent.getIntent().getComponent())) {
+        final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
+        final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2)) {
+            if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent = new Intent();
                 fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
@@ -551,8 +564,10 @@
             int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
             float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
         Intent fillInIntent = null;
-        if (launchSameAppAdjacently(pendingIntent, taskId)) {
-            if (supportMultiInstancesSplit(pendingIntent.getIntent().getComponent())) {
+        final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent);
+        final String packageName2 = SplitScreenUtils.getPackageName(taskId, mTaskOrganizer);
+        if (samePackage(packageName1, packageName2)) {
+            if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent = new Intent();
                 fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
                 ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Adding MULTIPLE_TASK");
@@ -568,13 +583,16 @@
     }
 
     private void startIntentsWithLegacyTransition(PendingIntent pendingIntent1,
-            @Nullable Bundle options1, PendingIntent pendingIntent2,
-            @Nullable Bundle options2, @SplitPosition int splitPosition,
-            float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
+            PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2,
+            @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
+            RemoteAnimationAdapter adapter, InstanceId instanceId) {
         Intent fillInIntent1 = null;
         Intent fillInIntent2 = null;
-        if (launchSameAppAdjacently(pendingIntent1, pendingIntent2)) {
-            if (supportMultiInstancesSplit(pendingIntent1.getIntent().getComponent())) {
+        final String packageName1 = SplitScreenUtils.getPackageName(pendingIntent1);
+        final String packageName2 = SplitScreenUtils.getPackageName(pendingIntent2);
+        if (samePackage(packageName1, packageName2)) {
+            if (supportMultiInstancesSplit(packageName1)) {
                 fillInIntent1 = new Intent();
                 fillInIntent1.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
                 fillInIntent2 = new Intent();
@@ -588,9 +606,9 @@
                         Toast.LENGTH_SHORT).show();
             }
         }
-        mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1, options1,
-                pendingIntent2, fillInIntent2, options2, splitPosition, splitRatio, adapter,
-                instanceId);
+        mStageCoordinator.startIntentsWithLegacyTransition(pendingIntent1, fillInIntent1,
+                shortcutInfo1, options1, pendingIntent2, fillInIntent2, shortcutInfo2, options2,
+                splitPosition, splitRatio, adapter, instanceId);
     }
 
     @Override
@@ -602,13 +620,15 @@
         if (fillInIntent == null) fillInIntent = new Intent();
         fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
 
-        if (launchSameAppAdjacently(position, intent)) {
-            final ComponentName launching = intent.getIntent().getComponent();
-            if (supportMultiInstancesSplit(launching)) {
+        final String packageName1 = SplitScreenUtils.getPackageName(intent);
+        final String packageName2 = getPackageName(reverseSplitPosition(position));
+        if (SplitScreenUtils.samePackage(packageName1, packageName2)) {
+            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(launching))
+                        .map(recentTasks -> recentTasks.findTaskInBackground(
+                                intent.getIntent().getComponent()))
                         .orElse(null);
                 if (taskInfo != null) {
                     startTask(taskInfo.taskId, position, options);
@@ -636,63 +656,32 @@
         mStageCoordinator.startIntent(intent, fillInIntent, position, options);
     }
 
+    /** Retrieve package name of a specific split position if split screen is activated, otherwise
+     *  returns the package name of the top running task. */
     @Nullable
-    private String getPackageName(Intent intent) {
-        if (intent == null || intent.getComponent() == null) {
-            return null;
-        }
-        return intent.getComponent().getPackageName();
-    }
-
-    private boolean launchSameAppAdjacently(@SplitPosition int position,
-            PendingIntent pendingIntent) {
-        ActivityManager.RunningTaskInfo adjacentTaskInfo = null;
+    private String getPackageName(@SplitPosition int position) {
+        ActivityManager.RunningTaskInfo taskInfo;
         if (isSplitScreenVisible()) {
-            adjacentTaskInfo = getTaskInfo(SplitLayout.reversePosition(position));
+            taskInfo = getTaskInfo(position);
         } else {
-            adjacentTaskInfo = mRecentTasksOptional
-                    .map(recentTasks -> recentTasks.getTopRunningTask()).orElse(null);
-            if (!isValidToEnterSplitScreen(adjacentTaskInfo)) {
-                return false;
+            taskInfo = mRecentTasksOptional
+                    .map(recentTasks -> recentTasks.getTopRunningTask())
+                    .orElse(null);
+            if (!isValidToSplit(taskInfo)) {
+                return null;
             }
         }
 
-        if (adjacentTaskInfo == null) {
-            return false;
-        }
-
-        final String targetPackageName = getPackageName(pendingIntent.getIntent());
-        final String adjacentPackageName = getPackageName(adjacentTaskInfo.baseIntent);
-        return targetPackageName != null && targetPackageName.equals(adjacentPackageName);
-    }
-
-    private boolean launchSameAppAdjacently(PendingIntent pendingIntent, int taskId) {
-        final ActivityManager.RunningTaskInfo adjacentTaskInfo =
-                mTaskOrganizer.getRunningTaskInfo(taskId);
-        if (adjacentTaskInfo == null) {
-            return false;
-        }
-        final String targetPackageName = getPackageName(pendingIntent.getIntent());
-        final String adjacentPackageName = getPackageName(adjacentTaskInfo.baseIntent);
-        return targetPackageName != null && targetPackageName.equals(adjacentPackageName);
-    }
-
-    private boolean launchSameAppAdjacently(PendingIntent pendingIntent1,
-            PendingIntent pendingIntent2) {
-        final String targetPackageName = getPackageName(pendingIntent1.getIntent());
-        final String adjacentPackageName = getPackageName(pendingIntent2.getIntent());
-        return targetPackageName != null && targetPackageName.equals(adjacentPackageName);
+        return taskInfo != null ? SplitScreenUtils.getPackageName(taskInfo.baseIntent) : null;
     }
 
     @VisibleForTesting
-    /** Returns {@code true} if the component supports multi-instances split. */
-    boolean supportMultiInstancesSplit(@Nullable ComponentName launching) {
-        if (launching == null) return false;
-
-        final String packageName = launching.getPackageName();
-        for (int i = 0; i < mAppsSupportMultiInstances.length; i++) {
-            if (mAppsSupportMultiInstances[i].equals(packageName)) {
-                return true;
+    boolean supportMultiInstancesSplit(String packageName) {
+        if (packageName != null) {
+            for (int i = 0; i < mAppsSupportMultiInstances.length; i++) {
+                if (mAppsSupportMultiInstances[i].equals(packageName)) {
+                    return true;
+                }
             }
         }
 
@@ -1011,7 +1000,7 @@
                 InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController,
                     "startShortcutAndTaskWithLegacyTransition", (controller) ->
-                            controller.mStageCoordinator.startShortcutAndTaskWithLegacyTransition(
+                            controller.startShortcutAndTaskWithLegacyTransition(
                                     shortcutInfo, options1, taskId, options2, splitPosition,
                                     splitRatio, adapter, instanceId));
         }
@@ -1049,13 +1038,14 @@
 
         @Override
         public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1,
-                @Nullable Bundle options1, PendingIntent pendingIntent2, @Nullable Bundle options2,
-                @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
-                InstanceId instanceId) {
+                @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
+                PendingIntent pendingIntent2, @Nullable ShortcutInfo shortcutInfo2,
+                @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
+                RemoteAnimationAdapter adapter, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntentsWithLegacyTransition",
                     (controller) ->
-                        controller.startIntentsWithLegacyTransition(
-                                pendingIntent1, options1, pendingIntent2, options2, splitPosition,
+                        controller.startIntentsWithLegacyTransition(pendingIntent1, shortcutInfo1,
+                                options1, pendingIntent2, shortcutInfo2, options2, splitPosition,
                                 splitRatio, adapter, instanceId)
                     );
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 39cf5f1..2a4bae9 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
@@ -36,12 +36,11 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
 
 import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
-import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
-import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
 import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
+import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -76,8 +75,10 @@
 import android.app.IActivityTaskManager;
 import android.app.PendingIntent;
 import android.app.WindowConfiguration;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherApps;
 import android.content.pm.ShortcutInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -87,6 +88,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
 import android.view.Choreographer;
@@ -370,7 +372,7 @@
         int sideStagePosition;
         if (stageType == STAGE_TYPE_MAIN) {
             targetStage = mMainStage;
-            sideStagePosition = SplitLayout.reversePosition(stagePosition);
+            sideStagePosition = reverseSplitPosition(stagePosition);
         } else if (stageType == STAGE_TYPE_SIDE) {
             targetStage = mSideStage;
             sideStagePosition = stagePosition;
@@ -428,6 +430,72 @@
         return mLogger;
     }
 
+    void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
+            Bundle options, UserHandle user) {
+        final boolean isEnteringSplit = !isSplitActive();
+
+        IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
+            @Override
+            public void onAnimationStart(@WindowManager.TransitionOldType int transit,
+                    RemoteAnimationTarget[] apps,
+                    RemoteAnimationTarget[] wallpapers,
+                    RemoteAnimationTarget[] nonApps,
+                    final IRemoteAnimationFinishedCallback finishedCallback) {
+                boolean openingToSide = false;
+                if (apps != null) {
+                    for (int i = 0; i < apps.length; ++i) {
+                        if (apps[i].mode == MODE_OPENING
+                                && mSideStage.containsTask(apps[i].taskId)) {
+                            openingToSide = true;
+                            break;
+                        }
+                    }
+                }
+
+                if (isEnteringSplit && !openingToSide) {
+                    mMainExecutor.execute(() -> exitSplitScreen(
+                            mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
+                            EXIT_REASON_UNKNOWN));
+                }
+
+                if (finishedCallback != null) {
+                    try {
+                        finishedCallback.onAnimationFinished();
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Error finishing legacy transition: ", e);
+                    }
+                }
+
+                if (!isEnteringSplit && openingToSide) {
+                    final WindowContainerTransaction evictWct = new WindowContainerTransaction();
+                    prepareEvictNonOpeningChildTasks(position, apps, evictWct);
+                    mSyncQueue.queue(evictWct);
+                }
+            }
+            @Override
+            public void onAnimationCancelled(boolean isKeyguardOccluded) {
+                if (isEnteringSplit) {
+                    mMainExecutor.execute(() -> exitSplitScreen(
+                            mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
+                            EXIT_REASON_UNKNOWN));
+                }
+            }
+        };
+        options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
+                null /* wct */);
+        RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper,
+                0 /* duration */, 0 /* statusBarTransitionDelay */);
+        ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
+        activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
+        try {
+            LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
+            launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
+                    activityOptions.toBundle(), user);
+        } catch (ActivityNotFoundException e) {
+            Slog.e(TAG, "Failed to launch shortcut", e);
+        }
+    }
+
     /** Launches an activity into split. */
     void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
             @Nullable Bundle options) {
@@ -624,9 +692,11 @@
 
     /** Starts a pair of intents using legacy transition. */
     void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, Intent fillInIntent1,
-            @Nullable Bundle options1, PendingIntent pendingIntent2, Intent fillInIntent2,
-            @Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
-            RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
+            @Nullable PendingIntent pendingIntent2, Intent fillInIntent2,
+            @Nullable ShortcutInfo shortcutInfo2, @Nullable Bundle options2,
+            @SplitPosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         if (options1 == null) options1 = new Bundle();
         if (pendingIntent2 == null) {
@@ -635,15 +705,23 @@
             activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
             options1 = activityOptions.toBundle();
             addActivityOptions(options1, null /* launchTarget */);
-            wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
+            if (shortcutInfo1 != null) {
+                wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1);
+            } else {
+                wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
+            }
             mSyncQueue.queue(wct);
             return;
         }
 
         addActivityOptions(options1, mSideStage);
-        wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
-        startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, options2, splitPosition,
-                splitRatio, adapter, instanceId);
+        if (shortcutInfo1 != null) {
+            wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1);
+        } else {
+            wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
+        }
+        startWithLegacyTransition(wct, pendingIntent2, fillInIntent2, shortcutInfo2, options2,
+                splitPosition, splitRatio, adapter, instanceId);
     }
 
     void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent,
@@ -695,18 +773,19 @@
 
     private void startWithLegacyTransition(WindowContainerTransaction wct,
             @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
-            @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
-            RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions,
+            @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
         startWithLegacyTransition(wct, INVALID_TASK_ID, mainPendingIntent, mainFillInIntent,
-                mainOptions, sidePosition, splitRatio, adapter, instanceId);
+                mainShortcutInfo, mainOptions, sidePosition, splitRatio, adapter, instanceId);
     }
 
     private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
             @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
             RemoteAnimationAdapter adapter, InstanceId instanceId) {
         startWithLegacyTransition(wct, mainTaskId, null /* mainPendingIntent */,
-                null /* mainFillInIntent */, mainOptions, sidePosition, splitRatio, adapter,
-                instanceId);
+                null /* mainFillInIntent */, null /* mainShortcutInfo */, mainOptions, sidePosition,
+                splitRatio, adapter, instanceId);
     }
 
     /**
@@ -716,8 +795,9 @@
      */
     private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
             @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
-            @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
-            RemoteAnimationAdapter adapter, InstanceId instanceId) {
+            @Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle options,
+            @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter,
+            InstanceId instanceId) {
         if (!isSplitScreenVisible()) {
             exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
         }
@@ -741,15 +821,19 @@
             mMainStage.activate(wct, false /* reparent */);
         }
 
-        if (mainOptions == null) mainOptions = new Bundle();
-        addActivityOptions(mainOptions, mMainStage);
-        mainOptions = wrapAsSplitRemoteAnimation(adapter, mainOptions);
+        if (options == null) options = new Bundle();
+        addActivityOptions(options, mMainStage);
+        options = wrapAsSplitRemoteAnimation(adapter, options);
 
         updateWindowBounds(mSplitLayout, wct);
-        if (mainTaskId == INVALID_TASK_ID) {
-            wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
+
+        // TODO(b/268008375): Merge APIs to start a split pair into one.
+        if (mainTaskId != INVALID_TASK_ID) {
+            wct.startTask(mainTaskId, options);
+        } else if (mainShortcutInfo != null) {
+            wct.startShortcut(mContext.getPackageName(), mainShortcutInfo, options);
         } else {
-            wct.startTask(mainTaskId, mainOptions);
+            wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, options);
         }
 
         wct.reorder(mRootTaskInfo.token, true);
@@ -899,7 +983,7 @@
             case STAGE_TYPE_MAIN: {
                 if (position != SPLIT_POSITION_UNDEFINED) {
                     // Set the side stage opposite of what we want to the main stage.
-                    setSideStagePosition(SplitLayout.reversePosition(position), wct);
+                    setSideStagePosition(reverseSplitPosition(position), wct);
                 } else {
                     position = getMainStagePosition();
                 }
@@ -923,7 +1007,7 @@
 
     @SplitPosition
     int getMainStagePosition() {
-        return SplitLayout.reversePosition(mSideStagePosition);
+        return reverseSplitPosition(mSideStagePosition);
     }
 
     int getTaskId(@SplitPosition int splitPosition) {
@@ -950,7 +1034,7 @@
         mSplitLayout.splitSwitching(t, topLeftStage.mRootLeash, bottomRightStage.mRootLeash,
                 insets -> {
                     WindowContainerTransaction wct = new WindowContainerTransaction();
-                    setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), wct);
+                    setSideStagePosition(reverseSplitPosition(mSideStagePosition), wct);
                     mSyncQueue.queue(wct);
                     mSyncQueue.runInSync(st -> {
                         updateSurfaceBounds(mSplitLayout, st, false /* applyResizingOffset */);
@@ -1694,12 +1778,6 @@
         }
     }
 
-    boolean isValidToEnterSplitScreen(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
-        return taskInfo.supportsMultiWindow
-                && ArrayUtils.contains(CONTROLLED_ACTIVITY_TYPES, taskInfo.getActivityType())
-                && ArrayUtils.contains(CONTROLLED_WINDOWING_MODES, taskInfo.getWindowingMode());
-    }
-
     @Override
     public void onSnappedToDismiss(boolean bottomOrRight, int reason) {
         final boolean mainStageToTop =
@@ -2108,7 +2186,7 @@
 
             // Use normal animations.
             return false;
-        } else if (mMixedHandler != null && hasDisplayChange(info)) {
+        } else if (mMixedHandler != null && Transitions.hasDisplayChange(info)) {
             // A display-change has been un-expectedly inserted into the transition. Redirect
             // handling to the mixed-handler to deal with splitting it up.
             if (mMixedHandler.animatePendingSplitWithDisplayChange(transition, info,
@@ -2151,15 +2229,6 @@
         return true;
     }
 
-    private boolean hasDisplayChange(TransitionInfo info) {
-        boolean has = false;
-        for (int iC = 0; iC < info.getChanges().size() && !has; ++iC) {
-            final TransitionInfo.Change change = info.getChanges().get(iC);
-            has = change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0;
-        }
-        return has;
-    }
-
     /** Called to clean-up state and do house-keeping after the animation is done. */
     public void onTransitionAnimationComplete() {
         // If still playing, let it finish.
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 b4e0584..02f19eb 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
@@ -93,6 +93,11 @@
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
             @NonNull Transitions.TransitionFinishCallback finishCallback) {
+        if (!Transitions.SHELL_TRANSITIONS_ROTATION && Transitions.hasDisplayChange(info)) {
+            // Note that if the remote doesn't have permission ACCESS_SURFACE_FLINGER, some
+            // operations of the start transaction may be ignored.
+            return false;
+        }
         RemoteTransition pendingRemote = mRequestedRemotes.get(transition);
         if (pendingRemote == null) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s doesn't have "
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 44d6a0d..5275e90 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
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.fixScale;
+import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
 import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
@@ -328,6 +329,17 @@
         return type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK;
     }
 
+    /** Returns {@code true} if the transition has a display change. */
+    public static boolean hasDisplayChange(@NonNull TransitionInfo info) {
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            final TransitionInfo.Change change = info.getChanges().get(i);
+            if (change.getMode() == TRANSIT_CHANGE && change.hasFlags(FLAG_IS_DISPLAY)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Sets up visibility/alpha/transforms to resemble the starting state of an animation.
      */
@@ -817,7 +829,15 @@
         }
         mOrganizer.startTransition(transitionToken, wct != null && wct.isEmpty() ? null : wct);
         active.mToken = transitionToken;
-        mActiveTransitions.add(active);
+        int insertIdx = 0;
+        for (; insertIdx < mActiveTransitions.size(); ++insertIdx) {
+            if (mActiveTransitions.get(insertIdx).mInfo == null) {
+                // A `startNewTransition` was sent to WMCore, but wasn't acknowledged before WMCore
+                // made this request, so insert this request beforehand to keep order in sync.
+                break;
+            }
+        }
+        mActiveTransitions.add(insertIdx, active);
     }
 
     /** Start a new transition directly. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
index eab82f0..87e447b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/FullscreenUnfoldTaskAnimator.java
@@ -85,7 +85,7 @@
 
     @Override
     public void insetsChanged(InsetsState insetsState) {
-        mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+        mTaskbarInsetsSource = insetsState.peekSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
         for (int i = mAnimationContextByTaskId.size() - 1; i >= 0; i--) {
             AnimationContext context = mAnimationContextByTaskId.valueAt(i);
             context.update(mTaskbarInsetsSource, context.mTaskInfo);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/animation/SplitTaskUnfoldAnimator.java
index 6e10ebe..8a0fbe3 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
@@ -126,7 +126,7 @@
 
     @Override
     public void insetsChanged(InsetsState insetsState) {
-        mTaskbarInsetsSource = insetsState.getSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
+        mTaskbarInsetsSource = insetsState.peekSource(InsetsState.ITYPE_EXTRA_NAVIGATION_BAR);
         updateContexts();
     }
 
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 606cf28..44e4a31 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
@@ -156,6 +156,7 @@
         }
 
         decoration.relayout(taskInfo);
+        setupCaptionColor(taskInfo, decoration);
     }
 
     @Override
@@ -227,7 +228,11 @@
         public void onClick(View v) {
             final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
             final int id = v.getId();
-            if (id == R.id.caption_handle) {
+            if (id == R.id.close_window || id == R.id.close_button) {
+                mTaskOperations.closeTask(mTaskToken);
+            } else if (id == R.id.back_button) {
+                mTaskOperations.injectBackKey();
+            } else if (id == R.id.caption_handle) {
                 decoration.createHandleMenu();
             } else if (id == R.id.desktop_button) {
                 mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
@@ -238,6 +243,8 @@
                 mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
                 decoration.closeHandleMenu();
                 decoration.setButtonVisibility(false);
+            } else if (id == R.id.collapse_menu_button) {
+                decoration.closeHandleMenu();
             }
         }
 
@@ -301,18 +308,11 @@
                     mDragPositioningCallback.onDragPositioningEnd(
                             e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
                     if (e.getRawY(dragPointerIdx) <= statusBarHeight) {
-                        if (DesktopModeStatus.isProto2Enabled()) {
-                            if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
-                                // Switch a single task to fullscreen
-                                mDesktopTasksController.ifPresent(
-                                        c -> c.moveToFullscreen(taskInfo));
-                            }
-                        } else if (DesktopModeStatus.isProto1Enabled()) {
-                            if (DesktopModeStatus.isActive(mContext)) {
-                                // Turn off desktop mode
-                                mDesktopModeController.ifPresent(
-                                        c -> c.setDesktopModeActive(false));
-                            }
+                        if (DesktopModeStatus.isProto2Enabled()
+                                && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+                            // Switch a single task to fullscreen
+                            mDesktopTasksController.ifPresent(
+                                    c -> c.moveToFullscreen(taskInfo));
                         }
                     }
                     break;
@@ -402,10 +402,6 @@
                     || focusedDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
                 handleCaptionThroughStatusBar(ev);
             }
-        } else if (DesktopModeStatus.isProto1Enabled()) {
-            if (!DesktopModeStatus.isActive(mContext)) {
-                handleCaptionThroughStatusBar(ev);
-            }
         }
         handleEventOutsideFocusedCaption(ev);
         // Prevent status bar from reacting to a caption drag.
@@ -451,9 +447,6 @@
                         // In proto2 any full screen task can be dragged to freeform
                         dragFromStatusBarAllowed = focusedDecor.mTaskInfo.getWindowingMode()
                                 == WINDOWING_MODE_FULLSCREEN;
-                    } else if (DesktopModeStatus.isProto1Enabled()) {
-                        // In proto1 task can be dragged to freeform when not in desktop mode
-                        dragFromStatusBarAllowed = !DesktopModeStatus.isActive(mContext);
                     }
 
                     if (dragFromStatusBarAllowed && focusedDecor.checkTouchEventInHandle(ev)) {
@@ -522,9 +515,16 @@
         }
     }
 
+    private void setupCaptionColor(RunningTaskInfo taskInfo,
+            DesktopModeWindowDecoration decoration) {
+        if (taskInfo == null || taskInfo.taskDescription == null) return;
+        final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
+        decoration.setCaptionColor(statusBarColor);
+    }
+
     private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
         if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
-        return DesktopModeStatus.isAnyEnabled()
+        return DesktopModeStatus.isProto2Enabled()
                 && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
                 && mDisplayController.getDisplayContext(taskInfo.displayId)
                 .getResources().getConfiguration().smallestScreenWidthDp >= 600;
@@ -560,6 +560,7 @@
         windowDecoration.setDragPositioningCallback(taskPositioner);
         windowDecoration.setDragDetector(touchEventListener.mDragDetector);
         windowDecoration.relayout(taskInfo, startT, finishT);
+        setupCaptionColor(taskInfo, windowDecoration);
         incrementEventReceiverTasks(taskInfo.displayId);
     }
 
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 744c18f..245cc8d 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
@@ -20,18 +20,25 @@
 
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.VectorDrawable;
 import android.os.Handler;
+import android.util.Log;
 import android.view.Choreographer;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.widget.ImageView;
+import android.widget.TextView;
 import android.window.WindowContainerTransaction;
 
 import com.android.wm.shell.R;
@@ -48,6 +55,7 @@
  * The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
  */
 public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
+    private static final String TAG = "DesktopModeWindowDecoration";
     private final Handler mHandler;
     private final Choreographer mChoreographer;
     private final SyncTransactionQueue mSyncQueue;
@@ -59,12 +67,14 @@
     private DragDetector mDragDetector;
 
     private RelayoutParams mRelayoutParams = new RelayoutParams();
-    private final int mCaptionMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
+    private final int mCaptionMenuHeightId = R.dimen.freeform_decor_caption_menu_height;
     private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
             new WindowDecoration.RelayoutResult<>();
 
     private boolean mDesktopActive;
     private AdditionalWindow mHandleMenu;
+    private final int mHandleMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
+    private PointF mHandleMenuPosition = new PointF();
 
     DesktopModeWindowDecoration(
             Context context,
@@ -211,21 +221,46 @@
         final View fullscreen = menu.findViewById(R.id.fullscreen_button);
         fullscreen.setOnClickListener(mOnCaptionButtonClickListener);
         final View desktop = menu.findViewById(R.id.desktop_button);
-        desktop.setOnClickListener(mOnCaptionButtonClickListener);
+        if (DesktopModeStatus.isProto2Enabled()) {
+            desktop.setOnClickListener(mOnCaptionButtonClickListener);
+        } else if (DesktopModeStatus.isProto1Enabled()) {
+            desktop.setVisibility(View.GONE);
+        }
         final View split = menu.findViewById(R.id.split_screen_button);
         split.setOnClickListener(mOnCaptionButtonClickListener);
+        final View close = menu.findViewById(R.id.close_button);
+        close.setOnClickListener(mOnCaptionButtonClickListener);
+        final View collapse = menu.findViewById(R.id.collapse_menu_button);
+        collapse.setOnClickListener(mOnCaptionButtonClickListener);
+        menu.setOnTouchListener(mOnCaptionTouchListener);
+
+        String packageName = mTaskInfo.baseActivity.getPackageName();
+        PackageManager pm = mContext.getApplicationContext().getPackageManager();
+        // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
+        try {
+            ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
+                    PackageManager.ApplicationInfoFlags.of(0));
+            final ImageView appIcon = menu.findViewById(R.id.application_icon);
+            appIcon.setImageDrawable(pm.getApplicationIcon(applicationInfo));
+            final TextView appName = menu.findViewById(R.id.application_name);
+            appName.setText(pm.getApplicationLabel(applicationInfo));
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Package not found: " + packageName, e);
+        }
     }
 
     /**
      * Sets caption visibility based on task focus.
-     *
+     * Note: Only applicable to Desktop Proto 1; Proto 2 only closes handle menu on focus loss
      * @param visible whether or not the caption should be visible
      */
     private void setCaptionVisibility(boolean visible) {
+        if (!visible) closeHandleMenu();
+        if (!DesktopModeStatus.isProto1Enabled()) return;
         final int v = visible ? View.VISIBLE : View.GONE;
         final View captionView = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
         captionView.setVisibility(v);
-        if (!visible) closeHandleMenu();
+
     }
 
     /**
@@ -244,8 +279,13 @@
      * Show or hide buttons
      */
     void setButtonVisibility(boolean visible) {
-        final int visibility = visible ? View.VISIBLE : View.GONE;
+        final int visibility = visible && DesktopModeStatus.isProto1Enabled()
+                ? View.VISIBLE : View.GONE;
         final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
+        final View back = caption.findViewById(R.id.back_button);
+        final View close = caption.findViewById(R.id.close_window);
+        back.setVisibility(visibility);
+        close.setVisibility(visibility);
         final int buttonTintColorRes =
                 mDesktopActive ? R.color.decor_button_dark_color
                         : R.color.decor_button_light_color;
@@ -254,13 +294,33 @@
         final View handle = caption.findViewById(R.id.caption_handle);
         final VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
         handleBackground.setTintList(buttonTintColor);
-        caption.getBackground().setTint(visible ? Color.WHITE : Color.TRANSPARENT);
     }
 
     boolean isHandleMenuActive() {
         return mHandleMenu != null;
     }
 
+    void setCaptionColor(int captionColor) {
+        if (mResult.mRootView == null) {
+            return;
+        }
+
+        final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
+        final GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
+        captionDrawable.setColor(captionColor);
+
+        final int buttonTintColorRes =
+                Color.valueOf(captionColor).luminance() < 0.5
+                        ? R.color.decor_button_light_color
+                        : R.color.decor_button_dark_color;
+        final ColorStateList buttonTintColor =
+                caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
+
+        final View handle = caption.findViewById(R.id.caption_handle);
+        final Drawable handleBackground = handle.getBackground();
+        handleBackground.setTintList(buttonTintColor);
+    }
+
     private void closeDragResizeListener() {
         if (mDragResizeListener == null) {
             return;
@@ -277,16 +337,21 @@
         final Resources resources = mDecorWindowContext.getResources();
         final int captionWidth = mTaskInfo.getConfiguration()
                 .windowConfiguration.getBounds().width();
-        final int menuWidth = loadDimensionPixelSize(
-                resources, mCaptionMenuWidthId);
-        final int height = loadDimensionPixelSize(
-                resources, mRelayoutParams.mCaptionHeightId);
+        final int menuWidth = loadDimensionPixelSize(resources, mHandleMenuWidthId);
+        final int menuHeight = loadDimensionPixelSize(resources, mCaptionMenuHeightId);
+
+        // Elevation gives the appearance of a changed x/y coordinate; this is to fix that
+        int elevationOffset = 2 * loadDimensionPixelSize(resources,
+                R.dimen.caption_menu_elevation);
+
         final int x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
-                - mResult.mDecorContainerOffsetX;
-        final int y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+                - mResult.mDecorContainerOffsetX - elevationOffset;
+        final int y =
+                mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY - elevationOffset;
+        mHandleMenuPosition.set(x, y);
         String namePrefix = "Caption Menu";
         mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
-                menuWidth, height);
+                menuWidth, menuHeight, 2 * elevationOffset);
         mSyncQueue.runInSync(transaction -> {
             transaction.merge(t);
             t.close();
@@ -315,10 +380,17 @@
      * @param ev the tapped point to compare against
      */
     void closeHandleMenuIfNeeded(MotionEvent ev) {
-        if (isHandleMenuActive()) {
-            if (!checkEventInCaptionView(ev, R.id.desktop_mode_caption)) {
-                closeHandleMenu();
-            }
+        if (!isHandleMenuActive()) return;
+
+        // When this is called before the layout is fully inflated, width will be 0.
+        // Menu is not visible in this scenario, so skip the check if that is the case.
+        if (mHandleMenu.mWindowViewHost.getView().getWidth() == 0) return;
+
+        PointF inputPoint = offsetCaptionLocation(ev);
+        if (!pointInView(mHandleMenu.mWindowViewHost.getView(),
+                inputPoint.x - mHandleMenuPosition.x - mResult.mDecorContainerOffsetX,
+                inputPoint.y - mHandleMenuPosition.y - mResult.mDecorContainerOffsetY)) {
+            closeHandleMenu();
         }
     }
 
@@ -380,12 +452,8 @@
             final int menuX = mRelayoutParams.mCaptionX + (captionWidth / 2)
                     - (menu.getWidth() / 2);
             final PointF inputPoint = new PointF(ev.getX() - menuX, ev.getY());
-            final View fullscreen = menu.findViewById(R.id.fullscreen_button);
-            if (clickIfPointInView(inputPoint, fullscreen)) return;
-            final View desktop = menu.findViewById(R.id.desktop_button);
-            if (clickIfPointInView(inputPoint, desktop)) return;
-            final View split = menu.findViewById(R.id.split_screen_button);
-            if (clickIfPointInView(inputPoint, split)) return;
+            final View collapse = menu.findViewById(R.id.collapse_menu_button);
+            if (clickIfPointInView(inputPoint, collapse)) return;
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 62b72f3..ae685ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -391,10 +391,11 @@
      * @param yPos y position of new window
      * @param width width of new window
      * @param height height of new window
+     * @param cropPadding padding to add to window crop to ensure shadows display properly
      * @return
      */
-    AdditionalWindow addWindow(int layoutId, String namePrefix,
-            SurfaceControl.Transaction t, int xPos, int yPos, int width, int height) {
+    AdditionalWindow addWindow(int layoutId, String namePrefix, SurfaceControl.Transaction t,
+            int xPos, int yPos, int width, int height, int cropPadding) {
         final SurfaceControl.Builder builder = mSurfaceControlBuilderSupplier.get();
         SurfaceControl windowSurfaceControl = builder
                 .setName(namePrefix + " of Task=" + mTaskInfo.taskId)
@@ -405,7 +406,7 @@
 
         t.setPosition(
                 windowSurfaceControl, xPos, yPos)
-                .setWindowCrop(windowSurfaceControl, width, height)
+                .setWindowCrop(windowSurfaceControl, width + cropPadding, height + cropPadding)
                 .show(windowSurfaceControl);
         final WindowManager.LayoutParams lp =
                 new WindowManager.LayoutParams(width, height,
@@ -426,6 +427,7 @@
         RunningTaskInfo mRunningTaskInfo;
         int mLayoutResId;
         int mCaptionHeightId;
+        int mCaptionWidthId;
         int mShadowRadiusId;
 
         int mOutsetTopId;
@@ -451,6 +453,7 @@
         void reset() {
             mLayoutResId = Resources.ID_NULL;
             mCaptionHeightId = Resources.ID_NULL;
+            mCaptionWidthId = Resources.ID_NULL;
             mShadowRadiusId = Resources.ID_NULL;
 
             mOutsetTopId = Resources.ID_NULL;
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
index 122c18d..aafd7ed 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
@@ -32,7 +32,7 @@
 import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible
 import com.android.server.wm.flicker.taskBarLayerIsVisibleAtStartAndEnd
 import com.android.server.wm.flicker.taskBarWindowIsAlwaysVisible
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Assume
 import org.junit.Test
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index 5186914..bd18108 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -22,7 +22,7 @@
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.traces.layers.LayerTraceEntrySubject
 import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
-import com.android.server.wm.traces.common.IComponentMatcher
+import com.android.server.wm.traces.common.component.matchers.IComponentMatcher
 import com.android.server.wm.traces.common.region.Region
 import com.android.server.wm.traces.common.service.PlatformConsts
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index 651d935..e9c805e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -18,7 +18,7 @@
 
 package com.android.wm.shell.flicker
 
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 
 const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
 const val LAUNCHER_UI_PACKAGE_NAME = "com.google.android.apps.nexuslauncher"
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index 4f3facb..88cf15e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -54,7 +54,7 @@
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @FlakyTest(bugId = 238367575)
-class AutoEnterPipOnGoToHomeTest(flicker: FlickerTest) : EnterPipTest(flicker) {
+class AutoEnterPipOnGoToHomeTest(flicker: FlickerTest) : EnterPipViaAppUiButtonTest(flicker) {
     /** Defines the transition used to run the test */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
similarity index 82%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index 1b48965..88542d5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
@@ -20,10 +20,8 @@
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
-import com.android.server.wm.traces.common.service.PlatformConsts
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -54,7 +52,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipWithSwipeDownTest(flicker: FlickerTest) : ExitPipTransition(flicker) {
+open class ClosePipBySwipingDownTest(flicker: FlickerTest) : ClosePipTransition(flicker) {
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             super.transition(this)
@@ -96,20 +94,4 @@
     fun focusDoesNotChange() {
         flicker.assertEventLog { this.focusDoesNotChange() }
     }
-
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
-         * and navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt
similarity index 94%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt
index 9f26018..fb1eb01 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt
@@ -28,7 +28,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipWithSwipeDownTestCfArm(flicker: FlickerTest) : ExitPipWithSwipeDownTest(flicker) {
+class ClosePipBySwipingDownTestCfArm(flicker: FlickerTest) : ClosePipBySwipingDownTest(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
similarity index 79%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
index 1b5c227..080e033 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
@@ -19,14 +19,16 @@
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.ComponentNameMatcher.Companion.LAUNCHER
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher.Companion.LAUNCHER
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Test
+import org.junit.runners.Parameterized
 
 /** Base class for exiting pip (closing pip window) without returning to the app */
-abstract class ExitPipTransition(flicker: FlickerTest) : PipTransition(flicker) {
+abstract class ClosePipTransition(flicker: FlickerTest) : PipTransition(flicker) {
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
             setup { this.setRotation(flicker.scenario.startRotation) }
@@ -77,4 +79,20 @@
                 .isVisible(LAUNCHER)
         }
     }
+
+    companion object {
+        /**
+         * Creates the test configurations.
+         *
+         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
+         * and navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+            )
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
similarity index 77%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
index 8a1a31a..f27fa4a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
@@ -20,9 +20,7 @@
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -54,7 +52,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipWithDismissButtonTest(flicker: FlickerTest) : ExitPipTransition(flicker) {
+open class ClosePipWithDismissButtonTest(flicker: FlickerTest) : ClosePipTransition(flicker) {
 
     override val transition: FlickerBuilder.() -> Unit
         get() = {
@@ -71,20 +69,4 @@
     fun focusChanges() {
         flicker.assertEventLog { this.focusChanges("PipMenuView", "NexusLauncherActivity") }
     }
-
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
-         * and navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt
similarity index 93%
copy from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
copy to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt
index 9f26018..fbada69 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt
@@ -28,7 +28,8 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipWithSwipeDownTestCfArm(flicker: FlickerTest) : ExitPipWithSwipeDownTest(flicker) {
+open class ClosePipWithDismissButtonTestCfArm(flicker: FlickerTest) :
+    ClosePipWithDismissButtonTest(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 82617dd..47537c6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -52,7 +52,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipOnUserLeaveHintTest(flicker: FlickerTest) : EnterPipTest(flicker) {
+open class EnterPipOnUserLeaveHintTest(flicker: FlickerTest) : EnterPipTransition(flicker) {
     /** Defines the transition used to run the test */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTestCfArm.kt
deleted file mode 100644
index d2e8645..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTestCfArm.kt
+++ /dev/null
@@ -1,47 +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.wm.shell.flicker.pip
-
-import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
-import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterPipTestCfArm(flicker: FlickerTest) : EnterPipTest(flicker) {
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
-         * and navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
similarity index 97%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index afc4106..db50489 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -30,7 +30,7 @@
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions.Pip.ACTION_ENTER_PIP
 import com.android.server.wm.flicker.testapp.ActivityOptions.PortraitOnlyActivity.EXTRA_FIXED_ORIENTATION
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
 import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_PORTRAIT
@@ -67,7 +67,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipToOtherOrientationTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class EnterPipToOtherOrientation(flicker: FlickerTest) : PipTransition(flicker) {
     private val testApp = FixedOrientationAppHelper(instrumentation)
     private val startingBounds = WindowUtils.getDisplayBounds(PlatformConsts.Rotation.ROTATION_90)
     private val endingBounds = WindowUtils.getDisplayBounds(PlatformConsts.Rotation.ROTATION_0)
@@ -179,8 +179,7 @@
     fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
         Assume.assumeFalse(tapl.isTablet)
         flicker.assertLayersStart {
-            visibleRegion(pipApp.or(ComponentNameMatcher.LETTERBOX))
-                .coversExactly(startingBounds)
+            visibleRegion(pipApp.or(ComponentNameMatcher.LETTERBOX)).coversExactly(startingBounds)
         }
     }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTestCfArm.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt
index 39aab6e..ec5f13c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt
@@ -29,8 +29,8 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipToOtherOrientationTestCfArm(flicker: FlickerTest) :
-    EnterPipToOtherOrientationTest(flicker) {
+open class EnterPipToOtherOrientationCfArm(flicker: FlickerTest) :
+    EnterPipToOtherOrientation(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
similarity index 74%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
index 33a6405..3ef66d7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 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.
@@ -17,51 +17,20 @@
 package com.android.wm.shell.flicker.pip
 
 import android.platform.test.annotations.Presubmit
-import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.FlickerTestFactory
-import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
-import org.junit.FixMethodOrder
 import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
 
-/**
- * Test entering pip from an app by interacting with the app UI
- *
- * To run this test: `atest WMShellFlickerTests:EnterPipTest`
- *
- * Actions:
- * ```
- *     Launch an app in full screen
- *     Press an "enter pip" button to put [pipApp] in pip mode
- * ```
- * Notes:
- * ```
- *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
- *        are inherited from [PipTransition]
- *     2. Part of the test setup occurs automatically via
- *        [com.android.server.wm.flicker.TransitionRunnerWithRules],
- *        including configuring navigation mode, initial orientation and ensuring no
- *        apps are running before setup
- * ```
- */
-@RequiresDevice
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipTest(flicker: FlickerTest) : PipTransition(flicker) {
-
+abstract class EnterPipTransition(flicker: FlickerTest) : PipTransition(flicker) {
     /** {@inheritDoc} */
     override val transition: FlickerBuilder.() -> Unit
         get() = {
             setup { pipApp.launchViaIntent(wmHelper) }
             teardown { pipApp.exit(wmHelper) }
-            transitions { pipApp.clickEnterPipButton(wmHelper) }
         }
 
     /** Checks [pipApp] window remains visible throughout the animation */
@@ -101,7 +70,7 @@
     @Presubmit
     @Test
     open fun pipLayerOrOverlayRemainInsideVisibleBounds() {
-        flicker.assertLayersVisibleRegion(pipApp.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY) ) {
+        flicker.assertLayersVisibleRegion(pipApp.or(ComponentNameMatcher.PIP_CONTENT_OVERLAY)) {
             coversAtMost(displayBounds)
         }
     }
@@ -129,7 +98,7 @@
         }
     }
 
-    /** Checks [ComponentMatcher.LAUNCHER] layer remains visible throughout the animation */
+    /** Checks [ComponentNameMatcher.LAUNCHER] layer remains visible throughout the animation */
     @Presubmit
     @Test
     fun launcherLayerBecomesVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
new file mode 100644
index 0000000..c3c705e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip
+
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerBuilder
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from an app by interacting with the app UI
+ *
+ * To run this test: `atest WMShellFlickerTests:EnterPipTest`
+ *
+ * Actions:
+ * ```
+ *     Launch an app in full screen
+ *     Press an "enter pip" button to put [pipApp] in pip mode
+ * ```
+ * Notes:
+ * ```
+ *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ *        are inherited from [PipTransition]
+ *     2. Part of the test setup occurs automatically via
+ *        [com.android.server.wm.flicker.TransitionRunnerWithRules],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ * ```
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class EnterPipViaAppUiButtonTest(flicker: FlickerTest) : EnterPipTransition(flicker) {
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit
+        get() = {
+            super.transition(this)
+            transitions { pipApp.clickEnterPipButton(wmHelper) }
+        }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt
similarity index 94%
copy from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
copy to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt
index 9f26018..b487ff4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt
@@ -28,7 +28,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipWithSwipeDownTestCfArm(flicker: FlickerTest) : ExitPipWithSwipeDownTest(flicker) {
+class EnterPipViaAppUiButtonTestCfArm(flicker: FlickerTest) : EnterPipViaAppUiButtonTest(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
index 691b087..f88f8d6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
@@ -18,9 +18,12 @@
 
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
+import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Test
+import org.junit.runners.Parameterized
 
 /** Base class for pip expand tests */
 abstract class ExitPipToAppTransition(flicker: FlickerTest) : PipTransition(flicker) {
@@ -80,7 +83,8 @@
             isVisible(testApp)
                 .isVisible(pipApp.or(ComponentNameMatcher.TRANSITION_SNAPSHOT))
                 .then()
-                .isInvisible(testApp).isVisible(pipApp)
+                .isInvisible(testApp)
+                .isVisible(pipApp)
         }
     }
 
@@ -121,4 +125,20 @@
 
     /** {@inheritDoc} */
     @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
+
+    companion object {
+        /**
+         * Creates the test configurations.
+         *
+         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+         * navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+            )
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
similarity index 82%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
index 3bfcde3..d2fbb2a2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
@@ -21,10 +21,8 @@
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -58,7 +56,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipViaExpandButtonClickTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
+open class ExitPipToAppViaExpandButtonTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
 
     /** Defines the transition used to run the test */
     override val transition: FlickerBuilder.() -> Unit
@@ -89,20 +87,4 @@
         Assume.assumeTrue(isShellTransitionsEnabled)
         super.pipLayerExpands()
     }
-
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
-         * navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt
similarity index 93%
copy from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestCfArm.kt
copy to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt
index 5feb73e..8b3755e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt
@@ -28,7 +28,8 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExpandPipOnDoubleClickTestCfArm(flicker: FlickerTest) : ExpandPipOnDoubleClickTest(flicker) {
+class ExitPipToAppViaExpandButtonTestCfArm(flicker: FlickerTest) :
+    ExitPipToAppViaExpandButtonTest(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
similarity index 83%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
index 2c5455f..a9eb18d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
@@ -21,10 +21,8 @@
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -57,7 +55,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipViaIntentTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
+open class ExitPipToAppViaIntentTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
 
     /** Defines the transition used to run the test */
     override val transition: FlickerBuilder.() -> Unit
@@ -106,20 +104,4 @@
         Assume.assumeTrue(isShellTransitionsEnabled)
         super.pipLayerExpands()
     }
-
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
-         * and navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt
similarity index 94%
copy from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
copy to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt
index 9f26018..39b1c82 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt
@@ -28,7 +28,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipWithSwipeDownTestCfArm(flicker: FlickerTest) : ExitPipWithSwipeDownTest(flicker) {
+class ExitPipToAppViaIntentTestCfArm(flicker: FlickerTest) : ExitPipToAppViaIntentTest(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTestCfArm.kt
deleted file mode 100644
index f77e335..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTestCfArm.kt
+++ /dev/null
@@ -1,48 +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.wm.shell.flicker.pip
-
-import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
-import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipViaExpandButtonClickTestCfArm(flicker: FlickerTest) :
-    ExitPipViaExpandButtonClickTest(flicker) {
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
-         * navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTestCfArm.kt
deleted file mode 100644
index 03dfa5b..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTestCfArm.kt
+++ /dev/null
@@ -1,47 +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.wm.shell.flicker.pip
-
-import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
-import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipViaIntentTestCfArm(flicker: FlickerTest) : ExitPipViaIntentTest(flicker) {
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
-         * and navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTestCfArm.kt
deleted file mode 100644
index a3f214c..0000000
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTestCfArm.kt
+++ /dev/null
@@ -1,48 +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.wm.shell.flicker.pip
-
-import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
-import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
-import org.junit.FixMethodOrder
-import org.junit.runner.RunWith
-import org.junit.runners.MethodSorters
-import org.junit.runners.Parameterized
-
-@RunWith(Parameterized::class)
-@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipWithDismissButtonTestCfArm(flicker: FlickerTest) :
-    ExitPipWithDismissButtonTest(flicker) {
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
-         * and navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index eff2df8..d577b4f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -22,7 +22,7 @@
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -31,7 +31,7 @@
 import org.junit.runners.Parameterized
 
 /**
- * Test expanding a pip window by double clicking it
+ * Test expanding a pip window by double-clicking it
  *
  * To run this test: `atest WMShellFlickerTests:ExpandPipOnDoubleClickTest`
  *
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt
similarity index 93%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestCfArm.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt
index 5feb73e..08db8ae 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt
@@ -28,7 +28,8 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExpandPipOnDoubleClickTestCfArm(flicker: FlickerTest) : ExpandPipOnDoubleClickTest(flicker) {
+class ExpandPipOnDoubleClickTestTestCfArm(flicker: FlickerTest) :
+    ExpandPipOnDoubleClickTest(flicker) {
     companion object {
         /**
          * Creates the test configurations.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
similarity index 78%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
index 16acc11..39ac49f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
@@ -20,9 +20,7 @@
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.wm.shell.flicker.Direction
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -56,8 +54,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class MovePipDownShelfHeightChangeTest(flicker: FlickerTest) :
-    MovePipShelfHeightTransition(flicker) {
+class MovePipDownOnShelfHeightChange(flicker: FlickerTest) : MovePipShelfHeightTransition(flicker) {
     /** Defines the transition used to run the test */
     override val transition: FlickerBuilder.() -> Unit
         get() = buildTransition {
@@ -73,20 +70,4 @@
 
     /** Checks that the visible region of [pipApp] layer always moves down during the animation. */
     @Presubmit @Test fun pipLayerMovesDown() = pipLayerMoves(Direction.DOWN)
-
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
-         * navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
similarity index 94%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
index 3939e7f..7db80a8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume.assumeFalse
 import org.junit.Before
@@ -41,7 +41,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class PipKeyboardTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class MovePipOnImeVisibilityChangeTest(flicker: FlickerTest) : PipTransition(flicker) {
     private val imeApp = ImeAppHelper(instrumentation)
 
     @Before
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestCfArm.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt
index 9e2d27d..be3bd60 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt
@@ -28,7 +28,8 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class PipKeyboardTestCfArm(flicker: FlickerTest) : PipKeyboardTest(flicker) {
+class MovePipOnImeVisibilityChangeTestCfArm(flicker: FlickerTest) :
+    MovePipOnImeVisibilityChangeTest(flicker) {
     companion object {
         private const val TAG_IME_VISIBLE = "imeIsVisible"
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestShellTransit.kt
similarity index 92%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestShellTransit.kt
index 901814e..ef9920c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTestShellTransit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestShellTransit.kt
@@ -33,7 +33,8 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class PipKeyboardTestShellTransit(flicker: FlickerTest) : PipKeyboardTest(flicker) {
+class MovePipOnImeVisibilityChangeTestShellTransit(flicker: FlickerTest) :
+    MovePipOnImeVisibilityChangeTest(flicker) {
 
     @Before
     override fun before() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
index 35525cb..77a8c3c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
@@ -18,10 +18,13 @@
 
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
 import com.android.server.wm.flicker.traces.region.RegionSubject
+import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.wm.shell.flicker.Direction
 import org.junit.Test
+import org.junit.runners.Parameterized
 
 /** Base class for pip tests with Launcher shelf height change */
 abstract class MovePipShelfHeightTransition(flicker: FlickerTest) : PipTransition(flicker) {
@@ -103,4 +106,20 @@
         regions.zipWithNext { previous, current -> current.isHigherOrEqual(previous.region) }
         regions.last().isHigher(regions.first())
     }
+
+    companion object {
+        /**
+         * Creates the test configurations.
+         *
+         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+         * navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): List<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests(
+                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
+            )
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
similarity index 80%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
index 3a12a34..511a651 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
@@ -20,9 +20,7 @@
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerBuilder
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.wm.shell.flicker.Direction
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -56,7 +54,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class MovePipUpShelfHeightChangeTest(flicker: FlickerTest) :
+open class MovePipUpOnShelfHeightChangeTest(flicker: FlickerTest) :
     MovePipShelfHeightTransition(flicker) {
     /** Defines the transition used to run the test */
     override val transition: FlickerBuilder.() -> Unit
@@ -72,20 +70,4 @@
 
     /** Checks that the visible region of [pipApp] layer always moves up during the animation. */
     @Presubmit @Test fun pipLayerMovesUp() = pipLayerMoves(Direction.UP)
-
-    companion object {
-        /**
-         * Creates the test configurations.
-         *
-         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
-         * navigation modes.
-         */
-        @Parameterized.Parameters(name = "{0}")
-        @JvmStatic
-        fun getParams(): List<FlickerTest> {
-            return FlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(PlatformConsts.Rotation.ROTATION_0)
-            )
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index 415c270..166416a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.wm.shell.flicker.BaseTest
 import com.google.common.truth.Truth
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
similarity index 96%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
index 871515b..3f5d067 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
@@ -46,7 +46,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SetRequestedOrientationWhilePinnedTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class SetRequestedOrientationWhilePinned(flicker: FlickerTest) : PipTransition(flicker) {
     private val startingBounds = WindowUtils.getDisplayBounds(PlatformConsts.Rotation.ROTATION_0)
     private val endingBounds = WindowUtils.getDisplayBounds(PlatformConsts.Rotation.ROTATION_90)
 
@@ -71,9 +71,7 @@
                     .withStatusBarVisible()
                     .waitForAndVerify()
             }
-            teardown {
-                pipApp.exit(wmHelper)
-            }
+            teardown { pipApp.exit(wmHelper) }
             transitions {
                 // Launch the activity back into fullscreen and ensure that it is now in landscape
                 pipApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
similarity index 98%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
index 4557a15..720fe72 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
@@ -57,7 +57,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class PipRotationTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class ShowPipAndRotateDisplay(flicker: FlickerTest) : PipTransition(flicker) {
     private val testApp = SimpleAppHelper(instrumentation)
     private val screenBoundsStart = WindowUtils.getDisplayBounds(flicker.scenario.startRotation)
     private val screenBoundsEnd = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt
similarity index 94%
rename from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTestCfArm.kt
rename to libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt
index e72d604..daf3e1b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt
@@ -27,7 +27,7 @@
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class PipRotationTestCfArm(flicker: FlickerTest) : PipRotationTest(flicker) {
+class ShowPipAndRotateDisplayCfArm(flicker: FlickerTest) : ShowPipAndRotateDisplay(flicker) {
     companion object {
         /**
          * Creates the test configurations.
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 70a1523..247403a 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
@@ -24,8 +24,8 @@
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
-import com.android.server.wm.traces.common.EdgeExtensionComponentMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.EdgeExtensionComponentMatcher
 import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
 import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
 import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
@@ -116,7 +116,6 @@
     /** {@inheritDoc} */
     @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
 
-
     /** {@inheritDoc} */
     @Presubmit
     @Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
index f3927d4..4f8cfca 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
@@ -34,9 +34,9 @@
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
-import com.android.server.wm.traces.common.IComponentMatcher
-import com.android.server.wm.traces.common.IComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.IComponentMatcher
+import com.android.server.wm.traces.common.component.matchers.IComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 import com.android.wm.shell.flicker.LAUNCHER_UI_PACKAGE_NAME
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java
new file mode 100644
index 0000000..35c374d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TransitionInfoBuilder.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.ActivityManager;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.TransitionInfo;
+
+/**
+ * Utility for creating/editing synthetic TransitionInfos for tests.
+ */
+public class TransitionInfoBuilder {
+    final TransitionInfo mInfo;
+
+    public TransitionInfoBuilder(@WindowManager.TransitionType int type) {
+        this(type, 0 /* flags */);
+    }
+
+    public TransitionInfoBuilder(@WindowManager.TransitionType int type,
+            @WindowManager.TransitionFlags int flags) {
+        mInfo = new TransitionInfo(type, flags);
+        mInfo.setRootLeash(createMockSurface(true /* valid */), 0, 0);
+    }
+
+    public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode,
+            @TransitionInfo.ChangeFlags int flags, ActivityManager.RunningTaskInfo taskInfo) {
+        final TransitionInfo.Change change = new TransitionInfo.Change(
+                taskInfo != null ? taskInfo.token : null, createMockSurface(true /* valid */));
+        change.setMode(mode);
+        change.setFlags(flags);
+        change.setTaskInfo(taskInfo);
+        return addChange(change);
+    }
+
+    public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode,
+            ActivityManager.RunningTaskInfo taskInfo) {
+        return addChange(mode, TransitionInfo.FLAG_NONE, taskInfo);
+    }
+
+    public TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode) {
+        return addChange(mode, TransitionInfo.FLAG_NONE, null /* taskInfo */);
+    }
+
+    public TransitionInfoBuilder addChange(TransitionInfo.Change change) {
+        mInfo.addChange(change);
+        return this;
+    }
+
+    public TransitionInfo build() {
+        return mInfo;
+    }
+
+    private static SurfaceControl createMockSurface(boolean valid) {
+        SurfaceControl sc = mock(SurfaceControl.class);
+        doReturn(valid).when(sc).isValid();
+        doReturn("TestSurface").when(sc).toString();
+        return sc;
+    }
+}
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 79070b1..a625346 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
@@ -35,6 +35,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.TransitionInfoBuilder;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -60,10 +62,9 @@
 
     @Test
     public void testStartAnimation() {
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createChange();
-        embeddingChange.setFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
-        info.addChange(embeddingChange);
+        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());
 
         mAnimRunner.startAnimation(mTransition, info, mStartTransaction, mFinishTransaction);
@@ -84,10 +85,9 @@
 
     @Test
     public void testChangesBehindStartingWindow() {
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createChange();
-        embeddingChange.setFlags(FLAG_IS_BEHIND_STARTING_WINDOW);
-        info.addChange(embeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createChange(FLAG_IS_BEHIND_STARTING_WINDOW))
+                .build();
         final Animator animator = mAnimRunner.createAnimator(
                 info, mStartTransaction, mFinishTransaction,
                 () -> mFinishCallback.onTransitionFinished(null /* wct */, null /* wctCB */),
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 54a12ab..4f4f356 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
@@ -82,9 +82,11 @@
     }
 
     /** Creates a mock {@link TransitionInfo.Change}. */
-    static TransitionInfo.Change createChange() {
-        return new TransitionInfo.Change(mock(WindowContainerToken.class),
+    static TransitionInfo.Change createChange(@TransitionInfo.ChangeFlags int flags) {
+        TransitionInfo.Change c = new TransitionInfo.Change(mock(WindowContainerToken.class),
                 mock(SurfaceControl.class));
+        c.setFlags(flags);
+        return c;
     }
 
     /**
@@ -93,8 +95,7 @@
      */
     static TransitionInfo.Change createEmbeddedChange(@NonNull Rect startBounds,
             @NonNull Rect endBounds, @NonNull Rect taskBounds) {
-        final TransitionInfo.Change change = createChange();
-        change.setFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
+        final TransitionInfo.Change change = createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
         change.setStartAbsBounds(startBounds);
         change.setEndAbsBounds(endBounds);
         if (taskBounds.width() == startBounds.width()
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 4d98b6b..cbbb291 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
@@ -34,6 +34,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.TransitionInfoBuilder;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -80,12 +82,11 @@
 
     @Test
     public void testStartAnimation_containsNonActivityEmbeddingChange() {
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_LEFT_BOUNDS,
-                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
-        final TransitionInfo.Change nonEmbeddingChange = createChange();
-        info.addChange(embeddingChange);
-        info.addChange(nonEmbeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(
+                        EMBEDDED_LEFT_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS))
+                .addChange(createChange(0 /* flags */))
+                .build();
 
         // No-op because it contains non-embedded change.
         assertFalse(mController.startAnimation(mTransition, info, mStartTransaction,
@@ -98,10 +99,9 @@
 
     @Test
     public void testStartAnimation_containsOnlyFillTaskActivityEmbeddingChange() {
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createEmbeddedChange(TASK_BOUNDS, TASK_BOUNDS,
-                TASK_BOUNDS);
-        info.addChange(embeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(TASK_BOUNDS, TASK_BOUNDS, TASK_BOUNDS))
+                .build();
 
         // No-op because it only contains embedded change that fills the Task. We will let the
         // default handler to animate such transition.
@@ -116,10 +116,10 @@
     @Test
     public void testStartAnimation_containsActivityEmbeddingSplitChange() {
         // Change that occupies only part of the Task.
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_LEFT_BOUNDS,
-                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
-        info.addChange(embeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(
+                        EMBEDDED_LEFT_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS))
+                .build();
 
         // ActivityEmbeddingController will handle such transition.
         assertTrue(mController.startAnimation(mTransition, info, mStartTransaction,
@@ -133,10 +133,9 @@
     @Test
     public void testStartAnimation_containsChangeEnterActivityEmbeddingSplit() {
         // Change that is entering ActivityEmbedding split.
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createEmbeddedChange(TASK_BOUNDS,
-                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
-        info.addChange(embeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(TASK_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS))
+                .build();
 
         // ActivityEmbeddingController will handle such transition.
         assertTrue(mController.startAnimation(mTransition, info, mStartTransaction,
@@ -150,10 +149,9 @@
     @Test
     public void testStartAnimation_containsChangeExitActivityEmbeddingSplit() {
         // Change that is exiting ActivityEmbedding split.
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_RIGHT_BOUNDS,
-                TASK_BOUNDS, TASK_BOUNDS);
-        info.addChange(embeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(EMBEDDED_RIGHT_BOUNDS, TASK_BOUNDS, TASK_BOUNDS))
+                .build();
 
         // ActivityEmbeddingController will handle such transition.
         assertTrue(mController.startAnimation(mTransition, info, mStartTransaction,
@@ -170,10 +168,10 @@
         assertThrows(IllegalStateException.class,
                 () -> mController.onAnimationFinished(mTransition));
 
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        final TransitionInfo.Change embeddingChange = createEmbeddedChange(EMBEDDED_LEFT_BOUNDS,
-                EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS);
-        info.addChange(embeddingChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(createEmbeddedChange(
+                        EMBEDDED_LEFT_BOUNDS, EMBEDDED_LEFT_BOUNDS, TASK_BOUNDS))
+                .build();
         mController.startAnimation(mTransition, info, mStartTransaction,
                 mFinishTransaction, mFinishCallback);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index ffb1a4d..01e2f98 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -17,7 +17,7 @@
 package com.android.wm.shell.common;
 
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.Surface.ROTATION_0;
 import static android.view.WindowInsets.Type.ime;
 
@@ -138,15 +138,15 @@
     private InsetsSourceControl[] insetsSourceControl() {
         return new InsetsSourceControl[]{
                 new InsetsSourceControl(
-                        ITYPE_IME, ime(), mock(SurfaceControl.class), false, new Point(0, 0),
+                        ID_IME, ime(), mock(SurfaceControl.class), false, new Point(0, 0),
                         Insets.NONE)
         };
     }
 
     private InsetsState insetsStateWithIme(boolean visible) {
         InsetsState state = new InsetsState();
-        state.addSource(new InsetsSource(ITYPE_IME, ime()));
-        state.setSourceVisible(ITYPE_IME, visible);
+        state.addSource(new InsetsSource(ID_IME, ime()));
+        state.setSourceVisible(ID_IME, visible);
         return state;
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index 7997a7e..43f8f7b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -22,6 +22,7 @@
 import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
@@ -446,7 +447,7 @@
         final ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass(
                 WindowContainerTransaction.class);
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            verify(mTransitions).startTransition(eq(TRANSIT_TO_FRONT), arg.capture(), any());
+            verify(mTransitions).startTransition(eq(TRANSIT_NONE), arg.capture(), any());
         } else {
             verify(mShellTaskOrganizer).applyTransaction(arg.capture());
         }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index f16beee..95e78a8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -26,6 +26,8 @@
 import android.os.Binder
 import android.testing.AndroidTestingRunner
 import android.view.WindowManager
+import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_NONE
 import android.view.WindowManager.TRANSIT_OPEN
 import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.TransitionRequestInfo
@@ -55,6 +57,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.eq
 import org.mockito.ArgumentMatchers.isNull
 import org.mockito.Mock
 import org.mockito.Mockito
@@ -141,7 +144,7 @@
 
         controller.showDesktopApps()
 
-        val wct = getLatestWct()
+        val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(3)
         // Expect order to be from bottom: home, task1, task2
         wct.assertReorderAt(index = 0, homeTask)
@@ -159,7 +162,7 @@
 
         controller.showDesktopApps()
 
-        val wct = getLatestWct()
+        val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(3)
         // Expect order to be from bottom: home, task1, task2
         wct.assertReorderAt(index = 0, homeTask)
@@ -177,7 +180,7 @@
 
         controller.showDesktopApps()
 
-        val wct = getLatestWct()
+        val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(3)
         // Expect order to be from bottom: home, task1, task2
         wct.assertReorderAt(index = 0, homeTask)
@@ -191,7 +194,7 @@
 
         controller.showDesktopApps()
 
-        val wct = getLatestWct()
+        val wct = getLatestWct(expectTransition = TRANSIT_NONE)
         assertThat(wct.hierarchyOps).hasSize(1)
         wct.assertReorderAt(index = 0, homeTask)
     }
@@ -221,7 +224,7 @@
     fun moveToDesktop() {
         val task = setUpFullscreenTask()
         controller.moveToDesktop(task)
-        val wct = getLatestWct()
+        val wct = getLatestWct(expectTransition = TRANSIT_CHANGE)
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
             .isEqualTo(WINDOWING_MODE_FREEFORM)
     }
@@ -241,7 +244,7 @@
 
         controller.moveToDesktop(fullscreenTask)
 
-        with(getLatestWct()) {
+        with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
             assertThat(hierarchyOps).hasSize(3)
             assertReorderSequence(homeTask, freeformTask, fullscreenTask)
             assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode)
@@ -253,7 +256,7 @@
     fun moveToFullscreen() {
         val task = setUpFreeformTask()
         controller.moveToFullscreen(task)
-        val wct = getLatestWct()
+        val wct = getLatestWct(expectTransition = TRANSIT_CHANGE)
         assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
             .isEqualTo(WINDOWING_MODE_FULLSCREEN)
     }
@@ -415,10 +418,12 @@
         desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = false)
     }
 
-    private fun getLatestWct(): WindowContainerTransaction {
+    private fun getLatestWct(
+        @WindowManager.TransitionType expectTransition: Int = TRANSIT_OPEN
+    ): WindowContainerTransaction {
         val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
         if (ENABLE_SHELL_TRANSITIONS) {
-            verify(transitions).startTransition(anyInt(), arg.capture(), isNull())
+            verify(transitions).startTransition(eq(expectTransition), arg.capture(), isNull())
         } else {
             verify(shellTaskOrganizer).applyTransaction(arg.capture())
         }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
index 48415d4..69f664a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserverTest.java
@@ -37,6 +37,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.TransitionInfoBuilder;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
@@ -94,8 +95,8 @@
     public void testCreatesWindowDecorOnOpenTransition_freeform() {
         final TransitionInfo.Change change =
                 createChange(TRANSIT_OPEN, 1, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info = new TransitionInfo(TRANSIT_OPEN, 0);
-        info.addChange(change);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(change).build();
 
         final IBinder transition = mock(IBinder.class);
         final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
@@ -111,8 +112,8 @@
     public void testPreparesWindowDecorOnCloseTransition_freeform() {
         final TransitionInfo.Change change =
                 createChange(TRANSIT_CLOSE, 1, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info.addChange(change);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(change).build();
 
         final IBinder transition = mock(IBinder.class);
         final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
@@ -128,8 +129,8 @@
     public void testDoesntCloseWindowDecorDuringCloseTransition() throws Exception {
         final TransitionInfo.Change change =
                 createChange(TRANSIT_CLOSE, 1, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info.addChange(change);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(change).build();
 
         final IBinder transition = mock(IBinder.class);
         final SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
@@ -144,8 +145,8 @@
     public void testClosesWindowDecorAfterCloseTransition() throws Exception {
         final TransitionInfo.Change change =
                 createChange(TRANSIT_CLOSE, 1, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info.addChange(change);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(change).build();
 
         final AutoCloseable windowDecor = mock(AutoCloseable.class);
 
@@ -164,8 +165,8 @@
         // The playing transition
         final TransitionInfo.Change change1 =
                 createChange(TRANSIT_OPEN, 1, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info1 = new TransitionInfo(TRANSIT_OPEN, 0);
-        info1.addChange(change1);
+        final TransitionInfo info1 = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
+                .addChange(change1).build();
 
         final IBinder transition1 = mock(IBinder.class);
         final SurfaceControl.Transaction startT1 = mock(SurfaceControl.Transaction.class);
@@ -176,8 +177,8 @@
         // The merged transition
         final TransitionInfo.Change change2 =
                 createChange(TRANSIT_CLOSE, 2, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info2 = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info2.addChange(change2);
+        final TransitionInfo info2 = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(change2).build();
 
         final IBinder transition2 = mock(IBinder.class);
         final SurfaceControl.Transaction startT2 = mock(SurfaceControl.Transaction.class);
@@ -195,8 +196,8 @@
         // The playing transition
         final TransitionInfo.Change change1 =
                 createChange(TRANSIT_CLOSE, 1, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info1 = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info1.addChange(change1);
+        final TransitionInfo info1 = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(change1).build();
 
         final IBinder transition1 = mock(IBinder.class);
         final SurfaceControl.Transaction startT1 = mock(SurfaceControl.Transaction.class);
@@ -207,8 +208,8 @@
         // The merged transition
         final TransitionInfo.Change change2 =
                 createChange(TRANSIT_CLOSE, 2, WINDOWING_MODE_FREEFORM);
-        final TransitionInfo info2 = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info2.addChange(change2);
+        final TransitionInfo info2 = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(change2).build();
 
         final IBinder transition2 = mock(IBinder.class);
         final SurfaceControl.Transaction startT2 = mock(SurfaceControl.Transaction.class);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 2da4af8..e907cd3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -104,8 +104,8 @@
                 new PipSnapAlgorithm(), new PipKeepClearAlgorithmInterface() {},
                 mPipSizeSpecHandler);
         mMainExecutor = new TestShellExecutor();
-        mPipTaskOrganizer = new PipTaskOrganizer(mContext,
-                mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState,
+        mPipTaskOrganizer = new PipTaskOrganizer(mContext, mMockSyncTransactionQueue,
+                mPipTransitionState, mPipBoundsState, mPipSizeSpecHandler,
                 mPipBoundsAlgorithm, mMockPhonePipMenuController, mMockPipAnimationController,
                 mMockPipSurfaceTransactionHelper, mMockPipTransitionController,
                 mMockPipParamsChangedForwarder, mMockOptionalSplitScreen, mMockDisplayController,
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 82392ad9..b542fae 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
@@ -253,10 +253,10 @@
     }
 
     @Test
-    public void testGetRecentTasks_groupActiveFreeformTasks() {
+    public void testGetRecentTasks_hasActiveDesktopTasks_proto2Enabled_groupFreeformTasks() {
         StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
                 DesktopModeStatus.class).startMocking();
-        when(DesktopModeStatus.isActive(any())).thenReturn(true);
+        when(DesktopModeStatus.isProto2Enabled()).thenReturn(true);
 
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
@@ -293,6 +293,39 @@
     }
 
     @Test
+    public void testGetRecentTasks_hasActiveDesktopTasks_proto2Disabled_doNotGroupFreeformTasks() {
+        StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
+                DesktopModeStatus.class).startMocking();
+        when(DesktopModeStatus.isProto2Enabled()).thenReturn(false);
+
+        ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
+        ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
+        ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
+        ActivityManager.RecentTaskInfo t4 = makeTaskInfo(4);
+        setRawList(t1, t2, t3, t4);
+
+        when(mDesktopModeTaskRepository.isActiveTask(1)).thenReturn(true);
+        when(mDesktopModeTaskRepository.isActiveTask(3)).thenReturn(true);
+
+        ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
+                MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+
+        // Expect no grouping of tasks
+        assertEquals(4, recentTasks.size());
+        assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(0).getType());
+        assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(1).getType());
+        assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(2).getType());
+        assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, recentTasks.get(3).getType());
+
+        assertEquals(t1, recentTasks.get(0).getTaskInfo1());
+        assertEquals(t2, recentTasks.get(1).getTaskInfo1());
+        assertEquals(t3, recentTasks.get(2).getTaskInfo1());
+        assertEquals(t4, recentTasks.get(3).getTaskInfo1());
+
+        mockitoSession.finishMocking();
+    }
+
+    @Test
     public void testRemovedTaskRemovesSplit() {
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index ea3af9d..d0e2601 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -27,8 +27,6 @@
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -201,7 +199,6 @@
         ActivityManager.RunningTaskInfo topRunningTask =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
         doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
-        doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any());
 
         mSplitScreenController.startIntent(pendingIntent, null, SPLIT_POSITION_TOP_OR_LEFT, null);
 
@@ -222,7 +219,6 @@
         ActivityManager.RunningTaskInfo topRunningTask =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
         doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
-        doReturn(true).when(mStageCoordinator).isValidToEnterSplitScreen(any());
         // Put the same component into a task in the background
         ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();
         doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any());
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 652f9b3..e9f1df2 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
@@ -64,6 +64,7 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.TransitionInfoBuilder;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayImeController;
 import com.android.wm.shell.common.DisplayInsetsController;
@@ -156,12 +157,10 @@
         assertTrue(containsSplitEnter(result));
 
         // simulate the transition
-        TransitionInfo.Change openChange = createChange(TRANSIT_OPEN, newTask);
-        TransitionInfo.Change reparentChange = createChange(TRANSIT_CHANGE, reparentTask);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
-        info.addChange(openChange);
-        info.addChange(reparentChange);
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0)
+                .addChange(TRANSIT_OPEN, newTask)
+                .addChange(TRANSIT_CHANGE, reparentTask)
+                .build();
         mSideStage.onTaskAppeared(newTask, createMockSurface());
         mMainStage.onTaskAppeared(reparentTask, createMockSurface());
         boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -216,12 +215,10 @@
         assertFalse(containsSplitExit(result));
 
         // simulate the transition
-        TransitionInfo.Change openChange = createChange(TRANSIT_TO_FRONT, newTask);
-        TransitionInfo.Change hideChange = createChange(TRANSIT_TO_BACK, mSideChild);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
-        info.addChange(openChange);
-        info.addChange(hideChange);
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0)
+                .addChange(TRANSIT_TO_FRONT, newTask)
+                .addChange(TRANSIT_TO_BACK, mSideChild)
+                .build();
         mSideStage.onTaskAppeared(newTask, createMockSurface());
         boolean accepted = mStageCoordinator.startAnimation(transition, info,
                 mock(SurfaceControl.Transaction.class),
@@ -237,12 +234,10 @@
         assertNotNull(result);
         assertFalse(containsSplitExit(result));
 
-        TransitionInfo.Change showChange = createChange(TRANSIT_TO_FRONT, mSideChild);
-        TransitionInfo.Change closeChange = createChange(TRANSIT_CLOSE, newTask);
-
-        info = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info.addChange(showChange);
-        info.addChange(closeChange);
+        info = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(TRANSIT_TO_FRONT, mSideChild)
+                .addChange(TRANSIT_CLOSE, newTask)
+                .build();
         mSideStage.onTaskVanished(newTask);
         accepted = mStageCoordinator.startAnimation(transition, info,
                 mock(SurfaceControl.Transaction.class),
@@ -273,14 +268,11 @@
         assertTrue(mStageCoordinator.isSplitScreenVisible());
 
         // simulate the transition
-        TransitionInfo.Change homeChange = createChange(TRANSIT_TO_FRONT, homeTask);
-        TransitionInfo.Change mainChange = createChange(TRANSIT_TO_BACK, mMainChild);
-        TransitionInfo.Change sideChange = createChange(TRANSIT_TO_BACK, mSideChild);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
-        info.addChange(homeChange);
-        info.addChange(mainChange);
-        info.addChange(sideChange);
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0)
+                .addChange(TRANSIT_TO_FRONT, homeTask)
+                .addChange(TRANSIT_TO_BACK, mMainChild)
+                .addChange(TRANSIT_TO_BACK, mSideChild)
+                .build();
         mMainStage.onTaskVanished(mMainChild);
         mSideStage.onTaskVanished(mSideChild);
         mStageCoordinator.startAnimation(transition, info,
@@ -311,14 +303,11 @@
         assertTrue(mStageCoordinator.isSplitScreenVisible());
 
         // simulate the transition
-        TransitionInfo.Change normalChange = createChange(TRANSIT_TO_FRONT, normalTask);
-        TransitionInfo.Change mainChange = createChange(TRANSIT_TO_BACK, mMainChild);
-        TransitionInfo.Change sideChange = createChange(TRANSIT_TO_BACK, mSideChild);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
-        info.addChange(normalChange);
-        info.addChange(mainChange);
-        info.addChange(sideChange);
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0)
+                .addChange(TRANSIT_TO_FRONT, normalTask)
+                .addChange(TRANSIT_TO_BACK, mMainChild)
+                .addChange(TRANSIT_TO_BACK, mSideChild)
+                .build();
         mMainStage.onTaskVanished(mMainChild);
         mSideStage.onTaskVanished(mSideChild);
         mStageCoordinator.startAnimation(transition, info,
@@ -334,11 +323,10 @@
         enterSplit();
 
         // simulate the transition
-        TransitionInfo.Change mainChange = createChange(TRANSIT_TO_BACK, mMainChild);
-        TransitionInfo.Change sideChange = createChange(TRANSIT_TO_BACK, mSideChild);
-        TransitionInfo info = new TransitionInfo(TRANSIT_TO_BACK, 0);
-        info.addChange(mainChange);
-        info.addChange(sideChange);
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_BACK, 0)
+                .addChange(TRANSIT_TO_BACK, mMainChild)
+                .addChange(TRANSIT_TO_BACK, mSideChild)
+                .build();
         IBinder transition = mSplitScreenTransitions.startDismissTransition(
                 new WindowContainerTransaction(), mStageCoordinator,
                 EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, STAGE_TYPE_SIDE);
@@ -356,12 +344,10 @@
         enterSplit();
 
         // simulate the transition
-        TransitionInfo.Change mainChange = createChange(TRANSIT_TO_BACK, mMainChild);
-        TransitionInfo.Change sideChange = createChange(TRANSIT_CHANGE, mSideChild);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_TO_BACK, 0);
-        info.addChange(mainChange);
-        info.addChange(sideChange);
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_BACK, 0)
+                .addChange(TRANSIT_TO_BACK, mMainChild)
+                .addChange(TRANSIT_CHANGE, mSideChild)
+                .build();
         IBinder transition = mSplitScreenTransitions.startDismissTransition(
                 new WindowContainerTransaction(), mStageCoordinator, EXIT_REASON_DRAG_DIVIDER,
                 STAGE_TYPE_SIDE);
@@ -391,12 +377,10 @@
         assertTrue(mStageCoordinator.isSplitScreenVisible());
 
         // simulate the transition
-        TransitionInfo.Change mainChange = createChange(TRANSIT_CHANGE, mMainChild);
-        TransitionInfo.Change sideChange = createChange(TRANSIT_CLOSE, mSideChild);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_CLOSE, 0);
-        info.addChange(mainChange);
-        info.addChange(sideChange);
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_CLOSE, 0)
+                .addChange(TRANSIT_CHANGE, mMainChild)
+                .addChange(TRANSIT_CLOSE, mSideChild)
+                .build();
         mMainStage.onTaskVanished(mMainChild);
         mSideStage.onTaskVanished(mSideChild);
         boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -408,13 +392,10 @@
     }
 
     private TransitionInfo createEnterPairInfo() {
-        TransitionInfo.Change mainChange = createChange(TRANSIT_OPEN, mMainChild);
-        TransitionInfo.Change sideChange = createChange(TRANSIT_OPEN, mSideChild);
-
-        TransitionInfo info = new TransitionInfo(TRANSIT_SPLIT_SCREEN_PAIR_OPEN, 0);
-        info.addChange(mainChange);
-        info.addChange(sideChange);
-        return info;
+        return new TransitionInfoBuilder(TRANSIT_SPLIT_SCREEN_PAIR_OPEN, 0)
+                .addChange(TRANSIT_OPEN, mMainChild)
+                .addChange(TRANSIT_OPEN, mSideChild)
+                .build();
     }
 
     private void enterSplit() {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
index 595c3b4..6c9b186 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java
@@ -45,6 +45,7 @@
 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.eq;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.clearInvocations;
@@ -83,6 +84,7 @@
 
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestShellExecutor;
+import com.android.wm.shell.TransitionInfoBuilder;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
@@ -119,8 +121,8 @@
 
     @Before
     public void setUp() {
-        doAnswer(invocation -> invocation.getArguments()[1])
-                .when(mOrganizer).startTransition(any(), any());
+        doAnswer(invocation -> new Binder())
+                .when(mOrganizer).startNewTransition(anyInt(), any());
     }
 
     @Test
@@ -562,6 +564,32 @@
     }
 
     @Test
+    public void testTransitionOrderMatchesCore() {
+        Transitions transitions = createTestTransitions();
+        transitions.replaceDefaultHandlerForTest(mDefaultHandler);
+
+        IBinder transitToken = new Binder();
+        IBinder shellInit = transitions.startTransition(TRANSIT_CLOSE,
+                new WindowContainerTransaction(), null /* handler */);
+        // make sure we are testing the "New" API.
+        verify(mOrganizer, times(1)).startNewTransition(eq(TRANSIT_CLOSE), any());
+        // WMCore may not receive the new transition before requesting its own.
+        transitions.requestStartTransition(transitToken,
+                new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */));
+        verify(mOrganizer, times(1)).startTransition(eq(transitToken), any());
+
+        // At this point, WM is working on its transition (the shell-initialized one is still
+        // queued), so continue the transition lifecycle for that.
+        TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build();
+        transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class),
+                mock(SurfaceControl.Transaction.class));
+        // At this point, if things are not working, we'd get an NPE due to attempting to merge
+        // into the shellInit transition which hasn't started yet.
+        assertEquals(1, mDefaultHandler.activeCount());
+    }
+
+    @Test
     public void testShouldRotateSeamlessly() throws Exception {
         final RunningTaskInfo taskInfo =
                 createTaskInfo(1, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
@@ -920,43 +948,6 @@
         verify(observer, times(0)).onTransitionFinished(eq(transitToken3), anyBoolean());
     }
 
-    class TransitionInfoBuilder {
-        final TransitionInfo mInfo;
-
-        TransitionInfoBuilder(@WindowManager.TransitionType int type) {
-            this(type, 0 /* flags */);
-        }
-
-        TransitionInfoBuilder(@WindowManager.TransitionType int type,
-                @WindowManager.TransitionFlags int flags) {
-            mInfo = new TransitionInfo(type, flags);
-            mInfo.setRootLeash(createMockSurface(true /* valid */), 0, 0);
-        }
-
-        TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode,
-                RunningTaskInfo taskInfo) {
-            final TransitionInfo.Change change =
-                    new TransitionInfo.Change(null /* token */, createMockSurface(true));
-            change.setMode(mode);
-            change.setTaskInfo(taskInfo);
-            mInfo.addChange(change);
-            return this;
-        }
-
-        TransitionInfoBuilder addChange(@WindowManager.TransitionType int mode) {
-            return addChange(mode, null /* taskInfo */);
-        }
-
-        TransitionInfoBuilder addChange(TransitionInfo.Change change) {
-            mInfo.addChange(change);
-            return this;
-        }
-
-        TransitionInfo build() {
-            return mInfo;
-        }
-    }
-
     class ChangeBuilder {
         final TransitionInfo.Change mChange;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index 2f5263c..b80edce 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -431,7 +431,7 @@
         verify(additionalWindowSurfaceBuilder).setParent(decorContainerSurface);
         verify(additionalWindowSurfaceBuilder).build();
         verify(mMockSurfaceControlAddWindowT).setPosition(additionalWindowSurface, 20, 40);
-        verify(mMockSurfaceControlAddWindowT).setWindowCrop(additionalWindowSurface, 432, 64);
+        verify(mMockSurfaceControlAddWindowT).setWindowCrop(additionalWindowSurface, 442, 74);
         verify(mMockSurfaceControlAddWindowT).show(additionalWindowSurface);
         verify(mMockSurfaceControlViewHostFactory, Mockito.times(2))
                 .create(any(), eq(defaultDisplay), any());
@@ -565,7 +565,7 @@
                             mMockSurfaceControlAddWindowT,
                             x - mRelayoutResult.mDecorContainerOffsetX,
                             y - mRelayoutResult.mDecorContainerOffsetY,
-                            width, height);
+                            width, height, 10);
             return additionalWindow;
         }
     }
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index eeed226..9e3f115 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -511,6 +511,7 @@
         "canvas/CanvasOpBuffer.cpp",
         "canvas/CanvasOpRasterizer.cpp",
         "effects/StretchEffect.cpp",
+        "effects/GainmapRenderer.cpp",
         "pipeline/skia/HolePunch.cpp",
         "pipeline/skia/SkiaDisplayList.cpp",
         "pipeline/skia/SkiaRecordingCanvas.cpp",
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 430e69e..659aec0 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -19,9 +19,9 @@
 #include <GrRecordingContext.h>
 #include <SkMesh.h>
 #include <hwui/Paint.h>
+#include <log/log.h>
 
 #include <experimental/type_traits>
-#include <log/log.h>
 #include <utility>
 
 #include "SkAndroidFrameworkUtils.h"
@@ -45,7 +45,8 @@
 #include "SkVertices.h"
 #include "Tonemapper.h"
 #include "VectorDrawable.h"
-#include "include/gpu/GpuTypes.h" // from Skia
+#include "effects/GainmapRenderer.h"
+#include "include/gpu/GpuTypes.h"  // from Skia
 #include "include/gpu/GrDirectContext.h"
 #include "pipeline/skia/AnimatedDrawables.h"
 #include "pipeline/skia/FunctorDrawable.h"
@@ -332,9 +333,15 @@
 
 struct DrawImage final : Op {
     static const auto kType = Type::DrawImage;
-    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y,
-              const SkSamplingOptions& sampling, const SkPaint* paint, BitmapPalette palette)
-            : image(std::move(image)), x(x), y(y), sampling(sampling), palette(palette) {
+    DrawImage(DrawImagePayload&& payload, SkScalar x, SkScalar y, const SkSamplingOptions& sampling,
+              const SkPaint* paint)
+            : image(std::move(payload.image))
+            , x(x)
+            , y(y)
+            , sampling(sampling)
+            , palette(payload.palette)
+            , gainmap(std::move(payload.gainmapImage))
+            , gainmapInfo(payload.gainmapInfo) {
         if (paint) {
             this->paint = *paint;
         }
@@ -344,19 +351,34 @@
     SkSamplingOptions sampling;
     SkPaint paint;
     BitmapPalette palette;
+    sk_sp<const SkImage> gainmap;
+    SkGainmapInfo gainmapInfo;
+
     void draw(SkCanvas* c, const SkMatrix&) const {
-        SkPaint newPaint = paint;
-        tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
-        c->drawImage(image.get(), x, y, sampling, &newPaint);
+        if (gainmap) {
+            SkRect src = SkRect::MakeWH(image->width(), image->height());
+            SkRect dst = SkRect::MakeXYWH(x, y, src.width(), src.height());
+            DrawGainmapBitmap(c, image, src, dst, sampling, &paint,
+                              SkCanvas::kFast_SrcRectConstraint, gainmap, gainmapInfo);
+        } else {
+            SkPaint newPaint = paint;
+            tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
+            c->drawImage(image.get(), x, y, sampling, &newPaint);
+        }
     }
 };
 struct DrawImageRect final : Op {
     static const auto kType = Type::DrawImageRect;
-    DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
+    DrawImageRect(DrawImagePayload&& payload, const SkRect* src, const SkRect& dst,
                   const SkSamplingOptions& sampling, const SkPaint* paint,
-                  SkCanvas::SrcRectConstraint constraint, BitmapPalette palette)
-            : image(std::move(image)), dst(dst), sampling(sampling), constraint(constraint)
-            , palette(palette) {
+                  SkCanvas::SrcRectConstraint constraint)
+            : image(std::move(payload.image))
+            , dst(dst)
+            , sampling(sampling)
+            , constraint(constraint)
+            , palette(payload.palette)
+            , gainmap(std::move(payload.gainmapImage))
+            , gainmapInfo(payload.gainmapInfo) {
         this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
         if (paint) {
             this->paint = *paint;
@@ -368,25 +390,32 @@
     SkPaint paint;
     SkCanvas::SrcRectConstraint constraint;
     BitmapPalette palette;
+    sk_sp<const SkImage> gainmap;
+    SkGainmapInfo gainmapInfo;
+
     void draw(SkCanvas* c, const SkMatrix&) const {
-        SkPaint newPaint = paint;
-        tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
-        c->drawImageRect(image.get(), src, dst, sampling, &newPaint, constraint);
+        if (gainmap) {
+            DrawGainmapBitmap(c, image, src, dst, sampling, &paint, constraint, gainmap,
+                              gainmapInfo);
+        } else {
+            SkPaint newPaint = paint;
+            tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
+            c->drawImageRect(image.get(), src, dst, sampling, &newPaint, constraint);
+        }
     }
 };
 struct DrawImageLattice final : Op {
     static const auto kType = Type::DrawImageLattice;
-    DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
-                     const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
-                     BitmapPalette palette)
-            : image(std::move(image))
+    DrawImageLattice(DrawImagePayload&& payload, int xs, int ys, int fs, const SkIRect& src,
+                     const SkRect& dst, SkFilterMode filter, const SkPaint* paint)
+            : image(std::move(payload.image))
             , xs(xs)
             , ys(ys)
             , fs(fs)
             , src(src)
             , dst(dst)
             , filter(filter)
-            , palette(palette) {
+            , palette(payload.palette) {
         if (paint) {
             this->paint = *paint;
         }
@@ -399,6 +428,8 @@
     SkPaint paint;
     BitmapPalette palette;
     void draw(SkCanvas* c, const SkMatrix&) const {
+        // TODO: Support drawing a gainmap 9-patch?
+
         auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int));
         auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int));
         auto flags =
@@ -781,27 +812,25 @@
                                   const SkPaint* paint) {
     this->push<DrawPicture>(0, picture, matrix, paint);
 }
-void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
-                                const SkSamplingOptions& sampling, const SkPaint* paint,
-                                BitmapPalette palette) {
-    this->push<DrawImage>(0, std::move(image), x, y, sampling, paint, palette);
+void DisplayListData::drawImage(DrawImagePayload&& payload, SkScalar x, SkScalar y,
+                                const SkSamplingOptions& sampling, const SkPaint* paint) {
+    this->push<DrawImage>(0, std::move(payload), x, y, sampling, paint);
 }
-void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
+void DisplayListData::drawImageRect(DrawImagePayload&& payload, const SkRect* src,
                                     const SkRect& dst, const SkSamplingOptions& sampling,
-                                    const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
-                                    BitmapPalette palette) {
-    this->push<DrawImageRect>(0, std::move(image), src, dst, sampling, paint, constraint, palette);
+                                    const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
+    this->push<DrawImageRect>(0, std::move(payload), src, dst, sampling, paint, constraint);
 }
-void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
-                                       const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
-                                       BitmapPalette palette) {
+void DisplayListData::drawImageLattice(DrawImagePayload&& payload, const SkCanvas::Lattice& lattice,
+                                       const SkRect& dst, SkFilterMode filter,
+                                       const SkPaint* paint) {
     int xs = lattice.fXCount, ys = lattice.fYCount;
     int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
     size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) +
                    fs * sizeof(SkColor);
     LOG_FATAL_IF(!lattice.fBounds);
-    void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
-                                             dst, filter, paint, palette);
+    void* pod = this->push<DrawImageLattice>(bytes, std::move(payload), xs, ys, fs,
+                                             *lattice.fBounds, dst, filter, paint);
     copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
            fs);
 }
@@ -1108,57 +1137,55 @@
     fDL->drawRippleDrawable(params);
 }
 
-void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
-                                const SkSamplingOptions& sampling, const SkPaint* paint,
-                                BitmapPalette palette) {
-    fDL->drawImage(image, x, y, sampling, paint, palette);
+void RecordingCanvas::drawImage(DrawImagePayload&& payload, SkScalar x, SkScalar y,
+                                const SkSamplingOptions& sampling, const SkPaint* paint) {
+    fDL->drawImage(std::move(payload), x, y, sampling, paint);
 }
 
-void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
+void RecordingCanvas::drawImageRect(DrawImagePayload&& payload, const SkRect& src,
                                     const SkRect& dst, const SkSamplingOptions& sampling,
-                                    const SkPaint* paint, SrcRectConstraint constraint,
-                                    BitmapPalette palette) {
-    fDL->drawImageRect(image, &src, dst, sampling, paint, constraint, palette);
+                                    const SkPaint* paint, SrcRectConstraint constraint) {
+    fDL->drawImageRect(std::move(payload), &src, dst, sampling, paint, constraint);
 }
 
-void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
-                                       const SkRect& dst, SkFilterMode filter, const SkPaint* paint,
-                                       BitmapPalette palette) {
-    if (!image || dst.isEmpty()) {
+void RecordingCanvas::drawImageLattice(DrawImagePayload&& payload, const Lattice& lattice,
+                                       const SkRect& dst, SkFilterMode filter,
+                                       const SkPaint* paint) {
+    if (!payload.image || dst.isEmpty()) {
         return;
     }
 
     SkIRect bounds;
     Lattice latticePlusBounds = lattice;
     if (!latticePlusBounds.fBounds) {
-        bounds = SkIRect::MakeWH(image->width(), image->height());
+        bounds = SkIRect::MakeWH(payload.image->width(), payload.image->height());
         latticePlusBounds.fBounds = &bounds;
     }
 
-    if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
-        fDL->drawImageLattice(image, latticePlusBounds, dst, filter, paint, palette);
+    if (SkLatticeIter::Valid(payload.image->width(), payload.image->height(), latticePlusBounds)) {
+        fDL->drawImageLattice(std::move(payload), latticePlusBounds, dst, filter, paint);
     } else {
         SkSamplingOptions sampling(filter, SkMipmapMode::kNone);
-        fDL->drawImageRect(image, nullptr, dst, sampling, paint, kFast_SrcRectConstraint, palette);
+        fDL->drawImageRect(std::move(payload), nullptr, dst, sampling, paint,
+                           kFast_SrcRectConstraint);
     }
 }
 
 void RecordingCanvas::onDrawImage2(const SkImage* img, SkScalar x, SkScalar y,
                                    const SkSamplingOptions& sampling, const SkPaint* paint) {
-    fDL->drawImage(sk_ref_sp(img), x, y, sampling, paint, BitmapPalette::Unknown);
+    fDL->drawImage(DrawImagePayload(img), x, y, sampling, paint);
 }
 
 void RecordingCanvas::onDrawImageRect2(const SkImage* img, const SkRect& src, const SkRect& dst,
                                        const SkSamplingOptions& sampling, const SkPaint* paint,
                                        SrcRectConstraint constraint) {
-    fDL->drawImageRect(sk_ref_sp(img), &src, dst, sampling, paint, constraint,
-                       BitmapPalette::Unknown);
+    fDL->drawImageRect(DrawImagePayload(img), &src, dst, sampling, paint, constraint);
 }
 
 void RecordingCanvas::onDrawImageLattice2(const SkImage* img, const SkCanvas::Lattice& lattice,
                                           const SkRect& dst, SkFilterMode filter,
                                           const SkPaint* paint) {
-    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, filter, paint, BitmapPalette::Unknown);
+    fDL->drawImageLattice(DrawImagePayload(img), lattice, dst, filter, paint);
 }
 
 void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index b7d4dc9..8409e13 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -16,6 +16,14 @@
 
 #pragma once
 
+#include <SkCanvas.h>
+#include <SkCanvasVirtualEnforcer.h>
+#include <SkDrawable.h>
+#include <SkGainmapInfo.h>
+#include <SkNoDrawCanvas.h>
+#include <SkPaint.h>
+#include <SkPath.h>
+#include <SkRect.h>
 #include <SkRuntimeEffect.h>
 #include <log/log.h>
 
@@ -23,13 +31,7 @@
 #include <vector>
 
 #include "CanvasTransform.h"
-#include "SkCanvas.h"
-#include "SkCanvasVirtualEnforcer.h"
-#include "SkDrawable.h"
-#include "SkNoDrawCanvas.h"
-#include "SkPaint.h"
-#include "SkPath.h"
-#include "SkRect.h"
+#include "Gainmap.h"
 #include "hwui/Bitmap.h"
 #include "pipeline/skia/AnimatedDrawables.h"
 #include "utils/AutoMalloc.h"
@@ -64,6 +66,32 @@
 
 static_assert(sizeof(DisplayListOp) == 4);
 
+struct DrawImagePayload {
+    explicit DrawImagePayload(Bitmap& bitmap)
+            : image(bitmap.makeImage()), palette(bitmap.palette()) {
+        if (bitmap.hasGainmap()) {
+            auto gainmap = bitmap.gainmap();
+            gainmapInfo = gainmap->info;
+            gainmapImage = gainmap->bitmap->makeImage();
+        }
+    }
+
+    explicit DrawImagePayload(const SkImage* image)
+            : image(sk_ref_sp(image)), palette(BitmapPalette::Unknown) {}
+
+    DrawImagePayload(const DrawImagePayload&) = default;
+    DrawImagePayload(DrawImagePayload&&) = default;
+    DrawImagePayload& operator=(const DrawImagePayload&) = default;
+    DrawImagePayload& operator=(DrawImagePayload&&) = default;
+    ~DrawImagePayload() = default;
+
+    sk_sp<SkImage> image;
+    BitmapPalette palette;
+
+    sk_sp<SkImage> gainmapImage;
+    SkGainmapInfo gainmapInfo;
+};
+
 class RecordingCanvas;
 
 class DisplayListData final {
@@ -122,13 +150,12 @@
 
     void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);
 
-    void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkSamplingOptions&,
-                   const SkPaint*, BitmapPalette palette);
-    void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
-    void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkSamplingOptions&,
-                       const SkPaint*, SkCanvas::SrcRectConstraint, BitmapPalette palette);
-    void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
-                          SkFilterMode, const SkPaint*, BitmapPalette);
+    void drawImage(DrawImagePayload&&, SkScalar, SkScalar, const SkSamplingOptions&,
+                   const SkPaint*);
+    void drawImageRect(DrawImagePayload&&, const SkRect*, const SkRect&, const SkSamplingOptions&,
+                       const SkPaint*, SkCanvas::SrcRectConstraint);
+    void drawImageLattice(DrawImagePayload&&, const SkCanvas::Lattice&, const SkRect&, SkFilterMode,
+                          const SkPaint*);
 
     void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
                    const SkPaint&);
@@ -195,14 +222,14 @@
 
     void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
 
-    void drawImage(const sk_sp<SkImage>&, SkScalar left, SkScalar top, const SkSamplingOptions&,
-                   const SkPaint* paint, BitmapPalette pallete);
     void drawRippleDrawable(const skiapipeline::RippleDrawableParams& params);
 
-    void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
-                       const SkSamplingOptions&, const SkPaint*, SrcRectConstraint, BitmapPalette);
-    void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
-                          SkFilterMode, const SkPaint* paint, BitmapPalette palette);
+    void drawImage(DrawImagePayload&&, SkScalar, SkScalar, const SkSamplingOptions&,
+                   const SkPaint*);
+    void drawImageRect(DrawImagePayload&&, const SkRect&, const SkRect&, const SkSamplingOptions&,
+                       const SkPaint*, SrcRectConstraint);
+    void drawImageLattice(DrawImagePayload&&, const Lattice& lattice, const SkRect&, SkFilterMode,
+                          const SkPaint*);
 
     void onDrawImage2(const SkImage*, SkScalar, SkScalar, const SkSamplingOptions&,
                       const SkPaint*) override;
diff --git a/libs/hwui/effects/GainmapRenderer.cpp b/libs/hwui/effects/GainmapRenderer.cpp
new file mode 100644
index 0000000..a544ae8
--- /dev/null
+++ b/libs/hwui/effects/GainmapRenderer.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GainmapRenderer.h"
+
+#include <SkGainmapShader.h>
+
+#include "Gainmap.h"
+#include "Rect.h"
+#include "utils/Trace.h"
+
+#ifdef __ANDROID__
+#include "renderthread/CanvasContext.h"
+#endif
+
+namespace android::uirenderer {
+
+using namespace renderthread;
+
+void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkRect& src,
+                       const SkRect& dst, const SkSamplingOptions& sampling, const SkPaint* paint,
+                       SkCanvas::SrcRectConstraint constraint,
+                       const sk_sp<const SkImage>& gainmapImage, const SkGainmapInfo& gainmapInfo) {
+    ATRACE_CALL();
+#ifdef __ANDROID__
+    CanvasContext* context = CanvasContext::getActiveContext();
+    float targetSdrHdrRatio = context ? context->targetSdrHdrRatio() : 1.f;
+    if (targetSdrHdrRatio > 1.f && gainmapImage) {
+        SkPaint gainmapPaint = *paint;
+        float sX = gainmapImage->width() / (float)image->width();
+        float sY = gainmapImage->height() / (float)image->height();
+        SkRect gainmapSrc = src;
+        // TODO: Tweak rounding?
+        gainmapSrc.fLeft *= sX;
+        gainmapSrc.fRight *= sX;
+        gainmapSrc.fTop *= sY;
+        gainmapSrc.fBottom *= sY;
+        // TODO: Temporary workaround for SkGainmapShader::Make not having a const variant
+        sk_sp<SkImage> mutImage = sk_ref_sp(const_cast<SkImage*>(image.get()));
+        sk_sp<SkImage> mutGainmap = sk_ref_sp(const_cast<SkImage*>(gainmapImage.get()));
+        auto shader = SkGainmapShader::Make(mutImage, src, sampling, mutGainmap, gainmapSrc,
+                                            sampling, gainmapInfo, dst, targetSdrHdrRatio,
+                                            c->imageInfo().refColorSpace());
+        gainmapPaint.setShader(shader);
+        c->drawRect(dst, gainmapPaint);
+    } else
+#endif
+        c->drawImageRect(image.get(), src, dst, sampling, paint, constraint);
+}
+
+}  // namespace android::uirenderer
\ No newline at end of file
diff --git a/libs/hwui/effects/GainmapRenderer.h b/libs/hwui/effects/GainmapRenderer.h
new file mode 100644
index 0000000..7c56d94
--- /dev/null
+++ b/libs/hwui/effects/GainmapRenderer.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <SkCanvas.h>
+#include <SkGainmapInfo.h>
+#include <SkImage.h>
+#include <SkPaint.h>
+
+#include "hwui/Bitmap.h"
+
+namespace android::uirenderer {
+
+void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkRect& src,
+                       const SkRect& dst, const SkSamplingOptions& sampling, const SkPaint* paint,
+                       SkCanvas::SrcRectConstraint constraint,
+                       const sk_sp<const SkImage>& gainmapImage, const SkGainmapInfo& gainmapInfo);
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 0a755f0..cbebae9 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -41,6 +41,7 @@
 #include <SkHighContrastFilter.h>
 #include <SkImageEncoder.h>
 #include <SkImagePriv.h>
+#include <SkJpegGainmapEncoder.h>
 #include <SkPixmap.h>
 #include <SkRect.h>
 #include <SkStream.h>
@@ -458,6 +459,16 @@
 }
 
 bool Bitmap::compress(JavaCompressFormat format, int32_t quality, SkWStream* stream) {
+#ifdef __ANDROID__  // TODO: This isn't built for host for some reason?
+    if (hasGainmap() && format == JavaCompressFormat::Jpeg) {
+        SkBitmap baseBitmap = getSkBitmap();
+        SkBitmap gainmapBitmap = gainmap()->bitmap->getSkBitmap();
+        SkJpegEncoder::Options options{.fQuality = quality};
+        return SkJpegGainmapEncoder::EncodeJpegR(stream, baseBitmap.pixmap(), options,
+                                                 gainmapBitmap.pixmap(), options, gainmap()->info);
+    }
+#endif
+
     SkBitmap skbitmap;
     getSkBitmap(&skbitmap);
     return compress(skbitmap, format, quality, stream);
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 0d5995a..571ab83 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -2,6 +2,20 @@
 #define LOG_TAG "BitmapFactory"
 
 #include "BitmapFactory.h"
+
+#include <Gainmap.h>
+#include <HardwareBitmapUploader.h>
+#include <androidfw/Asset.h>
+#include <androidfw/ResourceTypes.h>
+#include <cutils/compiler.h>
+#include <fcntl.h>
+#include <nativehelper/JNIPlatformHelp.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include <memory>
+
 #include "CreateJavaOutputStreamAdaptor.h"
 #include "FrontBufferedStream.h"
 #include "GraphicsJNI.h"
@@ -13,6 +27,7 @@
 #include "SkCanvas.h"
 #include "SkColorSpace.h"
 #include "SkEncodedImageFormat.h"
+#include "SkGainmapInfo.h"
 #include "SkImageInfo.h"
 #include "SkPaint.h"
 #include "SkPixelRef.h"
@@ -24,17 +39,6 @@
 #include "SkString.h"
 #include "Utils.h"
 
-#include <HardwareBitmapUploader.h>
-#include <nativehelper/JNIPlatformHelp.h>
-#include <androidfw/Asset.h>
-#include <androidfw/ResourceTypes.h>
-#include <cutils/compiler.h>
-#include <fcntl.h>
-#include <memory>
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/stat.h>
-
 jfieldID gOptions_justBoundsFieldID;
 jfieldID gOptions_sampleSizeFieldID;
 jfieldID gOptions_configFieldID;
@@ -182,6 +186,115 @@
            needsFineScale(fullSize.height(), decodedSize.height(), sampleSize);
 }
 
+static bool decodeGainmap(std::unique_ptr<SkStream> gainmapStream, const SkGainmapInfo& gainmapInfo,
+                          sp<uirenderer::Gainmap>* outGainmap, const int sampleSize, float scale) {
+    std::unique_ptr<SkAndroidCodec> codec;
+    codec = SkAndroidCodec::MakeFromStream(std::move(gainmapStream), nullptr);
+    if (!codec) {
+        ALOGE("Can not create a codec for Gainmap.");
+        return false;
+    }
+    SkColorType decodeColorType = codec->computeOutputColorType(kN32_SkColorType);
+    sk_sp<SkColorSpace> decodeColorSpace = codec->computeOutputColorSpace(decodeColorType, nullptr);
+
+    SkISize size = codec->getSampledDimensions(sampleSize);
+
+    int scaledWidth = size.width();
+    int scaledHeight = size.height();
+    bool willScale = false;
+
+    // Apply a fine scaling step if necessary.
+    if (needsFineScale(codec->getInfo().dimensions(), size, sampleSize) || scale != 1.0f) {
+        willScale = true;
+        // The operation below may loose precision (integer division), but it is put this way to
+        // mimic main image scale calculation
+        scaledWidth = static_cast<int>((codec->getInfo().width() / sampleSize) * scale + 0.5f);
+        scaledHeight = static_cast<int>((codec->getInfo().height() / sampleSize) * scale + 0.5f);
+    }
+
+    SkAlphaType alphaType = codec->computeOutputAlphaType(false);
+
+    const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(), decodeColorType,
+                                                     alphaType, decodeColorSpace);
+
+    const SkImageInfo& bitmapInfo = decodeInfo;
+    SkBitmap decodeBitmap;
+    sk_sp<Bitmap> nativeBitmap = nullptr;
+
+    if (!decodeBitmap.setInfo(bitmapInfo)) {
+        ALOGE("Failed to setInfo.");
+        return false;
+    }
+
+    if (willScale) {
+        if (!decodeBitmap.tryAllocPixels(nullptr)) {
+            ALOGE("OOM allocating gainmap pixels.");
+            return false;
+        }
+    } else {
+        nativeBitmap = android::Bitmap::allocateHeapBitmap(&decodeBitmap);
+        if (!nativeBitmap) {
+            ALOGE("OOM allocating gainmap pixels.");
+            return false;
+        }
+    }
+
+    // Use SkAndroidCodec to perform the decode.
+    SkAndroidCodec::AndroidOptions codecOptions;
+    codecOptions.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
+    codecOptions.fSampleSize = sampleSize;
+    SkCodec::Result result = codec->getAndroidPixels(decodeInfo, decodeBitmap.getPixels(),
+                                                     decodeBitmap.rowBytes(), &codecOptions);
+    switch (result) {
+        case SkCodec::kSuccess:
+        case SkCodec::kIncompleteInput:
+            break;
+        default:
+            ALOGE("Error decoding gainmap.");
+            return false;
+    }
+
+    if (willScale) {
+        SkBitmap gainmapBitmap;
+        const float scaleX = scaledWidth / float(decodeBitmap.width());
+        const float scaleY = scaledHeight / float(decodeBitmap.height());
+
+        SkColorType scaledColorType = decodeBitmap.colorType();
+        gainmapBitmap.setInfo(
+                bitmapInfo.makeWH(scaledWidth, scaledHeight).makeColorType(scaledColorType));
+
+        nativeBitmap = android::Bitmap::allocateHeapBitmap(&gainmapBitmap);
+        if (!nativeBitmap) {
+            ALOGE("OOM allocating gainmap pixels.");
+            return false;
+        }
+
+        SkPaint paint;
+        // kSrc_Mode instructs us to overwrite the uninitialized pixels in
+        // outputBitmap.  Otherwise we would blend by default, which is not
+        // what we want.
+        paint.setBlendMode(SkBlendMode::kSrc);
+
+        SkCanvas canvas(gainmapBitmap, SkCanvas::ColorBehavior::kLegacy);
+        canvas.scale(scaleX, scaleY);
+        decodeBitmap.setImmutable();  // so .asImage() doesn't make a copy
+        canvas.drawImage(decodeBitmap.asImage(), 0.0f, 0.0f,
+                         SkSamplingOptions(SkFilterMode::kLinear), &paint);
+    }
+
+    auto gainmap = sp<uirenderer::Gainmap>::make();
+    if (!gainmap) {
+        ALOGE("OOM allocating Gainmap");
+        return false;
+    }
+
+    gainmap->info = gainmapInfo;
+    gainmap->bitmap = std::move(nativeBitmap);
+    *outGainmap = std::move(gainmap);
+
+    return true;
+}
+
 static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
                         jobject padding, jobject options, jlong inBitmapHandle,
                         jlong colorSpaceHandle) {
@@ -485,6 +598,19 @@
         return nullObjectReturn("Got null SkPixelRef");
     }
 
+    bool hasGainmap = false;
+    SkGainmapInfo gainmapInfo;
+    std::unique_ptr<SkStream> gainmapStream = nullptr;
+    sp<uirenderer::Gainmap> gainmap = nullptr;
+    if (result == SkCodec::kSuccess) {
+        hasGainmap = codec->getAndroidGainmap(&gainmapInfo, &gainmapStream);
+    }
+
+    if (hasGainmap) {
+        hasGainmap =
+                decodeGainmap(std::move(gainmapStream), gainmapInfo, &gainmap, sampleSize, scale);
+    }
+
     if (!isMutable && javaBitmap == NULL) {
         // promise we will never change our pixels (great for sharing and pictures)
         outputBitmap.setImmutable();
@@ -492,6 +618,9 @@
 
     bool isPremultiplied = !requireUnpremultiplied;
     if (javaBitmap != nullptr) {
+        if (hasGainmap) {
+            reuseBitmap->setGainmap(std::move(gainmap));
+        }
         bitmap::reinitBitmap(env, javaBitmap, outputBitmap.info(), isPremultiplied);
         outputBitmap.notifyPixelsChanged();
         // If a java bitmap was passed in for reuse, pass it back
@@ -507,13 +636,22 @@
         if (!hardwareBitmap.get()) {
             return nullObjectReturn("Failed to allocate a hardware bitmap");
         }
+        if (hasGainmap) {
+            hardwareBitmap->setGainmap(std::move(gainmap));
+        }
+
         return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags,
                 ninePatchChunk, ninePatchInsets, -1);
     }
 
+    Bitmap* heapBitmap = defaultAllocator.getStorageObjAndReset();
+    if (hasGainmap && heapBitmap != nullptr) {
+        heapBitmap->setGainmap(std::move(gainmap));
+    }
+
     // now create the java bitmap
-    return bitmap::createBitmap(env, defaultAllocator.getStorageObjAndReset(),
-            bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1);
+    return bitmap::createBitmap(env, heapBitmap, bitmapCreateFlags, ninePatchChunk, ninePatchInsets,
+                                -1);
 }
 
 static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
diff --git a/libs/hwui/jni/Mesh.cpp b/libs/hwui/jni/Mesh.cpp
index 3aac48d..b13d9ba 100644
--- a/libs/hwui/jni/Mesh.cpp
+++ b/libs/hwui/jni/Mesh.cpp
@@ -38,8 +38,8 @@
 }
 
 static jlong make(JNIEnv* env, jobject, jlong meshSpec, jint mode, jobject vertexBuffer,
-                  jboolean isDirect, jint vertexCount, jint vertexOffset, jint left, jint top,
-                  jint right, jint bottom) {
+                  jboolean isDirect, jint vertexCount, jint vertexOffset, jfloat left, jfloat top,
+                  jfloat right, jfloat bottom) {
     auto skMeshSpec = sk_ref_sp(reinterpret_cast<SkMeshSpecification*>(meshSpec));
     sk_sp<SkMesh::VertexBuffer> skVertexBuffer =
             genVertexBuffer(env, vertexBuffer, vertexCount * skMeshSpec->stride(), isDirect);
@@ -60,7 +60,7 @@
 static jlong makeIndexed(JNIEnv* env, jobject, jlong meshSpec, jint mode, jobject vertexBuffer,
                          jboolean isVertexDirect, jint vertexCount, jint vertexOffset,
                          jobject indexBuffer, jboolean isIndexDirect, jint indexCount,
-                         jint indexOffset, jint left, jint top, jint right, jint bottom) {
+                         jint indexOffset, jfloat left, jfloat top, jfloat right, jfloat bottom) {
     auto skMeshSpec = sk_ref_sp(reinterpret_cast<SkMeshSpecification*>(meshSpec));
     sk_sp<SkMesh::VertexBuffer> skVertexBuffer =
             genVertexBuffer(env, vertexBuffer, vertexCount * skMeshSpec->stride(), isVertexDirect);
@@ -210,8 +210,8 @@
 
 static const JNINativeMethod gMeshMethods[] = {
         {"nativeGetFinalizer", "()J", (void*)getMeshFinalizer},
-        {"nativeMake", "(JILjava/nio/Buffer;ZIIIIII)J", (void*)make},
-        {"nativeMakeIndexed", "(JILjava/nio/Buffer;ZIILjava/nio/ShortBuffer;ZIIIIII)J",
+        {"nativeMake", "(JILjava/nio/Buffer;ZIIFFFF)J", (void*)make},
+        {"nativeMakeIndexed", "(JILjava/nio/Buffer;ZIILjava/nio/ShortBuffer;ZIIFFFF)J",
          (void*)makeIndexed},
         {"nativeUpdateMesh", "(JZ)V", (void*)updateMesh},
         {"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V", (void*)updateFloatArrayUniforms},
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index fa8e2e7..8a0db1c 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -71,11 +71,9 @@
     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
 }
 
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
-                                      jint tileModeX, jint tileModeY, bool filter,
-                                      bool isDirectSampled) {
+static jlong createBitmapShaderHelper(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
+                                      jint tileModeX, jint tileModeY, bool isDirectSampled,
+                                      const SkSamplingOptions& sampling) {
     const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     sk_sp<SkImage> image;
     if (bitmapHandle) {
@@ -88,8 +86,7 @@
         SkBitmap bitmap;
         image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
     }
-    SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
-                               SkMipmapMode::kNone);
+
     sk_sp<SkShader> shader;
     if (isDirectSampled) {
         shader = image->makeRawShader((SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
@@ -107,6 +104,26 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
+static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
+                                      jint tileModeX, jint tileModeY, bool filter,
+                                      bool isDirectSampled) {
+    SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
+                               SkMipmapMode::kNone);
+    return createBitmapShaderHelper(env, o, matrixPtr, bitmapHandle, tileModeX, tileModeY,
+                                    isDirectSampled, sampling);
+}
+
+static jlong BitmapShader_constructorWithMaxAniso(JNIEnv* env, jobject o, jlong matrixPtr,
+                                                  jlong bitmapHandle, jint tileModeX,
+                                                  jint tileModeY, jint maxAniso,
+                                                  bool isDirectSampled) {
+    auto sampling = SkSamplingOptions::Aniso(static_cast<int>(maxAniso));
+    return createBitmapShaderHelper(env, o, matrixPtr, bitmapHandle, tileModeX, tileModeY,
+                                    isDirectSampled, sampling);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
 static std::vector<SkColor4f> convertColorLongs(JNIEnv* env, jlongArray colorArray) {
     const size_t count = env->GetArrayLength(colorArray);
     const jlong* colorValues = env->GetLongArrayElements(colorArray, nullptr);
@@ -408,6 +425,8 @@
 
 static const JNINativeMethod gBitmapShaderMethods[] = {
         {"nativeCreate", "(JJIIZZ)J", (void*)BitmapShader_constructor},
+        {"nativeCreateWithMaxAniso", "(JJIIIZ)J", (void*)BitmapShader_constructorWithMaxAniso},
+
 };
 
 static const JNINativeMethod gLinearGradientMethods[] = {
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index c9d79ab..e1c8877 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -208,40 +208,52 @@
     }
 }
 
+void SkiaRecordingCanvas::handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload) {
+    // if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
+    // it is not safe to store a raw SkImage pointer, because the image object will be destroyed
+    // when this function ends.
+    if (!bitmap.isImmutable() && payload.image.get() && !payload.image->unique()) {
+        mDisplayList->mMutableImages.push_back(payload.image.get());
+    }
+
+    if (bitmap.hasGainmap()) {
+        auto gainmapBitmap = bitmap.gainmap()->bitmap;
+        // Not all DrawImagePayload receivers will store the gainmap (such as DrawImageLattice),
+        // so only store it in the mutable list if it was actually recorded
+        if (!gainmapBitmap->isImmutable() && payload.gainmapImage.get() &&
+            !payload.gainmapImage->unique()) {
+            mDisplayList->mMutableImages.push_back(payload.gainmapImage.get());
+        }
+    }
+}
+
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) {
-    sk_sp<SkImage> image = bitmap.makeImage();
+    auto payload = DrawImagePayload(bitmap);
 
     applyLooper(
             paint,
             [&](const Paint& p) {
-                mRecorder.drawImage(image, left, top, p.sampling(), &p, bitmap.palette());
+                mRecorder.drawImage(DrawImagePayload(payload), left, top, p.sampling(), &p);
             },
             FilterForImage);
 
-    // if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
-    // it is not safe to store a raw SkImage pointer, because the image object will be destroyed
-    // when this function ends.
-    if (!bitmap.isImmutable() && image.get() && !image->unique()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    handleMutableImages(bitmap, payload);
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint* paint) {
     SkAutoCanvasRestore acr(&mRecorder, true);
     concat(matrix);
 
-    sk_sp<SkImage> image = bitmap.makeImage();
+    auto payload = DrawImagePayload(bitmap);
 
     applyLooper(
             paint,
             [&](const Paint& p) {
-                mRecorder.drawImage(image, 0, 0, p.sampling(), &p, bitmap.palette());
+                mRecorder.drawImage(DrawImagePayload(payload), 0, 0, p.sampling(), &p);
             },
             FilterForImage);
 
-    if (!bitmap.isImmutable() && image.get() && !image->unique()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    handleMutableImages(bitmap, payload);
 }
 
 void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
@@ -250,20 +262,17 @@
     SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
     SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
 
-    sk_sp<SkImage> image = bitmap.makeImage();
+    auto payload = DrawImagePayload(bitmap);
 
     applyLooper(
             paint,
             [&](const Paint& p) {
-                mRecorder.drawImageRect(image, srcRect, dstRect, p.sampling(), &p,
-                                        SkCanvas::kFast_SrcRectConstraint, bitmap.palette());
+                mRecorder.drawImageRect(DrawImagePayload(payload), srcRect, dstRect, p.sampling(),
+                                        &p, SkCanvas::kFast_SrcRectConstraint);
             },
             FilterForImage);
 
-    if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty() &&
-        !dstRect.isEmpty()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    handleMutableImages(bitmap, payload);
 }
 
 void SkiaRecordingCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, float dstLeft,
@@ -291,7 +300,7 @@
 
     lattice.fBounds = nullptr;
     SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
-    sk_sp<SkImage> image = bitmap.makeImage();
+    auto payload = DrawImagePayload(bitmap);
 
     // HWUI always draws 9-patches with linear filtering, regardless of the Paint.
     const SkFilterMode filter = SkFilterMode::kLinear;
@@ -299,13 +308,11 @@
     applyLooper(
             paint,
             [&](const SkPaint& p) {
-                mRecorder.drawImageLattice(image, lattice, dst, filter, &p, bitmap.palette());
+                mRecorder.drawImageLattice(DrawImagePayload(payload), lattice, dst, filter, &p);
             },
             FilterForImage);
 
-    if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
-        mDisplayList->mMutableImages.push_back(image.get());
-    }
+    handleMutableImages(bitmap, payload);
 }
 
 double SkiaRecordingCanvas::drawAnimatedImage(AnimatedImageDrawable* animatedImage) {
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 7844e2c..3fd8fa3 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -102,6 +102,8 @@
      */
     void initDisplayList(uirenderer::RenderNode* renderNode, int width, int height);
 
+    void handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload);
+
     using INHERITED = SkiaCanvas;
 };
 
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
index a835167..24cfc9d 100644
--- a/libs/input/MouseCursorController.cpp
+++ b/libs/input/MouseCursorController.cpp
@@ -38,6 +38,8 @@
       : mContext(context) {
     std::scoped_lock lock(mLock);
 
+    mLocked.stylusHoverMode = false;
+
     mLocked.animationFrameIndex = 0;
     mLocked.lastFrameUpdatedTime = 0;
 
@@ -47,7 +49,8 @@
     mLocked.pointerAlpha = 0.0f; // pointer is initially faded
     mLocked.pointerSprite = mContext.getSpriteController()->createSprite();
     mLocked.updatePointerIcon = false;
-    mLocked.requestedPointerType = mContext.getPolicy()->getDefaultPointerIconId();
+    mLocked.requestedPointerType = PointerIconStyle::TYPE_NOT_SPECIFIED;
+    mLocked.resolvedPointerType = PointerIconStyle::TYPE_NOT_SPECIFIED;
 
     mLocked.resourcesLoaded = false;
 
@@ -184,6 +187,15 @@
     }
 }
 
+void MouseCursorController::setStylusHoverMode(bool stylusHoverMode) {
+    std::scoped_lock lock(mLock);
+
+    if (mLocked.stylusHoverMode != stylusHoverMode) {
+        mLocked.stylusHoverMode = stylusHoverMode;
+        mLocked.updatePointerIcon = true;
+    }
+}
+
 void MouseCursorController::reloadPointerResources(bool getAdditionalMouseResources) {
     std::scoped_lock lock(mLock);
 
@@ -339,7 +351,7 @@
 
 bool MouseCursorController::doBitmapAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
     std::map<PointerIconStyle, PointerAnimation>::const_iterator iter =
-            mLocked.animationResources.find(mLocked.requestedPointerType);
+            mLocked.animationResources.find(mLocked.resolvedPointerType);
     if (iter == mLocked.animationResources.end()) {
         return false;
     }
@@ -381,14 +393,23 @@
     }
 
     if (mLocked.updatePointerIcon) {
-        if (mLocked.requestedPointerType == mContext.getPolicy()->getDefaultPointerIconId()) {
+        mLocked.resolvedPointerType = mLocked.requestedPointerType;
+        const PointerIconStyle defaultPointerIconId =
+                mContext.getPolicy()->getDefaultPointerIconId();
+        if (mLocked.resolvedPointerType == PointerIconStyle::TYPE_NOT_SPECIFIED) {
+            mLocked.resolvedPointerType = mLocked.stylusHoverMode
+                    ? mContext.getPolicy()->getDefaultStylusIconId()
+                    : defaultPointerIconId;
+        }
+
+        if (mLocked.resolvedPointerType == defaultPointerIconId) {
             mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
         } else {
             std::map<PointerIconStyle, SpriteIcon>::const_iterator iter =
-                    mLocked.additionalMouseResources.find(mLocked.requestedPointerType);
+                    mLocked.additionalMouseResources.find(mLocked.resolvedPointerType);
             if (iter != mLocked.additionalMouseResources.end()) {
                 std::map<PointerIconStyle, PointerAnimation>::const_iterator anim_iter =
-                        mLocked.animationResources.find(mLocked.requestedPointerType);
+                        mLocked.animationResources.find(mLocked.resolvedPointerType);
                 if (anim_iter != mLocked.animationResources.end()) {
                     mLocked.animationFrameIndex = 0;
                     mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -396,7 +417,7 @@
                 }
                 mLocked.pointerSprite->setIcon(iter->second);
             } else {
-                ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerType);
+                ALOGW("Can't find the resource for icon id %d", mLocked.resolvedPointerType);
                 mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
             }
         }
diff --git a/libs/input/MouseCursorController.h b/libs/input/MouseCursorController.h
index 208d33d..db0ab56 100644
--- a/libs/input/MouseCursorController.h
+++ b/libs/input/MouseCursorController.h
@@ -53,6 +53,7 @@
     void fade(PointerControllerInterface::Transition transition);
     void unfade(PointerControllerInterface::Transition transition);
     void setDisplayViewport(const DisplayViewport& viewport, bool getAdditionalMouseResources);
+    void setStylusHoverMode(bool stylusHoverMode);
 
     void updatePointerIcon(PointerIconStyle iconId);
     void setCustomPointerIcon(const SpriteIcon& icon);
@@ -74,6 +75,7 @@
 
     struct Locked {
         DisplayViewport viewport;
+        bool stylusHoverMode;
 
         size_t animationFrameIndex;
         nsecs_t lastFrameUpdatedTime;
@@ -92,6 +94,7 @@
         std::map<PointerIconStyle, PointerAnimation> animationResources;
 
         PointerIconStyle requestedPointerType;
+        PointerIconStyle resolvedPointerType;
 
         int32_t buttonState;
 
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 099efd3..fedf58d 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -195,7 +195,11 @@
         return;
     }
 
-    if (presentation == Presentation::POINTER) {
+    if (presentation == Presentation::POINTER || presentation == Presentation::STYLUS_HOVER) {
+        // For now, we support stylus hover using the mouse cursor implementation.
+        // TODO: Add proper support for stylus hover icons.
+        mCursorController.setStylusHoverMode(presentation == Presentation::STYLUS_HOVER);
+
         mCursorController.getAdditionalMouseResources();
         clearSpotsLocked();
     }
@@ -249,7 +253,8 @@
 
     if (mCursorController.resourcesLoaded()) {
         bool getAdditionalMouseResources = false;
-        if (mLocked.presentation == PointerController::Presentation::POINTER) {
+        if (mLocked.presentation == PointerController::Presentation::POINTER ||
+            mLocked.presentation == PointerController::Presentation::STYLUS_HOVER) {
             getAdditionalMouseResources = true;
         }
         mCursorController.reloadPointerResources(getAdditionalMouseResources);
@@ -260,7 +265,8 @@
     std::scoped_lock lock(getLock());
 
     bool getAdditionalMouseResources = false;
-    if (mLocked.presentation == PointerController::Presentation::POINTER) {
+    if (mLocked.presentation == PointerController::Presentation::POINTER ||
+        mLocked.presentation == PointerController::Presentation::STYLUS_HOVER) {
         getAdditionalMouseResources = true;
     }
     mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
diff --git a/libs/input/PointerControllerContext.h b/libs/input/PointerControllerContext.h
index 1797428..96d83a5 100644
--- a/libs/input/PointerControllerContext.h
+++ b/libs/input/PointerControllerContext.h
@@ -79,6 +79,7 @@
             std::map<PointerIconStyle, PointerAnimation>* outAnimationResources,
             int32_t displayId) = 0;
     virtual PointerIconStyle getDefaultPointerIconId() = 0;
+    virtual PointerIconStyle getDefaultStylusIconId() = 0;
     virtual PointerIconStyle getCustomPointerIconId() = 0;
     virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) = 0;
 };
diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp
index a6a4115..c820d00 100644
--- a/libs/input/tests/PointerController_test.cpp
+++ b/libs/input/tests/PointerController_test.cpp
@@ -35,6 +35,7 @@
     CURSOR_TYPE_ANCHOR,
     CURSOR_TYPE_ADDITIONAL,
     CURSOR_TYPE_ADDITIONAL_ANIM,
+    CURSOR_TYPE_STYLUS,
     CURSOR_TYPE_CUSTOM = -1,
 };
 
@@ -57,6 +58,7 @@
             std::map<PointerIconStyle, PointerAnimation>* outAnimationResources,
             int32_t displayId) override;
     virtual PointerIconStyle getDefaultPointerIconId() override;
+    virtual PointerIconStyle getDefaultStylusIconId() override;
     virtual PointerIconStyle getCustomPointerIconId() override;
     virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) override;
 
@@ -105,6 +107,11 @@
     (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon;
     (*outAnimationResources)[static_cast<PointerIconStyle>(cursorType)] = anim;
 
+    // CURSOR_TYPE_STYLUS doesn't have animation resource.
+    cursorType = CURSOR_TYPE_STYLUS;
+    loadPointerIconForType(&icon, cursorType);
+    (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon;
+
     additionalMouseResourcesLoaded = true;
 }
 
@@ -112,6 +119,10 @@
     return static_cast<PointerIconStyle>(CURSOR_TYPE_DEFAULT);
 }
 
+PointerIconStyle MockPointerControllerPolicyInterface::getDefaultStylusIconId() {
+    return static_cast<PointerIconStyle>(CURSOR_TYPE_STYLUS);
+}
+
 PointerIconStyle MockPointerControllerPolicyInterface::getCustomPointerIconId() {
     return static_cast<PointerIconStyle>(CURSOR_TYPE_CUSTOM);
 }
@@ -214,6 +225,21 @@
     mPointerController->reloadPointerResources();
 }
 
+TEST_F(PointerControllerTest, useStylusTypeForStylusHover) {
+    ensureDisplayViewportIsSet();
+    mPointerController->setPresentation(PointerController::Presentation::STYLUS_HOVER);
+    mPointerController->unfade(PointerController::Transition::IMMEDIATE);
+    std::pair<float, float> hotspot = getHotSpotCoordinatesForType(CURSOR_TYPE_STYLUS);
+    EXPECT_CALL(*mPointerSprite, setVisible(true));
+    EXPECT_CALL(*mPointerSprite, setAlpha(1.0f));
+    EXPECT_CALL(*mPointerSprite,
+                setIcon(AllOf(Field(&SpriteIcon::style,
+                                    static_cast<PointerIconStyle>(CURSOR_TYPE_STYLUS)),
+                              Field(&SpriteIcon::hotSpotX, hotspot.first),
+                              Field(&SpriteIcon::hotSpotY, hotspot.second))));
+    mPointerController->reloadPointerResources();
+}
+
 TEST_F(PointerControllerTest, updatePointerIcon) {
     ensureDisplayViewportIsSet();
     mPointerController->setPresentation(PointerController::Presentation::POINTER);
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index dea6097..b0cdb05 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -1275,7 +1275,10 @@
                     || (preset == MediaRecorder.AudioSource.VOICE_UPLINK)
                     || (preset == MediaRecorder.AudioSource.VOICE_CALL)
                     || (preset == MediaRecorder.AudioSource.ECHO_REFERENCE)
-                    || (preset == MediaRecorder.AudioSource.ULTRASOUND)) {
+                    || (preset == MediaRecorder.AudioSource.ULTRASOUND)
+                    // AUDIO_SOURCE_INVALID is used by convention on default initialized
+                    // audio attributes
+                    || (preset == MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID)) {
                 mSource = preset;
             } else {
                 setCapturePreset(preset);
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index 77fa9dc..bf3612d 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -146,13 +146,16 @@
          * @param register true for registering, false for unregistering
          * @param device device for which volume is monitored
          */
+        @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+                android.Manifest.permission.BLUETOOTH_PRIVILEGED })
         public void register(boolean register, @NonNull AudioDeviceAttributes device,
-                @NonNull List<VolumeInfo> volumes, boolean handlesVolumeAdjustment) {
+                @NonNull List<VolumeInfo> volumes, boolean handlesVolumeAdjustment,
+                @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
             try {
                 getService().registerDeviceVolumeDispatcherForAbsoluteVolume(register,
                         this, mPackageName,
                         Objects.requireNonNull(device), Objects.requireNonNull(volumes),
-                        handlesVolumeAdjustment);
+                        handlesVolumeAdjustment, behavior);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
@@ -234,6 +237,77 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnAudioDeviceVolumeChangedListener vclistener,
             boolean handlesVolumeAdjustment) {
+        baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
+                handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+    }
+
+    /**
+     * @hide
+     * Configures a device to use absolute volume model, and registers a listener for receiving
+     * volume updates to apply on that device.
+     *
+     * Should be used instead of {@link #setDeviceAbsoluteVolumeBehavior} when there is no reliable
+     * way to set the device's volume to a percentage.
+     *
+     * @param device the audio device set to absolute volume mode
+     * @param volume the type of volume this device responds to
+     * @param executor the Executor used for receiving volume updates through the listener
+     * @param vclistener the callback for volume updates
+     */
+    @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED })
+    public void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
+            @NonNull AudioDeviceAttributes device,
+            @NonNull VolumeInfo volume,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnAudioDeviceVolumeChangedListener vclistener,
+            boolean handlesVolumeAdjustment) {
+        final ArrayList<VolumeInfo> volumes = new ArrayList<>(1);
+        volumes.add(volume);
+        setDeviceAbsoluteMultiVolumeAdjustOnlyBehavior(device, volumes, executor, vclistener,
+                handlesVolumeAdjustment);
+    }
+
+    /**
+     * @hide
+     * Configures a device to use absolute volume model applied to different volume types, and
+     * registers a listener for receiving volume updates to apply on that device.
+     *
+     * Should be used instead of {@link #setDeviceAbsoluteMultiVolumeBehavior} when there is
+     * no reliable way to set the device's volume to a percentage.
+     *
+     * @param device the audio device set to absolute multi-volume mode
+     * @param volumes the list of volumes the given device responds to
+     * @param executor the Executor used for receiving volume updates through the listener
+     * @param vclistener the callback for volume updates
+     */
+    @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED })
+    public void setDeviceAbsoluteMultiVolumeAdjustOnlyBehavior(
+            @NonNull AudioDeviceAttributes device,
+            @NonNull List<VolumeInfo> volumes,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnAudioDeviceVolumeChangedListener vclistener,
+            boolean handlesVolumeAdjustment) {
+        baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
+                handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+    }
+
+    /**
+     * Base method for configuring a device to use absolute volume behavior, or one of its variants.
+     * See {@link AudioManager#AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
+     *
+     * @param behavior the variant of absolute device volume behavior to adopt
+     */
+    @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+            android.Manifest.permission.BLUETOOTH_PRIVILEGED })
+    private void baseSetDeviceAbsoluteMultiVolumeBehavior(
+            @NonNull AudioDeviceAttributes device,
+            @NonNull List<VolumeInfo> volumes,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnAudioDeviceVolumeChangedListener vclistener,
+            boolean handlesVolumeAdjustment,
+            @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
         Objects.requireNonNull(device);
         Objects.requireNonNull(volumes);
         Objects.requireNonNull(executor);
@@ -253,7 +327,8 @@
                 mDeviceVolumeListeners.removeIf(info -> info.mDevice.equalTypeAddress(device));
             }
             mDeviceVolumeListeners.add(listenerInfo);
-            mDeviceVolumeDispatcherStub.register(true, device, volumes, handlesVolumeAdjustment);
+            mDeviceVolumeDispatcherStub.register(true, device, volumes, handlesVolumeAdjustment,
+                    behavior);
         }
     }
 
@@ -375,6 +450,8 @@
                 return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE";
             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
                 return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE";
+            case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
+                return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY";
             default:
                 return "invalid volume behavior " + behavior;
         }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 0636451..7de3abc3 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1422,7 +1422,7 @@
     public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
         Preconditions.checkNotNull(attributes, "Audio Attributes must not be null");
         return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(attributes,
-                /* fallbackOnDefault= */ false);
+                /* fallbackOnDefault= */ true);
     }
 
     /**
@@ -6231,6 +6231,15 @@
     @SystemApi
     public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
 
+    /**
+     * @hide
+     * A variant of {@link #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} where the host cannot reliably set
+     * the volume percentage of the audio device. Specifically, {@link #setStreamVolume} will have
+     * no effect, or an unreliable effect.
+     */
+    @SystemApi
+    public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5;
+
     /** @hide */
     @IntDef({
             DEVICE_VOLUME_BEHAVIOR_VARIABLE,
@@ -6238,6 +6247,7 @@
             DEVICE_VOLUME_BEHAVIOR_FIXED,
             DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
             DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface DeviceVolumeBehavior {}
@@ -6250,11 +6260,23 @@
             DEVICE_VOLUME_BEHAVIOR_FIXED,
             DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
             DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface DeviceVolumeBehaviorState {}
 
     /**
+     * Variants of absolute volume behavior that are set in {@link AudioDeviceVolumeManager}.
+     * @hide
+     */
+    @IntDef({
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AbsoluteDeviceVolumeBehavior {}
+
+    /**
      * @hide
      * Throws IAE on an invalid volume behavior value
      * @param volumeBehavior behavior value to check
@@ -6266,6 +6288,7 @@
             case DEVICE_VOLUME_BEHAVIOR_FIXED:
             case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
             case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
                 return;
             default:
                 throw new IllegalArgumentException("Illegal volume behavior " + volumeBehavior);
@@ -6305,6 +6328,16 @@
 
     /**
      * @hide
+     * Controls whether DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY may be returned by
+     * getDeviceVolumeBehavior. If this is disabled, DEVICE_VOLUME_BEHAVIOR_FULL is returned
+     * in its place.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public static final long RETURN_DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 240663182L;
+
+    /**
+     * @hide
      * Returns the volume device behavior for the given audio device
      * @param device the audio device
      * @return the volume behavior for the device
@@ -6322,7 +6355,12 @@
         // communicate with service
         final IAudioService service = getService();
         try {
-            return service.getDeviceVolumeBehavior(device);
+            int behavior = service.getDeviceVolumeBehavior(device);
+            if (!CompatChanges.isChangeEnabled(RETURN_DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY)
+                    && behavior == DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
+                return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
+            }
+            return behavior;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 3e0356f..1c517e7 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -629,12 +629,13 @@
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
     int[] getActiveAssistantServiceUids();
 
-    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)")
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
     void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
             in IAudioDeviceVolumeDispatcher cb,
             in String packageName,
             in AudioDeviceAttributes device, in List<VolumeInfo> volumes,
-            boolean handlesvolumeAdjustment);
+            boolean handlesvolumeAdjustment,
+            int volumeBehavior);
 
     AudioHalVersionInfo getHalVersion();
 
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 015602e..5bc8c04 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -41,6 +41,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.util.Log;
 import android.util.Singleton;
 
@@ -360,14 +361,14 @@
         @Override
         public void handleMessage(Message msg) {
             if (msg.what == MSG_CAS_EVENT) {
-                mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2,
-                        toBytes((ArrayList<Byte>) msg.obj));
+                byte[] data = (msg.obj == null) ? new byte[0] : (byte[]) msg.obj;
+                mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2, data);
             } else if (msg.what == MSG_CAS_SESSION_EVENT) {
                 Bundle bundle = msg.getData();
                 byte[] sessionId = bundle.getByteArray(SESSION_KEY);
-                mListener.onSessionEvent(MediaCas.this,
-                        createFromSessionId(sessionId), msg.arg1, msg.arg2,
-                        bundle.getByteArray(DATA_KEY));
+                byte[] data = bundle.getByteArray(DATA_KEY);
+                mListener.onSessionEvent(
+                        MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, data);
             } else if (msg.what == MSG_CAS_STATUS_EVENT) {
                 if ((msg.arg1 == PLUGIN_STATUS_SESSION_NUMBER_CHANGED)
                         && (mTunerResourceManager != null)) {
@@ -599,7 +600,11 @@
 
             try {
                 if (mICas != null) {
-                    mICas.setSessionPrivateData(mSessionId, data);
+                    try {
+                        mICas.setSessionPrivateData(mSessionId, data);
+                    } catch (ServiceSpecificException se) {
+                        MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                    }
                 } else {
                     MediaCasException.throwExceptionIfNeeded(
                             mICasHidl.setSessionPrivateData(
@@ -628,7 +633,12 @@
 
             try {
                 if (mICas != null) {
-                    mICas.processEcm(mSessionId, data);
+                    try {
+                        mICas.processEcm(
+                                mSessionId, Arrays.copyOfRange(data, offset, length + offset));
+                    } catch (ServiceSpecificException se) {
+                        MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                    }
                 } else {
                     MediaCasException.throwExceptionIfNeeded(
                             mICasHidl.processEcm(
@@ -671,23 +681,26 @@
             validateSessionInternalStates();
             if (mICas != null) {
                 try {
+                    if (data == null) {
+                        data = new byte[0];
+                    }
                     mICas.sendSessionEvent(mSessionId, event, arg, data);
                 } catch (RemoteException e) {
                     cleanupAndRethrowIllegalState();
                 }
-            }
+            } else {
+                if (mICasHidl11 == null) {
+                    Log.d(TAG, "Send Session Event isn't supported by cas@1.0 interface");
+                    throw new UnsupportedCasException("Send Session Event is not supported");
+                }
 
-            if (mICasHidl11 == null) {
-                Log.d(TAG, "Send Session Event isn't supported by cas@1.0 interface");
-                throw new UnsupportedCasException("Send Session Event is not supported");
-            }
-
-            try {
-                MediaCasException.throwExceptionIfNeeded(
-                        mICasHidl11.sendSessionEvent(
-                                toByteArray(mSessionId), event, arg, toByteArray(data)));
-            } catch (RemoteException e) {
-                cleanupAndRethrowIllegalState();
+                try {
+                    MediaCasException.throwExceptionIfNeeded(
+                            mICasHidl11.sendSessionEvent(
+                                    toByteArray(mSessionId), event, arg, toByteArray(data)));
+                } catch (RemoteException e) {
+                    cleanupAndRethrowIllegalState();
+                }
             }
         }
 
@@ -931,10 +944,11 @@
     }
 
     /**
-     * Check if the HAL is an AIDL implementation
+     * Check if the HAL is an AIDL implementation. For CTS testing purpose.
      *
      * @hide
      */
+    @TestApi
     public boolean isAidlHal() {
         return mICas != null;
     }
@@ -1038,7 +1052,11 @@
 
         try {
             if (mICas != null) {
-                mICas.setPrivateData(data);
+                try {
+                    mICas.setPrivateData(data);
+                } catch (ServiceSpecificException se) {
+                    MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                }
             } else {
                 MediaCasException.throwExceptionIfNeeded(
                         mICasHidl.setPrivateData(toByteArray(data, 0, data.length)));
@@ -1126,7 +1144,21 @@
         int sessionResourceHandle = getSessionResourceHandle();
 
         try {
-            if (mICasHidl != null) {
+            if (mICas != null) {
+                try {
+                    byte[] sessionId = mICas.openSessionDefault();
+                    Session session = createFromSessionId(sessionId);
+                    Log.d(TAG, "Write Stats Log for succeed to Open Session.");
+                    FrameworkStatsLog.write(
+                            FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS,
+                            mUserId,
+                            mCasSystemId,
+                            FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED);
+                    return session;
+                } catch (ServiceSpecificException se) {
+                    MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                }
+            } else if (mICasHidl != null) {
                 OpenSessionCallback cb = new OpenSessionCallback();
                 mICasHidl.openSession(cb);
                 MediaCasException.throwExceptionIfNeeded(cb.mStatus);
@@ -1183,7 +1215,7 @@
                         mCasSystemId,
                         FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED);
                 return session;
-            } catch (RemoteException e) {
+            } catch (ServiceSpecificException | RemoteException e) {
                 cleanupAndRethrowIllegalState();
             }
         }
@@ -1229,7 +1261,11 @@
 
         try {
             if (mICas != null) {
-                mICas.processEmm(Arrays.copyOfRange(data, offset, length));
+                try {
+                    mICas.processEmm(Arrays.copyOfRange(data, offset, length));
+                } catch (ServiceSpecificException se) {
+                    MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                }
             } else {
                 MediaCasException.throwExceptionIfNeeded(
                         mICasHidl.processEmm(toByteArray(data, offset, length)));
@@ -1272,7 +1308,14 @@
 
         try {
             if (mICas != null) {
-                mICas.sendEvent(event, arg, data);
+                try {
+                    if (data == null) {
+                        data = new byte[0];
+                    }
+                    mICas.sendEvent(event, arg, data);
+                } catch (ServiceSpecificException se) {
+                    MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                }
             } else {
                 MediaCasException.throwExceptionIfNeeded(
                         mICasHidl.sendEvent(event, arg, toByteArray(data)));
@@ -1298,7 +1341,11 @@
 
         try {
             if (mICas != null) {
-                mICas.provision(provisionString);
+                try {
+                    mICas.provision(provisionString);
+                } catch (ServiceSpecificException se) {
+                    MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                }
             } else {
                 MediaCasException.throwExceptionIfNeeded(mICasHidl.provision(provisionString));
             }
@@ -1323,7 +1370,14 @@
 
         try {
             if (mICas != null) {
-                mICas.refreshEntitlements(refreshType, refreshData);
+                try {
+                    if (refreshData == null) {
+                        refreshData = new byte[0];
+                    }
+                    mICas.refreshEntitlements(refreshType, refreshData);
+                } catch (ServiceSpecificException se) {
+                    MediaCasException.throwExceptionIfNeeded(se.errorCode);
+                }
             } else {
                 MediaCasException.throwExceptionIfNeeded(
                         mICasHidl.refreshEntitlements(refreshType, toByteArray(refreshData)));
diff --git a/media/java/android/media/MediaDescrambler.java b/media/java/android/media/MediaDescrambler.java
index b4bdf93d..3c276d6 100644
--- a/media/java/android/media/MediaDescrambler.java
+++ b/media/java/android/media/MediaDescrambler.java
@@ -17,24 +17,16 @@
 package android.media;
 
 import android.annotation.NonNull;
-import android.hardware.cas.DestinationBuffer;
+import android.annotation.TestApi;
 import android.hardware.cas.IDescrambler;
 import android.hardware.cas.ScramblingControl;
-import android.hardware.cas.SharedBuffer;
-import android.hardware.cas.SubSample;
 import android.hardware.cas.V1_0.IDescramblerBase;
-import android.hardware.common.Ashmem;
-import android.hardware.common.NativeHandle;
 import android.media.MediaCasException.UnsupportedCasException;
 import android.os.IHwBinder;
-import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
-import android.os.SharedMemory;
-import android.system.ErrnoException;
 import android.util.Log;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 
@@ -52,6 +44,7 @@
 public final class MediaDescrambler implements AutoCloseable {
     private static final String TAG = "MediaDescrambler";
     private DescramblerWrapper mIDescrambler;
+    private boolean mIsAidlHal;
 
     private interface DescramblerWrapper {
 
@@ -68,50 +61,18 @@
         void setMediaCasSession(byte[] sessionId) throws RemoteException;
 
         void release() throws RemoteException;
-    }
-    ;
-
-    private long getSubsampleInfo(
-            int numSubSamples,
-            int[] numBytesOfClearData,
-            int[] numBytesOfEncryptedData,
-            SubSample[] subSamples) {
-        long totalSize = 0;
-
-        for (int i = 0; i < numSubSamples; i++) {
-            totalSize += numBytesOfClearData[i];
-            subSamples[i].numBytesOfClearData = numBytesOfClearData[i];
-            totalSize += numBytesOfEncryptedData[i];
-            subSamples[i].numBytesOfEncryptedData = numBytesOfEncryptedData[i];
-        }
-        return totalSize;
-    }
-
-    private ParcelFileDescriptor createSharedMemory(ByteBuffer buffer, String name)
-            throws RemoteException {
-        byte[] source = buffer.array();
-        if (source.length == 0) {
-            return null;
-        }
-        ParcelFileDescriptor fd = null;
-        try {
-            SharedMemory ashmem = SharedMemory.create(name == null ? "" : name, source.length);
-            ByteBuffer ptr = ashmem.mapReadWrite();
-            ptr.put(buffer);
-            ashmem.unmap(ptr);
-            fd = ashmem.getFdDup();
-            return fd;
-        } catch (ErrnoException | IOException e) {
-            throw new RemoteException(e);
-        }
-    }
+    };
 
     private class AidlDescrambler implements DescramblerWrapper {
 
         IDescrambler mAidlDescrambler;
 
-        AidlDescrambler(IDescrambler aidlDescrambler) {
-            mAidlDescrambler = aidlDescrambler;
+        AidlDescrambler(IDescrambler aidlDescrambler) throws Exception {
+            if (aidlDescrambler != null) {
+                mAidlDescrambler = aidlDescrambler;
+            } else {
+                throw new Exception("Descrambler could not be created");
+            }
         }
 
         @Override
@@ -125,47 +86,17 @@
                 @NonNull ByteBuffer dst,
                 @NonNull MediaCodec.CryptoInfo cryptoInfo)
                 throws RemoteException {
-            SubSample[] subSamples = new SubSample[cryptoInfo.numSubSamples];
-            long totalLength =
-                    getSubsampleInfo(
-                            cryptoInfo.numSubSamples,
-                            cryptoInfo.numBytesOfClearData,
-                            cryptoInfo.numBytesOfEncryptedData,
-                            subSamples);
-            SharedBuffer srcBuffer = new SharedBuffer();
-            DestinationBuffer dstBuffer;
-            srcBuffer.heapBase = new Ashmem();
-            srcBuffer.heapBase.fd = createSharedMemory(src, "Descrambler Source Buffer");
-            srcBuffer.heapBase.size = src.array().length;
-            if (dst == null) {
-                dstBuffer = DestinationBuffer.nonsecureMemory(srcBuffer);
-            } else {
-                ParcelFileDescriptor pfd =
-                        createSharedMemory(dst, "Descrambler Destination Buffer");
-                NativeHandle nh = new NativeHandle();
-                nh.fds = new ParcelFileDescriptor[] {pfd};
-                nh.ints = new int[] {1}; // Mark 1 since source buffer also uses it?
-                dstBuffer = DestinationBuffer.secureMemory(nh);
-            }
-            @ScramblingControl int control = cryptoInfo.key[0];
-
-            return mAidlDescrambler.descramble(
-                    (byte) control,
-                    subSamples,
-                    srcBuffer,
-                    src.position(),
-                    dstBuffer,
-                    dst.position());
+            throw new RemoteException("Not supported");
         }
 
         @Override
         public boolean requiresSecureDecoderComponent(@NonNull String mime) throws RemoteException {
-            return mAidlDescrambler.requiresSecureDecoderComponent(mime);
+            throw new RemoteException("Not supported");
         }
 
         @Override
         public void setMediaCasSession(byte[] sessionId) throws RemoteException {
-            mAidlDescrambler.setMediaCasSession(sessionId);
+            throw new RemoteException("Not supported");
         }
 
         @Override
@@ -178,9 +109,13 @@
 
         IDescramblerBase mHidlDescrambler;
 
-        HidlDescrambler(IDescramblerBase hidlDescrambler) {
-            mHidlDescrambler = hidlDescrambler;
-            native_setup(hidlDescrambler.asBinder());
+        HidlDescrambler(IDescramblerBase hidlDescrambler) throws Exception {
+            if (hidlDescrambler != null) {
+                mHidlDescrambler = hidlDescrambler;
+                native_setup(hidlDescrambler.asBinder());
+            } else {
+                throw new Exception("Descrambler could not be created");
+            }
         }
 
         @Override
@@ -267,10 +202,14 @@
             if (MediaCas.getService() != null) {
                 mIDescrambler =
                         new AidlDescrambler(MediaCas.getService().createDescrambler(CA_system_id));
+                mIsAidlHal = true;
             } else if (MediaCas.getServiceHidl() != null) {
                 mIDescrambler =
                         new HidlDescrambler(
                                 MediaCas.getServiceHidl().createDescrambler(CA_system_id));
+                mIsAidlHal = false;
+            } else {
+                throw new Exception("No CAS service found!");
             }
         } catch(Exception e) {
             Log.e(TAG, "Failed to create descrambler: " + e);
@@ -282,6 +221,16 @@
         }
     }
 
+    /**
+     * Check if the underlying HAL is AIDL. For CTS testing purpose.
+     *
+     * @hide
+     */
+    @TestApi
+    public boolean isAidlHal() {
+        return mIsAidlHal;
+    }
+
     IHwBinder getBinder() {
         validateInternalStates();
 
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 28496f1..c5202dc 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -108,133 +108,148 @@
     public static final int PLAYBACK_VOLUME_VARIABLE = 1;
 
     /** @hide */
-    @IntDef({
-            TYPE_UNKNOWN, TYPE_BUILTIN_SPEAKER, TYPE_WIRED_HEADSET,
-            TYPE_WIRED_HEADPHONES, TYPE_BLUETOOTH_A2DP, TYPE_HDMI, TYPE_USB_DEVICE,
-            TYPE_USB_ACCESSORY, TYPE_DOCK, TYPE_USB_HEADSET, TYPE_HEARING_AID, TYPE_BLE_HEADSET,
-            TYPE_REMOTE_TV, TYPE_REMOTE_SPEAKER, TYPE_GROUP})
+    @IntDef(
+            prefix = {"TYPE_"},
+            value = {
+                TYPE_UNKNOWN,
+                TYPE_BUILTIN_SPEAKER,
+                TYPE_WIRED_HEADSET,
+                TYPE_WIRED_HEADPHONES,
+                TYPE_BLUETOOTH_A2DP,
+                TYPE_HDMI,
+                TYPE_USB_DEVICE,
+                TYPE_USB_ACCESSORY,
+                TYPE_DOCK,
+                TYPE_USB_HEADSET,
+                TYPE_HEARING_AID,
+                TYPE_BLE_HEADSET,
+                TYPE_REMOTE_TV,
+                TYPE_REMOTE_SPEAKER,
+                TYPE_REMOTE_AUDIO_VIDEO_RECEIVER,
+                TYPE_GROUP
+            })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Type {}
 
     /**
-     * The default route type indicating the type is unknown.
+     * Indicates the route's type is unknown or undefined.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_UNKNOWN = 0;
 
     /**
-     * A route type describing the speaker system (i.e. a mono speaker or stereo speakers) built
-     * in a device.
+     * Indicates the route is the speaker system (i.e. a mono speaker or stereo speakers) built into
+     * the device.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_BUILTIN_SPEAKER = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
 
     /**
-     * A route type describing a headset, which is the combination of a headphones and microphone.
+     * Indicates the route is a headset, which is the combination of a headphones and a microphone.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_WIRED_HEADSET = AudioDeviceInfo.TYPE_WIRED_HEADSET;
 
     /**
-     * A route type describing a pair of wired headphones.
+     * Indicates the route is a pair of wired headphones.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_WIRED_HEADPHONES = AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
 
     /**
-     * A route type indicating the presentation of the media is happening
-     * on a bluetooth device such as a bluetooth speaker.
+     * Indicates the route is a bluetooth device, such as a bluetooth speaker or headphones.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_BLUETOOTH_A2DP = AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
 
     /**
-     * A route type describing an HDMI connection.
+     * Indicates the route is an HDMI connection.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_HDMI = AudioDeviceInfo.TYPE_HDMI;
 
     /**
-     * A route type describing a USB audio device.
+     * Indicates the route is a USB audio device.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_USB_DEVICE = AudioDeviceInfo.TYPE_USB_DEVICE;
 
     /**
-     * A route type describing a USB audio device in accessory mode.
+     * Indicates the route is a USB audio device in accessory mode.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_USB_ACCESSORY = AudioDeviceInfo.TYPE_USB_ACCESSORY;
 
     /**
-     * A route type describing the audio device associated with a dock.
+     * Indicates the route is the audio device associated with a dock.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_DOCK = AudioDeviceInfo.TYPE_DOCK;
 
     /**
-     * A device type describing a USB audio headset.
+     * Indicates the route is a USB audio headset.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_USB_HEADSET = AudioDeviceInfo.TYPE_USB_HEADSET;
 
     /**
-     * A route type describing a Hearing Aid.
+     * Indicates the route is a hearing aid.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_HEARING_AID = AudioDeviceInfo.TYPE_HEARING_AID;
 
     /**
-     * A route type describing a BLE HEADSET.
+     * Indicates the route is a Bluetooth Low Energy (BLE) HEADSET.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_BLE_HEADSET = AudioDeviceInfo.TYPE_BLE_HEADSET;
 
     /**
-     * A route type indicating the presentation of the media is happening on a TV.
+     * Indicates the route is a remote TV.
+     *
+     * <p>A remote device uses a routing protocol managed by the application, as opposed to the
+     * routing being done by the system.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_REMOTE_TV = 1001;
 
     /**
-     * A route type indicating the presentation of the media is happening on a speaker.
+     * Indicates the route is a remote speaker.
+     *
+     * <p>A remote device uses a routing protocol managed by the application, as opposed to the
+     * routing being done by the system.
      *
      * @see #getType
-     * @hide
      */
     public static final int TYPE_REMOTE_SPEAKER = 1002;
 
     /**
-     * A route type indicating the presentation of the media is happening on multiple devices.
+     * Indicates the route is a remote Audio/Video Receiver (AVR).
+     *
+     * <p>A remote device uses a routing protocol managed by the application, as opposed to the
+     * routing being done by the system.
      *
      * @see #getType
-     * @hide
+     */
+    public static final int TYPE_REMOTE_AUDIO_VIDEO_RECEIVER = 1003;
+
+    /**
+     * Indicates the route is a group of devices.
+     *
+     * @see #getType
      */
     public static final int TYPE_GROUP = 2000;
 
@@ -436,16 +451,23 @@
     }
 
     /**
-     * Gets the type of this route.
+     * Returns the type of this route.
      *
-     * @return The type of this route:
-     * {@link #TYPE_UNKNOWN},
-     * {@link #TYPE_BUILTIN_SPEAKER}, {@link #TYPE_WIRED_HEADSET}, {@link #TYPE_WIRED_HEADPHONES},
-     * {@link #TYPE_BLUETOOTH_A2DP}, {@link #TYPE_HDMI}, {@link #TYPE_DOCK},
-     * {@Link #TYPE_USB_DEVICE}, {@link #TYPE_USB_ACCESSORY}, {@link #TYPE_USB_HEADSET}
-     * {@link #TYPE_HEARING_AID},
-     * {@link #TYPE_REMOTE_TV}, {@link #TYPE_REMOTE_SPEAKER}, {@link #TYPE_GROUP}.
-     * @hide
+     * @see #TYPE_UNKNOWN
+     * @see #TYPE_BUILTIN_SPEAKER
+     * @see #TYPE_WIRED_HEADSET
+     * @see #TYPE_WIRED_HEADPHONES
+     * @see #TYPE_BLUETOOTH_A2DP
+     * @see #TYPE_HDMI
+     * @see #TYPE_DOCK
+     * @see #TYPE_USB_DEVICE
+     * @see #TYPE_USB_ACCESSORY
+     * @see #TYPE_USB_HEADSET
+     * @see #TYPE_HEARING_AID
+     * @see #TYPE_REMOTE_TV
+     * @see #TYPE_REMOTE_SPEAKER
+     * @see #TYPE_REMOTE_AUDIO_VIDEO_RECEIVER
+     * @see #TYPE_GROUP
      */
     @Type
     public int getType() {
@@ -657,6 +679,7 @@
         pw.println(indent + "mId=" + mId);
         pw.println(indent + "mName=" + mName);
         pw.println(indent + "mFeatures=" + mFeatures);
+        pw.println(indent + "mType=" + getDeviceTypeString(mType));
         pw.println(indent + "mIsSystem=" + mIsSystem);
         pw.println(indent + "mIconUri=" + mIconUri);
         pw.println(indent + "mDescription=" + mDescription);
@@ -787,6 +810,42 @@
         dest.writeString8Array(mAllowedPackages.toArray(new String[0]));
     }
 
+    private static String getDeviceTypeString(@Type int deviceType) {
+        switch (deviceType) {
+            case TYPE_BUILTIN_SPEAKER:
+                return "BUILTIN_SPEAKER";
+            case TYPE_WIRED_HEADSET:
+                return "WIRED_HEADSET";
+            case TYPE_WIRED_HEADPHONES:
+                return "WIRED_HEADPHONES";
+            case TYPE_BLUETOOTH_A2DP:
+                return "BLUETOOTH_A2DP";
+            case TYPE_HDMI:
+                return "HDMI";
+            case TYPE_DOCK:
+                return "DOCK";
+            case TYPE_USB_DEVICE:
+                return "USB_DEVICE";
+            case TYPE_USB_ACCESSORY:
+                return "USB_ACCESSORY";
+            case TYPE_USB_HEADSET:
+                return "USB_HEADSET";
+            case TYPE_HEARING_AID:
+                return "HEARING_AID";
+            case TYPE_REMOTE_TV:
+                return "REMOTE_TV";
+            case TYPE_REMOTE_SPEAKER:
+                return "REMOTE_SPEAKER";
+            case TYPE_REMOTE_AUDIO_VIDEO_RECEIVER:
+                return "REMOTE_AUDIO_VIDEO_RECEIVER";
+            case TYPE_GROUP:
+                return "GROUP";
+            case TYPE_UNKNOWN:
+            default:
+                return TextUtils.formatSimple("UNKNOWN(%d)", deviceType);
+        }
+    }
+
     /**
      * Builder for {@link MediaRoute2Info media route info}.
      */
@@ -932,7 +991,8 @@
 
         /**
          * Sets the route's type.
-         * @hide
+         *
+         * @see MediaRoute2Info#getType()
          */
         @NonNull
         public Builder setType(@Type int type) {
diff --git a/media/java/android/media/RouteListingPreference.java b/media/java/android/media/RouteListingPreference.java
index a26249a..ee1f203 100644
--- a/media/java/android/media/RouteListingPreference.java
+++ b/media/java/android/media/RouteListingPreference.java
@@ -180,6 +180,7 @@
         /** Creates a new instance with default values (documented in the setters). */
         public Builder() {
             mItems = List.of();
+            mUseSystemOrdering = true;
         }
 
         /**
@@ -190,7 +191,6 @@
         @NonNull
         public Builder setItems(@NonNull List<Item> items) {
             mItems = List.copyOf(Objects.requireNonNull(items));
-            mUseSystemOrdering = true;
             return this;
         }
 
@@ -259,7 +259,7 @@
         @IntDef(
                 flag = true,
                 prefix = {"FLAG_"},
-                value = {FLAG_ONGOING_SESSION, FLAG_SUGGESTED_ROUTE})
+                value = {FLAG_ONGOING_SESSION, FLAG_ONGOING_SESSION_MANAGED, FLAG_SUGGESTED})
         public @interface Flags {}
 
         /**
@@ -269,6 +269,22 @@
         public static final int FLAG_ONGOING_SESSION = 1;
 
         /**
+         * Signals that the ongoing session on the corresponding route is managed by the current
+         * user of the app.
+         *
+         * <p>The system can use this flag to provide visual indication that the route is not only
+         * hosting a session, but also that the user has ownership over said session.
+         *
+         * <p>This flag is ignored if {@link #FLAG_ONGOING_SESSION} is not set, or if the
+         * corresponding route is not currently selected.
+         *
+         * <p>This flag does not affect volume adjustment (see {@link VolumeProvider}, and {@link
+         * MediaRoute2Info#getVolumeHandling()}), or any aspect other than the visual representation
+         * of the corresponding item.
+         */
+        public static final int FLAG_ONGOING_SESSION_MANAGED = 1 << 1;
+
+        /**
          * The corresponding route is specially likely to be selected by the user.
          *
          * <p>A UI reflecting this preference may reserve a specific space for suggested routes,
@@ -276,7 +292,7 @@
          * number supported by the UI, the routes listed first in {@link
          * RouteListingPreference#getItems()} will take priority.
          */
-        public static final int FLAG_SUGGESTED_ROUTE = 1 << 1;
+        public static final int FLAG_SUGGESTED = 1 << 2;
 
         /** @hide */
         @Retention(RetentionPolicy.SOURCE)
@@ -284,9 +300,13 @@
                 prefix = {"SUBTEXT_"},
                 value = {
                     SUBTEXT_NONE,
+                    SUBTEXT_ERROR_UNKNOWN,
                     SUBTEXT_SUBSCRIPTION_REQUIRED,
                     SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED,
                     SUBTEXT_AD_ROUTING_DISALLOWED,
+                    SUBTEXT_DEVICE_LOW_POWER,
+                    SUBTEXT_UNAUTHORIZED,
+                    SUBTEXT_TRACK_UNSUPPORTED,
                     SUBTEXT_CUSTOM
                 })
         public @interface SubText {}
@@ -294,20 +314,40 @@
         /** The corresponding route has no associated subtext. */
         public static final int SUBTEXT_NONE = 0;
         /**
+         * The corresponding route's subtext must indicate that it is not available because of an
+         * unknown error.
+         */
+        public static final int SUBTEXT_ERROR_UNKNOWN = 1;
+        /**
          * The corresponding route's subtext must indicate that it requires a special subscription
          * in order to be available for routing.
          */
-        public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 1;
+        public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 2;
         /**
          * The corresponding route's subtext must indicate that downloaded content cannot be routed
          * to it.
          */
-        public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 2;
+        public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 3;
         /**
          * The corresponding route's subtext must indicate that it is not available because an ad is
          * in progress.
          */
-        public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 3;
+        public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 4;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because the
+         * device is in low-power mode.
+         */
+        public static final int SUBTEXT_DEVICE_LOW_POWER = 5;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because the user
+         * is not authorized to route to it.
+         */
+        public static final int SUBTEXT_UNAUTHORIZED = 6;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because the
+         * device does not support the current media track.
+         */
+        public static final int SUBTEXT_TRACK_UNSUPPORTED = 7;
         /**
          * The corresponding route's subtext must be obtained from {@link
          * #getCustomSubtextMessage()}.
@@ -345,6 +385,7 @@
             mFlags = builder.mFlags;
             mSubText = builder.mSubText;
             mCustomSubtextMessage = builder.mCustomSubtextMessage;
+            validateCustomMessageSubtext();
         }
 
         private Item(Parcel in) {
@@ -354,6 +395,7 @@
             mFlags = in.readInt();
             mSubText = in.readInt();
             mCustomSubtextMessage = in.readCharSequence();
+            validateCustomMessageSubtext();
         }
 
         /**
@@ -381,7 +423,8 @@
          * Returns the flags associated to the route that corresponds to this item.
          *
          * @see #FLAG_ONGOING_SESSION
-         * @see #FLAG_SUGGESTED_ROUTE
+         * @see #FLAG_ONGOING_SESSION_MANAGED
+         * @see #FLAG_SUGGESTED
          */
         @Flags
         public int getFlags() {
@@ -397,10 +440,14 @@
          * <p>If this method returns {@link #SUBTEXT_CUSTOM}, then the subtext is obtained form
          * {@link #getCustomSubtextMessage()}.
          *
-         * @see #SUBTEXT_NONE
-         * @see #SUBTEXT_SUBSCRIPTION_REQUIRED
-         * @see #SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED
-         * @see #SUBTEXT_AD_ROUTING_DISALLOWED
+         * @see #SUBTEXT_NONE,
+         * @see #SUBTEXT_ERROR_UNKNOWN,
+         * @see #SUBTEXT_SUBSCRIPTION_REQUIRED,
+         * @see #SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED,
+         * @see #SUBTEXT_AD_ROUTING_DISALLOWED,
+         * @see #SUBTEXT_DEVICE_LOW_POWER,
+         * @see #SUBTEXT_UNAUTHORIZED ,
+         * @see #SUBTEXT_TRACK_UNSUPPORTED,
          * @see #SUBTEXT_CUSTOM
          */
         @SubText
@@ -467,6 +514,16 @@
                     mRouteId, mSelectionBehavior, mFlags, mSubText, mCustomSubtextMessage);
         }
 
+        // Internal methods.
+
+        private void validateCustomMessageSubtext() {
+            Preconditions.checkArgument(
+                    mSubText != SUBTEXT_CUSTOM || mCustomSubtextMessage != null,
+                    "The custom subtext message cannot be null if subtext is SUBTEXT_CUSTOM.");
+        }
+
+        // Internal classes.
+
         /** Builder for {@link Item}. */
         public static final class Builder {
 
diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java
index ee82588..244292d 100644
--- a/media/java/android/media/midi/MidiManager.java
+++ b/media/java/android/media/midi/MidiManager.java
@@ -228,7 +228,7 @@
      * Registers a callback to receive notifications when MIDI 1.0 devices are added and removed.
      * These are devices that do not default to Universal MIDI Packets. To register for a callback
      * for those, call {@link #registerDeviceCallback} instead.
-
+     *
      * The {@link  DeviceCallback#onDeviceStatusChanged} method will be called immediately
      * for any devices that have open ports. This allows applications to know which input
      * ports are already in use and, therefore, unavailable.
@@ -289,7 +289,7 @@
 
     /**
      * Unregisters a {@link DeviceCallback}.
-      *
+     *
      * @param callback a {@link DeviceCallback} to unregister
      */
     public void unregisterDeviceCallback(DeviceCallback callback) {
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 985ac3c..9e9012e 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -253,23 +253,19 @@
         public void onStop() { }
 
         /**
-         * Indicates the width and height of the captured region in pixels. Called immediately after
-         * capture begins to provide the app with accurate sizing for the stream. Also called
-         * when the region captured in this MediaProjection session is resized.
+         * Invoked immediately after capture begins or when the size of the captured region changes,
+         * providing the accurate sizing for the streamed capture.
          * <p>
          * The given width and height, in pixels, corresponds to the same width and height that
-         * would be returned from {@link android.view.WindowMetrics#getBounds()}
+         * would be returned from {@link android.view.WindowMetrics#getBounds()} of the captured
+         * region.
          * </p>
          * <p>
-         * Without the application resizing the {@link VirtualDisplay} (returned from
-         * {@code MediaProjection#createVirtualDisplay}) and output {@link Surface} (provided
-         * to {@code MediaProjection#createVirtualDisplay}), the captured stream will have
-         * letterboxing (black bars) around the recorded content to make up for the
-         * difference in aspect ratio.
-         * </p>
-         * <p>
-         * The application can prevent the letterboxing by overriding this method, and
-         * updating the size of both the {@link VirtualDisplay} and output {@link Surface}:
+         * If the recorded content has a different aspect ratio from either the
+         * {@link VirtualDisplay} or output {@link Surface}, the captured stream has letterboxing
+         * (black bars) around the recorded content. The application can avoid the letterboxing
+         * around the recorded content by updating the size of both the {@link VirtualDisplay} and
+         * output {@link Surface}:
          * </p>
          *
          * <pre>
@@ -293,27 +289,29 @@
         public void onCapturedContentResize(int width, int height) { }
 
         /**
-         * Indicates the visibility of the captured region has changed. Called immediately after
-         * capture begins with the initial visibility state, and when visibility changes. Provides
-         * the app with accurate state for presenting its own UI. The application can take advantage
-         * of this by showing or hiding the captured content, based on if the captured region is
-         * currently visible to the user.
+         * Invoked immediately after capture begins or when the visibility of the captured region
+         * changes, providing the current visibility of the captured region.
+         * <p>
+         * Applications can take advantage of this callback by showing or hiding the captured
+         * content from the output {@link Surface}, based on if the captured region is currently
+         * visible to the user.
+         * </p>
          * <p>
          * For example, if the user elected to capture a single app (from the activity shown from
-         * {@link MediaProjectionManager#createScreenCaptureIntent()}), the callback may be
-         * triggered for the following reasons:
+         * {@link MediaProjectionManager#createScreenCaptureIntent()}), the following scenarios
+         * trigger the callback:
          * <ul>
          *     <li>
-         *         The captured region may become visible ({@code isVisible} with value
-         *         {@code true}), because the captured app is at least partially visible. This may
-         *         happen if the captured app was previously covered by another app. The other app
-         *         moves to show at least some portion of the captured app.
+         *         The captured region is visible ({@code isVisible} with value {@code true}),
+         *         because the captured app is at least partially visible. This may happen if the
+         *         user moves the covering app to show at least some portion of the captured app
+         *         (e.g. the user has multiple apps visible in a multi-window mode such as split
+         *         screen).
          *     </li>
          *     <li>
-         *         The captured region may become invisible ({@code isVisible} with value
-         *         {@code false}) if it is entirely hidden. This may happen if the captured app is
-         *         entirely covered by another app, or the user navigates away from the captured
-         *         app.
+         *         The captured region is invisible ({@code isVisible} with value {@code false}) if
+         *         it is entirely hidden. This may happen if another app entirely covers the
+         *         captured app, or the user navigates away from the captured app.
          *     </li>
          * </ul>
          * </p>
diff --git a/media/java/android/media/projection/TEST_MAPPING b/media/java/android/media/projection/TEST_MAPPING
index a792498..4324930 100644
--- a/media/java/android/media/projection/TEST_MAPPING
+++ b/media/java/android/media/projection/TEST_MAPPING
@@ -13,6 +13,20 @@
           "exclude-annotation": "org.junit.Ignore"
         }
       ]
+    },
+    {
+      "name": "CtsMediaProjectionTestCases",
+      "options": [
+        {
+          "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
     }
   ]
 }
diff --git a/media/java/android/media/tv/AdBuffer.java b/media/java/android/media/tv/AdBuffer.java
index ed44508..230d763 100644
--- a/media/java/android/media/tv/AdBuffer.java
+++ b/media/java/android/media/tv/AdBuffer.java
@@ -24,9 +24,8 @@
 
 /**
  * Buffer for advertisement data.
- * @hide
  */
-public class AdBuffer implements Parcelable {
+public final class AdBuffer implements Parcelable {
     private final int mId;
     @NonNull
     private final String mMimeType;
@@ -60,6 +59,8 @@
 
     /**
      * Gets corresponding AD request ID.
+     *
+     * @return The ID of the ad request
      */
     public int getId() {
         return mId;
@@ -67,6 +68,8 @@
 
     /**
      * Gets the mime type of the data.
+     *
+     * @return The mime type of the data.
      */
     @NonNull
     public String getMimeType() {
@@ -74,7 +77,17 @@
     }
 
     /**
-     * Gets the shared memory which stores the data.
+     * Gets the {@link SharedMemory} which stores the data.
+     *
+     * <p> Information on how the data in this buffer is formatted can be found using
+     * {@link AdRequest#getMetadata()}
+     * <p> This data lives in a {@link SharedMemory} instance because of the
+     * potentially large amount of data needed to store the ad. This optimizes the
+     * data communication between the ad data source and the service responsible for
+     * its display.
+     *
+     * @see SharedMemory#create(String, int)
+     * @return The {@link SharedMemory} that stores the data for this ad buffer.
      */
     @NonNull
     public SharedMemory getSharedMemory() {
@@ -82,28 +95,38 @@
     }
 
     /**
-     * Gets the offset of the buffer.
+     * Gets the offset into the shared memory to begin mapping.
+     *
+     * @see SharedMemory#map(int, int, int)
+     * @return The offset of this ad buffer in the shared memory in bytes.
      */
     public int getOffset() {
         return mOffset;
     }
 
     /**
-     * Gets the data length.
+     * Gets the data length of this ad buffer.
+     *
+     * @return The data length of this ad buffer in bytes.
      */
     public int getLength() {
         return mLength;
     }
 
     /**
-     * Gets the presentation time in microseconds.
+     * Gets the presentation time.
+     *
+     * @return The presentation time in microseconds.
      */
     public long getPresentationTimeUs() {
         return mPresentationTimeUs;
     }
 
     /**
-     * Gets the flags.
+     * Gets the buffer flags for this ad buffer.
+     *
+     * @see android.media.MediaCodec
+     * @return The buffer flags for this ad buffer.
      */
     @BufferFlag
     public int getFlags() {
diff --git a/media/java/android/media/tv/AdRequest.java b/media/java/android/media/tv/AdRequest.java
index 60dfc5e..d8cddfc 100644
--- a/media/java/android/media/tv/AdRequest.java
+++ b/media/java/android/media/tv/AdRequest.java
@@ -79,7 +79,6 @@
                 mediaFileType, metadata);
     }
 
-    /** @hide */
     public AdRequest(int id, @RequestType int requestType, @Nullable Uri uri, long startTime,
             long stopTime, long echoInterval, @NonNull Bundle metadata) {
         this(id, requestType, null, uri, startTime, stopTime, echoInterval, null, metadata);
@@ -153,7 +152,6 @@
      *
      * @return The URI of the AD media. Can be {@code null} for {@link #REQUEST_TYPE_STOP} or a file
      *         descriptor is used.
-     * @hide
      */
     @Nullable
     public Uri getUri() {
diff --git a/media/java/android/media/tv/AdResponse.java b/media/java/android/media/tv/AdResponse.java
index a15e8c1..7ec4eb2 100644
--- a/media/java/android/media/tv/AdResponse.java
+++ b/media/java/android/media/tv/AdResponse.java
@@ -43,7 +43,6 @@
     public static final int RESPONSE_TYPE_FINISHED = 2;
     public static final int RESPONSE_TYPE_STOPPED = 3;
     public static final int RESPONSE_TYPE_ERROR = 4;
-    /** @hide */
     public static final int RESPONSE_TYPE_BUFFERING = 5;
 
     public static final @NonNull Parcelable.Creator<AdResponse> CREATOR =
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 46573f2..465b617 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -77,6 +77,7 @@
     private static final int DO_NOTIFY_AD_BUFFER = 28;
     private static final int DO_SELECT_AUDIO_PRESENTATION = 29;
     private static final int DO_TIME_SHIFT_SET_MODE = 30;
+    private static final int DO_SET_TV_MESSAGE_ENABLED = 31;
 
     private final boolean mIsRecordingSession;
     private final HandlerCaller mCaller;
@@ -263,6 +264,11 @@
                 mTvInputSessionImpl.setInteractiveAppNotificationEnabled((Boolean) msg.obj);
                 break;
             }
+            case DO_SET_TV_MESSAGE_ENABLED: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                mTvInputSessionImpl.setTvMessageEnabled((String) args.arg1, (Boolean) args.arg2);
+                break;
+            }
             case DO_REQUEST_AD: {
                 mTvInputSessionImpl.requestAd((AdRequest) msg.obj);
                 break;
diff --git a/media/java/android/media/tv/TableRequest.java b/media/java/android/media/tv/TableRequest.java
index a9ea6d3..d9587f6 100644
--- a/media/java/android/media/tv/TableRequest.java
+++ b/media/java/android/media/tv/TableRequest.java
@@ -33,7 +33,8 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({TABLE_NAME_PAT, TABLE_NAME_PMT, TABLE_NAME_CAT})
+    @IntDef({TABLE_NAME_PAT, TABLE_NAME_PMT, TABLE_NAME_CAT, TABLE_NAME_NIT, TABLE_NAME_BAT,
+            TABLE_NAME_SDT, TABLE_NAME_EIT, TABLE_NAME_TDT, TABLE_NAME_TOT, TABLE_NAME_SIT})
     public @interface TableName {}
 
     /** Program Association Table */
@@ -42,42 +43,34 @@
     public static final int TABLE_NAME_PMT = 1;
     /**
      * Conditional Access Table
-     * @hide
      */
     public static final int TABLE_NAME_CAT = 2;
     /**
      * Network Information Table
-     * @hide
      */
     public static final int TABLE_NAME_NIT = 3;
     /**
      * Bouquet Association Table
-     * @hide
      */
     public static final int TABLE_NAME_BAT = 4;
     /**
      * Service Description Table
-     * @hide
      */
     public static final int TABLE_NAME_SDT = 5;
     /**
      * Event Information Table
-     * @hide
      */
     public static final int TABLE_NAME_EIT = 6;
     /**
      * Time and Date Table
-     * @hide
      */
     public static final int TABLE_NAME_TDT = 7;
     /**
      * Time Offset Table
-     * @hide
      */
     public static final int TABLE_NAME_TOT = 8;
     /**
      * Selection Information Table
-     * @hide
      */
     public static final int TABLE_NAME_SIT = 9;
 
diff --git a/media/java/android/media/tv/TableResponse.java b/media/java/android/media/tv/TableResponse.java
index 1c314b0..fb4e99c 100644
--- a/media/java/android/media/tv/TableResponse.java
+++ b/media/java/android/media/tv/TableResponse.java
@@ -54,6 +54,17 @@
         return new TableResponse(in);
     }
 
+    /**
+     * Constructs a TableResponse with a table URI.
+     *
+     * @param requestId The ID is used to associate the response with the request.
+     * @param sequence The sequence number which indicates the order of related responses.
+     * @param responseResult The result for the response. It's one of {@link #RESPONSE_RESULT_OK},
+     *                       {@link #RESPONSE_RESULT_CANCEL}, {@link #RESPONSE_RESULT_ERROR}.
+     * @param tableUri The URI of the table in the database.
+     * @param version The version number of requested table.
+     * @param size The Size number of table in bytes.
+     */
     public TableResponse(int requestId, int sequence, @ResponseResult int responseResult,
             @Nullable Uri tableUri, int version, int size) {
         super(RESPONSE_TYPE, requestId, sequence, responseResult);
@@ -64,7 +75,19 @@
         mTableSharedMemory = null;
     }
 
-    /** @hide */
+    /**
+     * Constructs a TableResponse with a table URI.
+     *
+     * @param requestId The ID is used to associate the response with the request.
+     * @param sequence The sequence number which indicates the order of related responses.
+     * @param responseResult The result for the response. It's one of {@link #RESPONSE_RESULT_OK},
+     *                       {@link #RESPONSE_RESULT_CANCEL}, {@link #RESPONSE_RESULT_ERROR}.
+     * @param tableByteArray The byte array which stores the table in bytes. The structure and
+     *                       syntax of the table depends on the table name in
+     *                       {@link TableRequest#getTableName()} and the corresponding standard.
+     * @param version The version number of requested table.
+     * @param size The Size number of table in bytes.
+     */
     public TableResponse(int requestId, int sequence, @ResponseResult int responseResult,
             @NonNull byte[] tableByteArray, int version, int size) {
         super(RESPONSE_TYPE, requestId, sequence, responseResult);
@@ -75,7 +98,21 @@
         mTableSharedMemory = null;
     }
 
-    /** @hide */
+    /**
+     * Constructs a TableResponse with a table URI.
+     *
+     * @param requestId The ID is used to associate the response with the request.
+     * @param sequence The sequence number which indicates the order of related responses.
+     * @param responseResult The result for the response. It's one of {@link #RESPONSE_RESULT_OK},
+     *                       {@link #RESPONSE_RESULT_CANCEL}, {@link #RESPONSE_RESULT_ERROR}.
+     * @param tableSharedMemory The shared memory which stores the table. The table size can be
+     *                          large so using a shared memory optimizes the data
+     *                          communication between the table data source and the receiver. The
+     *                          structure syntax of the table depends on the table name in
+     *                          {@link TableRequest#getTableName()} and the corresponding standard.
+     * @param version The version number of requested table.
+     * @param size The Size number of table in bytes.
+     */
     public TableResponse(int requestId, int sequence, @ResponseResult int responseResult,
             @NonNull SharedMemory tableSharedMemory, int version, int size) {
         super(RESPONSE_TYPE, requestId, sequence, responseResult);
@@ -115,7 +152,6 @@
      *
      * @return the table data as a byte array, or {@code null} if the data is not stored as a byte
      *         array.
-     * @hide
      */
     @Nullable
     public byte[] getTableByteArray() {
@@ -125,9 +161,14 @@
     /**
      * Gets the data of the table as a {@link SharedMemory} object.
      *
+     * <p> This data lives in a {@link SharedMemory} instance because of the potentially large
+     * amount of data needed to store the table. This optimizes the data communication between the
+     * table data source and the receiver.
+     *
      * @return the table data as a {@link SharedMemory} object, or {@code null} if the data is not
      *         stored in shared memory.
-     * @hide
+     *
+     * @see SharedMemory#map(int, int, int)
      */
     @Nullable
     public SharedMemory getTableSharedMemory() {
diff --git a/media/java/android/media/tv/TimelineRequest.java b/media/java/android/media/tv/TimelineRequest.java
index d04c58a..77613dc 100644
--- a/media/java/android/media/tv/TimelineRequest.java
+++ b/media/java/android/media/tv/TimelineRequest.java
@@ -17,6 +17,7 @@
 package android.media.tv;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -54,7 +55,6 @@
         mSelector = null;
     }
 
-    /** @hide */
     public TimelineRequest(int requestId, @RequestOption int option, int intervalMillis,
             @NonNull String selector) {
         super(REQUEST_TYPE, requestId, option);
@@ -81,8 +81,8 @@
      * {@code urn:dvb:css:timeline:pts} is a selector in DVB standard.
      *
      * @return the selector if it's set; {@code null} otherwise.
-     * @hide
      */
+    @Nullable
     public String getSelector() {
         return mSelector;
     }
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 67d28d0..de1b164 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -133,18 +133,15 @@
             VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING, VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN})
     public @interface VideoUnavailableReason {}
 
-    /**
-     * @hide
-     */
+    /** Indicates that this TV message contains watermarking data */
     public static final String TV_MESSAGE_TYPE_WATERMARK = "Watermark";
-    /**
-     * @hide
-     */
-    public static final String TV_MESSAGE_TYPE_ATSC_CC = "ATSC_CC";
+
+    /** Indicates that this TV message contains Closed Captioning data */
+    public static final String TV_MESSAGE_TYPE_CLOSED_CAPTION = "CC";
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @StringDef({TV_MESSAGE_TYPE_WATERMARK, TV_MESSAGE_TYPE_ATSC_CC})
+    @StringDef({TV_MESSAGE_TYPE_WATERMARK, TV_MESSAGE_TYPE_CLOSED_CAPTION})
     public @interface TvMessageType {}
 
     static final int VIDEO_UNAVAILABLE_REASON_START = 0;
@@ -792,11 +789,11 @@
         }
 
         /**
-         * This is called when the session receives a new Tv Message
+         * This is called when the session receives a new TV Message
          *
-         * @param type the type of {@link TvMessageType}
-         * @param data the raw data of the message
-         * @hide
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param type The type of message received, such as {@link #TV_MESSAGE_TYPE_WATERMARK}
+         * @param data The raw data of the message
          */
         public void onTvMessage(Session session, @TvInputManager.TvMessageType String type,
                 Bundle data) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 7a4d988d..000ed3b 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -1005,9 +1005,10 @@
 
         /**
          * Notifies the advertisement buffer is consumed.
-         * @hide
+         *
+         * @param buffer the {@link AdBuffer} that was consumed.
          */
-        public void notifyAdBufferConsumed(AdBuffer buffer) {
+        public void notifyAdBufferConsumed(@NonNull AdBuffer buffer) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
                 @Override
@@ -1024,6 +1025,31 @@
             });
         }
 
+        /**
+         * Sends the raw data from the received TV message as well as the type of message received.
+         *
+         * @param type The of message that was sent, such as
+         * {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
+         * @param data The data sent with the message.
+         */
+        public void notifyTvMessage(@NonNull @TvInputManager.TvMessageType String type,
+                @NonNull Bundle data) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTvMessage");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTvMessage(type, data);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTvMessage", e);
+                    }
+                }
+            });
+        }
+
         private void notifyTimeShiftStartPositionChanged(final long timeMs) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
@@ -1320,10 +1346,11 @@
         }
 
         /**
-         * Called when advertisement buffer is ready.
-         * @hide
+         * Called when an advertisement buffer is ready for playback.
+         *
+         * @param buffer The {@link AdBuffer} that became ready for playback.
          */
-        public void onAdBuffer(AdBuffer buffer) {
+        public void onAdBuffer(@NonNull AdBuffer buffer) {
         }
 
         /**
@@ -1456,6 +1483,17 @@
         }
 
         /**
+         * Called when the application enables or disables the detection of the specified message
+         * type.
+         * @param type The {@link TvInputManager.TvMessageType} of message that was sent.
+         * @param enabled {@code true} if TV message detection is enabled,
+         *                {@code false} otherwise.
+         */
+        public void onSetTvMessageEnabled(@NonNull @TvInputManager.TvMessageType String type,
+                boolean enabled){
+        }
+
+        /**
          * Called when the application requests to play a given recorded TV program.
          *
          * @param recordedProgramUri The URI of a recorded TV program.
@@ -1807,6 +1845,13 @@
         }
 
         /**
+         * Calls {@link #onSetTvMessageEnabled(String, boolean)}.
+         */
+        void setTvMessageEnabled(String type, boolean enabled) {
+            onSetTvMessageEnabled(type, enabled);
+        }
+
+        /**
          * Calls {@link #onAppPrivateCommand}.
          */
         void appPrivateCommand(String action, Bundle data) {
@@ -2276,27 +2321,6 @@
         }
 
         /**
-         * Informs the application of the raw data from the TV message.
-         * @param type The {@link TvInputManager.TvMessageType} of message that was sent.
-         * @param data The data sent with the message.
-         * @hide
-         */
-        public void notifyTvMessage(@TvInputManager.TvMessageType String type, Bundle data) {
-        }
-
-        /**
-         * Called when the application enables or disables the detection of the specified message
-         * type.
-         * @param type The {@link TvInputManager.TvMessageType} of message that was sent.
-         * @param enabled {@code true} if you want to enable TV message detecting
-         *                {@code false} otherwise.
-         * @hide
-         */
-        public void onSetTvMessageEnabled(@TvInputManager.TvMessageType String type,
-                boolean enabled) {
-        }
-
-        /**
          * Called when the application requests to tune to a given channel for TV program recording.
          *
          * <p>The application may call this method before starting or after stopping recording, but
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index b1356f5..cdeef2b 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -575,7 +575,7 @@
                 Log.w(TAG, "onError - session not created");
                 return;
             }
-            if (mCallback == null) {
+            if (mCallback != null) {
                 mCallback.onError(error);
             }
             if (mTvIAppView != null) {
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 3864983..372fa6d 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -722,14 +722,14 @@
     }
 
     /**
-     * Enables or disables TV message detecting in the streams of bound TV input.
+     * Enables or disables TV message detection in the stream of the bound TV input.
      *
      * @param type The type of {@link android.media.tv.TvInputManager.TvMessageType}
-     * @param enabled {@code true} if you want to enable TV message detecting
+     * @param enabled {@code true} if you want to enable TV message detection
      *                {@code false} otherwise.
-     * @hide
      */
-    public void setTvMessageEnabled(@TvInputManager.TvMessageType String type, boolean enabled) {
+    public void setTvMessageEnabled(@NonNull @TvInputManager.TvMessageType String type,
+            boolean enabled) {
     }
 
     @Override
@@ -1233,14 +1233,14 @@
         }
 
         /**
-         * This is called when the session has been tuned to the given channel.
+         * This is called when a new TV Message has been received.
          *
+         * @param inputId The ID of the TV input bound to this view.
          * @param type The type of {@link android.media.tv.TvInputManager.TvMessageType}
          * @param data The raw data of the message
-         * @hide
          */
-        public void onTvMessage(@NonNull String inputId, @TvInputManager.TvMessageType String type,
-                Bundle data) {
+        public void onTvMessage(@NonNull String inputId,
+                @NonNull @TvInputManager.TvMessageType String type, @NonNull Bundle data) {
         }
     }
 
diff --git a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java
index fa339ce..f009cea 100644
--- a/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java
+++ b/media/java/android/media/tv/interactive/ITvInteractiveAppSessionWrapper.java
@@ -521,7 +521,7 @@
     @Override
     public void notifyTvMessage(String type, Bundle data) {
         mCaller.executeOrSendMessage(
-                mCaller.obtainMessageOO(DO_NOTIFY_TRACK_SELECTED, type, data));
+                mCaller.obtainMessageOO(DO_NOTIFY_TV_MESSAGE, type, data));
     }
 
     @Override
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index cdaa3e5..80b6e21 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -145,30 +145,29 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = "PLAYBACK_COMMAND_STOP_MODE_", value = {
-            PLAYBACK_COMMAND_STOP_MODE_BLANK,
-            PLAYBACK_COMMAND_STOP_MODE_FREEZE
+    @IntDef(prefix = "COMMAND_PARAMETER_VALUE_STOP_MODE_", value = {
+            COMMAND_PARAMETER_VALUE_STOP_MODE_BLANK,
+            COMMAND_PARAMETER_VALUE_STOP_MODE_FREEZE
     })
     public @interface PlaybackCommandStopMode {}
 
     /**
      * Playback command stop mode: show a blank screen.
-     * @hide
+     * @see #PLAYBACK_COMMAND_TYPE_STOP
      */
-    public static final int PLAYBACK_COMMAND_STOP_MODE_BLANK = 1;
+    public static final int COMMAND_PARAMETER_VALUE_STOP_MODE_BLANK = 1;
 
     /**
      * Playback command stop mode: freeze the video.
-     * @hide
+     * @see #PLAYBACK_COMMAND_TYPE_STOP
      */
-    public static final int PLAYBACK_COMMAND_STOP_MODE_FREEZE = 2;
+    public static final int COMMAND_PARAMETER_VALUE_STOP_MODE_FREEZE = 2;
 
     /**
      * Playback command parameter: stop mode.
      * <p>Type: int
      *
      * @see #PLAYBACK_COMMAND_TYPE_STOP
-     * @hide
      */
     public static final String COMMAND_PARAMETER_KEY_STOP_MODE = "command_stop_mode";
 
@@ -550,7 +549,8 @@
 
         /**
          * Receives current video bounds.
-         * @hide
+         *
+         * @param bounds the rectangle area for rendering the current video.
          */
         public void onCurrentVideoBounds(@NonNull Rect bounds) {
         }
@@ -896,17 +896,21 @@
 
         /**
          * Called when an advertisement buffer is consumed.
-         * @hide
+         *
+         * @param buffer The {@link AdBuffer} that was consumed.
          */
-        public void onAdBufferConsumed(AdBuffer buffer) {
-
+        public void onAdBufferConsumed(@NonNull AdBuffer buffer) {
         }
 
         /**
-         * Called when a tv message is received
-         * @hide
+         * Called when a TV message is received
+         *
+         * @param type The type of message received, such as
+         * {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
+         * @param data The raw data of the message
          */
-        public void onTvMessage(@NonNull String type, @NonNull Bundle data) {
+        public void onTvMessage(@NonNull @TvInputManager.TvMessageType String type,
+                @NonNull Bundle data) {
         }
 
         @Override
@@ -1131,7 +1135,6 @@
 
         /**
          * Requests the bounds of the current video.
-         * @hide
          */
         @CallSuper
         public void requestCurrentVideoBounds() {
@@ -1919,10 +1922,11 @@
 
         /**
          * Notifies when the advertisement buffer is filled and ready to be read.
-         * @hide
+         *
+         * @param buffer The {@link AdBuffer} to be received
          */
         @CallSuper
-        public void notifyAdBuffer(AdBuffer buffer) {
+        public void notifyAdBuffer(@NonNull AdBuffer buffer) {
             executeOrPostRunnableOnMainThread(new Runnable() {
                 @MainThread
                 @Override
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
index 0b44a89..2c40f39 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
@@ -516,7 +516,8 @@
 
     /**
      * Sends current video bounds to related TV interactive app.
-     * @hide
+     *
+     * @param bounds the rectangle area for rendering the current video.
      */
     public void sendCurrentVideoBounds(@NonNull Rect bounds) {
         if (DEBUG) {
@@ -918,6 +919,25 @@
         }
     }
 
+    /**
+     * This is called to notify the corresponding interactive app service when a new TV message
+     * is received.
+     *
+     * @param type The type of message received, such as
+     * {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
+     * @param data The raw data of the message
+     */
+    public void notifyTvMessage(@NonNull @TvInputManager.TvMessageType String type,
+            @NonNull Bundle data) {
+        if (DEBUG) {
+            Log.d(TAG, "notifyTvMessage type=" + type
+                    + "; data=" + data);
+        }
+        if (mSession != null) {
+            mSession.notifyTvMessage(type, data);
+        }
+    }
+
     private void resetInternal() {
         mSessionCallback = null;
         if (mSession != null) {
@@ -1112,7 +1132,6 @@
          * is called.
          *
          * @param iAppServiceId The ID of the TV interactive app service bound to this view.
-         * @hide
          */
         public void onRequestCurrentVideoBounds(@NonNull String iAppServiceId) {
         }
diff --git a/media/java/android/media/tv/tuner/frontend/IptvFrontendCapabilities.java b/media/java/android/media/tv/tuner/frontend/IptvFrontendCapabilities.java
new file mode 100644
index 0000000..b04fe17
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/IptvFrontendCapabilities.java
@@ -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 android.media.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * IPTV Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class IptvFrontendCapabilities extends FrontendCapabilities {
+    private final int mProtocolCap;
+
+    // Used by native code
+    private IptvFrontendCapabilities(int protocolCap) {
+        mProtocolCap = protocolCap;
+    }
+
+    /**
+     * Gets the protocols of IPTV transmission (UDP/RTP) defined in
+     * {@link IptvFrontendSettings}.
+     */
+    public int getProtocolCapability() {
+        return mProtocolCap;
+    }
+}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index f56e236..7f4c03b 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1617,6 +1617,15 @@
             interleaveModeCap, codeRateCap, bandwidthCap);
 }
 
+jobject JTuner::getIptvFrontendCaps(JNIEnv *env, FrontendCapabilities &caps) {
+    jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IptvFrontendCapabilities");
+    jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(I)V");
+
+    jint protocolCap = caps.get<FrontendCapabilities::Tag::iptvCaps>()->protocolCap;
+
+    return env->NewObject(clazz, capsInit, protocolCap);
+}
+
 jobject JTuner::getFrontendInfo(int id) {
     shared_ptr<FrontendInfo> feInfo;
     feInfo = sTunerClient->getFrontendInfo(id);
@@ -1695,6 +1704,11 @@
                 jcaps = getDtmbFrontendCaps(env, caps);
             }
             break;
+        case FrontendType::IPTV:
+            if (FrontendCapabilities::Tag::iptvCaps == caps.getTag()) {
+                jcaps = getIptvFrontendCaps(env, caps);
+            }
+            break;
         default:
             break;
     }
@@ -3518,17 +3532,18 @@
 
 static FrontendIptvSettingsFec getIptvFrontendSettingsFec(JNIEnv *env, const jobject &settings) {
     jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IptvFrontendSettings");
-    jobject fec = env->GetObjectField(settings, env->GetFieldID(clazz, "mFec",
-            "[Landroid/media/tv/tuner/frontend/IptvFrontendSettingsFec;"));
     jclass fecClazz = env->FindClass("android/media/tv/tuner/frontend/IptvFrontendSettingsFec");
-    FrontendIptvSettingsFecType fecType =
+    jobject fec = env->GetObjectField(settings, env->GetFieldID(clazz, "mFec",
+            "Landroid/media/tv/tuner/frontend/IptvFrontendSettingsFec;"));
+
+    FrontendIptvSettingsFecType type =
             static_cast<FrontendIptvSettingsFecType>(
-                    env->GetIntField(fec, env->GetFieldID(fecClazz, "mFec", "I")));
+                    env->GetIntField(fec, env->GetFieldID(fecClazz, "mFecType", "I")));
     int32_t fecColNum = env->GetIntField(fec, env->GetFieldID(fecClazz, "mFecColNum", "I"));
     int32_t fecRowNum = env->GetIntField(fec, env->GetFieldID(fecClazz, "mFecRowNum", "I"));
 
-    FrontendIptvSettingsFec frontendIptvSettingsFec {
-        .type = fecType,
+    FrontendIptvSettingsFec frontendIptvSettingsFec = {
+        .type = type,
         .fecColNum = fecColNum,
         .fecRowNum = fecRowNum,
     };
@@ -3538,31 +3553,36 @@
 
 static FrontendSettings getIptvFrontendSettings(JNIEnv *env, const jobject &settings) {
     FrontendSettings frontendSettings;
-    const char *clazzName = "android/media/tv/tuner/frontend/IptvFrontendSettings";
-    jclass clazz = env->FindClass(clazzName);
+    const char *className = "android/media/tv/tuner/frontend/IptvFrontendSettings";
+    jclass clazz = env->FindClass(className);
     FrontendIptvSettingsProtocol protocol =
             static_cast<FrontendIptvSettingsProtocol>(
                     env->GetIntField(settings, env->GetFieldID(clazz, "mProtocol", "I")));
     FrontendIptvSettingsIgmp igmp =
             static_cast<FrontendIptvSettingsIgmp>(
                     env->GetIntField(settings, env->GetFieldID(clazz, "mIgmp", "I")));
-    FrontendIptvSettingsFec fec = getIptvFrontendSettingsFec(env, settings);
     int64_t bitrate = env->GetIntField(settings, env->GetFieldID(clazz, "mBitrate", "J"));
-    jstring contentUrlJString = (jstring) env->GetObjectField(settings, env->GetFieldID(
-                                clazz, "mContentUrl",
-                                "[Landroid/media/tv/tuner/frontend/IptvFrontendSettings;"));
-    const char *contentUrl = env->GetStringUTFChars(contentUrlJString, 0);
-    DemuxIpAddress ipAddr = getDemuxIpAddress(env, settings, clazzName);
+    jstring jContentUrl = (jstring) env->GetObjectField(settings, env->GetFieldID(
+                                clazz, "mContentUrl", "Ljava/lang/String;"));
+    const char *contentUrl = env->GetStringUTFChars(jContentUrl, 0);
+    DemuxIpAddress ipAddr = getDemuxIpAddress(env, settings, className);
 
     FrontendIptvSettings frontendIptvSettings{
             .protocol = protocol,
-            .fec = fec,
             .igmp = igmp,
             .bitrate = bitrate,
             .ipAddr = ipAddr,
             .contentUrl = contentUrl,
     };
+
+    jobject jFec = env->GetObjectField(settings, env->GetFieldID(clazz, "mFec",
+            "Landroid/media/tv/tuner/frontend/IptvFrontendSettingsFec;"));
+    if (jFec != nullptr) {
+        frontendIptvSettings.fec = getIptvFrontendSettingsFec(env, settings);
+    }
+
     frontendSettings.set<FrontendSettings::Tag::iptv>(frontendIptvSettings);
+    env->ReleaseStringUTFChars(jContentUrl, contentUrl);
     return frontendSettings;
 }
 
@@ -3879,7 +3899,6 @@
     return tuner->openLnbByName(name);
 }
 
-
 static jobject android_media_tv_Tuner_open_filter(
         JNIEnv *env, jobject thiz, jint type, jint subType, jlong bufferSize) {
     sp<JTuner> tuner = getTuner(env, thiz);
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 4069aaf..2bb14f6 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -236,6 +236,7 @@
     static jobject getIsdbsFrontendCaps(JNIEnv* env, FrontendCapabilities& caps);
     static jobject getIsdbtFrontendCaps(JNIEnv* env, FrontendCapabilities& caps);
     static jobject getDtmbFrontendCaps(JNIEnv* env, FrontendCapabilities& caps);
+    static jobject getIptvFrontendCaps(JNIEnv* env, FrontendCapabilities& caps);
 };
 
 class C2DataIdInfo : public C2Param {
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 987b23f..f258c27 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -345,6 +345,7 @@
     extern "C++" {
         ASurfaceControl_registerSurfaceStatsListener*;
         ASurfaceControl_unregisterSurfaceStatsListener*;
+        ASurfaceControl_getChoreographer*;
         ASurfaceControlStats_getAcquireTime*;
         ASurfaceControlStats_getFrameNumber*;
     };
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index b3628fa..27666caa 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(SessionHint hint);
+    int sendHint(int32_t 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(SessionHint hint) {
+int APerformanceHintSession::sendHint(int32_t 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, SessionHint hint) {
+int APerformanceHint_sendHint(void* session, int32_t hint) {
     return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint);
 }
 
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index ea20c6c..b7f3596 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -180,6 +180,18 @@
             reinterpret_cast<void*>(func));
 }
 
+AChoreographer* ASurfaceControl_getChoreographer(ASurfaceControl* aSurfaceControl) {
+    LOG_ALWAYS_FATAL_IF(aSurfaceControl == nullptr, "aSurfaceControl should not be nullptr");
+    SurfaceControl* surfaceControl =
+            ASurfaceControl_to_SurfaceControl(reinterpret_cast<ASurfaceControl*>(aSurfaceControl));
+    if (!surfaceControl->isValid()) {
+        ALOGE("Attempted to get choreographer from invalid surface control");
+        return nullptr;
+    }
+    SurfaceControl_acquire(surfaceControl);
+    return reinterpret_cast<AChoreographer*>(surfaceControl->getChoreographer().get());
+}
+
 int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats) {
     if (const auto* fence = std::get_if<sp<Fence>>(&stats->acquireTimeOrFence)) {
         // We got a fence instead of the acquire time due to latch unsignaled.
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 791adfd..321a7dd 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);
 
-    SessionHint hintId = SessionHint::CPU_LOAD_RESET;
+    int hintId = 2;
     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, static_cast<SessionHint>(-1));
+    result = APerformanceHint_sendHint(session, -1);
     EXPECT_EQ(EINVAL, result);
 
     EXPECT_CALL(*iSession, close()).Times(Exactly(1));
diff --git a/omapi/OWNERS b/omapi/OWNERS
index 1dce1e0..39c5c5b 100644
--- a/omapi/OWNERS
+++ b/omapi/OWNERS
@@ -1,6 +1,2 @@
 # Bug component: 456592
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
-jackcwyu@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/omapi/java/android/se/OWNERS b/omapi/java/android/se/OWNERS
index 1dce1e0..39c5c5b 100644
--- a/omapi/java/android/se/OWNERS
+++ b/omapi/java/android/se/OWNERS
@@ -1,6 +1,2 @@
 # Bug component: 456592
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
-jackcwyu@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/omapi/java/android/se/omapi/OWNERS b/omapi/java/android/se/omapi/OWNERS
index 1dce1e0..39c5c5b 100644
--- a/omapi/java/android/se/omapi/OWNERS
+++ b/omapi/java/android/se/omapi/OWNERS
@@ -1,6 +1,2 @@
 # Bug component: 456592
-
-sattiraju@google.com
-henrichataing@google.com
-alisher@google.com
-jackcwyu@google.com
+include platform/packages/apps/Nfc:/OWNERS
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
index ab2d815..6c463e1 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -22,7 +22,7 @@
               android:orientation="horizontal"
               android:paddingStart="32dp"
               android:paddingEnd="32dp"
-              android:paddingBottom="14dp">
+              android:paddingTop="12dp">
 
     <ImageView
         android:id="@+id/permission_icon"
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index a8e5143..d621ca2 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Metgeseltoestel-bestuurder"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot jou &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; bestuur te word"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê, en sal toegang hê tot jou Foon-, SMS-, Kontakte-, Kalender-, Oproeprekords- en Toestelle in die Omtrek-toestemming."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met die volgende toestemmings te hê:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om inligting te sinkroniseer, soos die naam van iemand wat bel, interaksie met jou kennisgewings te hê, en sal toegang tot jou Foon-, SMS-, Kontakte-, Mikrofoon-, en Toestelle in die Omtrek-toestemmings hê."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om inligting te sinkroniseer, soos die naam van iemand wat bel, en toegang tot hierdie toestemmings:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"bril"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê en sal toegang tot jou Foon-, SMS-, Kontakte-, Mikrofoon, en Toestelle in die Omtrek-toestemmings hê."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met die volgende toestemmings te hê:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Hierdie app is nodig om <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê en sal toegang tot jou Foon-, SMS-, Kontakte-, Mikrofoon-, en Toestelle in die Omtrek-toestemmings hê."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Hierdie app is nodig om <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met die volgende toestemmings te hê:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Oorkruistoesteldienste"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-toestemming om inhoud na toestelle in die omtrek te stroom"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en die gekose toestel."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
     <string name="consent_no" msgid="2640796915611404382">"Moenie toelaat nie"</string>
     <string name="consent_back" msgid="2560683030046918882">"Terug"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index f6abda8..86d8652 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"አጃቢ የመሣሪያ አስተዳዳሪ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; የእርስዎን &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; መሣሪያ እንዲደርስ ይፍቀዱለት"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string>
     <string name="chooser_title" msgid="2262294130493605839">"በ&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; የሚተዳደር <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"የእርስዎን <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ለማስተዳደር መተግበሪያው ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> ከማሳወቂያዎችዎ ጋር መስተጋብር እንዲፈጥር እና የእርስዎን ስልክ፣ ኤስኤምኤስ፣ ዕውቂያዎች፣ የቀን መቁጠሪያ፣ የጥሪ ምዝገባ ማስታወሻዎች እና በአቅራቢያ ያሉ የመሣሪያዎች ፈቃዶች እንዲደርስ ይፈቀድለታል።"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"የእርስዎን <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ለማስተዳደር መተግበሪያው ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> ከእነዚህ ፈቃዶች ጋር መስተጋብር እንዲፈጥር ይፈቀድለታል፦"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"መነጽሮች"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"የእርስዎን <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="5725890636605211803">"የእርስዎን <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ለማስተዳደር መተግበሪያው ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> ከእነዚህ ፈቃዶች ጋር መስተጋብር እንዲፈጥር ይፈቀድለታል፦"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> በአቅራቢያ ወዳሉ መሣሪያዎች ይዘትን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
     <string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ተመለስ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 013e1ec..5864ec9 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"تطبيق \"مدير الجهاز المصاحب\""</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"الساعة"</string>
     <string name="chooser_title" msgid="2262294130493605839">"‏اختَر <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ليديرها تطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"التطبيق مطلوب لإدارة \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". سيتم السماح لتطبيق \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" بالتفاعل مع الإشعارات والوصول إلى أذونات الهاتف والرسائل القصيرة وجهات الاتصال والتقويم وسجلّات المكالمات والأجهزة المجاورة."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"التطبيق مطلوب لإدارة \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". سيتم السماح للتطبيق \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" بالتفاعل مع هذه الأذونات."</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"النظارة"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"هذا التطبيق مطلوب لإدارة \"<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="5725890636605211803">"التطبيق مطلوب لإدارة \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". سيتم السماح للتطبيق \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" بالتفاعل مع هذه الأذونات."</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"يطلب تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> لمشاركة التطبيقات بين أجهزتك."</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"خدمات تعمل على عدة أجهزة"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" لبثّ محتوى إلى أجهزتك المجاورة."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
     <string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
     <string name="consent_back" msgid="2560683030046918882">"رجوع"</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index f2f0b1e..38be80f 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"কম্পেনিয়ন ডিভাইচ মেনেজাৰ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; এক্সেছ কৰিবলৈ দিয়ক"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;এ পৰিচালনা কৰিব লগা এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এপ্‌টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক আপোনাৰ জাননী ব্যৱহাৰ কৰিবলৈ আৰু আপোনাৰ ফ’ন, এছএমএছ, সম্পৰ্ক ,কেলেণ্ডাৰ, কল লগ আৰু নিকটৱৰ্তী ডিভাইচৰ অনুমতি এক্সেছ কৰিবলৈ দিয়া হ’ব।"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এপ্‌টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক এই অনুমতিসমূহৰ সৈতে ভাব-বিনিময় কৰিবলৈ দিয়া হ’ব:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"চছ্‌মা"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"আপোনাৰ <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="5725890636605211803">"আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এপ্‌টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক এই অনুমতিসমূহৰ সৈতে ভাব-বিনিময় কৰিবলৈ দিয়া হ’ব:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ নিকটৱৰ্তী ডিভাইচত সমল ষ্ট্ৰীম কৰাৰ অনুমতি দিবলৈ অনুৰোধ জনাইছে"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
     <string name="consent_back" msgid="2560683030046918882">"উভতি যাওক"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 454fa73..e333c51 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Kompanyon Cihaz Meneceri"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinin &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınıza girişinə icazə verin"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızı idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> bildirişlərinizə, Telefon, SMS, Kontaktlar, Təqvim, Zəng qeydləri və Yaxınlıqdakı cihaz icazələrinə giriş əldə edəcək."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızı idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> bu icazələrlə qarşılıqlı əlaqəyə icazə veriləcək:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"eynək"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Bu tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızı idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> bildirişlərinizə, Telefon, SMS, Kontaktlar, Mikrofon və Yaxınlıqdakı cihazlar icazələrinə giriş əldə edəcək."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızı idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> bu icazələrlə qarşılıqlı əlaqəyə icazə veriləcək:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cihazlararası xidmətlər"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından yaxınlıqdakı cihazlarda yayımlamaq üçün icazə istəyir"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
     <string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
     <string name="consent_back" msgid="2560683030046918882">"Geriyə"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 7734726..8564793 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Menadžer pridruženog uređaja"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, kalendar, evidencije poziva i uređaje u blizini."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa ovim dozvolama:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"naočare"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, mikrofon i uređaje u blizini."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa ovim dozvolama:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Usluge na više uređaja"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> da strimuje sadržaj na uređaje u blizini"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 0e60654..071dd6f 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Менеджар спадарожнай прылады"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ да вашай прылады &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Выберыце прыладу (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Гэта праграма неабходная для кіравання прыладай \"<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="1523091550243476756">"Гэта праграма неабходная для кіравання прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> зможа выкарыстоўваць наступныя дазволы:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"акуляры"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Гэта праграма неабходная для кіравання прыладай \"<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="5725890636605211803">"Гэта праграма неабходная для кіравання прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> зможа выкарыстоўваць наступныя дазволы:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на трансляцыю праграм паміж вашымі прыладамі"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Сэрвісы для некалькіх прылад"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на перадачу змесціва плынню на прылады паблізу."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 1db64e4..780924a 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Разрешаване на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до устройството ви &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Това приложение е необходимо за управление на устройството ви (<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="1523091550243476756">"Това приложение е необходимо за управление на устройството ви (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи разрешение да взаимодейства със следните разрешения:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"очилата"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Това приложение е необходимо за управление на <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="5725890636605211803">"Това приложение е необходимо за управление на <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ви. <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи разрешение да взаимодейства със следните разрешения:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Услуги за различни устройства"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно съдържание към устройства в близост"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
     <string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 3013457..88e334e 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"আপনার &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; অ্যাক্সেস করার জন্য &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে অনুমতি দিন"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ি"</string>
     <string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন যেটি &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ম্যানেজ করবে"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করার জন্য অ্যাপটি প্রয়োজন। <xliff:g id="APP_NAME">%2$s</xliff:g>-কে আপনার বিজ্ঞপ্তির সাথে ইন্টার‌্যাক্ট করার এবং ফোন, এসএমএস, পরিচিতি, ক্যালেন্ডার, কল লগ ও আশেপাশের ডিভাইস অ্যাক্সেস করার অনুমতি দেওয়া হবে।"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করার জন্য অ্যাপটি প্রয়োজন। <xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপকে এইসব অনুমতির সাথে ইন্টার‌্যাক্ট করার জন্য অনুমোদন দেওয়া হবে:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"চশমা"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"আপনার <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="5725890636605211803">"আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করার জন্য অ্যাপটি প্রয়োজন। <xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপকে এইসব অনুমতির সাথে ইন্টার‌্যাক্ট করার জন্য অনুমোদন দেওয়া হবে:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ক্রস-ডিভাইস পরিষেবা"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"আশেপাশের ডিভাইসে কন্টেন্ট স্ট্রিম করার জন্য আপনার <xliff:g id="DEVICE_TYPE">%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" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
     <string name="consent_back" msgid="2560683030046918882">"ফিরুন"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index f3829b0..4f8d37a 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Prateći upravitelj uređaja"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Dopustite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"sat"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"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 se dozvoliti da ostvaruje interakciju s vašim obavještenjima i da pristupa odobrenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"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 dozvoljena interakcija s ovim odobrenjima:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će sinkronizirati podatke, primjerice ime pozivatelja, stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će sinkronizirati podatke, primjerice ime pozivatelja i pristupati sljedećim dopuštenjima:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"naočale"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"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 dozvoljeno da stupi u interakciju s obavještenjima i pristupa odobrenjima telefona, SMS-a, kontakata, mikrofona i uređaja u blizini."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"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 dozvoljena interakcija s ovim odobrenjima:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Ta je aplikacija potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, mikrofon i uređaje u blizini."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s ovim dopuštenjima:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama s telefona"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Usluga na više uređaja"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva odobrenje u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> da prenosi sadržaj na uređajima u blizini"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"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>
+    <string name="summary_generic" msgid="4988130802522924650">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i odabranog uređaja, primjerice ime pozivatelja."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 0e0919c..c407a1c 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gestor de dispositius complementaris"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> perquè el gestioni &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"L\'aplicació és necessària per gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per interaccionar amb les teves notificacions i accedir al telèfon, als SMS, als contactes, al calendari, als registres de trucades i als dispositius propers."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"L\'aplicació és necessària per gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per interaccionar amb aquests permisos:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"ulleres"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Aquesta aplicació es necessita per gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per interaccionar amb les teves notificacions i accedir al telèfon, als SMS, als contactes, al micròfon i als dispositius propers."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"L\'aplicació és necessària per gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per interaccionar amb aquests permisos:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per reproduir en continu aplicacions entre els dispositius"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Serveis multidispositiu"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) per reproduir contingut en continu en dispositius propers"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
     <string name="consent_back" msgid="2560683030046918882">"Enrere"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 6f1bad7..7ef6846 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Správce doprovodných zařízení"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k vašemu zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Povolit aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s vašimi oznámeními a získá přístup k telefonu, SMS, kontaktům, kalendáři, seznamům hovorů a zařízením v okolí."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s těmito oprávněními:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"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="7443464525873186735">"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, a získat přístup k těmto oprávněním:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"brýle"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"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 interagovat s vašimi oznámeními a získat přístup k vašim oprávněním k telefonu, SMS, kontaktům, mikrofonu a zařízením v okolí."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s těmito oprávněními:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"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 interagovat s vašimi oznámeními a získat přístup k vašim oprávněním k telefonu, SMS, kontaktům, mikrofonu a zařízením v okolí."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s těmito oprávněními:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Služby pro více zařízení"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování obsahu do zařízení v okolí"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a zařízením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a vybraným zařízením."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
     <string name="consent_back" msgid="2560683030046918882">"Zpět"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 2b6c42b..f1bf633 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Medfølgende enhedsadministrator"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Tillad, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får adgang til dit &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ur"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Vælg det <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, som skal administreres af &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at interagere med dine notifikationer og får adgang til dine tilladelser for Opkald, Sms, Kalender, Opkaldshistorik og Enheder i nærheden."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får mulighed for at interagere med følgende tilladelser:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"briller"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at interagere med dine notifikationer og tilgå tilladelserne Telefon, Sms, Kontakter, Mikrofon og Enheder i nærheden."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får mulighed for at interagere med følgende tilladelser:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Giv &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; adgang til disse oplysninger fra din telefon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Tjenester til flere enheder"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame indhold til enheder i nærheden"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tilbage"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 32873c0..b914f2f 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Begleitgerät-Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; erlauben, auf dein Gerät (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;) zuzugreifen"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Gerät „<xliff:g id="PROFILE_NAME">%1$s</xliff:g>“ auswählen, das von &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; verwaltet werden soll"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Die App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf mit deinen Benachrichtigungen interagieren und auf die Berechtigungen „Telefon“, „SMS“, „Kontakte“, „Kalender“, „Anrufliste“ und „Geräte in der Nähe“ zugreifen."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Die App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf mit diesen Berechtigungen interagieren:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"Glass-Geräte"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Diese App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf mit deinen Benachrichtigungen interagieren und auf die Berechtigungen „Telefon“, „SMS“, „Kontakte“, „Mikrofon“ und „Geräte in der Nähe“ zugreifen."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Die App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf mit diesen Berechtigungen interagieren:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Geräteübergreifende Dienste"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein Gerät (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) um die Berechtigung zum Streamen von Inhalten auf Geräte in der Nähe"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nicht zulassen"</string>
     <string name="consent_back" msgid="2560683030046918882">"Zurück"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 5567f3a..f817de0 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Διαχείριση συνοδευτικής εφαρμογής"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση στη συσκευή &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση στη συσκευή &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για διαχείριση από την εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <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="1523091550243476756">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> θα επιτρέπεται να αλληλεπιδρά με τις εξής άδειες:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <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="7443464525873186735">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> θα μπορεί να συγχρονίζει πληροφορίες, όπως το όνομα ενός ατόμου που σας καλεί, και να αποκτά πρόσβαση σε αυτές τις άδειες:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"γυαλιά"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Αυτή η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <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="5725890636605211803">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> θα επιτρέπεται να αλληλεπιδρά με τις εξής άδειες:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Αυτή η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <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="7051392780285915640">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Υπηρεσίες πολλών συσκευών"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά άδεια εκ μέρους της συσκευής <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> για ροή περιεχομένου σε συσκευές σε κοντινή απόσταση."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, όπως το όνομα ενός ατόμου που σας καλεί."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της επιλεγμένης συσκευής σας, όπως το όνομα ενός ατόμου που σας καλεί."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
     <string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
     <string name="consent_back" msgid="2560683030046918882">"Πίσω"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 897f343..5708fdc 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, calendar, call logs and Nearby devices permissions."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"The app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cross-device services"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream content to nearby devices"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 9905f28..ea0ceb2 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"The app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cross-device services"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream content to nearby devices"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don’t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 897f343..5708fdc 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, calendar, call logs and Nearby devices permissions."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"The app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cross-device services"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream content to nearby devices"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 897f343..5708fdc 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access your &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"watch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, calendar, call logs and Nearby devices permissions."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"This app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"The app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with these permissions:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cross-device services"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream content to nearby devices"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index 073aeca..ffad25b 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎Companion Device Manager‎‏‎‎‏‎"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access your &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎watch‎‏‎‎‏‎"</string>
     <string name="chooser_title" msgid="2262294130493605839">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎Choose a ‎‏‎‎‏‏‎<xliff:g id="PROFILE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ to be managed by &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;‎‏‎‎‏‎"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎The app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.‎‏‎‎‏‎"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎The app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to interact with these permissions:‎‏‎‎‏‎"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎The app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.‎‏‎‎‏‎"</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎The app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to sync info, like the name of someone calling, and access these permissions:‎‏‎‎‏‎"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎glasses‎‏‎‎‏‎"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎This app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions.‎‏‎‎‏‎"</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‎The app is needed to manage your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to interact with these permissions:‎‏‎‎‏‎"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‎This app is needed to manage ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions.‎‏‎‎‏‎"</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎The app is needed to manage ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ will be allowed to interact with these permissions:‎‏‎‎‏‎"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎Cross-device services‎‏‎‎‏‎"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps between your devices‎‏‎‎‏‎"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎Cross-device services‎‏‎‎‏‎"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream content to nearby devices‎‏‎‎‏‎"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎This app will be able to sync info, like the name of someone calling, between your phone and ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
+    <string name="summary_generic" msgid="4988130802522924650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎This app will be able to sync info, like the name of someone calling, between your phone and the chosen device.‎‏‎‎‏‎"</string>
     <string name="consent_yes" msgid="8344487259618762872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎Allow‎‏‎‎‏‎"</string>
     <string name="consent_no" msgid="2640796915611404382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎Don’t allow‎‏‎‎‏‎"</string>
     <string name="consent_back" msgid="2560683030046918882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎Back‎‏‎‎‏‎"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 804c80b..85333a9 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Administrador de dispositivo complementario"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a tu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para que la app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; lo administre"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a los permisos de Teléfono, SMS, Contactos, Calendario, Llamadas y Dispositivos cercanos."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con estos permisos:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"Gafas"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a los permisos de Teléfono, SMS, Contactos, Micrófono y Dispositivos cercanos."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con estos permisos:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Servicios multidispositivo"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir contenido a dispositivos cercanos"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index 5b25e15..c5127e8 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos complementario"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a tu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para gestionarlo con &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Se necesita la aplicación para gestionar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a tus permisos de teléfono, SMS, contactos, calendario, registros de llamadas y dispositivos cercanos."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Se necesita la aplicación para gestionar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Se permitirá que <xliff:g id="APP_NAME">%2$s</xliff:g> interaccione con los siguientes permisos:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"gafas"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Se necesita esta aplicación para gestionar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a tus permisos de teléfono, SMS, contactos, micrófono y dispositivos cercanos."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Se necesita la aplicación para gestionar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Se permitirá que <xliff:g id="APP_NAME">%2$s</xliff:g> interaccione con los siguientes permisos:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Servicios multidispositivo"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para reproducir contenido en dispositivos cercanos"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index ed7507b..cd362de 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Kaasseadme haldur"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; teie seadmele &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; juurde pääseda"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"käekell"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Valige <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Seda rakendust on vaja teie seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada teie märguandeid ning pääseda juurde teie telefoni, SMS-ide, kontaktide, kalendri, kõnelogide ja läheduses olevate seadmete lubadele."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Seda rakendust on vaja teie seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada järgmisi lube."</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"prillid"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Seda rakendust on vaja teie seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada teie märguandeid ning pääseda juurde teie telefoni, SMS-ide, kontaktide, mikrofoni ja läheduses olevate seadmete lubadele."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Seda rakendust on vaja teie seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada järgmisi lube."</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Seadmeülesed teenused"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba voogesitada sisu läheduses olevates seadmetes"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tagasi"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 4b71149..d2a7d98 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -17,28 +17,36 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gailu osagarriaren kudeatzailea"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Eman &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; atzitzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Aukeratu &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko behar da aplikazioa. Jakinarazpenekin interakzioan aritzeko, eta telefonoa, SMSak, kontaktuak, egutegia, deien erregistroak eta inguruko gailuak erabiltzeko baimenak izango ditu <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko behar da aplikazioa. Baimen hauek izango ditu <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"betaurrekoak"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Aplikazioa <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 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="5725890636605211803">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko behar da aplikazioa. Baimen hauek izango ditu <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
     <string name="title_automotive_projection" msgid="3296005598978412847"></string>
     <string name="summary_automotive_projection" msgid="8683801274662496164"></string>
-    <string name="title_computer" msgid="4693714143506569253">"Eman telefonoko informazio hau atzitzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
+    <string name="title_computer" msgid="4693714143506569253">"Eman telefonoko informazio hau erabiltzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
     <string name="summary_computer" msgid="3798467601598297062"></string>
     <string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
-    <string name="helper_summary_computer" msgid="9050724687678157852">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak atzitzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
+    <string name="helper_summary_computer" msgid="9050724687678157852">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak erabiltzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
     <string name="title_nearby_device_streaming" msgid="179278282547719200">"Eman telefonotik ekintza hau gauzatzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Gailu baterako baino gehiagotarako zerbitzuak"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Inguruko gailuetara edukia igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atzera"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 101353e..1d283f0 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"مدیر دستگاه مرتبط"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"‏به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; اجازه دهید به &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; دسترسی داشته باشد"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string>
     <string name="chooser_title" msgid="2262294130493605839">"‏انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای مدیریت کردن با &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>‏&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما لازم است. <xliff:g id="APP_NAME">%2$s</xliff:g> می‌تواند با اعلان‌های شما تعامل داشته باشد و به اجازه‌های «تلفن»، «پیامک»، «مخاطبین»، «تقویم»، «گزارش‌های تماس» و «دستگاه‌های اطراف» دسترسی خواهد داشت."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما لازم است. <xliff:g id="APP_NAME">%2$s</xliff:g> مجاز است با این اجازه‌ها تعامل داشته باشد:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"عینک"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"این برنامه برای مدیریت <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="5725890636605211803">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما لازم است. <xliff:g id="APP_NAME">%2$s</xliff:g> مجاز می‌شود با این اجازه‌ها تعامل داشته باشد:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"‏اجازه دادن به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای دسترسی به اطلاعات تلفن"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویس‌های بین‌دستگاهی"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه می‌خواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامه‌ها را بین دستگاه‌های شما جاری‌سازی کند"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"سرویس‌های بین‌دستگاهی"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> اجازه می‌خواهد تا در دستگاه‌های اطراف محتوا جاری‌سازی کند."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"اجازه دادن"</string>
     <string name="consent_no" msgid="2640796915611404382">"اجازه ندادن"</string>
     <string name="consent_back" msgid="2560683030046918882">"برگشتن"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index e92cabb..9f5c57f 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn laitteeseesi: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn laitteeseen: &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"kello"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, jota &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; hallinnoi"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Laitteen (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ylläpitoon tarvitaan tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, kalenteriin, puhelulokeihin ja lähellä olevat laitteet ‑lupiin."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Laitteen (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) ylläpitoon tarvitaan tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa käyttää näitä lupia:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"<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 synkronoida tietoja (esimerkiksi soittajan nimen), hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, kalenteriin, puhelulokeihin ja lähellä olevat laitteet ‑lupiin."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"<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 synkronoida tietoja (esimerkiksi soittajan nimen) ja pääsyn näihin lupiin:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"lasit"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Ylläpitoon (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) tarvitaan 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_single_device" msgid="5725890636605211803">"Ylläpitoon (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) tarvitaan tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa käyttää näitä lupia:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"<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_single_device" msgid="7051392780285915640">"<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 käyttää näitä lupia:"</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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Laitteidenväliset palvelut"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa striimata sisältöä lähellä oleviin laitteisiin"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja laitteen (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) välillä."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja valitun laitteen välillä."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Takaisin"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 6e3df3e..3f9ec0b 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareil compagnon"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Choisissez un(e) <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"L\'application est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec vos notifications et d\'accéder aux autorisations suivantes : téléphone, messages texte, contacts, agenda, journaux d\'appels et appareils à proximité."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"L\'application est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec ces autorisations :"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"lunettes"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Cette application est nécessaire pour gérer votre <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_single_device" msgid="5725890636605211803">"L\'application est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec ces autorisations :"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Services multiappareils"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de diffuser du contenu aux appareils à proximité"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
     <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 5a93dc4..d05087d 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareils associés"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à votre &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Sélectionnez le/la <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec vos notifications et d\'accéder au téléphone, aux SMS, aux contacts, à l\'agenda, aux journaux d\'appels et aux appareils à proximité."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> pourra interagir avec ces autorisations :"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"lunettes"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec vos notifications et d\'accéder aux autorisations du téléphone, des SMS, des contacts, du micro et des appareils à proximité."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> pourra interagir avec ces autorisations :"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Services inter-appareils"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de diffuser du contenu en streaming sur les appareils à proximité"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
     <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 25ce2ba..f3e2d43 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Xestor de dispositivos complementarios"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda ao teu dispositivo (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Escolle un dispositivo (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"A aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar coas túas notificacións e acceder aos permisos do teu teléfono, das SMS, dos contactos, do calendario, dos rexistros de chamadas e dos dispositivos próximos."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"A aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar con estes permisos:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"lentes"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Esta aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar coas túas notificacións e acceder aos permisos do teléfono, das SMS, dos contactos, do micrófono e dos dispositivos próximos."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"A aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar con estes permisos:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir contido de aplicacións entre os teus aparellos"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Servizos multidispositivo"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir contido aos dispositivos próximos"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 4cfea49..5e21ccb 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"કમ્પેનિયન ડિવાઇસ મેનેજર"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"તમારા &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ને ઍક્સેસ કરવાની &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; દ્વારા મેનેજ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"તમારી <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="1523091550243476756">"તમારી <xliff:g id="DEVICE_NAME">%1$s</xliff:g> મેનેજ કરવા માટે ઍપ જરૂરી છે. <xliff:g id="APP_NAME">%2$s</xliff:g>ને આ પરવાનગીઓ સાથે ક્રિયાપ્રતિક્રિયા કરવાની મંજૂરી આપવામાં આવશે:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"ચશ્માં"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"તમારા <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="5725890636605211803">"તમારા <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ને મેનેજ કરવા માટે ઍપ જરૂરી છે. <xliff:g id="APP_NAME">%2$s</xliff:g>ને આ પરવાનગીઓ સાથે ક્રિયાપ્રતિક્રિયા કરવાની મંજૂરી આપવામાં આવશે:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ક્રૉસ-ડિવાઇસ સેવાઓ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> નજીકના ડિવાઇસ પર કન્ટેન્ટ સ્ટ્રીમ કરવા માટે તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી પરવાનગીની વિનંતી કરી રહી છે"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
     <string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
     <string name="consent_back" msgid="2560683030046918882">"પાછળ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index b9492cc..4c52ad7 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"सहयोगी डिवाइस मैनेजर"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ऐक्सेस करने की अनुमति दें"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string>
     <string name="chooser_title" msgid="2262294130493605839">"कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें, ताकि उसे &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; की मदद से मैनेज किया जा सके"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> को अनुमति होगी कि यह आपकी सूचनाओं पर कार्रवाई कर सके और आपके फ़ोन, एसएमएस, संपर्कों, कैलेंडर, कॉल लॉग, और आस-पास मौजूद डिवाइसों को ऐक्सेस कर सके."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g>, इन अनुमतियों का इस्तेमाल कर पाएगा:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"चश्मा"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"यह ऐप्लिकेशन, <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="5725890636605211803">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g>, इन अनुमतियों का इस्तेमाल करके इंटरैक्ट कर पाएगा:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन को स्ट्रीम करने की अनुमति मांग रहा है"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, कॉन्टेंट को आस-पास मौजूद डिवाइसों पर स्ट्रीम करने की अनुमति मांग रहा है"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
     <string name="consent_back" msgid="2560683030046918882">"वापस जाएं"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 15e2b22..c901d70 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Dopustite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa vašem uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Dopustite 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">"satom"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati dopuštenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s ovim dopuštenjima:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će sinkronizirati podatke, primjerice ime pozivatelja, stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će sinkronizirati podatke, primjerice ime pozivatelja i pristupati sljedećim dopuštenjima:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"naočale"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Ta je aplikacija potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, mikrofon i uređaje u blizini."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s ovim dopuštenjima:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Ta je aplikacija potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, mikrofon i uređaje u blizini."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s ovim dopuštenjima:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za emitiranje aplikacija između vaših uređaja"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Usluge na različitim uređajima"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za streamanje sadržaja na uređaje u blizini"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"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>
+    <string name="summary_generic" msgid="4988130802522924650">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i odabranog uređaja, primjerice ime pozivatelja."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nemoj dopustiti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Natrag"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index 6a07011..cfd6ad4 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Társeszközök kezelője"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; hozzáférésének engedélyezése a(z) &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; eszközhöz"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"óra"</string>
     <string name="chooser_title" msgid="2262294130493605839">"A(z) &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; alkalmazással kezelni kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiválasztása"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Szükség van az alkalmazásra a következő kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> műveleteket végezhet majd az értesítésekkel, és hozzáférhet a telefonra, az SMS-ekre, a névjegyekre, a naptárra, a hívásnaplókra és a közeli eszközökre vonatkozó engedélyekhez."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Szükség van az alkalmazásra a következő kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> műveleteket végezhet majd ezekkel az engedélyekkel:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"szemüveg"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Szükség van erre az alkalmazásra a következő kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> műveleteket végezhet majd az értesítésekkel, és hozzáférhet majd a Telefon, az SMS, a Névjegyek, a Mikrofon és a Közeli eszközök engedélyekhez."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Szükség van az alkalmazásra a következő kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> műveleteket végezhet majd ezekkel az engedélyekkel:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Többeszközös szolgáltatások"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a közeli eszközökre való streameléséhez."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tiltás"</string>
     <string name="consent_back" msgid="2560683030046918882">"Vissza"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 4ff57bc..719496c 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին կառավարել ձեր &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; սարքը"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին կառավարել &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; սարքը"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը, որը պետք է կառավարվի &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; հավելվածի կողմից"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Այս հավելվածն անհրաժեշտ է ձեր <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="1523091550243476756">"Այս հավելվածն անհրաժեշտ է ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g> պրոֆիլը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածին կթույլատրվի օգտվել այս թույլտվություններից․"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Հավելվածն անհրաժեշտ է ձեր <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="7443464525873186735">"Հավելվածն անհրաժեշտ է ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածը կկարողանա համաժամացնել տվյալները, օր․՝ զանգողի անունը, և կստանա հետևյալ թույլտվությունները․"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"ակնոց"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Այս հավելվածն անհրաժեշտ է ձեր <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="5725890636605211803">"Հավելվածն անհրաժեշտ է ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածին կթույլատրվի օգտվել այս թույլտվություններից․"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Այս հավելվածն անհրաժեշտ է <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="7051392780285915640">"Հավելվածն անհրաժեշտ է <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Միջսարքային ծառայություններ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ մոտակա սարքերին բովանդակություն հեռարձակելու համար"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքի տվյալները, օր․՝ զանգողի անունը։"</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և ընտրված սարքի տվյալները, օր․՝ զանգողի անունը։"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
     <string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
     <string name="consent_back" msgid="2560683030046918882">"Հետ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 39e288a..5394808 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Pengelola Perangkat Pendamping"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk dikelola oleh &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplikasi 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 Telepon, SMS, Kontak, Kalender, Log panggilan, dan Perangkat di sekitar."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplikasi 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 izin ini:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"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 Telepon, SMS, Kontak, Mikrofon, dan Perangkat di sekitar."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Aplikasi 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 izin ini:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <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>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Layanan lintas perangkat"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming konten ke perangkat di sekitar"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index 655b843..81c7864 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Stjórnun fylgdartækja"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"úr"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Velja <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sem &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; á að stjórna"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Forritið er nauðsynlegt til að hafa umsjón með <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær aðgang að tilkynningum og heimildum síma, SMS, tengiliða, dagatals, símtalaskráa og nálægra tækja."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Forritið er nauðsynlegt til að hafa umsjón með <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær aðgang að eftirfarandi heimildum:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"gleraugu"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Þetta forrit er nauðsynlegt til að hafa umsjón með <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær heimild til að bregðast við tilkynningum og fær aðgang að heimildum fyrir síma, SMS, tengiliði, hljóðnema og nálæg tæki."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Forritið er nauðsynlegt til að stjórna <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær aðgang að eftirfarandi heimildum:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild til straumspilunar forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Þjónustur á milli tækja"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> biður um heimild fyrir <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til að streyma efni í nálægum tækjum"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
     <string name="consent_back" msgid="2560683030046918882">"Til baka"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 49b1fbd..0d2d9ad 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gestione dispositivi companion"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Consenti all\'app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Consenti all\'app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"orologio"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da gestire con &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Calendario, Registri chiamate e Dispositivi nelle vicinanze."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le seguenti autorizzazioni:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà sincronizzare informazioni, ad esempio il nome di un chiamante, interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Calendario, Registri chiamate e Dispositivi nelle vicinanze."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà sincronizzare informazioni, ad esempio il nome di un chiamante, e accedere alle seguenti autorizzazioni:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"occhiali"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Microfono e Dispositivi nelle vicinanze."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le seguenti autorizzazioni:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Microfono e Dispositivi nelle vicinanze."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le seguenti autorizzazioni:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a queste informazioni dal tuo telefono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Servizi cross-device"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto di <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere contenuti in streaming ai dispositivi nelle vicinanze"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e il dispositivo scelto."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
     <string name="consent_back" msgid="2560683030046918882">"Indietro"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 167e216..df7ab6d 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"ניהול מכשיר מותאם"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"‏אישור לאפליקציה ‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&amp;g;‎‏ לגשת אל ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‎‏"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"‏אישור לאפליקציה ‎&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_watch" msgid="576290739483672360">"שעון"</string>
     <string name="chooser_title" msgid="2262294130493605839">"‏בחירת <xliff:g id="PROFILE_NAME">%1$s</xliff:g> לניהול באמצעות &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"‏האפליקציה הזו נחוצה כדי לנהל את <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="1523091550243476756">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לקיים אינטראקציה עם ההרשאות הבאות:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"‏האפליקציה הזו נחוצה כדי לנהל את <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="7443464525873186735">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, ולקיים אינטראקציה עם ההרשאות הבאות:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"משקפיים"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"‏האפליקציה הזו נחוצה כדי לנהל את <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="5725890636605211803">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לקיים אינטראקציה עם ההרשאות הבאות:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"‏האפליקציה הזו נחוצה כדי לנהל את <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="7051392780285915640">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"שירותים למספר מכשירים"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי להעביר תוכן בסטרימינג למכשירים בקרבת מקום."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך ל-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך למכשיר שבחרת."</string>
     <string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
     <string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
     <string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 599bffa..6eda60b 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャー"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; へのアクセスを許可"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"このアプリは<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="1523091550243476756">"このアプリは<xliff:g id="DEVICE_NAME">%1$s</xliff:g>の管理に必要です。<xliff:g id="APP_NAME">%2$s</xliff:g> は、次の権限の使用が可能となります。"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"このアプリは<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="5725890636605211803">"このアプリは<xliff:g id="DEVICE_NAME">%1$s</xliff:g>の管理に必要です。<xliff:g id="APP_NAME">%2$s</xliff:g> は、次の権限の使用が可能となります。"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"クロスデバイス サービス"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わって付近のデバイスにコンテンツをストリーミングする権限をリクエストしています"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"許可"</string>
     <string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
     <string name="consent_back" msgid="2560683030046918882">"戻る"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 0f578ea..21b703d 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"კომპანიონი მოწყობილობების მენეჯერი"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"დაუშვით &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/strong&gt;, წვდომა თქვენს &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ზე&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"დაუშვით &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/strong&gt; წვდომა &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ზე&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"საათი"</string>
     <string name="chooser_title" msgid="2262294130493605839">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, რომელიც უნდა მართოს &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;-მა"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ეს აპი საჭიროა, რომ მართოთ თქვენი <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="1523091550243476756">"ეს აპი საჭიროა, რომ მართოთ თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> შეძლებს ინტერაქციას შემდეგი ნებართვებით:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"ეს აპი საჭიროა თქვენი <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="7443464525873186735">"ეს აპი საჭიროა თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ის სამართავად. <xliff:g id="APP_NAME">%2$s</xliff:g>-ს ექნება უფლება, მოახდინოს ისეთი ინფორმციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, და ჰქონდეს წვდომა შემდეგ ნებართვებზე:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"სათვალე"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ეს აპი საჭიროა თქვენი <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="5725890636605211803">"ეს აპი საჭიროა, რომ მართოთ თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> შეძლებს ინტერაქციას შემდეგი ნებართვებით:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"ეს აპი საჭიროა თქვენი <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="7051392780285915640">"ეს აპი საჭიროა <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ის სამართავად. <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის აპების სტრიმინგი შეძლოს"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"მოწყობილობათშორისი სერვისები"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს ნებართვას თქვენი სახელით<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> კონტენტის სტრიმინგისთვის ახლომდებარე მოწყობილობებზე"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"ეს აპი შეძლებს, მოახდინოს ისეთი ინფორმაციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, თქვენს ტელეფონსა და <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ს შორის."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"ეს აპი შეძლებს, მოახდინოს ისეთი ინფორმაციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, თქვენს ტელეფონსა და არჩეულ მოწყობილობას შორის."</string>
     <string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
     <string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
     <string name="consent_back" msgid="2560683030046918882">"უკან"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 883269d..622834b 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; құрылғысын пайдалануға рұқсат беру"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"сағат"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; арқылы басқарылатын <xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын таңдаңыз"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Қолданба <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="1523091550243476756">"Қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысын басқару үшін қажет. <xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына осы рұқсаттар беріледі:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"көзілдірік"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Бұл қолданба <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="5725890636605211803">"Қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысын басқару үшін қажет. <xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына осы рұқсаттар беріледі:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Аралық құрылғы қызметтері"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы маңайдағы құрылғыларға <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан контент трансляциялау үшін рұқсат сұрайды."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
     <string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артқа"</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index e46c791..455f882 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"កម្មវិធី​គ្រប់​គ្រង​ឧបករណ៍ដៃគូ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើប្រាស់ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; របស់អ្នក"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string>
     <string name="chooser_title" msgid="2262294130493605839">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីឱ្យស្ថិតក្រោម​ការគ្រប់គ្រងរបស់ &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <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="1523091550243476756">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក។ <xliff:g id="APP_NAME">%2$s</xliff:g> នឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើអន្តរកម្មជាមួយការអនុញ្ញាតទាំងនេះ៖"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"វ៉ែនតា"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <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="5725890636605211803">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក។ <xliff:g id="APP_NAME">%2$s</xliff:g> នឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើអន្តរកម្មជាមួយការអនុញ្ញាតទាំងនេះ៖"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីផ្សាយខ្លឹមសារទៅឧបករណ៍នៅជិត"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
     <string name="consent_no" msgid="2640796915611404382">"មិនអនុញ្ញាត"</string>
     <string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index c81a441..0bc7175 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"ಕಂಪ್ಯಾನಿಯನ್ ಸಾಧನ ನಿರ್ವಾಹಕರು"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"ನಿಮ್ಮ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ಪ್ರವೇಶಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ಅನ್ನು ಪ್ರವೇಶಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಮತ್ತು ನಿಮ್ಮ ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, Calendar, ಕರೆಯ ಲಾಗ್‌ಗಳು ಹಾಗೂ ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ಅನುಮತಿಗಳನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಈ ಅನುಮತಿಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಅನುಮತಿಸಲಾಗುವುದು:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. ಕರೆ ಮಾಡುವವರ ಹೆಸರು, ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಮತ್ತು ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, ಕ್ಯಾಲೆಂಡರ್, ಕರೆ ಲಾಗ್‌ಗಳು ಮತ್ತು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ದೃಢೀಕರಣಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಮತ್ತು ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"ಗ್ಲಾಸ್‌ಗಳು"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಈ ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. ನಿಮ್ಮ ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಹಾಗೂ ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಈ ಅನುಮತಿಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಅನುಮತಿಸಲಾಗುತ್ತದೆ:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಈ ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. ನಿಮ್ಮ ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಹಾಗೂ ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್‌ನ ಅಗತ್ಯವಿದೆ. <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"ಕಂಟೆಂಟ್ ಅನ್ನು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳಿಗೆ ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%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" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"ಈ ಆ್ಯಪ್, ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಸಾಧನದ ನಡುವೆ ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"ಈ ಆ್ಯಪ್, ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು ಆಯ್ಕೆಮಾಡಿದ ಸಾಧನದ ನಡುವೆ ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
     <string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ಹಿಂದೆ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 190ad22..38740f5 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"부속 기기 관리자"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;에서 내 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; 기기에 액세스하도록 허용"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"시계"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 알림과 상호작용하고 내 전화, SMS, 연락처, Calendar, 통화 기록, 근처 기기에 대한 권한을 갖게 됩니다."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 다음 권한과 상호작용할 수 있습니다."</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"안경"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"이 앱은 <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="5725890636605211803">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 다음 권한과 상호작용할 수 있습니다."</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;이 휴대전화의 이 정보에 액세스하도록 허용합니다."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"교차 기기 서비스"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 근처 기기로 콘텐츠를 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"허용"</string>
     <string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
     <string name="consent_back" msgid="2560683030046918882">"뒤로"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 8bd9a9c..5a30ae1 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүңүзгө кирүүгө уруксат бериңиз"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; түзмөгүнө кирүүгө уруксат бериңиз"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"саат"</string>
     <string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; тарабынан башкарылсын"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Бул колдонмо <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="1523091550243476756">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздү тескөө үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> төмөнкү уруксаттарды пайдалана алат:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Бул колдонмо <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="7443464525873186735">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздү тескөө үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын шайкештирет жана анын төмөнкү уруксаттары болот:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"көз айнектер"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Бул колдонмо <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="5725890636605211803">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздү тескөө үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> төмөнкү уруксаттарды пайдалана алат:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Бул колдонмо <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="7051392780285915640">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүн тескөө үчүн керек. <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду өткөрүүгө уруксат сурап жатат"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Түзмөктөр аралык кызматтар"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө контентти алып ойнотууга уруксат сурап жатат"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгү менен шайкештирет."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Ооба"</string>
     <string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артка"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index f093aba..5787bb1 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"ຕົວຈັດການອຸປະກອນປະກອບ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ຂອງທ່ານໄດ້"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ໄດ້"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ເພື່ອໃຫ້ຖືກຈັດການໂດຍ &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <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="1523091550243476756">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ໂຕ້ຕອບກັບການອະນຸຍາດເຫຼົ່ານີ້:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <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="7443464525873186735">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ຊິງ​ຂໍ້​ມູນ​ເຊັ່ນ: ຊື່​ຂອງ​ບາງ​ຄົນ​ທີ່​ກຳ​ລັງ​ໂທ ແລະ ເຂົ້າ​ເຖິງ​ການ​ອະ​ນຸ​ຍາດ​ເຫຼົ່າ​ນີ້:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"ແວ່ນຕາ"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ຕ້ອງໃຊ້ແອັບນີ້ເພື່ອຈັດການ <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="5725890636605211803">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ໂຕ້ຕອບກັບການອະນຸຍາດເຫຼົ່ານີ້:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"ຕ້ອງໃຊ້ແອັບນີ້ເພື່ອຈັດການ <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="7051392780285915640">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ບໍລິການຂ້າມອຸປະກອນ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ຂອງທ່ານເພື່ອສະຕຣີມເນື້ອຫາໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"ແອັບ​ນີ້​ຈະ​ສາ​ມາດ​ຊິງ​ຂໍ້​ມູນ​ເຊັ່ນ: ຊື່​ຂອງ​ບາງ​ຄົນ​ທີ່​ກຳ​ລັງ​ໂທ​ຢູ່​ລະ​ຫວ່າງ​ໂທ​ລະ​ສັບ​ຂອງ​ທ່ານ ແລະ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ໄດ້."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"ແອັບ​ນີ້​ຈະ​ສາ​ມາດ​ຊິງ​ຂໍ້​ມູນ​ເຊັ່ນ: ຊື່​ຂອງ​ບາງ​ຄົນ​ທີ່​ກຳ​ລັງ​ໂທ​ຢູ່​ລະ​ຫວ່າງ​ໂທ​ລະ​ສັບ​ຂອງ​ທ່ານ ແລະ ອຸ​ປະ​ກອນ​ທີ່​ເລືອກ​ໄດ້."</string>
     <string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ກັບຄືນ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 7c74c69..77f89ad 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti jūsų &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"laikrodį"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, kurį valdys &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; (pasirinkite)"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Programa reikalinga norint tvarkyti jūsų <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su pranešimų funkcija ir pasiekti Telefono, SMS, Kontaktų, Kalendoriaus, Skambučių žurnalų ir Įrenginių netoliese leidimus."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Programa reikalinga norint tvarkyti jūsų <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su toliau nurodytais leidimais."</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Programa reikalinga norint tvarkyti jūsų įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, sąveikauti su jūsų pranešimais ir pasiekti jūsų leidimus „Telefonas“, „SMS“, „Kontaktai“, „Kalendorius“, „Skambučių žurnalai“ ir „Įrenginiai netoliese“."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Programa reikalinga norint tvarkyti jūsų įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, ir pasiekti toliau nurodytus leidimus."</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"akiniai"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Ši programa reikalinga norint tvarkyti jūsų įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su jūsų pranešimais ir pasiekti jūsų leidimus „Telefonas“, „SMS“, „Kontaktai“, „Mikrofonas“ ir „Įrenginiai netoliese“."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Programa reikalinga norint tvarkyti jūsų įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su toliau nurodytais leidimais."</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Ši programa reikalinga norint tvarkyti įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su jūsų pranešimais ir pasiekti jūsų leidimus „Telefonas“, „SMS“, „Kontaktai“, „Mikrofonas“ ir „Įrenginiai netoliese“."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Programa reikalinga norint tvarkyti įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su toliau nurodytais leidimais."</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Keliais įreng. naud. paslaugos"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti turinį įrenginiams netoliese"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir įrenginiu „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir pasirinktu įrenginiu."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atgal"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 15cce52..581c84a 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Palīgierīču pārzinis"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Atļauja lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt jūsu ierīcei &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) izvēle, ko pārvaldīt lietotnē &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. Lietotnei <xliff:g id="APP_NAME">%2$s</xliff:g> tiks atļauts mijiedarboties ar jūsu paziņojumiem un piekļūt šādām atļaujām: Tālrunis, Īsziņas, Kontaktpersonas, Kalendārs, Zvanu žurnāli un Tuvumā esošas ierīces."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. Lietotnei <xliff:g id="APP_NAME">%2$s</xliff:g> tiks atļauts mijiedarboties ar šīm atļaujām:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"brilles"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. <xliff:g id="APP_NAME">%2$s</xliff:g> drīkstēs mijiedarboties ar jūsu paziņojumiem un piekļūt atļaujām Tālrunis, Īsziņas, Kontaktpersonas, Mikrofons un Tuvumā esošas ierīces."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. Lietotnei <xliff:g id="APP_NAME">%2$s</xliff:g> tiks atļauts mijiedarboties ar šīm atļaujām:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Vairāku ierīču pakalpojumi"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt saturu tuvumā esošās ierīcēs šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atpakaļ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 73afafac..2768d56 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Дозволете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до вашиот &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> со којшто ќе управува &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Апликацијата е потребна за управување со вашиот <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="1523091550243476756">"Апликацијата е потребна за управување со вашиот <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ќе може да остварува интеракција со следниве дозволи:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"очила"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Апликацијава е потребна за управување со вашиот <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="5725890636605211803">"Апликацијата е потребна за управување со вашиот <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ќе може да остварува интеракција со следниве дозволи:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Услуги на повеќе уреди"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува содржини на уредите во близина"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 0644dd9..920cf83 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"കമ്പാനിയൻ ഉപകരണ മാനേജർ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"നിങ്ങളുടെ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിനെ അനുവദിക്കുക"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിനെ അനുവദിക്കുക"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. നിങ്ങളുടെ അറിയിപ്പുകളുമായി സംവദിക്കാനും നിങ്ങളുടെ ഫോൺ, SMS, Contacts, Calendar, കോൾ ചരിത്രം, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്‌സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനെ അനുവദിക്കും."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. ഇനിപ്പറയുന്ന അനുമതികളുമായി സംവദിക്കാൻ <xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനെ അനുവദിക്കും:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ സമന്വയിപ്പിക്കുന്നതിനും നിങ്ങളുടെ അറിയിപ്പുകളുമായി സംവദിക്കാനും നിങ്ങളുടെ ഫോൺ, SMS, Contacts, Calendar, കോൾ ചരിത്രം, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്‌സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനെ അനുവദിക്കും."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ സമന്വയിപ്പിക്കുന്നതിനും ഈ അനുമതികൾ ആക്സസ് ചെയ്യുന്നതിനും <xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിനെ അനുവദിക്കും:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"ഗ്ലാസുകൾ"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ഈ ആപ്പ് ആവശ്യമാണ്. നിങ്ങളുടെ അറിയിപ്പുകളുമായി സംവദിക്കാനും ഫോൺ, SMS, കോൺടാക്റ്റുകൾ, മൈക്രോഫോൺ, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്‌സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിനെ അനുവദിക്കും."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. ഇനിപ്പറയുന്ന അനുമതികളുമായി സംവദിക്കാൻ <xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനെ അനുവദിക്കും:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ഈ ആപ്പ് ആവശ്യമാണ്. നിങ്ങളുടെ അറിയിപ്പുകളുമായി സംവദിക്കാനും ഫോൺ, SMS, കോൺടാക്റ്റുകൾ, മൈക്രോഫോൺ, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്‌സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിനെ അനുവദിക്കും."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. ഇനിപ്പറയുന്ന അനുമതികളുമായി സംവദിക്കാൻ <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"സമീപമുള്ള ഉപകരണങ്ങളിൽ ഉള്ളടക്കം സ്ട്രീം ചെയ്യാൻ നിങ്ങളുടെ <xliff:g id="DEVICE_TYPE">%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" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും തിരഞ്ഞെടുത്ത ഉപകരണത്തിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും."</string>
     <string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
     <string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
     <string name="consent_back" msgid="2560683030046918882">"മടങ്ങുക"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index d57b4d3..9ce4124 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;-д таны &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д хандахыг зөвшөөрнө үү"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"цаг"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;-н удирдах<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г сонгоно уу"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Энэ апп таны <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="1523091550243476756">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="APP_NAME">%2$s</xliff:g>-д эдгээр зөвшөөрөлтэй харилцан үйлдэл хийхийг зөвшөөрнө:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"нүдний шил"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Энэ апп таны <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="5725890636605211803">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="APP_NAME">%2$s</xliff:g>-д эдгээр зөвшөөрөлтэй харилцан үйлдэл хийхийг зөвшөөрнө:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Төхөөрөмж хоорондын үйлчилгээ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс ойролцоох төхөөрөмжүүд рүү контент дамжуулах зөвшөөрөл хүсэж байна"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
     <string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
     <string name="consent_back" msgid="2560683030046918882">"Буцах"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 70b0567..2c4d6f3 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"सहयोगी डिव्हाइस व्यवस्थापक"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"तुमचे &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; अ‍ॅक्सेस करण्यासाठी &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला अनुमती द्या"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"वॉच"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; द्वारे व्यवस्थापित करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"तुमचे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला तुमच्या सूचनांशी संवाद साधण्याची आणि तुमचा फोन, एसएमएस, संपर्क कॅलेंडर, कॉल लॉग व जवळपासच्या डिव्हाइसच्या परवानग्या अ‍ॅक्सेस करण्याची अनुमती मिळेल."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"तुमचे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला पुढील परवानग्यांशी संवाद साधण्याची अनुमती मिळेल:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"Glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"तुमची <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="5725890636605211803">"तुमचे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला पुढील परवानग्यांशी संवाद साधण्याची अनुमती मिळेल:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"क्रॉस-डिव्हाइस सेवा"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे जवळपासच्या डिव्हाइसवर आशय स्ट्रीम करण्यासाठी तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
     <string name="consent_back" msgid="2560683030046918882">"मागे जा"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 436ff9c..9fdedff 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Pengurus Peranti Rakan"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; anda"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk diurus oleh &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Kalendar, Log panggilan serta Peranti berdekatan anda."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan berinteraksi dengan kebenaran ini:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk menyegerakkan maklumat seperti nama individu yang memanggil, berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Kalendar, Log panggilan dan Peranti berdekatan anda."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk menyegerakkan maklumat seperti nama individu yang memanggil dan mengakses kebenaran ini:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"cermin mata"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Mikrofon dan Peranti berdekatan anda."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk berinteraksi dengan kebenaran ini:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Mikrofon dan Peranti berdekatan anda."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk berinteraksi dengan kebenaran ini:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses maklumat ini daripada telefon anda"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Perkhidmatan silang peranti"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim kandungan kepada peranti berdekatan"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan peranti yang dipilih."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Jangan benarkan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index eb03fb2..406e91c 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"တွဲဖက်ကိရိယာ မန်နေဂျာ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"သင်၏ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ကို သုံးရန် &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို ခွင့်ပြုပါ"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ကို သုံးရန် &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို ခွင့်ပြုပါ"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ သင်၏ဖုန်း၊ SMS စာတိုစနစ်၊ အဆက်အသွယ်များ၊ ပြက္ခဒိန်၊ ခေါ်ဆိုမှတ်တမ်းနှင့် အနီးတစ်ဝိုက်ရှိ စက်များဆိုင်ရာ ခွင့်ပြုချက်များသုံးရန်၊ အကြောင်းကြားချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်။"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ ဤခွင့်ပြုချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်-"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်ရန်၊ သင်၏ဖုန်း၊ SMS စာတိုစနစ်၊ အဆက်အသွယ်များ၊ ပြက္ခဒိန်၊ ခေါ်ဆိုမှတ်တမ်းနှင့် အနီးတစ်ဝိုက်ရှိ စက်များဆိုင်ရာ ခွင့်ပြုချက်များသုံးရန်၊ အကြောင်းကြားချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်။"</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်ရန်နှင့် ဤခွင့်ပြုချက်များသုံးရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်-"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"မျက်မှန်"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ သင့်အကြောင်းကြားချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန်နှင့် သင့်ဖုန်း၊ SMS စာတိုစနစ်၊ အဆက်အသွယ်၊ မိုက်ခရိုဖုန်းနှင့် အနီးတစ်ဝိုက်ရှိ စက်များ၏ ခွင့်ပြုချက်များအား <xliff:g id="APP_NAME">%2$s</xliff:g> ကို သုံးခွင့်ပြုပါမည်။"</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် အက်ပ်လိုအပ်သည်။ ဤခွင့်ပြုချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်-"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ သင်၏ဖုန်း၊ SMS စာတိုစနစ်၊ အဆက်အသွယ်များ၊ မိုက်ခရိုဖုန်းနှင့် အနီးတစ်ဝိုက်ရှိ စက်များဆိုင်ရာ ခွင့်ပြုချက်များသုံးရန်၊ အကြောင်းကြားချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်။"</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ ဤခွင့်ပြုချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"စက်များကြားသုံး ဝန်ဆောင်မှု"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အနီးတစ်ဝိုက်ရှိ စက်များတွင် အကြောင်းအရာတိုက်ရိုက်ဖွင့်ရန် သင့် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"ဤအက်ပ်သည် သင့်ဖုန်းနှင့် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်။"</string>
+    <string name="summary_generic" msgid="4988130802522924650">"ဤအက်ပ်သည် သင့်ဖုန်းနှင့် ရွေးထားသောစက်အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်။"</string>
     <string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
     <string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
     <string name="consent_back" msgid="2560683030046918882">"နောက်သို့"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 76c75617..8833591 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Tillat at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; bruker &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"klokke"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal administreres av &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å samhandle med varslene dine og har tilgang til tillatelsene for telefon, SMS, kontakter, kalender, samtalelogger og enheter i nærheten."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å samhandle med disse tillatelsene:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"briller"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Denne appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å samhandle med varslene dine og har tilgang til tillatelsene for telefon, SMS, kontakter, mikrofon og enheter i nærheten."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å samhandle med disse tillatelsene:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Tjenester på flere enheter"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til å strømme innhold til enheter i nærheten"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tilbake"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 149cbce..f494e79 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"सहयोगी डिभाइसको प्रबन्धक"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"आफ्नो &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; लाई &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; प्रयोग गर्ने अनुमति दिनुहोस्"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&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="summary_watch" msgid="4085794790142204006">"तपाईंको <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="1523091550243476756">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एपलाई अनुमति दिनु पर्ने हुन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई निम्न अनुमतिहरू फेरबदल गर्न दिइने छः"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"तपाईंको <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="7443464525873186735">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एप चाहिन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्ने र यी अनुमतिहरू हेर्ने तथा प्रयोग गर्ने अनुमति दिइने छ:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"चस्मा"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"तपाईंको <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="5725890636605211803">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एपलाई अनुमति दिनु पर्ने हुन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई निम्न अनुमतिहरू फेरबदल गर्न दिइने छ:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"<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="7051392780285915640">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एप चाहिन्छ। <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"क्रस-डिभाइस सेवाहरू"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट नजिकैका डिभाइसहरूमा सामग्री स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने <xliff:g id="DEVICE_NAME">%1$s</xliff:g> का बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।"</string>
+    <string name="summary_generic" msgid="4988130802522924650">"यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने डिभाइसका बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।"</string>
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
     <string name="consent_back" msgid="2560683030046918882">"पछाडि"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 97db70a..bec7e405 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot je &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om te beheren met &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"De app is vereist om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> kan interactie hebben met je meldingen en toegang krijgen tot rechten voor Telefoon, Sms, Contacten, Agenda, Gesprekslijsten en Apparaten in de buurt."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"De app is vereist om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> heeft toestemming om interactie te hebben met de volgende rechten:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"De app is nodig om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag informatie (zoals de naam van iemand die belt) synchroniseren, interactie hebben met je meldingen en krijgt toegang tot de rechten Telefoon, Sms, Contacten, Agenda, Gesprekslijsten en Apparaten in de buurt."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"De app is nodig om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag informatie (zoals de naam van iemand die belt) synchroniseren en krijgt toegang tot deze rechten:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"brillen"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Deze app is vereist om je <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_single_device" msgid="5725890636605211803">"De app is vereist om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> heeft toestemming om interactie te hebben met de volgende rechten:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"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_single_device" msgid="7051392780285915640">"De 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 deze rechten:"</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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cross-device-services"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens je <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om content te streamen naar apparaten in de buurt"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Deze app kan informatie, zoals de naam van iemand die belt, synchroniseren tussen je telefoon en <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Deze app kan informatie (zoals de naam van iemand die belt) synchroniseren tussen je telefoon en het gekozen apparaat."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Terug"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 519e711..b9794c4 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"ସହଯୋଗୀ ଡିଭାଇସ୍ ପରିଚାଳକ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"ଆପଣଙ୍କ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;କୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ବାଛନ୍ତୁ"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଆପ ଆବଶ୍ୟକ। ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ଏବଂ ଆପଣଙ୍କର ଫୋନ, SMS, କଣ୍ଟାକ୍ଟ, କେଲେଣ୍ଡର, କଲ ଲଗ ଓ ଆଖପାଖର ଡିଭାଇସ ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ।"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଆପ ଆବଶ୍ୟକ। ଏହି ଅନୁମତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"ଚଷମା"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଏହି ଆପ ଆବଶ୍ୟକ। ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ଏବଂ ଆପଣଙ୍କର ଫୋନ, SMS, କଣ୍ଟାକ୍ଟ, ମାଇକ୍ରୋଫୋନ ଓ ଆଖପାଖର ଡିଭାଇସ ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ।"</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଆପ ଆବଶ୍ୟକ। ଏହି ଅନୁମତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକରେ ବିଷୟବସ୍ତୁକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ପଛକୁ ଫେରନ୍ତୁ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 8bc9e94..f933c9a 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"ਸੰਬੰਧੀ ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਕ"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ਇਹ ਐਪ ਤੁਹਾਡੇ <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="1523091550243476756">"ਇਹ ਐਪ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="APP_NAME">%2$s</xliff:g> ਨੂੰ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"ਐਨਕਾਂ"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ਇਹ ਐਪ ਤੁਹਾਡੇ <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="5725890636605211803">"ਇਹ ਐਪ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="APP_NAME">%2$s</xliff:g> ਨੂੰ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਲਈ ਸਮੱਗਰੀ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"ਆਗਿਆ ਦਿਓ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 2fc8a47..6b71592 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Menedżer urządzeń towarzyszących"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Zezwól 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>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <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="summary_watch" msgid="4085794790142204006">"Aplikacja jest niezbędna do zarządzania profilem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła 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="1523091550243476756">"Aplikacja jest niezbędna do zarządzania profilem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła korzystać z tych powiadomień:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"Okulary"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"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 wchodzić w interakcję z powiadomieniami i korzystać z uprawnień dotyczących telefonu, SMS-ów, kontaktów, mikrofonu oraz urządzeń w pobliżu."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"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 korzystać z tych uprawnień:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Zezwól urządzeniu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści z aplikacji na innym urządzeniu"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Usługi na innym urządzeniu"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści na urządzeniach w pobliżu"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
     <string name="consent_back" msgid="2560683030046918882">"Wstecz"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index aa054a8..29f00ca 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"O app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. O <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com suas notificações e acessar os apps Telefone, SMS, Contatos, Google Agenda, registros de chamadas e as permissões de dispositivos por perto."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"O app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas permissões:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, interagir com suas notificações e acessar as permissões de telefone, SMS, contatos, agenda, registro de chamadas e dispositivos por perto."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar seu dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"óculos"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Esse app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. O <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com suas notificações e acessar os apps Telefone, SMS, Contatos, microfone e as permissões de dispositivos por perto."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"O app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas permissões:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá interagir com suas notificações e acessar suas permissões de telefone, SMS, contatos, microfone e dispositivos por perto."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá interagir com estas permissões:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Serviços entre dispositivos"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de conteúdo para dispositivos por perto"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"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>
+    <string name="summary_generic" msgid="4988130802522924650">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 852d994..d5978e2 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos associados"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda ao seu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda ao dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerido pela app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"A app é necessária para gerir o seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com as suas notificações e aceder às autorizações do Telemóvel, SMS, Contactos, Calendário, Registos de chamadas e Dispositivos próximos."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"A app é necessária para gerir o seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas autorizações:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"A app é necessária para gerir o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder sincronizar informações, como o nome do autor de uma chamada, interagir com as suas notificações e aceder às autorizações do Telefone, SMS, Contactos, Calendário, Registos de chamadas e Dispositivos próximos."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"A app é necessária para gerir o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder sincronizar informações, como o nome do autor de uma chamada, e aceder às seguintes autorizações:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"óculos"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Esta app é necessária para gerir o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com as suas notificações e aceder às autorizações do Telemóvel, SMS, Contactos, Microfone e Dispositivos próximos."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"A app é necessária para gerir o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas autorizações:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Esta app é necessária para gerir o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com as suas notificações e aceder às autorizações do Telemóvel, SMS, Contactos, Microfone e Dispositivos próximos."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"A app é necessária para gerir o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A app <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas autorizações:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Serviços entre dispositivos"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do dispositivo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer stream de conteúdo para dispositivos próximos"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"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>
+    <string name="summary_generic" msgid="4988130802522924650">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, entre o telemóvel e o dispositivo escolhido."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index aa054a8..29f00ca 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"O app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. O <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com suas notificações e acessar os apps Telefone, SMS, Contatos, Google Agenda, registros de chamadas e as permissões de dispositivos por perto."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"O app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas permissões:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, interagir com suas notificações e acessar as permissões de telefone, SMS, contatos, agenda, registro de chamadas e dispositivos por perto."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar seu dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"óculos"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Esse app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. O <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com suas notificações e acessar os apps Telefone, SMS, Contatos, microfone e as permissões de dispositivos por perto."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"O app é necessário para gerenciar seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> vai poder interagir com estas permissões:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá interagir com suas notificações e acessar suas permissões de telefone, SMS, contatos, microfone e dispositivos por perto."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá interagir com estas permissões:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Serviços entre dispositivos"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de conteúdo para dispositivos por perto"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"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>
+    <string name="summary_generic" msgid="4988130802522924650">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index be66dca..e3a86c1 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Manager de dispozitiv Companion"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze dispozitivul &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ceas"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Alege un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplicația este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu notificările tale și să îți acceseze permisiunile pentru Telefon, SMS, Agendă, Calendar, Jurnale de apeluri și Dispozitive din apropiere."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplicația este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu următoarele permisiuni:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"ochelari"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Această aplicație este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu notificările tale și să-ți acceseze permisiunile pentru telefon, SMS-uri, agendă, microfon și dispozitivele din apropiere."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Aplicația este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu următoarele permisiuni:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele tale"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Servicii pe mai multe dispozitive"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream conținut pe dispozitivele din apropiere"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Permite"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nu permite"</string>
     <string name="consent_back" msgid="2560683030046918882">"Înapoi"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 8e2aed1..832bfe9 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Управление подключенными устройствами"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ к устройству &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ к устройству &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"часы"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Выберите устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), которым будет управлять приложение &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Это приложение необходимо для управления устройством \"<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="1523091550243476756">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" получит следующие разрешения:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Это приложение необходимо для управления устройством \"<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="7443464525873186735">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" сможет синхронизировать данные, например журнала звонков, и получит следующие разрешения:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"Очки"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Это приложение необходимо для управления устройством \"<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="5725890636605211803">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" получит следующие разрешения:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Это приложение необходимо для управления устройством \"<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="7051392780285915640">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Сервисы взаимодействия устр-в"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение на трансляцию контента на устройства поблизости от имени вашего устройства \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\"."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Приложение сможет синхронизировать информацию между телефоном и устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", например данные из журнала звонков."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Приложение сможет синхронизировать информацию между телефоном и выбранным устройством, например данные из журнала звонков."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
     <string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 0b9248b..fbe4823 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"සහායක උපාංග කළමනාකරු"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; කළමනාකරණය කිරීමට ඉඩ දෙන්න"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; මගින් කළමනාකරණය කරනු ලැබීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනා කිරීමට මෙම යෙදුම අවශ්‍යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> ඔබේ දැනුම්දීම් සමග අන්තර්ක්‍රියා කිරීමට සහ ඔබේ දුරකථනය, කෙටිපණිවුඩය, සම්බන්‍ධතා, දිනදර්ශනය, ඇමතුම් ලොග සහ අවට උපාංග අවසර වෙත ප්‍රවේශ වීමට ඉඩ දෙයි."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනා කිරීමට මෙම යෙදුම අවශ්‍යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> හට මෙම අවසර සමග අන්තර්ක්‍රියා කිරීමට අවසර දෙනු ලැබේ:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"කණ්ණාඩි"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"මෙම යෙදුමට ඔබේ <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="5725890636605211803">"ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනා කිරීමට මෙම යෙදුම අවශ්‍යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> හට මෙම අවසර සමග අන්තර්ක්‍රියා කිරීමට අවසර දෙනු ලැබේ:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"හරස්-උපාංග සේවා"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> අවට උපාංග වෙත අන්තර්ගතය ප්‍රවාහ කිරීමට ඔබේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් අවසර ඉල්ලයි"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
     <string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
     <string name="consent_back" msgid="2560683030046918882">"ආපසු"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 6be4e2c..805c2c8 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Správca sprievodných zariadení"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k zariadeniu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k zariadeniu &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 profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý bude spravovať aplikácia &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s vašimi upozorneniami a získa prístup k povoleniam telefónu, SMS, kontaktov, kalendára, zoznamu hovorov a zariadení v okolí."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s týmito povoleniami:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Daná aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť synchronizovať informácie, napríklad meno volajúceho, interagovať s vašimi upozorneniami a získavať prístup k povoleniam telefónu, SMS, kontaktov, kalendára, zoznamu hovorov a zariadení v okolí."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Daná aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť synchronizovať informácie, napríklad meno volajúceho, a získavať prístup k týmto povoleniam:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"okuliare"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Táto aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s vašimi upozorneniami a získa prístup k povoleniam pre telefón, SMS, kontakty, mikrofón a zariadenia v okolí."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s týmito povoleniami:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Táto aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s vašimi upozorneniami a získa prístup k povoleniam pre telefón, SMS, kontakty, mikrofón a zariadenia v okolí."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Daná aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s týmito povoleniami:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Služby pre viacero zariadení"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> povolenie streamovať obsah do zariadení v okolí"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a vybraným zariadením."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
     <string name="consent_back" msgid="2560683030046918882">"Späť"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 7d3d168..6234286 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Upravitelj spremljevalnih naprav"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dovolite dostop do naprave &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <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="summary_watch" msgid="4085794790142204006">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bosta omogočeni 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="1523091550243476756">"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> bo omogočena interakcija s temi dovoljenji:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"očala"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bosta omogočeni interakcija z obvestili in uporaba dovoljenj Telefon, SMS, Stiki, Mikrofon in Naprave v bližini."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"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> bo omogočena interakcija s temi dovoljenji:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Storitve za zunanje naprave"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje vsebine v napravah v bližini."</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nazaj"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 6ff4ce8..0ca0173 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Menaxheri i pajisjes shoqëruese"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje te &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje te &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Zgjidh \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" që do të menaxhohet nga &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Aplikacioni nevojitet për të menaxhuar profilin tënd të \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Kalendarit\", \"Evidencave të telefonatave\" dhe të \"Pajisjeve në afërsi\"."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Aplikacioni nevojitet për të menaxhuar profilin tënd të \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të ndërveprojë me këto leje:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Aplikacioni nevojitet për të menaxhuar profilin tënd të <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të sinkronizojë informacione, si p.sh. emri i 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="7443464525873186735">"Aplikacioni nevojitet për të menaxhuar profilin tënd të <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të sinkronizojë informacione, si p.sh. emri i dikujt që po telefonon dhe të ketë qasje te këto leje:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"syzet"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"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ë ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Mikrofonit\" dhe të \"Pajisjeve në afërsi\"."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Ky aplikacion nevojitet për të menaxhuar profilin tënd të \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" do të lejohet të ndërveprojë me këto leje:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"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ë ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Mikrofonit\" dhe të \"Pajisjeve në afërsi\"."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Aplikacioni 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ë ndërveprojë me këto leje:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Shërbimet mes pajisjeve"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar përmbajtje te pajisjet në afërsi"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emri i dikujt që po telefonon, mes telefonit tënd dhe <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emri i dikujt që po telefonon, mes telefonit tënd dhe pajisjes së zgjedhur."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
     <string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
     <string name="consent_back" msgid="2560683030046918882">"Pas"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index fe9e5f9a..30f83e9 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа уређају &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"сат"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Одаберите <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Апликација је потребна за управљање уређајем <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="1523091550243476756">"Апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са овим дозволама:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"наочаре"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Ова апликација је потребна за управљање уређајем <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="5725890636605211803">"Апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са овим дозволама:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Услуге на више уређаја"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да стримује садржај на уређаје у близини"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 11f115d..c3c9721 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Tillåt att &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får åtkomst till din &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"klocka"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för hantering av &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att interagera med dina aviseringar och får åtkomst till behörigheterna Telefon, Sms, Kontakter, Kalender, Samtalsloggar och Enheter i närheten."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att interagera med följande behörigheter:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasögon"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får interagera med dina aviseringar och får åtkomst till behörigheterna Telefon, Sms, Kontakter, Mikrofon och Enheter i närheten."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att interagera med följande behörigheter:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Tjänster för flera enheter"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet för att streama innehåll till enheter i närheten för din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tillåt inte"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tillbaka"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 2c6bc8f..873c857 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Kidhibiti cha Vifaa Visaidizi"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; yako"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"saa"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili idhibitiwe na &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kufikia arifa zako na kufikia ruhusa zako za Simu, SMS, Anwani, Kalenda, Rekodi za nambari za simu na Vifaa vilivyo karibu."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kufikia ruhusa hizi:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"miwani"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kutumia arifa zako na kufikia ruhusa zako za Simu, SMS, Anwani, Maikrofoni na Vifaa vilivyo Karibu."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kufikia ruhusa hizi:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili itiririshe programu kati ya vifaa vyako"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Huduma za kifaa kilichounganishwa kwingine"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ili itiririshe maudhui kwenye vifaa vilivyo karibu"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
     <string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nyuma"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index ac454ba..fbfbc40 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"உங்கள் &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதியுங்கள்"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> தேர்ந்தெடுக்கப்பட வேண்டும்"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவை. உங்கள் மொபைல், மெசேஜ், தொடர்புகள், கேலெண்டர், அழைப்புப் பதிவுகள், அருகிலுள்ள சாதனங்கள் ஆகியவற்றுக்கான அணுகலையும், உங்கள் அறிவிப்புகளைப் பார்ப்பதற்கான அனுமதியையும் <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸ் பெறும்."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவை. இந்த அனுமதிகளைப் பயன்படுத்த <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸ் அனுமதிக்கப்படும்:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"கிளாஸஸ்"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"உங்கள் <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="5725890636605211803">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவை. இந்த அனுமதிகளைப் பயன்படுத்த <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸ் அனுமதிக்கப்படும்:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவும்"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"பன்முக சாதன சேவைகள்"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"அருகிலுள்ள சாதனங்களுடன் உள்ளடக்கத்தை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%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" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
     <string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
     <string name="consent_back" msgid="2560683030046918882">"பின்செல்"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index cb0356c..7c077ce 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"సహచర పరికర మేనేజర్"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"మీ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;ను యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ను అనుమతించండి"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; ద్వారా మేనేజ్ చేయబడటానికి ఒక <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>‌ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. మీ నోటిఫికేషన్‌లతో ఇంటరాక్ట్ అవ్వడానికి, అలాగే మీ ఫోన్, SMS, కాంటాక్ట్‌లు, క్యాలెండర్, కాల్ లాగ్‌లు, సమీపంలోని పరికరాల అనుమతులను యాక్సెస్ చేయడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>‌ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. ఈ అనుమతులతో ఇంటరాక్ట్ అవ్వడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"గ్లాసెస్"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"మీ <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="5725890636605211803">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>‌ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. ఈ అనుమతులతో ఇంటరాక్ట్ అవ్వడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <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">"Cross-device services"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"మీ పరికరాల మధ్య యాప్‌లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"క్రాస్-డివైజ్ సర్వీస్‌లు"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"సమీపంలోని పరికరాలకు కంటెంట్‌ను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"అనుమతించండి"</string>
     <string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
     <string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index e42bec5..7438ab32 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึง &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; ของคุณ"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึง &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string>
     <string name="chooser_title" msgid="2262294130493605839">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะให้มีการจัดการโดย &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"ต้องใช้แอปนี้ในการจัดการ<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="1523091550243476756">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้โต้ตอบกับสิทธิ์เหล่านี้"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"ต้องใช้แอปนี้ในการจัดการ<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="7443464525873186735">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้ซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา และมีสิทธิ์เข้าถึงสิ่งต่างๆ ต่อไปนี้"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"แว่นตา"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"ต้องใช้แอปนี้ในการจัดการ <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="5725890636605211803">"ต้องใช้แอปนี้ในการจัดการ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้โต้ตอบกับสิทธิ์เหล่านี้"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"ต้องใช้แอปนี้ในการจัดการ<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="7051392780285915640">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$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>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"บริการหลายอุปกรณ์"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมเนื้อหาไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและ<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ได้"</string>
+    <string name="summary_generic" msgid="4988130802522924650">"แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและอุปกรณ์ที่เลือกไว้ได้"</string>
     <string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
     <string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
     <string name="consent_back" msgid="2560683030046918882">"กลับ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 15b69a2..2fd2eda 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Kasamang Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang iyong &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"relo"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para pamahalaan ng &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Kailangan ang app para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na makipag-ugnayan sa mga notification mo at i-access ang iyong pahintulot sa Telepono, SMS, Mga Contact, Kalendaryo, Log ng mga tawag, at Mga kalapit na device."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Kailangan ang app para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na makipag-ugnayan sa mga pahintulot na ito:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"salamin"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Kailangan ang app na ito para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na makipag-ugnayan sa mga notification mo at i-access ang iyong mga pahintulot sa Telepono, SMS, Mga Contact, Mikropono, at Mga kalapit na device."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Kailangan ang app para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na makipag-ugnayan sa mga pahintulot na ito:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyong ito sa iyong telepono"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Mga cross-device na serbisyo"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Humihiling ng pahintulot ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng content sa mga kalapit na device"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Huwag payagan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Bumalik"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 35b99a7..8a73c65 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; cihazınıza erişmesi için &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasına izin verin"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"saat"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; tarafından yönetilecek bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> adlı uygulamanın bildirimlerinizle etkileşimde bulunup Telefon, SMS, Kişiler, Takvim, Arama kayıtları ve Yakındaki cihazlar izinlerinize erişmesine izin verilir."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> uygulamasının şu izinlerle etkileşime girmesine izin verilir:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> adlı uygulamanın bildirimlerinizle etkileşimde bulunup Telefon, SMS, Kişiler, Mikrofon ve Yakındaki cihazlar izinlerine erişmesine izin verilir."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> uygulamasının şu izinlerle etkileşime girmesine izin verilir:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Cihazlar arası hizmetler"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g>, yakındaki cihazlarda içerikleri canlı oynatmak için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
     <string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
     <string name="consent_back" msgid="2560683030046918882">"Geri"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index d1d0815..1ba997e 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Диспетчер супутніх пристроїв"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Надати додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до пристрою &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"годинник"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, яким керуватиме додаток &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Цей додаток потрібен, щоб керувати пристроєм \"<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="1523091550243476756">"Цей додаток потрібен, щоб керувати пристроєм \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Додаток <xliff:g id="APP_NAME">%2$s</xliff:g> зможе взаємодіяти з такими дозволами:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"окуляри"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Цей додаток потрібен, щоб керувати пристроєм \"<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="5725890636605211803">"Цей додаток потрібен, щоб керувати пристроєм \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Додаток <xliff:g id="APP_NAME">%2$s</xliff:g> зможе взаємодіяти з такими дозволами:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Сервіси для кількох пристроїв"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) запитує дозвіл на трансляцію контенту на пристрої поблизу"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 7cd681c..f83e216d 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"ساتھی آلہ مینیجر"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"‏‎&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;‎ کو اپنے ‎&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;‎ تک رسائی کی اجازت دیں"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string>
     <string name="chooser_title" msgid="2262294130493605839">"‏&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; کے ذریعے نظم کئے جانے کیلئے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو منتخب کریں"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"‏آپ کے <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="1523091550243476756">"آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کا نظم کرنے کے لئے ایپ کی ضرورت ہے۔ <xliff:g id="APP_NAME">%2$s</xliff:g> کو ان اجازتوں کے ساتھ تعامل کرنے کی اجازت ہوگی:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"گلاسز"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"‏آپ کے <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="5725890636605211803">"آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کا نظم کرنے کے لیے ایپ کی ضرورت ہے۔ <xliff:g id="APP_NAME">%2$s</xliff:g> کو ان اجازتوں کے ساتھ تعامل کرنے کی اجازت ہوگی:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"‏اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو اجازت دیں"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"کراس آلے کی سروسز"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے مواد کے قریبی آلات کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
     <string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
     <string name="consent_back" msgid="2560683030046918882">"پیچھے"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 4a6de17..4748e14 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasiga kirish uchun &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga ruxsat bering"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; qurilmasidan foydalanishga ruxsat bering"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"soat"</string>
     <string name="chooser_title" msgid="2262294130493605839">"&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; boshqaradigan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qurilmasini tanlang"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> profilini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, taqvim, chaqiruvlar jurnali va yaqin-atrofdagi qurilmalarga kirishga ruxsat beriladi."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> profilini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga quyidagi ruxsatlar bilan ishlashga ruxsat beriladi:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmangizni boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga chaqiruvchining ismi, bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, taqvim, chaqiruvlar jurnali va yaqin-atrofdagi qurilmalarni aniqlash kabi maʼlumotlarni sinxronlashga ruxsat beriladi."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmangizni boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga chaqiruvchining ismi kabi maʼlumotlarni sinxronlash va quyidagi amallarni bajarishga ruxsat beriladi:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"koʻzoynak"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Bu ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> profilini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, mikrofon va yaqin-atrofdagi qurilmalarga kirishga ruxsat beriladi."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> profilini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga quyidagi ruxsatlar bilan ishlashga ruxsat beriladi:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Bu ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, mikrofon va yaqin-atrofdagi qurilmalarga kirishga ruxsat beriladi."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga quyidagi ruxsatlar bilan ishlashga ruxsat beriladi:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Qurilmalararo xizmatlar"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> qurilmangizdan nomidan atrofdagi qurilmalarga kontent uzatish uchun ruxsat olmoqchi"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Bu ilova telefoningiz va <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasida chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Bu ilova telefoningiz va tanlangan qurilmada chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
     <string name="consent_back" msgid="2560683030046918882">"Orqaga"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 62f613b..e5f50af 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; của bạn"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sẽ do &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; quản lý"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép tương tác với thông báo và truy cập vào Điện thoại, SMS, Danh bạ, Lịch, Nhật ký cuộc gọi và Thiết bị ở gần."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> được quyền tương tác với những chức năng sau:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"kính"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép tương tác với thông báo cũng như sử dụng các quyền đối với Điện thoại, SMS, Danh bạ, Micrô của bạn và Thiết bị ở gần bạn."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép tương tác bằng những quyền truy cập sau:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Dịch vụ trên nhiều thiết bị"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang thay mặt <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yêu cầu quyền để truyền nội dung đến các thiết bị ở gần"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
     <string name="consent_no" msgid="2640796915611404382">"Không cho phép"</string>
     <string name="consent_back" msgid="2560683030046918882">"Quay lại"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index b6fa7fc..c863fa8 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"配套设备管理器"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"允许&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;访问您的&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"允许&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="summary_watch" msgid="4085794790142204006">"需要使用此应用,才能管理您的<xliff:g id="DEVICE_NAME">%1$s</xliff:g>。<xliff:g id="APP_NAME">%2$s</xliff:g>将能与通知交互,并可获得电话、短信、通讯录、日历、通话记录和附近设备的访问权限。"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"需要使用此应用,才能管理您的<xliff:g id="DEVICE_NAME">%1$s</xliff:g>。<xliff:g id="APP_NAME">%2$s</xliff:g>可与以下权限交互:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"需要使用此应用才能管理您的“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。<xliff:g id="APP_NAME">%2$s</xliff:g>将能同步信息(例如来电者的姓名),与通知交互,并可获得电话、短信、通讯录、日历、通话记录和附近设备的访问权限。"</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"需要使用此应用才能管理您的“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。<xliff:g id="APP_NAME">%2$s</xliff:g>将能同步信息(例如来电者的姓名),并可使用以下权限:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"眼镜"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"需要使用此应用才能管理您的设备“<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="5725890636605211803">"需要使用此应用,才能管理您的“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。“<xliff:g id="APP_NAME">%2$s</xliff:g>”将可使用以下权限:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"需要使用此应用才能管理“<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="7051392780285915640">"需要使用此应用才能管理“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。<xliff:g id="APP_NAME">%2$s</xliff:g>将可使用以下权限:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”&lt;strong&gt;&lt;/strong&gt;访问您手机中的这项信息"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"跨设备服务"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求向您附近的设备流式传输内容"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"此应用将能够在您的手机和“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”之间同步信息,例如来电者的姓名。"</string>
+    <string name="summary_generic" msgid="4988130802522924650">"此应用将能够在您的手机和所选设备之间同步信息,例如来电者的姓名。"</string>
     <string name="consent_yes" msgid="8344487259618762872">"允许"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允许"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 6f19a84..7620ce4 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"允許&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 存取您的 &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
     <string name="chooser_title" msgid="2262294130493605839">"選擇由 &lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt; 管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"必須使用此應用程式管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可存取通知、電話、短訊、通訊錄和日曆、通話記錄和咫尺共享裝置權限。"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可存取以下權限:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"必須使用此應用程式,才能管理「<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="5725890636605211803">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可存取以下權限:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取您手機中的這項資料"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在為 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求權限,以在裝置之間串流應用程式內容"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"跨裝置服務"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」將內容串流至附近的裝置"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 48c289c..a829961 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -17,14 +17,19 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"允許「<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;&lt;/strong&gt;"</string>
+    <!-- no translation found for confirmation_title (8024993972587946678) -->
+    <skip />
     <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string>
     <string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可存取通知、電話、簡訊、聯絡人和日曆、通話記錄和鄰近裝置的權限。"</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可與下列權限互動:"</string>
+    <!-- no translation found for summary_watch (6566922405914995759) -->
+    <skip />
+    <!-- no translation found for summary_watch_single_device (7443464525873186735) -->
+    <skip />
     <string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"這個應用程式是管理「<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="5725890636605211803">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可使用以下權限:"</string>
+    <!-- no translation found for summary_glasses (3808267780579061241) -->
+    <skip />
+    <!-- no translation found for summary_glasses_single_device (7051392780285915640) -->
+    <skip />
     <string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取手機中的這項資訊"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string>
@@ -38,7 +43,10 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"跨裝置服務"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」將內容串流傳輸到鄰近裝置"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <!-- no translation found for summary_generic_single_device (4735072202474939111) -->
+    <skip />
+    <!-- no translation found for summary_generic (4988130802522924650) -->
+    <skip />
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index f81406e..7af3531 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -17,14 +17,14 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"Isiphathi sedivayisi esihambisanayo"</string>
-    <string name="confirmation_title" msgid="3785000297483688997">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukuthi ifinyelele i-&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; yakho"</string>
+    <string name="confirmation_title" msgid="8024993972587946678">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukuthi ifinyelele i-&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"buka"</string>
     <string name="chooser_title" msgid="2262294130493605839">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ezophathwa yi-&lt;strong&gt;<xliff:g id="APP_NAME">%2$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="summary_watch" msgid="4085794790142204006">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuthi ihlanganyele nezaziso zakho futhi ifinyelele Ifoni yakho, i-SMS, Oxhumana nabo, Ikhalenda, Amarekhodi wamakholi Nezimvume zamadivayisi aseduze."</string>
-    <string name="summary_watch_single_device" msgid="1523091550243476756">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. <xliff:g id="APP_NAME">%2$s</xliff:g> uzovunyelwa ukusebenzisana nalezi zimvume:"</string>
+    <string name="summary_watch" msgid="6566922405914995759">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, ukusebenzisana nezaziso zakho futhi ufinyelele Ifoni yakho, i-SMS, Oxhumana Nabo, Ikhalenda, Amarekhodi Amakholi nezimvume zamadivayisi aseduze."</string>
+    <string name="summary_watch_single_device" msgid="7443464525873186735">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, futhi ufinyelele lezi zimvume:"</string>
     <string name="profile_name_glasses" msgid="8488394059007275998">"Izingilazi"</string>
-    <string name="summary_glasses" msgid="8987925853224595628">"Le app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuthi ihlanganyele nezaziso zakho futhi ifinyelele kufoni yakho, i-SMS, Oxhumana nabo, Imakrofoni nezimvume zamadivayisi aseduze."</string>
-    <string name="summary_glasses_single_device" msgid="5725890636605211803">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukusebenzisana nalezi zimvume:"</string>
+    <string name="summary_glasses" msgid="3808267780579061241">"Le app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuthi ihlanganyele nezaziso zakho futhi ifinyelele kufoni yakho, i-SMS, Oxhumana nabo, Imakrofoni nezimvume zamadivayisi aseduze."</string>
+    <string name="summary_glasses_single_device" msgid="7051392780285915640">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukusebenzisana nalezi zimvume:"</string>
     <string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifinyelele lolu lwazi kusukela efonini yakho"</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
     <string name="helper_summary_app_streaming" msgid="5977509499890099">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
@@ -38,7 +38,8 @@
     <string name="helper_title_nearby_device_streaming" msgid="6124438217620593669">"Amasevisi amadivayisi amaningi"</string>
     <string name="helper_summary_nearby_device_streaming" msgid="5538329403511524333">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze okuqukethwe kumadivayisi aseduze"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
-    <string name="summary_generic" msgid="2346762210105903720"></string>
+    <string name="summary_generic_single_device" msgid="4735072202474939111">"Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho ne-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="summary_generic" msgid="4988130802522924650">"Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho nedivayisi ekhethiwe."</string>
     <string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Emuva"</string>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 7397688..b842761 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -20,7 +20,7 @@
     <string name="app_label">Companion Device Manager</string>
 
     <!-- Title of the device association confirmation dialog. -->
-    <string name="confirmation_title">Allow &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; to access your &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%2$s</xliff:g>&lt;/strong&gt;</string>
+    <string name="confirmation_title">Allow &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%1$s</xliff:g>&lt;/strong&gt; to access &lt;strong&gt;<xliff:g id="device_name" example="ASUS ZenWatch 2">%2$s</xliff:g>&lt;/strong&gt;</string>
 
     <!-- ================= DEVICE_PROFILE_WATCH and null profile ================= -->
 
@@ -31,10 +31,10 @@
     <string name="chooser_title">Choose a <xliff:g id="profile_name" example="watch">%1$s</xliff:g> to be managed by &lt;strong&gt;<xliff:g id="app_name" example="Android Wear">%2$s</xliff:g>&lt;/strong&gt;</string>
 
     <!-- Description of the privileges the application will get if associated with the companion device of WATCH profile (type) [CHAR LIMIT=NONE] -->
-    <string name="summary_watch">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.</string>
+    <string name="summary_watch">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions.</string>
 
     <!-- Description of the privileges the application will get if associated with the companion device of WATCH profile for singleDevice(type) [CHAR LIMIT=NONE] -->
-    <string name="summary_watch_single_device">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to interact with these permissions:</string>
+    <string name="summary_watch_single_device">The app is needed to manage your <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>. <xliff:g id="app_name" example="Android Wear">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:</string>
 
     <!-- TODO(b/256140614) To replace all glasses related strings with final versions -->
     <!-- ================= DEVICE_PROFILE_GLASSES ================= -->
@@ -43,10 +43,10 @@
     <string name="profile_name_glasses">glasses</string>
 
     <!-- Description of the privileges the application will get if associated with the companion device of GLASSES profile (type) [CHAR LIMIT=NONE] -->
-    <string name="summary_glasses">This app is needed to manage your <xliff:g id="device_name" example="My Glasses">%1$s</xliff:g>. <xliff:g id="app_name" example="Glasses">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions.</string>
+    <string name="summary_glasses">This app is needed to manage <xliff:g id="device_name" example="My Glasses">%1$s</xliff:g>. <xliff:g id="app_name" example="Glasses">%2$s</xliff:g> will be allowed to interact with your notifications and access your Phone, SMS, Contacts, Microphone and Nearby devices permissions.</string>
 
     <!-- Description of the privileges the application will get if associated with the companion device of GLASSES profile for singleDevice(type) [CHAR LIMIT=NONE] -->
-    <string name="summary_glasses_single_device">The app is needed to manage your <xliff:g id="device_name" example="My Glasses">%1$s</xliff:g>. <xliff:g id="app_name" example="Glasses">%2$s</xliff:g> will be allowed to interact with these permissions:</string>
+    <string name="summary_glasses_single_device">The app is needed to manage <xliff:g id="device_name" example="My Glasses">%1$s</xliff:g>. <xliff:g id="app_name" example="Glasses">%2$s</xliff:g> will be allowed to interact with these permissions:</string>
 
     <!-- ================= DEVICE_PROFILE_APP_STREAMING ================= -->
 
@@ -99,7 +99,10 @@
     <string name="profile_name_generic">device</string>
 
     <!-- Description of the privileges the application will get if associated with the companion device of unspecified profile (type) [CHAR LIMIT=NONE] -->
-    <string name="summary_generic"></string>
+    <string name="summary_generic_single_device">This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="device_name" example="My Watch">%1$s</xliff:g>.</string>
+
+    <!-- Description of the privileges the application will get if associated with the companion device of unspecified profile (type) [CHAR LIMIT=NONE] -->
+    <string name="summary_generic">This app will be able to sync info, like the name of someone calling, between your phone and the chosen device.</string>
 
     <!-- ================= Buttons ================= -->
 
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index c5ed5c9..918f9c6 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -546,17 +546,16 @@
         }
 
         if (deviceProfile == null) {
-            // Summary is not needed for null profile.
-            mSummary.setVisibility(View.GONE);
+            summary = getHtmlFromResources(this, SUMMARIES.get(null), deviceName);
             mConstraintList.setVisibility(View.GONE);
         } else {
+            summary = getHtmlFromResources(this, SUMMARIES.get(deviceProfile),
+                    getString(PROFILES_NAME.get(deviceProfile)), appLabel);
             mPermissionTypes.addAll(PERMISSION_TYPES.get(deviceProfile));
             setupPermissionList();
         }
 
         title = getHtmlFromResources(this, TITLES.get(deviceProfile), appLabel, deviceName);
-        summary = getHtmlFromResources(this, SUMMARIES.get(deviceProfile),
-                getString(PROFILES_NAME.get(deviceProfile)), appLabel);
         profileIcon = getIcon(this, PROFILE_ICON.get(deviceProfile));
 
         mTitle.setText(title);
@@ -586,7 +585,6 @@
 
         if (deviceProfile == null) {
             summary = getHtmlFromResources(this, summaryResourceId);
-            mSummary.setVisibility(View.GONE);
         } else {
             summary = getHtmlFromResources(this, summaryResourceId, profileName, appLabel);
         }
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
index 6f5f4fe..e3fd354 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceResources.java
@@ -88,7 +88,7 @@
         final Map<String, Integer> map = new ArrayMap<>();
         map.put(DEVICE_PROFILE_WATCH, R.string.summary_watch_single_device);
         map.put(DEVICE_PROFILE_GLASSES, R.string.summary_glasses_single_device);
-        map.put(null, R.string.summary_generic);
+        map.put(null, R.string.summary_generic_single_device);
 
         SUMMARIES = unmodifiableMap(map);
     }
diff --git a/packages/CredentialManager/Android.bp b/packages/CredentialManager/Android.bp
index 2cb3468..00d42bd 100644
--- a/packages/CredentialManager/Android.bp
+++ b/packages/CredentialManager/Android.bp
@@ -31,6 +31,7 @@
         "androidx.compose.ui_ui",
         "androidx.compose.ui_ui-tooling",
         "androidx.core_core-ktx",
+        "androidx.credentials_credentials",
         "androidx.lifecycle_lifecycle-extensions",
         "androidx.lifecycle_lifecycle-livedata",
         "androidx.lifecycle_lifecycle-runtime-ktx",
diff --git a/packages/CredentialManager/AndroidManifest.xml b/packages/CredentialManager/AndroidManifest.xml
index 5a4d256..499d130 100644
--- a/packages/CredentialManager/AndroidManifest.xml
+++ b/packages/CredentialManager/AndroidManifest.xml
@@ -32,7 +32,6 @@
       android:supportsRtl="true"
       android:theme="@style/Theme.CredentialSelector">
 
-    <!--TODO: make sure implementing singleTop on NewIntent-->
     <activity
         android:name=".CredentialSelectorActivity"
         android:exported="true"
diff --git a/packages/CredentialManager/res/drawable/ic_passkeys_onboarding.png b/packages/CredentialManager/res/drawable/ic_passkeys_onboarding.png
deleted file mode 100644
index 388d098..0000000
--- a/packages/CredentialManager/res/drawable/ic_passkeys_onboarding.png
+++ /dev/null
Binary files differ
diff --git a/packages/CredentialManager/res/drawable/ic_passkeys_onboarding.xml b/packages/CredentialManager/res/drawable/ic_passkeys_onboarding.xml
new file mode 100644
index 0000000..91b23cc
--- /dev/null
+++ b/packages/CredentialManager/res/drawable/ic_passkeys_onboarding.xml
@@ -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.
+  -->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="vector"
+    android:width="316dp"
+    android:height="168dp"
+    android:viewportWidth="316"
+    android:viewportHeight="168">
+    <path
+        android:name="path"
+        android:pathData="M 238 56 C 238 42.75 227.26 32 214 32 C 200.75 32 190 42.75 190 56 L 190 74 C 190 77.31 192.69 80 196 80 L 214 80 C 227.26 80 238 69.26 238 56 Z"
+        android:fillColor="#ffba29"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_1"
+        android:pathData="M 199.42 51.71 C 199.34 51.65 199.29 51.56 199.27 51.44 C 199.26 51.31 199.27 51.21 199.33 51.13 C 201.08 48.8 203.23 46.98 205.79 45.67 C 208.35 44.36 211.07 43.71 213.96 43.71 C 216.85 43.71 219.64 44.34 222.25 45.61 C 224.86 46.88 227.03 48.69 228.75 51.05 C 228.86 51.19 228.9 51.32 228.85 51.45 C 228.81 51.57 228.72 51.68 228.58 51.76 C 228.5 51.82 228.38 51.84 228.23 51.84 C 228.08 51.84 227.96 51.76 227.88 51.59 C 226.27 49.34 224.23 47.63 221.78 46.47 C 219.32 45.3 216.72 44.72 213.97 44.72 C 211.22 44.72 208.68 45.32 206.26 46.51 C 203.84 47.7 201.83 49.4 200.22 51.59 C 200.08 51.76 199.94 51.84 199.8 51.84 C 199.66 51.84 199.54 51.8 199.42 51.72 Z M 218.75 72.42 C 216 71.7 213.72 70.28 211.9 68.17 C 210.08 66.06 209.17 63.49 209.17 60.46 C 209.17 59.13 209.65 58.02 210.61 57.15 C 211.57 56.27 212.71 55.84 214.05 55.84 C 215.39 55.84 216.48 56.28 217.43 57.15 C 218.37 58.02 218.85 59.13 218.85 60.46 C 218.85 61.49 219.23 62.34 220 63.02 C 220.76 63.7 221.66 64.04 222.69 64.04 C 223.72 64.04 224.64 63.69 225.38 63 C 226.12 62.31 226.48 61.46 226.48 60.46 C 226.48 57.13 225.25 54.32 222.79 52.04 C 220.33 49.76 217.39 48.62 213.98 48.62 C 210.57 48.62 207.63 49.76 205.19 52.04 C 202.75 54.32 201.52 57.12 201.52 60.46 C 201.52 61.13 201.61 61.97 201.79 63 C 201.97 64.03 202.28 65.22 202.73 66.58 C 202.79 66.72 202.79 66.84 202.75 66.93 C 202.71 67.03 202.6 67.12 202.44 67.2 C 202.3 67.28 202.17 67.3 202.04 67.24 C 201.91 67.18 201.82 67.09 201.77 66.95 C 201.35 65.78 201.04 64.68 200.83 63.64 C 200.62 62.6 200.52 61.54 200.52 60.45 C 200.52 56.81 201.85 53.76 204.5 51.3 C 207.15 48.84 210.31 47.61 213.98 47.61 C 217.65 47.61 220.86 48.84 223.52 51.3 C 226.19 53.76 227.52 56.81 227.52 60.45 C 227.52 61.73 227.05 62.81 226.1 63.7 C 225.16 64.59 224.02 65.03 222.68 65.03 C 221.34 65.03 220.24 64.59 219.28 63.7 C 218.32 62.81 217.84 61.73 217.84 60.45 C 217.84 59.42 217.46 58.56 216.72 57.87 C 215.98 57.18 215.08 56.83 214.05 56.83 C 213.02 56.83 212.08 57.18 211.32 57.87 C 210.56 58.56 210.17 59.43 210.17 60.45 C 210.17 63.26 211.01 65.6 212.69 67.47 C 214.37 69.35 216.49 70.66 219.04 71.41 C 219.21 71.47 219.32 71.55 219.39 71.66 C 219.46 71.77 219.47 71.9 219.41 72.04 C 219.35 72.15 219.28 72.25 219.18 72.35 C 219.08 72.45 218.94 72.47 218.74 72.41 Z M 204.42 43.04 C 204.36 43.04 204.27 43.03 204.15 43 C 204.02 42.97 203.95 42.9 203.92 42.79 C 203.86 42.71 203.84 42.6 203.86 42.46 C 203.87 42.32 203.92 42.22 204.01 42.17 C 205.54 41.31 207.16 40.66 208.86 40.23 C 210.57 39.8 212.3 39.58 214.05 39.58 C 215.8 39.58 217.51 39.79 219.17 40.2 C 220.84 40.62 222.45 41.24 224 42.08 C 224.17 42.16 224.27 42.27 224.31 42.41 C 224.35 42.55 224.35 42.67 224.29 42.79 C 224.23 42.9 224.14 42.98 224.02 43.04 C 223.89 43.1 223.78 43.1 223.67 43.04 C 222.2 42.18 220.65 41.55 219.02 41.16 C 217.39 40.77 215.74 40.58 214.04 40.58 C 212.34 40.58 210.7 40.8 209.1 41.23 C 207.5 41.66 205.94 42.26 204.41 43.04 Z M 209.92 71.96 C 208.36 70.29 207.14 68.55 206.25 66.73 C 205.36 64.91 204.92 62.82 204.92 60.46 C 204.92 58.1 205.82 55.91 207.61 54.23 C 209.4 52.55 211.55 51.71 214.05 51.71 C 216.55 51.71 218.7 52.55 220.49 54.23 C 222.28 55.91 223.18 57.99 223.18 60.46 C 223.18 60.6 223.14 60.72 223.06 60.81 C 222.98 60.91 222.85 60.96 222.68 60.96 C 222.6 60.96 222.49 60.91 222.37 60.81 C 222.25 60.71 222.18 60.6 222.18 60.46 C 222.18 58.27 221.38 56.43 219.78 54.94 C 218.18 53.45 216.27 52.71 214.05 52.71 C 211.83 52.71 209.92 53.45 208.32 54.94 C 206.72 56.43 205.92 58.27 205.92 60.46 C 205.92 62.77 206.32 64.72 207.13 66.34 C 207.94 67.95 209.1 69.58 210.63 71.22 C 210.77 71.39 210.82 71.53 210.78 71.66 C 210.74 71.78 210.69 71.89 210.63 71.97 C 210.55 72.05 210.44 72.1 210.3 72.12 C 210.16 72.13 210.04 72.09 209.92 71.97 Z M 222.34 68.96 C 219.95 68.96 217.88 68.15 216.11 66.54 C 214.35 64.93 213.46 62.9 213.46 60.46 C 213.46 60.32 213.5 60.2 213.58 60.11 C 213.66 60.01 213.79 59.96 213.96 59.96 C 214.1 59.96 214.22 60.01 214.31 60.11 C 214.41 60.21 214.46 60.33 214.46 60.46 C 214.46 62.65 215.24 64.45 216.81 65.86 C 218.38 67.26 220.22 67.96 222.33 67.96 C 222.64 67.96 222.95 67.95 223.27 67.92 C 223.59 67.89 223.9 67.85 224.21 67.8 C 224.32 67.8 224.42 67.83 224.5 67.88 C 224.58 67.93 224.64 68.03 224.67 68.17 C 224.73 68.31 224.71 68.43 224.63 68.52 C 224.55 68.62 224.42 68.68 224.25 68.71 C 224 68.79 223.7 68.86 223.35 68.9 C 223 68.94 222.66 68.96 222.33 68.96 Z"
+        android:fillColor="#1f1f1f"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_2"
+        android:pathData="M 134 72 L 134 60 C 134 46.75 144.75 36 158 36 C 171.25 36 182 46.75 182 60 L 182 72 M 124 72 L 192 72 C 195.712 72 199.275 73.476 201.899 76.101 C 204.524 78.725 206 82.288 206 86 L 206 146 C 206 149.712 204.524 153.275 201.899 155.899 C 199.275 158.524 195.712 160 192 160 L 124 160 C 120.288 160 116.725 158.524 114.101 155.899 C 111.476 153.275 110 149.712 110 146 L 110 86 C 110 82.288 111.476 78.725 114.101 76.101 C 116.725 73.476 120.288 72 124 72"
+        android:strokeColor="#1f1f1f"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"/>
+    <path
+        android:name="path_3"
+        android:pathData="M 155.67 114.83 C 153.22 114.83 151.15 113.98 149.46 112.29 C 147.77 110.6 146.92 108.53 146.92 106.08 C 146.92 103.63 147.77 101.56 149.46 99.87 C 151.15 98.18 153.22 97.33 155.67 97.33 C 158.12 97.33 160.19 98.18 161.88 99.87 C 163.57 101.56 164.42 103.63 164.42 106.08 C 164.42 108.53 163.57 110.6 161.88 112.29 C 160.19 113.98 158.12 114.83 155.67 114.83 Z M 172.59 137 L 169.67 133.5 L 169.67 124.92 C 168.27 124.38 167.14 123.51 166.29 122.32 C 165.44 121.13 165.01 119.8 165.01 118.32 C 165.01 116.38 165.69 114.72 167.05 113.36 C 168.41 112 170.06 111.32 172.01 111.32 C 173.96 111.32 175.61 112 176.97 113.36 C 178.33 114.72 179.01 116.37 179.01 118.32 C 179.01 119.8 178.58 121.13 177.73 122.32 C 176.88 123.51 175.75 124.37 174.35 124.92 L 174.35 125.33 L 176.68 127.66 L 174.35 129.99 L 176.68 132.32 L 172.6 136.99 Z M 172.01 121.83 C 172.98 121.83 173.81 121.49 174.49 120.81 C 175.17 120.13 175.51 119.3 175.51 118.33 C 175.51 117.36 175.17 116.53 174.49 115.85 C 173.81 115.17 172.98 114.83 172.01 114.83 C 171.04 114.83 170.21 115.17 169.53 115.85 C 168.85 116.53 168.51 117.36 168.51 118.33 C 168.51 119.3 168.85 120.13 169.53 120.81 C 170.21 121.49 171.04 121.83 172.01 121.83 Z M 160.46 119.85 C 160.65 121.44 161.15 122.9 161.95 124.23 C 162.75 125.55 163.77 126.7 165.01 127.67 L 165.01 134.67 L 137.01 134.67 L 137.01 129.13 C 137.01 127.81 137.38 126.6 138.12 125.51 C 138.86 124.42 139.81 123.59 140.98 123 C 143.27 121.83 145.66 120.96 148.13 120.38 C 150.6 119.8 153.12 119.5 155.68 119.5 C 156.46 119.5 157.26 119.53 158.07 119.59 C 158.89 119.65 159.68 119.74 160.46 119.85 Z"
+        android:fillColor="#1f1f1f"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_4"
+        android:pathData="M 63.481 27.427 L 102.118 17.075 C 102.457 16.984 102.815 16.984 103.154 17.075 C 103.493 17.166 103.802 17.344 104.05 17.592 C 104.298 17.841 104.477 18.15 104.568 18.489 L 110.779 41.671 C 110.87 42.01 110.87 42.367 110.779 42.706 C 110.689 43.045 110.51 43.355 110.262 43.603 C 110.014 43.851 109.704 44.03 109.365 44.121 L 70.728 54.473 C 70.216 54.611 69.67 54.539 69.211 54.274 C 68.751 54.008 68.416 53.571 68.279 53.059 L 62.067 29.877 C 61.976 29.538 61.976 29.181 62.067 28.842 C 62.158 28.503 62.336 28.193 62.585 27.945 C 62.833 27.697 63.142 27.518 63.481 27.427"
+        android:strokeColor="#e1e3e1"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"
+        android:strokeMiterLimit="10"/>
+    <path
+        android:name="path_5"
+        android:pathData="M 86.189 50.327 L 93.917 48.256 L 94.952 52.12 L 87.225 54.191 Z"
+        android:fillColor="#e1e3e1"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_6"
+        android:pathData="M 83.36 55.23 L 98.81 51.08"
+        android:strokeColor="#e1e3e1"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"
+        android:strokeMiterLimit="10"/>
+    <path
+        android:name="path_7"
+        android:pathData="M 90.9 37.2 L 88.3 35.7 L 89.4 33.8 C 89.59 33.48 89.37 33.07 89 33.05 L 81.88 32.62 C 81.47 32.6 81.21 33.05 81.43 33.39 L 85.36 39.34 C 85.56 39.65 86.02 39.64 86.21 39.31 L 87.31 37.41 L 89.91 38.91 C 90.39 39.19 91 39.02 91.28 38.54 C 91.56 38.06 91.39 37.45 90.91 37.17 Z"
+        android:fillColor="#e1e3e1"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_8"
+        android:pathData="M 86 160 L 222 160"
+        android:strokeColor="#1f1f1f"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"/>
+    <group android:name="group">
+        <path
+            android:name="path_9"
+            android:pathData="M 98 80 C 92.088 80 86.325 81.872 81.542 85.348 C 76.759 88.823 73.197 93.725 71.37 99.348 C 69.543 104.97 69.543 111.03 71.37 116.652 C 73.197 122.275 76.759 127.177 81.542 130.652 C 86.325 134.128 92.088 136 98 136 C 103.912 136 109.675 134.128 114.458 130.652 C 119.241 127.177 122.803 122.275 124.63 116.652 C 126.457 111.03 126.457 104.97 124.63 99.348 C 122.803 93.725 119.241 88.823 114.458 85.348 C 109.675 81.872 103.912 80 98 80 Z"
+            android:fillColor="#6dd48b"
+            android:strokeWidth="1"/>
+        <path
+            android:name="path_10"
+            android:pathData="M 98 90.5 C 93.36 90.5 88.906 92.345 85.626 95.626 C 82.345 98.906 80.5 103.36 80.5 108 C 80.5 112.64 82.345 117.094 85.626 120.374 C 88.906 123.655 93.36 125.5 98 125.5 C 102.64 125.5 107.094 123.655 110.374 120.374 C 113.655 117.094 115.5 112.64 115.5 108 C 115.5 103.36 113.655 98.906 110.374 95.626 C 107.094 92.345 102.64 90.5 98 90.5 Z"
+            android:strokeColor="#1f1f1f"
+            android:strokeWidth="1"
+            android:strokeMiterLimit="10"/>
+        <path
+            android:name="path_11"
+            android:pathData="M 92.31 104.5 C 92.31 105.22 91.72 105.81 91 105.81 C 90.28 105.81 89.69 105.22 89.69 104.5 C 89.69 103.78 90.28 103.19 91 103.19 C 91.72 103.19 92.31 103.78 92.31 104.5 Z M 106.31 104.5 C 106.31 105.22 105.72 105.81 105 105.81 C 104.28 105.81 103.69 105.22 103.69 104.5 C 103.69 103.78 104.28 103.19 105 103.19 C 105.72 103.19 106.31 103.78 106.31 104.5 Z"
+            android:fillColor="#1f1f1f"
+            android:strokeWidth="1"/>
+        <path
+            android:name="path_12"
+            android:pathData="M 98.88 107.12 L 98.88 110.62 L 96.61 110.62 M 100.11 116.16 C 98.94 117.33 97.06 117.33 95.89 116.16 C 95.29 115.56 95 114.76 95.02 113.97"
+            android:strokeColor="#1f1f1f"
+            android:strokeWidth="1"
+            android:strokeMiterLimit="10"/>
+    </group>
+    <group android:name="group_2">
+        <path
+            android:name="path_13"
+            android:pathData="M 264.23 104 L 296.23 104"
+            android:strokeColor="#e1e3e1"
+            android:strokeWidth="1"
+            android:strokeLineCap="round"
+            android:strokeMiterLimit="10"/>
+        <path
+            android:name="path_14"
+            android:pathData="M 273.16 81.21 C 272.82 80.19 271.87 79.5 270.79 79.5 L 243.01 79.5 C 242.2 79.5 241.46 79.88 240.98 80.54 C 240.5 81.2 240.38 82.02 240.64 82.79 L 247.31 102.79 C 247.65 103.81 248.6 104.5 249.68 104.5 L 280.93 104.5 L 273.17 81.21 Z M 248.25 87.93 C 247.45 88.14 246.57 87.45 246.28 86.39 C 245.99 85.33 246.41 84.28 247.21 84.07 C 248.01 83.86 248.89 84.55 249.18 85.61 C 249.47 86.68 249.05 87.72 248.25 87.93 Z"
+            android:fillColor="#e1e3e1"
+            android:strokeWidth="1"/>
+        <group android:name="group_1">
+            <path
+                android:name="path_15"
+                android:pathData="M 279 83 L 285 83 M 277 77 L 285 69 M 271 75 L 271 69"
+                android:strokeColor="#e1e3e1"
+                android:strokeWidth="1"
+                android:strokeLineCap="round"/>
+        </group>
+    </group>
+    <path
+        android:name="path_16"
+        android:pathData="M 58.16 105.86 C 57.83 105.28 57.29 104.87 56.64 104.69 L 45.05 101.58 C 43.72 101.22 42.34 102.02 41.99 103.35 L 35.78 126.53 C 35.61 127.17 35.7 127.85 36.03 128.43 C 36.36 129.01 36.9 129.42 37.55 129.6 L 49.14 132.71 C 49.36 132.77 49.57 132.79 49.79 132.79 C 50.89 132.79 51.91 132.05 52.21 130.94 L 58.42 107.76 C 58.59 107.11 58.5 106.44 58.17 105.86 Z M 50.65 107.75 C 50.51 108.28 49.96 108.6 49.43 108.46 C 48.9 108.32 48.58 107.77 48.72 107.24 C 48.86 106.71 49.41 106.39 49.94 106.53 C 50.47 106.67 50.79 107.22 50.65 107.75 Z"
+        android:fillColor="#e1e3e1"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_17"
+        android:pathData="M 230 160 L 246 160"
+        android:strokeColor="#1f1f1f"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"/>
+    <path
+        android:name="path_18"
+        android:pathData="M 204.63 80 C 202.38 75.27 197.58 72 192 72 L 190 72 L 190 74 C 190 77.31 192.69 80 196 80 L 204.63 80 Z"
+        android:fillColor="#1f1f1f"
+        android:strokeWidth="1"/>
+    <group android:name="group_4">
+        <path
+            android:name="path_19"
+            android:pathData="M 211.37 102.29 C 210.53 102.82 209.46 102.82 208.63 102.29 C 202.93 98.67 195.29 99.35 190.31 104.32 C 185.34 109.29 184.67 116.93 188.28 122.63 C 188.81 123.46 188.81 124.54 188.28 125.38 C 184.66 131.08 185.34 138.72 190.31 143.69 C 195.29 148.66 202.93 149.34 208.63 145.72 C 209.46 145.19 210.54 145.19 211.37 145.72 C 217.07 149.34 224.71 148.66 229.68 143.69 C 234.66 138.72 235.33 131.08 231.71 125.38 C 231.18 124.55 231.18 123.47 231.71 122.63 C 235.33 116.93 234.65 109.29 229.68 104.32 C 224.71 99.35 217.07 98.67 211.37 102.29 Z"
+            android:fillColor="#0b57cf"
+            android:strokeWidth="1"
+            android:fillType="evenOdd"/>
+        <group android:name="group_3">
+            <path
+                android:name="path_20"
+                android:pathData="M 198 110 C 197.47 110 196.961 110.211 196.586 110.586 C 196.211 110.961 196 111.47 196 112 C 196 112.53 196.211 113.039 196.586 113.414 C 196.961 113.789 197.47 114 198 114 C 198.53 114 199.039 113.789 199.414 113.414 C 199.789 113.039 200 112.53 200 112 C 200 111.47 199.789 110.961 199.414 110.586 C 199.039 110.211 198.53 110 198 110 Z M 210 110 C 209.47 110 208.961 110.211 208.586 110.586 C 208.211 110.961 208 111.47 208 112 C 208 112.53 208.211 113.039 208.586 113.414 C 208.961 113.789 209.47 114 210 114 C 210.53 114 211.039 113.789 211.414 113.414 C 211.789 113.039 212 112.53 212 112 C 212 111.47 211.789 110.961 211.414 110.586 C 211.039 110.211 210.53 110 210 110 Z M 222 110 C 221.47 110 220.961 110.211 220.586 110.586 C 220.211 110.961 220 111.47 220 112 C 220 112.53 220.211 113.039 220.586 113.414 C 220.961 113.789 221.47 114 222 114 C 222.53 114 223.039 113.789 223.414 113.414 C 223.789 113.039 224 112.53 224 112 C 224 111.47 223.789 110.961 223.414 110.586 C 223.039 110.211 222.53 110 222 110 Z M 198 122 C 197.47 122 196.961 122.211 196.586 122.586 C 196.211 122.961 196 123.47 196 124 C 196 124.53 196.211 125.039 196.586 125.414 C 196.961 125.789 197.47 126 198 126 C 198.53 126 199.039 125.789 199.414 125.414 C 199.789 125.039 200 124.53 200 124 C 200 123.47 199.789 122.961 199.414 122.586 C 199.039 122.211 198.53 122 198 122 Z M 210 122 C 209.47 122 208.961 122.211 208.586 122.586 C 208.211 122.961 208 123.47 208 124 C 208 124.53 208.211 125.039 208.586 125.414 C 208.961 125.789 209.47 126 210 126 C 210.53 126 211.039 125.789 211.414 125.414 C 211.789 125.039 212 124.53 212 124 C 212 123.47 211.789 122.961 211.414 122.586 C 211.039 122.211 210.53 122 210 122 Z M 222 122 C 221.47 122 220.961 122.211 220.586 122.586 C 220.211 122.961 220 123.47 220 124 C 220 124.53 220.211 125.039 220.586 125.414 C 220.961 125.789 221.47 126 222 126 C 222.53 126 223.039 125.789 223.414 125.414 C 223.789 125.039 224 124.53 224 124 C 224 123.47 223.789 122.961 223.414 122.586 C 223.039 122.211 222.53 122 222 122 Z M 198 134 C 197.47 134 196.961 134.211 196.586 134.586 C 196.211 134.961 196 135.47 196 136 C 196 136.53 196.211 137.039 196.586 137.414 C 196.961 137.789 197.47 138 198 138 C 198.53 138 199.039 137.789 199.414 137.414 C 199.789 137.039 200 136.53 200 136 C 200 135.47 199.789 134.961 199.414 134.586 C 199.039 134.211 198.53 134 198 134 Z M 210 134 C 209.47 134 208.961 134.211 208.586 134.586 C 208.211 134.961 208 135.47 208 136 C 208 136.53 208.211 137.039 208.586 137.414 C 208.961 137.789 209.47 138 210 138 C 210.53 138 211.039 137.789 211.414 137.414 C 211.789 137.039 212 136.53 212 136 C 212 135.47 211.789 134.961 211.414 134.586 C 211.039 134.211 210.53 134 210 134 Z M 222 134 C 221.47 134 220.961 134.211 220.586 134.586 C 220.211 134.961 220 135.47 220 136 C 220 136.53 220.211 137.039 220.586 137.414 C 220.961 137.789 221.47 138 222 138 C 222.53 138 223.039 137.789 223.414 137.414 C 223.789 137.039 224 136.53 224 136 C 224 135.47 223.789 134.961 223.414 134.586 C 223.039 134.211 222.53 134 222 134 Z"
+                android:fillColor="#ffffff"
+                android:strokeWidth="1"/>
+        </group>
+        <path
+            android:name="path_21"
+            android:pathData="M 222 112 L 198 136 L 222 136"
+            android:strokeColor="#ffffff"
+            android:strokeWidth="1"
+            android:strokeLineCap="round"/>
+    </group>
+</vector>
diff --git a/packages/CredentialManager/res/drawable/ic_passkeys_onboarding_dark.xml b/packages/CredentialManager/res/drawable/ic_passkeys_onboarding_dark.xml
new file mode 100644
index 0000000..53933cb
--- /dev/null
+++ b/packages/CredentialManager/res/drawable/ic_passkeys_onboarding_dark.xml
@@ -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.
+  -->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="vector"
+    android:width="316dp"
+    android:height="168dp"
+    android:viewportWidth="316"
+    android:viewportHeight="168">
+    <path
+        android:name="path"
+        android:pathData="M 238 56 C 238 42.75 227.26 32 214 32 C 200.75 32 190 42.75 190 56 L 190 74 C 190 77.31 192.69 80 196 80 L 214 80 C 227.26 80 238 69.26 238 56 Z"
+        android:fillColor="#f09d00"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_1"
+        android:pathData="M 199.42 51.71 C 199.34 51.65 199.29 51.56 199.27 51.44 C 199.26 51.31 199.27 51.21 199.33 51.13 C 201.08 48.8 203.23 46.98 205.79 45.67 C 208.35 44.36 211.07 43.71 213.96 43.71 C 216.85 43.71 219.64 44.34 222.25 45.61 C 224.86 46.88 227.03 48.69 228.75 51.05 C 228.86 51.19 228.9 51.32 228.85 51.45 C 228.81 51.57 228.72 51.68 228.58 51.76 C 228.5 51.82 228.38 51.84 228.23 51.84 C 228.08 51.84 227.96 51.76 227.88 51.59 C 226.27 49.34 224.23 47.63 221.78 46.47 C 219.32 45.3 216.72 44.72 213.97 44.72 C 211.22 44.72 208.68 45.32 206.26 46.51 C 203.84 47.7 201.83 49.4 200.22 51.59 C 200.08 51.76 199.94 51.84 199.8 51.84 C 199.66 51.84 199.54 51.8 199.42 51.72 Z M 218.75 72.42 C 216 71.7 213.72 70.28 211.9 68.17 C 210.08 66.06 209.17 63.49 209.17 60.46 C 209.17 59.13 209.65 58.02 210.61 57.15 C 211.57 56.27 212.71 55.84 214.05 55.84 C 215.39 55.84 216.48 56.28 217.43 57.15 C 218.37 58.02 218.85 59.13 218.85 60.46 C 218.85 61.49 219.23 62.34 220 63.02 C 220.76 63.7 221.66 64.04 222.69 64.04 C 223.72 64.04 224.64 63.69 225.38 63 C 226.12 62.31 226.48 61.46 226.48 60.46 C 226.48 57.13 225.25 54.32 222.79 52.04 C 220.33 49.76 217.39 48.62 213.98 48.62 C 210.57 48.62 207.63 49.76 205.19 52.04 C 202.75 54.32 201.52 57.12 201.52 60.46 C 201.52 61.13 201.61 61.97 201.79 63 C 201.97 64.03 202.28 65.22 202.73 66.58 C 202.79 66.72 202.79 66.84 202.75 66.93 C 202.71 67.03 202.6 67.12 202.44 67.2 C 202.3 67.28 202.17 67.3 202.04 67.24 C 201.91 67.18 201.82 67.09 201.77 66.95 C 201.35 65.78 201.04 64.68 200.83 63.64 C 200.62 62.6 200.52 61.54 200.52 60.45 C 200.52 56.81 201.85 53.76 204.5 51.3 C 207.15 48.84 210.31 47.61 213.98 47.61 C 217.65 47.61 220.86 48.84 223.52 51.3 C 226.19 53.76 227.52 56.81 227.52 60.45 C 227.52 61.73 227.05 62.81 226.1 63.7 C 225.16 64.59 224.02 65.03 222.68 65.03 C 221.34 65.03 220.24 64.59 219.28 63.7 C 218.32 62.81 217.84 61.73 217.84 60.45 C 217.84 59.42 217.46 58.56 216.72 57.87 C 215.98 57.18 215.08 56.83 214.05 56.83 C 213.02 56.83 212.08 57.18 211.32 57.87 C 210.56 58.56 210.17 59.43 210.17 60.45 C 210.17 63.26 211.01 65.6 212.69 67.47 C 214.37 69.35 216.49 70.66 219.04 71.41 C 219.21 71.47 219.32 71.55 219.39 71.66 C 219.46 71.77 219.47 71.9 219.41 72.04 C 219.35 72.15 219.28 72.25 219.18 72.35 C 219.08 72.45 218.94 72.47 218.74 72.41 Z M 204.42 43.04 C 204.36 43.04 204.27 43.03 204.15 43 C 204.02 42.97 203.95 42.9 203.92 42.79 C 203.86 42.71 203.84 42.6 203.86 42.46 C 203.87 42.32 203.92 42.22 204.01 42.17 C 205.54 41.31 207.16 40.66 208.86 40.23 C 210.57 39.8 212.3 39.58 214.05 39.58 C 215.8 39.58 217.51 39.79 219.17 40.2 C 220.84 40.62 222.45 41.24 224 42.08 C 224.17 42.16 224.27 42.27 224.31 42.41 C 224.35 42.55 224.35 42.67 224.29 42.79 C 224.23 42.9 224.14 42.98 224.02 43.04 C 223.89 43.1 223.78 43.1 223.67 43.04 C 222.2 42.18 220.65 41.55 219.02 41.16 C 217.39 40.77 215.74 40.58 214.04 40.58 C 212.34 40.58 210.7 40.8 209.1 41.23 C 207.5 41.66 205.94 42.26 204.41 43.04 Z M 209.92 71.96 C 208.36 70.29 207.14 68.55 206.25 66.73 C 205.36 64.91 204.92 62.82 204.92 60.46 C 204.92 58.1 205.82 55.91 207.61 54.23 C 209.4 52.55 211.55 51.71 214.05 51.71 C 216.55 51.71 218.7 52.55 220.49 54.23 C 222.28 55.91 223.18 57.99 223.18 60.46 C 223.18 60.6 223.14 60.72 223.06 60.81 C 222.98 60.91 222.85 60.96 222.68 60.96 C 222.6 60.96 222.49 60.91 222.37 60.81 C 222.25 60.71 222.18 60.6 222.18 60.46 C 222.18 58.27 221.38 56.43 219.78 54.94 C 218.18 53.45 216.27 52.71 214.05 52.71 C 211.83 52.71 209.92 53.45 208.32 54.94 C 206.72 56.43 205.92 58.27 205.92 60.46 C 205.92 62.77 206.32 64.72 207.13 66.34 C 207.94 67.95 209.1 69.58 210.63 71.22 C 210.77 71.39 210.82 71.53 210.78 71.66 C 210.74 71.78 210.69 71.89 210.63 71.97 C 210.55 72.05 210.44 72.1 210.3 72.12 C 210.16 72.13 210.04 72.09 209.92 71.97 Z M 222.34 68.96 C 219.95 68.96 217.88 68.15 216.11 66.54 C 214.35 64.93 213.46 62.9 213.46 60.46 C 213.46 60.32 213.5 60.2 213.58 60.11 C 213.66 60.01 213.79 59.96 213.96 59.96 C 214.1 59.96 214.22 60.01 214.31 60.11 C 214.41 60.21 214.46 60.33 214.46 60.46 C 214.46 62.65 215.24 64.45 216.81 65.86 C 218.38 67.26 220.22 67.96 222.33 67.96 C 222.64 67.96 222.95 67.95 223.27 67.92 C 223.59 67.89 223.9 67.85 224.21 67.8 C 224.32 67.8 224.42 67.83 224.5 67.88 C 224.58 67.93 224.64 68.03 224.67 68.17 C 224.73 68.31 224.71 68.43 224.63 68.52 C 224.55 68.62 224.42 68.68 224.25 68.71 C 224 68.79 223.7 68.86 223.35 68.9 C 223 68.94 222.66 68.96 222.33 68.96 Z"
+        android:fillColor="#1f1f1f"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_2"
+        android:pathData="M 134 72 L 134 60 C 134 46.75 144.75 36 158 36 C 171.25 36 182 46.75 182 60 L 182 72 M 124 72 L 192 72 C 195.712 72 199.275 73.476 201.899 76.101 C 204.524 78.725 206 82.288 206 86 L 206 146 C 206 149.712 204.524 153.275 201.899 155.899 C 199.275 158.524 195.712 160 192 160 L 124 160 C 120.288 160 116.725 158.524 114.101 155.899 C 111.476 153.275 110 149.712 110 146 L 110 86 C 110 82.288 111.476 78.725 114.101 76.101 C 116.725 73.476 120.288 72 124 72"
+        android:strokeColor="#e1e3e1"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"/>
+    <path
+        android:name="path_3"
+        android:pathData="M 155.67 114.83 C 153.22 114.83 151.15 113.98 149.46 112.29 C 147.77 110.6 146.92 108.53 146.92 106.08 C 146.92 103.63 147.77 101.56 149.46 99.87 C 151.15 98.18 153.22 97.33 155.67 97.33 C 158.12 97.33 160.19 98.18 161.88 99.87 C 163.57 101.56 164.42 103.63 164.42 106.08 C 164.42 108.53 163.57 110.6 161.88 112.29 C 160.19 113.98 158.12 114.83 155.67 114.83 Z M 172.59 137 L 169.67 133.5 L 169.67 124.92 C 168.27 124.38 167.14 123.51 166.29 122.32 C 165.44 121.13 165.01 119.8 165.01 118.32 C 165.01 116.38 165.69 114.72 167.05 113.36 C 168.41 112 170.06 111.32 172.01 111.32 C 173.96 111.32 175.61 112 176.97 113.36 C 178.33 114.72 179.01 116.37 179.01 118.32 C 179.01 119.8 178.58 121.13 177.73 122.32 C 176.88 123.51 175.75 124.37 174.35 124.92 L 174.35 125.33 L 176.68 127.66 L 174.35 129.99 L 176.68 132.32 L 172.6 136.99 Z M 172.01 121.83 C 172.98 121.83 173.81 121.49 174.49 120.81 C 175.17 120.13 175.51 119.3 175.51 118.33 C 175.51 117.36 175.17 116.53 174.49 115.85 C 173.81 115.17 172.98 114.83 172.01 114.83 C 171.04 114.83 170.21 115.17 169.53 115.85 C 168.85 116.53 168.51 117.36 168.51 118.33 C 168.51 119.3 168.85 120.13 169.53 120.81 C 170.21 121.49 171.04 121.83 172.01 121.83 Z M 160.46 119.85 C 160.65 121.44 161.15 122.9 161.95 124.23 C 162.75 125.55 163.77 126.7 165.01 127.67 L 165.01 134.67 L 137.01 134.67 L 137.01 129.13 C 137.01 127.81 137.38 126.6 138.12 125.51 C 138.86 124.42 139.81 123.59 140.98 123 C 143.27 121.83 145.66 120.96 148.13 120.38 C 150.6 119.8 153.12 119.5 155.68 119.5 C 156.46 119.5 157.26 119.53 158.07 119.59 C 158.89 119.65 159.68 119.74 160.46 119.85 Z"
+        android:fillColor="#e1e3e1"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_4"
+        android:pathData="M 63.481 27.427 L 102.118 17.075 C 102.457 16.984 102.815 16.984 103.154 17.075 C 103.493 17.166 103.802 17.344 104.05 17.592 C 104.298 17.841 104.477 18.15 104.568 18.489 L 110.779 41.671 C 110.87 42.01 110.87 42.367 110.779 42.706 C 110.689 43.045 110.51 43.355 110.262 43.603 C 110.014 43.851 109.704 44.03 109.365 44.121 L 70.728 54.473 C 70.216 54.611 69.67 54.539 69.211 54.274 C 68.751 54.008 68.416 53.571 68.279 53.059 L 62.067 29.877 C 61.976 29.538 61.976 29.181 62.067 28.842 C 62.158 28.503 62.336 28.193 62.585 27.945 C 62.833 27.697 63.142 27.518 63.481 27.427"
+        android:strokeColor="#444746"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"
+        android:strokeMiterLimit="10"/>
+    <path
+        android:name="path_5"
+        android:pathData="M 86.189 50.327 L 93.917 48.256 L 94.952 52.12 L 87.225 54.191 Z"
+        android:fillColor="#444746"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_6"
+        android:pathData="M 83.36 55.23 L 98.81 51.08"
+        android:strokeColor="#444746"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"
+        android:strokeMiterLimit="10"/>
+    <path
+        android:name="path_7"
+        android:pathData="M 90.9 37.2 L 88.3 35.7 L 89.4 33.8 C 89.59 33.48 89.37 33.07 89 33.05 L 81.88 32.62 C 81.47 32.6 81.21 33.05 81.43 33.39 L 85.36 39.34 C 85.56 39.65 86.02 39.64 86.21 39.31 L 87.31 37.41 L 89.91 38.91 C 90.39 39.19 91 39.02 91.28 38.54 C 91.56 38.06 91.39 37.45 90.91 37.17 Z"
+        android:fillColor="#444746"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_8"
+        android:pathData="M 86 160 L 222 160"
+        android:strokeColor="#e1e3e1"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"/>
+    <group android:name="group">
+        <path
+            android:name="path_9"
+            android:pathData="M 98 80 C 92.088 80 86.325 81.872 81.542 85.348 C 76.759 88.823 73.197 93.725 71.37 99.348 C 69.543 104.97 69.543 111.03 71.37 116.652 C 73.197 122.275 76.759 127.177 81.542 130.652 C 86.325 134.128 92.088 136 98 136 C 103.912 136 109.675 134.128 114.458 130.652 C 119.241 127.177 122.803 122.275 124.63 116.652 C 126.457 111.03 126.457 104.97 124.63 99.348 C 122.803 93.725 119.241 88.823 114.458 85.348 C 109.675 81.872 103.912 80 98 80 Z"
+            android:fillColor="#37be5f"
+            android:strokeWidth="1"/>
+        <path
+            android:name="path_10"
+            android:pathData="M 98 90.5 C 93.36 90.5 88.906 92.345 85.626 95.626 C 82.345 98.906 80.5 103.36 80.5 108 C 80.5 112.64 82.345 117.094 85.626 120.374 C 88.906 123.655 93.36 125.5 98 125.5 C 102.64 125.5 107.094 123.655 110.374 120.374 C 113.655 117.094 115.5 112.64 115.5 108 C 115.5 103.36 113.655 98.906 110.374 95.626 C 107.094 92.345 102.64 90.5 98 90.5 Z"
+            android:strokeColor="#1f1f1f"
+            android:strokeWidth="1"
+            android:strokeMiterLimit="10"/>
+        <path
+            android:name="path_11"
+            android:pathData="M 92.31 104.5 C 92.31 105.22 91.72 105.81 91 105.81 C 90.28 105.81 89.69 105.22 89.69 104.5 C 89.69 103.78 90.28 103.19 91 103.19 C 91.72 103.19 92.31 103.78 92.31 104.5 Z M 106.31 104.5 C 106.31 105.22 105.72 105.81 105 105.81 C 104.28 105.81 103.69 105.22 103.69 104.5 C 103.69 103.78 104.28 103.19 105 103.19 C 105.72 103.19 106.31 103.78 106.31 104.5 Z"
+            android:fillColor="#1f1f1f"
+            android:strokeWidth="1"/>
+        <path
+            android:name="path_12"
+            android:pathData="M 98.88 107.12 L 98.88 110.62 L 96.61 110.62 M 100.11 116.16 C 98.94 117.33 97.06 117.33 95.89 116.16 C 95.29 115.56 95 114.76 95.02 113.97"
+            android:strokeColor="#1f1f1f"
+            android:strokeWidth="1"
+            android:strokeMiterLimit="10"/>
+    </group>
+    <group android:name="group_2">
+        <path
+            android:name="path_13"
+            android:pathData="M 264.23 104 L 296.23 104"
+            android:strokeColor="#444746"
+            android:strokeWidth="1"
+            android:strokeLineCap="round"
+            android:strokeMiterLimit="10"/>
+        <path
+            android:name="path_14"
+            android:pathData="M 273.16 81.21 C 272.82 80.19 271.87 79.5 270.79 79.5 L 243.01 79.5 C 242.2 79.5 241.46 79.88 240.98 80.54 C 240.5 81.2 240.38 82.02 240.64 82.79 L 247.31 102.79 C 247.65 103.81 248.6 104.5 249.68 104.5 L 280.93 104.5 L 273.17 81.21 Z M 248.25 87.93 C 247.45 88.14 246.57 87.45 246.28 86.39 C 245.99 85.33 246.41 84.28 247.21 84.07 C 248.01 83.86 248.89 84.55 249.18 85.61 C 249.47 86.68 249.05 87.72 248.25 87.93 Z"
+            android:fillColor="#444746"
+            android:strokeWidth="1"/>
+        <group android:name="group_1">
+            <path
+                android:name="path_15"
+                android:pathData="M 279 83 L 285 83 M 277 77 L 285 69 M 271 75 L 271 69"
+                android:strokeColor="#444746"
+                android:strokeWidth="1"
+                android:strokeLineCap="round"/>
+        </group>
+    </group>
+    <path
+        android:name="path_16"
+        android:pathData="M 58.16 105.86 C 57.83 105.28 57.29 104.87 56.64 104.69 L 45.05 101.58 C 43.72 101.22 42.34 102.02 41.99 103.35 L 35.78 126.53 C 35.61 127.17 35.7 127.85 36.03 128.43 C 36.36 129.01 36.9 129.42 37.55 129.6 L 49.14 132.71 C 49.36 132.77 49.57 132.79 49.79 132.79 C 50.89 132.79 51.91 132.05 52.21 130.94 L 58.42 107.76 C 58.59 107.11 58.5 106.44 58.17 105.86 Z M 50.65 107.75 C 50.51 108.28 49.96 108.6 49.43 108.46 C 48.9 108.32 48.58 107.77 48.72 107.24 C 48.86 106.71 49.41 106.39 49.94 106.53 C 50.47 106.67 50.79 107.22 50.65 107.75 Z"
+        android:fillColor="#444746"
+        android:strokeWidth="1"/>
+    <path
+        android:name="path_17"
+        android:pathData="M 230 160 L 246 160"
+        android:strokeColor="#e1e3e1"
+        android:strokeWidth="1"
+        android:strokeLineCap="round"/>
+    <path
+        android:name="path_18"
+        android:pathData="M 204.63 80 C 202.38 75.27 197.58 72 192 72 L 190 72 L 190 74 C 190 77.31 192.69 80 196 80 L 204.63 80 Z"
+        android:fillColor="#e1e3e1"
+        android:strokeWidth="1"/>
+    <group android:name="group_4">
+        <path
+            android:name="path_19"
+            android:pathData="M 211.37 102.29 C 210.53 102.82 209.46 102.82 208.63 102.29 C 202.93 98.67 195.29 99.35 190.31 104.32 C 185.34 109.29 184.67 116.93 188.28 122.63 C 188.81 123.46 188.81 124.54 188.28 125.38 C 184.66 131.08 185.34 138.72 190.31 143.69 C 195.29 148.66 202.93 149.34 208.63 145.72 C 209.46 145.19 210.54 145.19 211.37 145.72 C 217.07 149.34 224.71 148.66 229.68 143.69 C 234.66 138.72 235.33 131.08 231.71 125.38 C 231.18 124.55 231.18 123.47 231.71 122.63 C 235.33 116.93 234.65 109.29 229.68 104.32 C 224.71 99.35 217.07 98.67 211.37 102.29 Z"
+            android:fillColor="#7cacf8"
+            android:strokeWidth="1"
+            android:fillType="evenOdd"/>
+        <group android:name="group_3">
+            <path
+                android:name="path_20"
+                android:pathData="M 198 110 C 197.47 110 196.961 110.211 196.586 110.586 C 196.211 110.961 196 111.47 196 112 C 196 112.53 196.211 113.039 196.586 113.414 C 196.961 113.789 197.47 114 198 114 C 198.53 114 199.039 113.789 199.414 113.414 C 199.789 113.039 200 112.53 200 112 C 200 111.47 199.789 110.961 199.414 110.586 C 199.039 110.211 198.53 110 198 110 Z M 210 110 C 209.47 110 208.961 110.211 208.586 110.586 C 208.211 110.961 208 111.47 208 112 C 208 112.53 208.211 113.039 208.586 113.414 C 208.961 113.789 209.47 114 210 114 C 210.53 114 211.039 113.789 211.414 113.414 C 211.789 113.039 212 112.53 212 112 C 212 111.47 211.789 110.961 211.414 110.586 C 211.039 110.211 210.53 110 210 110 Z M 222 110 C 221.47 110 220.961 110.211 220.586 110.586 C 220.211 110.961 220 111.47 220 112 C 220 112.53 220.211 113.039 220.586 113.414 C 220.961 113.789 221.47 114 222 114 C 222.53 114 223.039 113.789 223.414 113.414 C 223.789 113.039 224 112.53 224 112 C 224 111.47 223.789 110.961 223.414 110.586 C 223.039 110.211 222.53 110 222 110 Z M 198 122 C 197.47 122 196.961 122.211 196.586 122.586 C 196.211 122.961 196 123.47 196 124 C 196 124.53 196.211 125.039 196.586 125.414 C 196.961 125.789 197.47 126 198 126 C 198.53 126 199.039 125.789 199.414 125.414 C 199.789 125.039 200 124.53 200 124 C 200 123.47 199.789 122.961 199.414 122.586 C 199.039 122.211 198.53 122 198 122 Z M 210 122 C 209.47 122 208.961 122.211 208.586 122.586 C 208.211 122.961 208 123.47 208 124 C 208 124.53 208.211 125.039 208.586 125.414 C 208.961 125.789 209.47 126 210 126 C 210.53 126 211.039 125.789 211.414 125.414 C 211.789 125.039 212 124.53 212 124 C 212 123.47 211.789 122.961 211.414 122.586 C 211.039 122.211 210.53 122 210 122 Z M 222 122 C 221.47 122 220.961 122.211 220.586 122.586 C 220.211 122.961 220 123.47 220 124 C 220 124.53 220.211 125.039 220.586 125.414 C 220.961 125.789 221.47 126 222 126 C 222.53 126 223.039 125.789 223.414 125.414 C 223.789 125.039 224 124.53 224 124 C 224 123.47 223.789 122.961 223.414 122.586 C 223.039 122.211 222.53 122 222 122 Z M 198 134 C 197.47 134 196.961 134.211 196.586 134.586 C 196.211 134.961 196 135.47 196 136 C 196 136.53 196.211 137.039 196.586 137.414 C 196.961 137.789 197.47 138 198 138 C 198.53 138 199.039 137.789 199.414 137.414 C 199.789 137.039 200 136.53 200 136 C 200 135.47 199.789 134.961 199.414 134.586 C 199.039 134.211 198.53 134 198 134 Z M 210 134 C 209.47 134 208.961 134.211 208.586 134.586 C 208.211 134.961 208 135.47 208 136 C 208 136.53 208.211 137.039 208.586 137.414 C 208.961 137.789 209.47 138 210 138 C 210.53 138 211.039 137.789 211.414 137.414 C 211.789 137.039 212 136.53 212 136 C 212 135.47 211.789 134.961 211.414 134.586 C 211.039 134.211 210.53 134 210 134 Z M 222 134 C 221.47 134 220.961 134.211 220.586 134.586 C 220.211 134.961 220 135.47 220 136 C 220 136.53 220.211 137.039 220.586 137.414 C 220.961 137.789 221.47 138 222 138 C 222.53 138 223.039 137.789 223.414 137.414 C 223.789 137.039 224 136.53 224 136 C 224 135.47 223.789 134.961 223.414 134.586 C 223.039 134.211 222.53 134 222 134 Z"
+                android:fillColor="#1f1f1f"
+                android:strokeWidth="1"/>
+        </group>
+        <path
+            android:name="path_21"
+            android:pathData="M 222 112 L 198 136 L 222 136"
+            android:strokeColor="#1f1f1f"
+            android:strokeWidth="1"
+            android:strokeLineCap="round"/>
+    </group>
+</vector>
diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml
index f62b72d..2aded3b 100644
--- a/packages/CredentialManager/res/values-af/strings.xml
+++ b/packages/CredentialManager/res/values-af/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Gaan voort"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Meer opsies"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Kom meer te wete"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Wys wagwoord"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Versteek wagwoord"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Veiliger met wagwoordsleutels"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Met wagwoordsleutels hoef jy nie komplekse wagwoorde te skep of te onthou nie"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Wagwoordsleutels is geënkripteerde digitale sleutels wat jy met jou vingerafdruk, gesig of skermslot skep"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Aanmeldopsies"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Vir <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Geslote wagwoordbestuurders"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tik om te ontsluit"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Bestuur aanmeldings"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Van ’n ander toestel af"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Gebruik ’n ander toestel"</string>
diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml
index 5a35369..91a26c0 100644
--- a/packages/CredentialManager/res/values-am/strings.xml
+++ b/packages/CredentialManager/res/values-am/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"ቀጥል"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ተጨማሪ አማራጮች"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"የበለጠ ለመረዳት"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"የመግቢያ አማራጮች"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"ለ<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"የተቆለፉ የሚስጥር ቁልፍ አስተዳዳሪዎች"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ለመክፈት መታ ያድርጉ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"መግቢያዎችን ያስተዳድሩ"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ከሌላ መሣሪያ"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"የተለየ መሣሪያ ይጠቀሙ"</string>
diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml
index 7244489..8a88f3b 100644
--- a/packages/CredentialManager/res/values-ar/strings.xml
+++ b/packages/CredentialManager/res/values-ar/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"متابعة"</string>
     <string name="string_more_options" msgid="7990658711962795124">"خيارات إضافية"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"مزيد من المعلومات"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"خيارات تسجيل الدخول"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"معلومات تسجيل دخول \"<xliff:g id="USERNAME">%1$s</xliff:g>\""</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"خدمات إدارة كلمات المرور المقفولة"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"انقر لإلغاء القفل."</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"إداراة عمليات تسجيل الدخول"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"من جهاز آخر"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"استخدام جهاز مختلف"</string>
diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml
index 6f68adb..8040c7a 100644
--- a/packages/CredentialManager/res/values-as/strings.xml
+++ b/packages/CredentialManager/res/values-as/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"অব্যাহত ৰাখক"</string>
     <string name="string_more_options" msgid="7990658711962795124">"অধিক বিকল্প"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"অধিক জানক"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ছাইন ইনৰ বিকল্প"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>ৰ বাবে"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"লক হৈ থকা পাছৱৰ্ড পৰিচালক"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"আনলক কৰিবলৈ টিপক"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ছাইন ইন পৰিচালনা কৰক"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"অন্য এটা ডিভাইচৰ পৰা"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"অন্য এটা ডিভাইচ ব্যৱহাৰ কৰক"</string>
diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml
index bb35963..dd1db6f 100644
--- a/packages/CredentialManager/res/values-az/strings.xml
+++ b/packages/CredentialManager/res/values-az/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Davam edin"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Digər seçimlər"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Ətraflı məlumat"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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_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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Giriş seçimləri"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Kilidli parol menecerləri"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Kilidi açmaq üçün tıklayın"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Girişləri idarə edin"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Başqa cihazdan"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Başqa cihaz istifadə edin"</string>
diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
index 3182c13..10f80fe 100644
--- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Nastavi"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Još opcija"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saznajte više"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Bezbednije uz pristupne kodove"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Uz pristupne kodove nema potrebe da pravite ili pamtite složene lozinke"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pristupni kodovi su šifrovani digitalni kodovi koje pravite pomoću otiska prsta, lica ili zaključavanja ekrana"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opcije za prijavljivanje"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Za: <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Menadžeri zaključanih lozinki"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Dodirnite da biste otključali"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Upravljajte prijavljivanjima"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Sa drugog uređaja"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Koristi drugi uređaj"</string>
diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml
index 2979cff..39c8200 100644
--- a/packages/CredentialManager/res/values-be/strings.xml
+++ b/packages/CredentialManager/res/values-be/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Далей"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Дадатковыя параметры"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Даведацца больш"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Спосабы ўваходу"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Для карыстальніка <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заблакіраваныя спосабы ўваходу"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Націсніце, каб разблакіраваць"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Кіраваць спосабамі ўваходу"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"З іншай прылады"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Скарыстаць іншую прыладу"</string>
diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml
index 759f2d46..c2923b8 100644
--- a/packages/CredentialManager/res/values-bg/strings.xml
+++ b/packages/CredentialManager/res/values-bg/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Напред"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Още опции"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Научете повече"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Опции за влизане в профила"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"За <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заключени мениджъри на пароли"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Докоснете, за да отключите"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Управление на данните за вход"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"От друго устройство"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Използване на друго устройство"</string>
diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml
index 17905ee..6ede693 100644
--- a/packages/CredentialManager/res/values-bn/strings.xml
+++ b/packages/CredentialManager/res/values-bn/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"চালিয়ে যান"</string>
     <string name="string_more_options" msgid="7990658711962795124">"আরও বিকল্প"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"আরও জানুন"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"সাইন-ইন করার বিকল্প"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>-এর জন্য"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"লক করা Password Manager"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"আনলক করতে ট্যাপ করুন"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"সাইন-ইন করার ক্রেডেনশিয়াল ম্যানেজ করুন"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"অন্য ডিভাইস থেকে"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"আলাদা ডিভাইস ব্যবহার করুন"</string>
diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml
index e8d8ecc..ee42d75 100644
--- a/packages/CredentialManager/res/values-bs/strings.xml
+++ b/packages/CredentialManager/res/values-bs/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Nastavi"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Više opcija"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saznajte više"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Prikaži zaporku"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Sakrij zaporku"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Sigurniji ste uz pristupne ključeve"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Uz pristupne ključeve ne morate kreirati ili pamtiti složene lozinke"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pristupni ključevi su šifrirani digitalni ključevi koje kreirate pomoću otiska prsta, lica ili zaključavanja ekrana"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opcije prijave"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Za osobu <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Zaključani upravitelji lozinki"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Dodirnite da otključate"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Upravljajte prijavama"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"S drugog uređaja"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Upotrijebite drugi uređaj"</string>
diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml
index 300c95f..6b898e1 100644
--- a/packages/CredentialManager/res/values-ca/strings.xml
+++ b/packages/CredentialManager/res/values-ca/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Continua"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Més opcions"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Més informació"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Més seguretat amb les claus d\'accés"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Amb les claus d\'accés, no cal que creïs ni recordis contrasenyes difícils"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Les claus d\'accés són claus digitals encriptades que pots crear amb la teva cara, l\'empremta digital o el bloqueig de pantalla"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opcions d\'inici de sessió"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Per a <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gestors de contrasenyes bloquejats"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toca per desbloquejar"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gestiona els inicis de sessió"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Des d\'un altre dispositiu"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Utilitza un dispositiu diferent"</string>
diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml
index de5c5b6..00c037b 100644
--- a/packages/CredentialManager/res/values-cs/strings.xml
+++ b/packages/CredentialManager/res/values-cs/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Pokračovat"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Další možnosti"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Další informace"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Zobrazit heslo"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Skrýt heslo"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Přístupové klíče zvyšují bezpečnost"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"S přístupovými klíči si nemusíte vytvářet ani pamatovat složitá hesla"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Přístupové klíče jsou šifrované digitální klíče, které vytvoříte pomocí otisku prstu, obličeje nebo zámku obrazovky"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Možnosti přihlašování"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Pro uživatele <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Uzamčení správci hesel"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Klepnutím odemknete"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Spravovat přihlášení"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Z jiného zařízení"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Použít jiné zařízení"</string>
diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml
index b214c04..7583b7c 100644
--- a/packages/CredentialManager/res/values-da/strings.xml
+++ b/packages/CredentialManager/res/values-da/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Fortsæt"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Flere valgmuligheder"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Få flere oplysninger"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Øget beskyttelse med adgangsnøgler"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Når du bruger adgangsnøgler, behøver du ikke at oprette eller huske avancerede adgangskoder"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Adgangsnøgler er krypterede digitale nøgler, som du opretter ved hjælp af fingeraftryk, ansigtsgenkendelse eller skærmlås"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Valgmuligheder for login"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"For <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Låste adgangskodeadministratorer"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tryk for at låse op"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Administrer loginmetoder"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Fra en anden enhed"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Brug en anden enhed"</string>
diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml
index 91afe23..0946556 100644
--- a/packages/CredentialManager/res/values-de/strings.xml
+++ b/packages/CredentialManager/res/values-de/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Weiter"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Weitere Optionen"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Weitere Informationen"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mehr Sicherheit mit Passkeys"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Mit Passkeys musst du keine komplizierten Passwörter erstellen oder dir merken"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkeys sind verschlüsselte digitale Schlüssel, die du mithilfe deines Fingerabdrucks, Gesichts oder deiner Displaysperre erstellst"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Anmeldeoptionen"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Für <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gesperrte Passwortmanager"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Zum Entsperren tippen"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Anmeldedaten verwalten"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Von einem anderen Gerät"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Anderes Gerät verwenden"</string>
diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml
index 2797b37..909ec97 100644
--- a/packages/CredentialManager/res/values-el/strings.xml
+++ b/packages/CredentialManager/res/values-el/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Συνέχεια"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Περισσότερες επιλογές"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Μάθετε περισσότερα"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Εμφάνιση κωδικού πρόσβασης"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Απόκρυψη κωδικού πρόσβασης"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Επιλογές σύνδεσης"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Κλειδωμένοι διαχειριστές κωδικών πρόσβασης"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Πατήστε για ξεκλείδωμα"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Διαχείριση στοιχείων σύνδεσης"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Από άλλη συσκευή"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Χρήση διαφορετικής συσκευής"</string>
diff --git a/packages/CredentialManager/res/values-en-rAU/strings.xml b/packages/CredentialManager/res/values-en-rAU/strings.xml
index 76b58c7..42f61b9 100644
--- a/packages/CredentialManager/res/values-en-rAU/strings.xml
+++ b/packages/CredentialManager/res/values-en-rAU/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continue"</string>
     <string name="string_more_options" msgid="7990658711962795124">"More options"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Learn more"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Show password"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Hide password"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Safer with passkeys"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"With passkeys, you don’t need to create or remember complex passwords"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkeys are encrypted digital keys that you create using your fingerprint, face or screen lock"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Sign-in options"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"For <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Locked password managers"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tap to unlock"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Manage sign-ins"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"From another device"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use a different device"</string>
diff --git a/packages/CredentialManager/res/values-en-rCA/strings.xml b/packages/CredentialManager/res/values-en-rCA/strings.xml
index 5277f67..24d6bf2 100644
--- a/packages/CredentialManager/res/values-en-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-en-rCA/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continue"</string>
     <string name="string_more_options" msgid="7990658711962795124">"More options"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Learn more"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Show password"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Hide password"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Safer with passkeys"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"With passkeys, you don’t need to create or remember complex passwords"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkeys are encrypted digital keys you create using your fingerprint, face, or screen lock"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Sign-in options"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"For <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Locked password managers"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tap to unlock"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Manage sign-ins"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"From another device"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use a different device"</string>
diff --git a/packages/CredentialManager/res/values-en-rGB/strings.xml b/packages/CredentialManager/res/values-en-rGB/strings.xml
index 76b58c7..42f61b9 100644
--- a/packages/CredentialManager/res/values-en-rGB/strings.xml
+++ b/packages/CredentialManager/res/values-en-rGB/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continue"</string>
     <string name="string_more_options" msgid="7990658711962795124">"More options"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Learn more"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Show password"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Hide password"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Safer with passkeys"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"With passkeys, you don’t need to create or remember complex passwords"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkeys are encrypted digital keys that you create using your fingerprint, face or screen lock"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Sign-in options"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"For <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Locked password managers"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tap to unlock"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Manage sign-ins"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"From another device"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use a different device"</string>
diff --git a/packages/CredentialManager/res/values-en-rIN/strings.xml b/packages/CredentialManager/res/values-en-rIN/strings.xml
index 76b58c7..42f61b9 100644
--- a/packages/CredentialManager/res/values-en-rIN/strings.xml
+++ b/packages/CredentialManager/res/values-en-rIN/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continue"</string>
     <string name="string_more_options" msgid="7990658711962795124">"More options"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Learn more"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Show password"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Hide password"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Safer with passkeys"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"With passkeys, you don’t need to create or remember complex passwords"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Passkeys are encrypted digital keys that you create using your fingerprint, face or screen lock"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Sign-in options"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"For <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Locked password managers"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tap to unlock"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Manage sign-ins"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"From another device"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use a different device"</string>
diff --git a/packages/CredentialManager/res/values-en-rXC/strings.xml b/packages/CredentialManager/res/values-en-rXC/strings.xml
index 9ea9cf5..f646b49 100644
--- a/packages/CredentialManager/res/values-en-rXC/strings.xml
+++ b/packages/CredentialManager/res/values-en-rXC/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‎Continue‎‏‎‎‏‎"</string>
     <string name="string_more_options" msgid="7990658711962795124">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎More options‎‏‎‎‏‎"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎Learn more‎‏‎‎‏‎"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎Show password‎‏‎‎‏‎"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎Hide password‎‏‎‎‏‎"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎Safer with passkeys‎‏‎‎‏‎"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‎With passkeys, you don’t need to create or remember complex passwords‎‏‎‎‏‎"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎Passkeys are encrypted digital keys you create using your fingerprint, face, or screen lock‎‏‎‎‏‎"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎Sign-in options‎‏‎‎‏‎"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎For ‎‏‎‎‏‏‎<xliff:g id="USERNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎Locked password managers‎‏‎‎‏‎"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎Tap to unlock‎‏‎‎‏‎"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎Manage sign-ins‎‏‎‎‏‎"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎From another device‎‏‎‎‏‎"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎Use a different device‎‏‎‎‏‎"</string>
diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml
index c096d13..ec00eb6 100644
--- a/packages/CredentialManager/res/values-es-rUS/strings.xml
+++ b/packages/CredentialManager/res/values-es-rUS/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Más opciones"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Más información"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Más seguridad con llaves de acceso"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Con las llaves de acceso, no es necesario crear ni recordar contraseñas complejas"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Las llaves de acceso son claves digitales encriptadas que puedes crear usando tu huella dactilar, rostro o bloqueo de pantalla"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opciones de acceso"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Administradores de contraseñas bloqueados"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Presiona para desbloquear"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Administrar accesos"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Desde otro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar otra voz"</string>
diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml
index c6e67cf..94eaffd 100644
--- a/packages/CredentialManager/res/values-es/strings.xml
+++ b/packages/CredentialManager/res/values-es/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Más opciones"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Más información"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Más seguridad con las llaves de acceso"</string>
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opciones de inicio de sesión"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gestores de contraseñas bloqueados"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toca para desbloquear"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gestionar inicios de sesión"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De otro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar otro dispositivo"</string>
diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml
index 875460d..eb50711 100644
--- a/packages/CredentialManager/res/values-et/strings.xml
+++ b/packages/CredentialManager/res/values-et/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Jätka"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Rohkem valikuid"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Lisateave"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Pääsuvõtmed suurendavad turvalisust"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Pääsuvõtmetega ei pea te looma ega meelde jätma keerukaid paroole"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pääsuvõtmed on digitaalsed krüpteeritud võtmed, mille loote sõrmejälje, näo või ekraanilukuga"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Sisselogimise valikud"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Kasutajale <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Lukustatud paroolihaldurid"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Avamiseks puudutage"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Sisselogimisandmete haldamine"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Muus seadmes"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Kasuta teist seadet"</string>
diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml
index a037d78..985d897 100644
--- a/packages/CredentialManager/res/values-eu/strings.xml
+++ b/packages/CredentialManager/res/values-eu/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Egin aurrera"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Aukera gehiago"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Lortu informazio gehiago"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Sarbide-gako seguruagoak"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Sarbide-gakoei esker, ez duzu pasahitz konplexurik sortu edo gogoratu beharrik"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Hatz-marka, aurpegia edo pantailaren blokeoa erabilita sortzen dituzun giltza digital enkriptatuak dira sarbide-gakoak"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Saioa hasteko aukerak"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearenak"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Blokeatutako pasahitz-kudeatzaileak"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Desblokeatzeko, sakatu hau"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Kudeatu kredentzialak"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Beste gailu batean gordetakoak"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Erabili beste gailu bat"</string>
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index c833024..a24e6cb 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"ادامه"</string>
     <string name="string_more_options" msgid="7990658711962795124">"گزینه‌های بیشتر"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"بیشتر بدانید"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"گزینه‌های ورود به سیستم"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"برای <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"مدیران گذرواژه قفل‌شده"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"برای باز کردن قفل ضربه بزنید"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"مدیریت ورود به سیستم‌ها"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"از دستگاهی دیگر"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"استفاده از دستگاه دیگری"</string>
diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml
index 08dd739..73a964a 100644
--- a/packages/CredentialManager/res/values-fi/strings.xml
+++ b/packages/CredentialManager/res/values-fi/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Jatka"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Lisäasetukset"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Lue lisää"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Näytä salasana"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Piilota salasana"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Turvallisuutta avainkoodeilla"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kun käytät avainkoodeja, sinun ei tarvitse luoda tai muistaa monimutkaisia salasanoja"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Avainkoodit ovat salattuja digitaalisia avaimia, joita voit luoda sormenjäljen, kasvojen tai näytön lukituksen avulla"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Kirjautumisvaihtoehdot"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Käyttäjä: <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Lukitut salasanojen ylläpitotyökalut"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Avaa napauttamalla"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Muuta kirjautumistietoja"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Toiselta laitteelta"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Käytä toista laitetta"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index 445284d..c79e500 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuer"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Autres options"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"En savoir plus"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Une sécurité accrue grâce aux clés d\'accès"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Avec les clés d\'accès, nul besoin de créer ou de mémoriser des mots de passe complexes"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Les clés d\'accès sont des clés numériques chiffrées que vous créez en utilisant votre empreinte digitale, votre visage ou le verrouillage de votre écran"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Options de connexion"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gestionnaires de mots de passe verrouillés"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toucher pour déverrouiller"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gérer les connexions"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"À partir d\'un autre appareil"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Utiliser un autre appareil"</string>
diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml
index cc39214..27354d3 100644
--- a/packages/CredentialManager/res/values-fr/strings.xml
+++ b/packages/CredentialManager/res/values-fr/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuer"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Autres options"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"En savoir plus"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Sécurité renforcée grâce aux clés d\'accès"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Avec les clés d\'accès, plus besoin de créer ni de mémoriser des mots de passe complexes"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Les clés d\'accès sont des clés numériques chiffrées que vous créez à l\'aide de votre empreinte digitale, de votre visage ou du verrouillage de l\'écran"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Options de connexion"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gestionnaires de mots de passe verrouillés"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Appuyer pour déverrouiller"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gérer les connexions"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Depuis un autre appareil"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Utiliser un autre appareil"</string>
diff --git a/packages/CredentialManager/res/values-gl/strings.xml b/packages/CredentialManager/res/values-gl/strings.xml
index 4fb09cc..260933c 100644
--- a/packages/CredentialManager/res/values-gl/strings.xml
+++ b/packages/CredentialManager/res/values-gl/strings.xml
@@ -5,30 +5,24 @@
     <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string>
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Máis opcións"</string>
-    <!-- no translation found for string_learn_more (4541600451688392447) -->
+    <string name="string_learn_more" msgid="4541600451688392447">"Máis información"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
     <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Máis protección coas claves de acceso"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Cunha clave de acceso, non é necesario que crees ou lembres contrasinais complexos"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As claves de acceso son claves dixitais encriptadas que creas usando a túa impresión dixital, a túa cara ou o teu bloqueo de pantalla"</string>
     <string name="passkey_creation_intro_body_device" msgid="1203796455762131631">"As claves de acceso gárdanse nun xestor de contrasinais para que poidas iniciar sesión noutros dispositivos"</string>
-    <!-- no translation found for more_about_passkeys_title (7797903098728837795) -->
-    <skip />
-    <!-- no translation found for passwordless_technology_title (2497513482056606668) -->
-    <skip />
-    <!-- no translation found for passwordless_technology_detail (6853928846532955882) -->
-    <skip />
-    <!-- no translation found for public_key_cryptography_title (6751970819265298039) -->
-    <skip />
-    <!-- no translation found for public_key_cryptography_detail (6937631710280562213) -->
-    <skip />
-    <!-- no translation found for improved_account_security_title (1069841917893513424) -->
-    <skip />
-    <!-- no translation found for improved_account_security_detail (9123750251551844860) -->
-    <skip />
-    <!-- no translation found for seamless_transition_title (5335622196351371961) -->
-    <skip />
-    <!-- no translation found for seamless_transition_detail (4475509237171739843) -->
-    <skip />
+    <string name="more_about_passkeys_title" msgid="7797903098728837795">"Máis información sobre as claves de acceso"</string>
+    <string name="passwordless_technology_title" msgid="2497513482056606668">"Tecnoloxía sen contrasinais"</string>
+    <string name="passwordless_technology_detail" msgid="6853928846532955882">"As claves de acceso permítenche iniciar sesión sen depender de contrasinais. Tan só tes que usar a impresión dixital, o recoñecemento facial, o PIN ou o padrón de desbloqueo para verificar a túa identidade e crear unha clave de acceso."</string>
+    <string name="public_key_cryptography_title" msgid="6751970819265298039">"Criptografía das claves públicas"</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Segundo os estándares da Alianza FIDO (con Google, Apple, Microsoft…) e o W3C, as claves de acceso usan pares de claves criptográficas. A diferenza do nome de usuario e contrasinal, créase un par de claves público-privado para unha aplicación ou sitio web. A clave privada, que confirma a identidade, almacénase de xeito seguro no dispositivo ou xestor de contrasinais. A pública compártese co servidor da aplicación ou sitio web. Coas claves vinculadas, podes rexistrarte e conectarte ao momento."</string>
+    <string name="improved_account_security_title" msgid="1069841917893513424">"Mellora na seguranza das contas"</string>
+    <string name="improved_account_security_detail" msgid="9123750251551844860">"Cada clave está vinculada de xeito exclusivo coa aplicación ou o sitio web para o que foi creada, de tal forma que nunca poidas iniciar sesión nunha aplicación ou un sitio web fraudulentos por erro. Ademais, como os servidores só gardan as claves públicas, resulta moito máis difícil piratear."</string>
+    <string name="seamless_transition_title" msgid="5335622196351371961">"Transición fluída"</string>
+    <string name="seamless_transition_detail" msgid="4475509237171739843">"Durante este percorrido cara a un futuro sen contrasinais, estes seguirán estando dispoñibles a canda as claves de acceso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Escolle onde queres gardar: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un xestor de contrasinais para gardar a túa información e iniciar sesión máis rápido a próxima vez"</string>
     <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Queres crear unha clave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -65,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opcións de inicio de sesión"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Xestores de contrasinais bloqueados"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toca para desbloquear"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Xestionar os métodos de inicio de sesión"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Doutro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar outro dispositivo"</string>
diff --git a/packages/CredentialManager/res/values-gu/strings.xml b/packages/CredentialManager/res/values-gu/strings.xml
index 6afc6e6..bdf0257 100644
--- a/packages/CredentialManager/res/values-gu/strings.xml
+++ b/packages/CredentialManager/res/values-gu/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"ચાલુ રાખો"</string>
     <string name="string_more_options" msgid="7990658711962795124">"વધુ વિકલ્પો"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"વધુ જાણો"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"સાઇન-ઇનના વિકલ્પો"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> માટે"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"લૉક કરેલા પાસવર્ડ મેનેજર"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"અનલૉક કરવા માટે ટૅપ કરો"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"સાઇન-ઇન મેનેજ કરો"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"કોઈ અન્ય ડિવાઇસમાંથી"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"કોઈ અન્ય ડિવાઇસનો ઉપયોગ કરો"</string>
diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml
index 71ee22b..6533362 100644
--- a/packages/CredentialManager/res/values-hi/strings.xml
+++ b/packages/CredentialManager/res/values-hi/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"जारी रखें"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ज़्यादा विकल्प"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ज़्यादा जानें"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन इन करने के विकल्प"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> के लिए"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"लॉक किए गए पासवर्ड मैनेजर"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"अनलॉक करने के लिए टैप करें"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"साइन इन करने की सुविधा को मैनेज करें"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"किसी दूसरे डिवाइस से"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"दूसरे डिवाइस का इस्तेमाल करें"</string>
diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml
index aff78ff..392a8ed 100644
--- a/packages/CredentialManager/res/values-hr/strings.xml
+++ b/packages/CredentialManager/res/values-hr/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Nastavi"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Više opcija"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saznajte više"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Prikaži zaporku"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Sakrij zaporku"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Sigurniji s pristupnim ključevima"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Uz pristupne ključeve ne trebate izrađivati ili pamtiti složene zaporke"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Pristupni ključevi šifrirani su digitalni ključevi koje izrađujete pomoću svojeg otiska prsta, lica ili zaključavanja zaslona"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opcije prijave"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Upravitelji zaključanih zaporki"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Dodirnite za otključavanje"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Upravljanje prijavama"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Na drugom uređaju"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Upotrijebite drugi uređaj"</string>
diff --git a/packages/CredentialManager/res/values-hu/strings.xml b/packages/CredentialManager/res/values-hu/strings.xml
index 71e8cb3..e7ecc79 100644
--- a/packages/CredentialManager/res/values-hu/strings.xml
+++ b/packages/CredentialManager/res/values-hu/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Folytatás"</string>
     <string name="string_more_options" msgid="7990658711962795124">"További lehetőségek"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"További információ"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Fokozott biztonság – azonosítókulccsal"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Azonosítókulcs birtokában nincs szükség összetett jelszavak létrehozására vagy megjegyzésére"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Az azonosítókulcsok olyan digitális kulcsok, amelyeket ujjlenyomata, arca vagy képernyőzár használatával hoz létre"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Bejelentkezési beállítások"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Zárolt jelszókezelők"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Koppintson a feloldáshoz"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Bejelentkezési adatok kezelése"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Másik eszközről"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Másik eszköz használata"</string>
diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml
index 66aa664..d47154b 100644
--- a/packages/CredentialManager/res/values-hy/strings.xml
+++ b/packages/CredentialManager/res/values-hy/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Շարունակել"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Այլ տարբերակներ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Իմանալ ավելին"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Ցուցադրել գաղտնաբառը"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Թաքցնել գաղտնաբառը"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Մուտքի տարբերակներ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>-ի համար"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Գաղտնաբառերի կողպված կառավարիչներ"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Հպեք՝ ապակողպելու համար"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Մուտքի կառավարում"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Մեկ այլ սարքից"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Օգտագործել այլ սարք"</string>
diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml
index 8171335..d62de2f 100644
--- a/packages/CredentialManager/res/values-in/strings.xml
+++ b/packages/CredentialManager/res/values-in/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Lanjutkan"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Opsi lainnya"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Pelajari lebih lanjut"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Lebih aman dengan kunci sandi"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Dengan kunci sandi, Anda tidak perlu membuat atau mengingat sandi yang rumit"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kunci sandi adalah kunci digital terenkripsi yang Anda buat menggunakan sidik jari, wajah, atau kunci layar"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opsi login"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Pengelola sandi terkunci"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Ketuk untuk membuka kunci"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Kelola login"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Dari perangkat lain"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Gunakan perangkat lain"</string>
diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml
index 2e5218c..5339ece 100644
--- a/packages/CredentialManager/res/values-is/strings.xml
+++ b/packages/CredentialManager/res/values-is/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Áfram"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Fleiri valkostir"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Nánar"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Aukið öryggi með aðgangslyklum"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Með aðgangslyklum þarftu hvorki að búa til né muna flókin aðgangsorð"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Aðgangslyklar eru dulkóðaðir stafrænir lyklar sem þú býrð til með fingrafarinu þínu, andliti eða skjálás."</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Innskráningarkostir"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Fyrir: <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Læst aðgangsorðastjórnun"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Ýttu til að opna"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Stjórna innskráningu"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Úr öðru tæki"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Nota annað tæki"</string>
diff --git a/packages/CredentialManager/res/values-it/strings.xml b/packages/CredentialManager/res/values-it/strings.xml
index c28659b..d9b67fe 100644
--- a/packages/CredentialManager/res/values-it/strings.xml
+++ b/packages/CredentialManager/res/values-it/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continua"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Altre opzioni"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Scopri di più"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Mostra password"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Nascondi password"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Più al sicuro con le passkey"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Con le passkey non è necessario creare o ricordare password complesse"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Le passkey sono chiavi digitali criptate che crei usando la tua impronta, il tuo volto o il blocco schermo"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opzioni di accesso"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Per <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gestori delle password bloccati"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tocca per sbloccare"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gestisci gli accessi"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Da un altro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usa un dispositivo diverso"</string>
diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml
index 2082e7e..900c037 100644
--- a/packages/CredentialManager/res/values-iw/strings.xml
+++ b/packages/CredentialManager/res/values-iw/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"המשך"</string>
     <string name="string_more_options" msgid="7990658711962795124">"אפשרויות נוספות"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"מידע נוסף"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"הצגת הסיסמה"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"הסתרת הסיסמה"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"אפשרויות כניסה לחשבון"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"עבור <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"מנהלי סיסמאות נעולים"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"יש להקיש כדי לבטל את הנעילה"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ניהול כניסות"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ממכשיר אחר"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"צריך להשתמש במכשיר אחר"</string>
diff --git a/packages/CredentialManager/res/values-ja/strings.xml b/packages/CredentialManager/res/values-ja/strings.xml
index 3aab2e9f..48d73e4 100644
--- a/packages/CredentialManager/res/values-ja/strings.xml
+++ b/packages/CredentialManager/res/values-ja/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"続行"</string>
     <string name="string_more_options" msgid="7990658711962795124">"その他のオプション"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"詳細"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ログイン オプション"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> 用"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"パスワード マネージャー ロック中"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"タップしてロック解除"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ログインを管理"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"別のデバイスを使う"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"別のデバイスを使用"</string>
diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml
index ee94b7e..15b7c98 100644
--- a/packages/CredentialManager/res/values-ka/strings.xml
+++ b/packages/CredentialManager/res/values-ka/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"გაგრძელება"</string>
     <string name="string_more_options" msgid="7990658711962795124">"სხვა ვარიანტები"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"შეიტყვეთ მეტი"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"პაროლის ჩვენება"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"პაროლის დამალვა"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"სისტემაში შესვლის ვარიანტები"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>-ისთვის"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"ჩაკეტილი პაროლის მმართველები"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"შეეხეთ განსაბლოკად"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"სისტემაში შესვლის მონაცემების მართვა"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"სხვა მოწყობილობიდან"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"გამოიყენეთ სხვა მოწყობილობა"</string>
diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml
index 7daf552..3a481cb 100644
--- a/packages/CredentialManager/res/values-kk/strings.xml
+++ b/packages/CredentialManager/res/values-kk/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Жалғастыру"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Басқа опциялар"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Толық ақпарат"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Кіру опциялары"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> үшін"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Құлыпталған құпия сөз менеджерлері"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Құлыпты ашу үшін түртіңіз."</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Кіру әрекеттерін басқару"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Басқа құрылғыдан жасау"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Басқа құрылғыны пайдалану"</string>
diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml
index dce384d..f4ac3e2 100644
--- a/packages/CredentialManager/res/values-km/strings.xml
+++ b/packages/CredentialManager/res/values-km/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"បន្ត"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ជម្រើសច្រើនទៀត"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ស្វែងយល់បន្ថែម"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ជម្រើស​ចូលគណនី"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"សម្រាប់ <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"កម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ដែលបានចាក់សោ"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ចុចដើម្បីដោះសោ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"គ្រប់គ្រងការចូល​គណនី"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ពីឧបករណ៍ផ្សេងទៀត"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ប្រើឧបករណ៍ផ្សេង"</string>
diff --git a/packages/CredentialManager/res/values-kn/strings.xml b/packages/CredentialManager/res/values-kn/strings.xml
index cbc9a26..2e039da 100644
--- a/packages/CredentialManager/res/values-kn/strings.xml
+++ b/packages/CredentialManager/res/values-kn/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"ಮುಂದುವರಿಸಿ"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"ಪಾಸ್‌ವರ್ಡ್ ತೋರಿಸಿ"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಮರೆಮಾಡಿ"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ಸೈನ್ ಇನ್ ಆಯ್ಕೆಗಳು"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> ಗಾಗಿ"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"ಪಾಸ್‌ವರ್ಡ್ ನಿರ್ವಾಹಕರನ್ನು ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ಸೈನ್-ಇನ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ಮತ್ತೊಂದು ಸಾಧನದಿಂದ"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ಬೇರೆ ಸಾಧನವನ್ನು ಬಳಸಿ"</string>
diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml
index 4af16b3..21fce5d 100644
--- a/packages/CredentialManager/res/values-ko/strings.xml
+++ b/packages/CredentialManager/res/values-ko/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"계속"</string>
     <string name="string_more_options" msgid="7990658711962795124">"옵션 더보기"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"자세히 알아보기"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"로그인 옵션"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>님의 로그인 정보"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"잠긴 비밀번호 관리자"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"잠금 해제하려면 탭하세요."</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"로그인 관리"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"다른 기기에서"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"다른 기기 사용"</string>
diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml
index ac15c5b..37e078a 100644
--- a/packages/CredentialManager/res/values-ky/strings.xml
+++ b/packages/CredentialManager/res/values-ky/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Улантуу"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Башка варианттар"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Кеңири маалымат"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Сырсөздү көрсөтүү"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Сырсөздү жашыруу"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Аккаунтка кирүү параметрлери"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> үчүн"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Кулпуланган сырсөздөрдү башкаргычтар"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Кулпусун ачуу үчүн таптаңыз"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Кирүү параметрлерин тескөө"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Башка түзмөктөн"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Башка түзмөктү колдонуу"</string>
diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml
index 30d9219..1213259 100644
--- a/packages/CredentialManager/res/values-lo/strings.xml
+++ b/packages/CredentialManager/res/values-lo/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"ສືບຕໍ່"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ສຶກສາເພີ່ມເຕີມ"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"ສະແດງລະຫັດຜ່ານ"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"ເຊື່ອງລະຫັດຜ່ານ"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ຕົວເລືອກການເຂົ້າສູ່ລະບົບ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"ສຳລັບ <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"ຕົວຈັດການລະຫັດຜ່ານທີ່ລັອກໄວ້"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ແຕະເພື່ອປົດລັອກ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ຈັດການການເຂົ້າສູ່ລະບົບ"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ຈາກອຸປະກອນອື່ນ"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ໃຊ້ອຸປະກອນອື່ນ"</string>
diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml
index 4197e14..011d745 100644
--- a/packages/CredentialManager/res/values-lt/strings.xml
+++ b/packages/CredentialManager/res/values-lt/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Tęsti"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Daugiau parinkčių"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Prisijungimo parinktys"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Skirta <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Užrakintos slaptažodžių tvarkyklės"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Palieskite, kad atrakintumėte"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Tvarkyti prisijungimo informaciją"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Naudojant kitą įrenginį"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Naudoti kitą įrenginį"</string>
diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml
index d18dd15..899dc3d9 100644
--- a/packages/CredentialManager/res/values-lv/strings.xml
+++ b/packages/CredentialManager/res/values-lv/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Turpināt"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Citas opcijas"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Uzzināt vairāk"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Lielāka drošība ar piekļuves atslēgām"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Izmantojot piekļuves atslēgas, nav jāveido vai jāatceras sarežģītas paroles."</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Piekļuves atslēgas ir šifrētas digitālas atslēgas, ko varat izveidot, izmantojot pirksta nospiedumu, seju vai ekrāna bloķēšanas informāciju."</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Pierakstīšanās opcijas"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Lietotājam <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Paroļu pārvaldnieki, kuros nepieciešams autentificēties"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Pieskarieties, lai atbloķētu"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Pierakstīšanās informācijas pārvaldība"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"No citas ierīces"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Izmantot citu ierīci"</string>
diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml
index a75dbc2..ba7f029 100644
--- a/packages/CredentialManager/res/values-mk/strings.xml
+++ b/packages/CredentialManager/res/values-mk/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Продолжи"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Повеќе опции"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Дознајте повеќе"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Опции за најавување"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"За <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заклучени управници со лозинки"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Допрете за да отклучите"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Управувајте со најавувањата"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Од друг уред"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Употребете друг уред"</string>
diff --git a/packages/CredentialManager/res/values-ml/strings.xml b/packages/CredentialManager/res/values-ml/strings.xml
index aeef052..4c18ba0 100644
--- a/packages/CredentialManager/res/values-ml/strings.xml
+++ b/packages/CredentialManager/res/values-ml/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"തുടരുക"</string>
     <string name="string_more_options" msgid="7990658711962795124">"കൂടുതൽ ഓപ്‌ഷനുകൾ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"കൂടുതലറിയുക"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"പാസ്‌വേഡ് കാണിക്കുക"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"പാസ്‌വേഡ് മറയ്ക്കുക"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"സൈൻ ഇൻ ഓപ്ഷനുകൾ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> എന്നയാൾക്ക്"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"ലോക്ക് ചെയ്‌ത പാസ്‌വേഡ് സൈൻ ഇൻ മാനേജർമാർ"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"അൺലോക്ക് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"സൈൻ ഇന്നുകൾ മാനേജ് ചെയ്യുക"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"മറ്റൊരു ഉപകരണത്തിൽ നിന്ന്"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"മറ്റൊരു ഉപകരണം ഉപയോഗിക്കുക"</string>
diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml
index 2e4ed38..8b91f3b 100644
--- a/packages/CredentialManager/res/values-mn/strings.xml
+++ b/packages/CredentialManager/res/values-mn/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Үргэлжлүүлэх"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Бусад сонголт"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Нэмэлт мэдээлэл авах"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Нэвтрэх сонголт"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>-д"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Түгжээтэй нууц үгний менежерүүд"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Түгжээг тайлахын тулд товшино уу"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Нэвтрэлтийг удирдах"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Өөр төхөөрөмжөөс"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Өөр төхөөрөмж ашиглах"</string>
diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml
index 8626790..0ac9ce6 100644
--- a/packages/CredentialManager/res/values-mr/strings.xml
+++ b/packages/CredentialManager/res/values-mr/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"पुढे सुरू ठेवा"</string>
     <string name="string_more_options" msgid="7990658711962795124">"आणखी पर्याय"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"अधिक जाणून घ्या"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन इन पर्याय"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"लॉक केलेले पासवर्ड व्यवस्थापक"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"अनलॉक करण्यासाठी टॅप करा"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"साइन-इन व्यवस्थापित करा"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"दुसऱ्या डिव्हाइस वरून"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"वेगळे डिव्हाइस वापरा"</string>
diff --git a/packages/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml
index dcc1987..d762bed 100644
--- a/packages/CredentialManager/res/values-ms/strings.xml
+++ b/packages/CredentialManager/res/values-ms/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Teruskan"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Lagi pilihan"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Ketahui lebih lanjut"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Tunjukkan kata laluan"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Sembunyikan kata laluan"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Lebih selamat dengan kunci laluan"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Anda tidak perlu mencipta atau mengingati kata laluan yang rumit dengan kunci laluan"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Kunci laluan ialah kunci digital disulitkan yang anda cipta menggunakan cap jari, wajah atau kunci skrin anda"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Pilihan log masuk"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Password Manager dikunci"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Ketik untuk membuka kunci"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Urus log masuk"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Daripada peranti lain"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Gunakan peranti yang lain"</string>
diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml
index 047f738..0a03356 100644
--- a/packages/CredentialManager/res/values-my/strings.xml
+++ b/packages/CredentialManager/res/values-my/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"ရှေ့ဆက်ရန်"</string>
     <string name="string_more_options" msgid="7990658711962795124">"နောက်ထပ်ရွေးစရာများ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ပိုမိုလေ့လာရန်"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"စကားဝှက်ကို ပြရန်"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"စကားဝှက်ကို ဖျောက်ရန်"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"လက်မှတ်ထိုးဝင်ရန် နည်းလမ်းများ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> အတွက်"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"လော့ခ်ချထားသည့် စကားဝှက်မန်နေဂျာများ"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ဖွင့်ရန် တို့ပါ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"လက်မှတ်ထိုးဝင်မှုများ စီမံခြင်း"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"စက်နောက်တစ်ခုမှ"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"အခြားစက်သုံးရန်"</string>
diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml
index bee211e..774b35b 100644
--- a/packages/CredentialManager/res/values-nb/strings.xml
+++ b/packages/CredentialManager/res/values-nb/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Fortsett"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Flere alternativer"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Finn ut mer"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Påloggingsalternativer"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"For <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Låste løsninger for passordlagring"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Trykk for å låse opp"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Administrer pålogginger"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Fra en annen enhet"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Bruk en annen enhet"</string>
diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml
index ce33822..ca501bd 100644
--- a/packages/CredentialManager/res/values-ne/strings.xml
+++ b/packages/CredentialManager/res/values-ne/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"जारी राख्नुहोस्"</string>
     <string name="string_more_options" msgid="7990658711962795124">"थप विकल्पहरू"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"थप जान्नुहोस्"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"पासवर्ड देखाइयोस्"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"पासवर्ड लुकाइयोस्"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"साइन‍ इनसम्बन्धी विकल्पहरू"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> का लागि"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"लक गरिएका पासवर्ड म्यानेजरहरू"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"अनलक गर्न ट्याप गर्नुहोस्"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"साइन इनसम्बन्धी विकल्पहरू व्यवस्थापन गर्नुहोस्"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"अर्को डिभाइसका लागि"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"अर्कै डिभाइस प्रयोग गरी हेर्नुहोस्"</string>
diff --git a/packages/CredentialManager/res/values-nl/strings.xml b/packages/CredentialManager/res/values-nl/strings.xml
index adea5a3..ccba755 100644
--- a/packages/CredentialManager/res/values-nl/strings.xml
+++ b/packages/CredentialManager/res/values-nl/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Doorgaan"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Meer opties"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Meer informatie"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Wachtwoord tonen"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Wachtwoord verbergen"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Veiliger met toegangssleutels"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Met toegangssleutels hoef je geen ingewikkelde wachtwoorden te maken of te onthouden"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Toegangssleutels zijn versleutelde digitale sleutels die je maakt met je vingerafdruk, gezicht of schermvergrendeling"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opties voor inloggen"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Vergrendelde wachtwoordmanagers"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tik om te ontgrendelen"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Inloggegevens beheren"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Via een ander apparaat"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Een ander apparaat gebruiken"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 7e6d10a..73d5104 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"ଜାରି ରଖନ୍ତୁ"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ଅଧିକ ବିକଳ୍ପ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ସାଇନ ଇନ ବିକଳ୍ପଗୁଡ଼ିକ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>ରେ"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"ଲକ ଥିବା Password Manager"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ଅନଲକ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ସାଇନ-ଇନ ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ଅନ୍ୟ ଏକ ଡିଭାଇସରୁ"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ଏକ ଭିନ୍ନ ଡିଭାଇସ ବ୍ୟବହାର କରନ୍ତୁ"</string>
diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml
index cbf199e..aa6d853 100644
--- a/packages/CredentialManager/res/values-pa/strings.xml
+++ b/packages/CredentialManager/res/values-pa/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"ਜਾਰੀ ਰੱਖੋ"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ਹੋਰ ਵਿਕਲਪ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ਹੋਰ ਜਾਣੋ"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ਸਾਈਨ-ਇਨ ਕਰਨ ਦੇ ਵਿਕਲਪ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> ਲਈ"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"ਲਾਕ ਕੀਤੇ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ਸਾਈਨ-ਇਨਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"ਹੋਰ ਡੀਵਾਈਸ ਤੋਂ"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ਵੱਖਰੇ ਡੀਵਾਈਸ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml
index bf7a09e..8aca7ce 100644
--- a/packages/CredentialManager/res/values-pl/strings.xml
+++ b/packages/CredentialManager/res/values-pl/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Dalej"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Więcej opcji"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Więcej informacji"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Klucze zwiększają Twoje bezpieczeństwo"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Dzięki kluczom nie musisz tworzyć ani zapamiętywać skomplikowanych haseł"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Klucze są szyfrowanymi kluczami cyfrowymi, które tworzysz za pomocą funkcji rozpoznawania odcisku palca lub twarzy bądź blokady ekranu"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opcje logowania"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Zablokowane menedżery haseł"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Kliknij, aby odblokować"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Zarządzanie danymi logowania"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Na innym urządzeniu"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Użyj innego urządzenia"</string>
diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml
index 7a8e50a..ed0f275 100644
--- a/packages/CredentialManager/res/values-pt-rBR/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Mais opções"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saiba mais"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Mostrar senha"</string>
+    <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opções de login"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gerenciadores de senha bloqueados"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toque para desbloquear"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gerenciar logins"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De outro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar um dispositivo diferente"</string>
diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml
index 6ad17e0..d9884aa 100644
--- a/packages/CredentialManager/res/values-pt-rPT/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Mais opções"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saber mais"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Mostrar palavra-passe"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Ocultar palavra-passe"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mais segurança com chaves de acesso"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Com as chaves de acesso, não precisa de criar nem memorizar palavras-passe complexas"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"As chaves de acesso são chaves digitais encriptadas que cria através da sua impressão digital, rosto ou bloqueio de ecrã"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opções de início de sessão"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gestores de palavras-passe bloqueados"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toque para desbloquear"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Faça a gestão dos inícios de sessão"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De outro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Use um dispositivo diferente"</string>
diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml
index 7a8e50a..ed0f275 100644
--- a/packages/CredentialManager/res/values-pt/strings.xml
+++ b/packages/CredentialManager/res/values-pt/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuar"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Mais opções"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Saiba mais"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Mostrar senha"</string>
+    <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opções de login"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Gerenciadores de senha bloqueados"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Toque para desbloquear"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gerenciar logins"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De outro dispositivo"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Usar um dispositivo diferente"</string>
diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml
index b0a008f..e2a243c 100644
--- a/packages/CredentialManager/res/values-ro/strings.xml
+++ b/packages/CredentialManager/res/values-ro/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Continuă"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Mai multe opțiuni"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Află mai multe"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mai în siguranță cu chei de acces"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Dacă folosești chei de acces, nu este nevoie să creezi sau să reții parole complexe"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Cheile de acces sunt chei digitale criptate pe care le creezi folosindu-ți amprenta, fața sau blocarea ecranului"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opțiuni de conectare"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Pentru <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Manageri de parole blocate"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Atinge pentru a debloca"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Gestionează acreditările"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"De pe alt dispozitiv"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Folosește alt dispozitiv"</string>
diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml
index 3f12657..3542edc 100644
--- a/packages/CredentialManager/res/values-ru/strings.xml
+++ b/packages/CredentialManager/res/values-ru/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Продолжить"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Ещё"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Подробнее"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Показать пароль"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Скрыть пароль"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Варианты входа"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Для пользователя <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заблокированные менеджеры паролей"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Нажмите для разблокировки"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Управление входом"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"С другого устройства"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Использовать другое устройство"</string>
diff --git a/packages/CredentialManager/res/values-si/strings.xml b/packages/CredentialManager/res/values-si/strings.xml
index 64038ca..3064d26 100644
--- a/packages/CredentialManager/res/values-si/strings.xml
+++ b/packages/CredentialManager/res/values-si/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"ඉදිරියට යන්න"</string>
     <string name="string_more_options" msgid="7990658711962795124">"තවත් විකල්ප"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"තව දැන ගන්න"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"පුරනය වීමේ විකල්ප"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> සඳහා"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"අගුළු දැමූ මුරපද කළමනාකරුවන්"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"අගුළු හැරීමට තට්ටු කරන්න"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"පුරනය වීම් කළමනාකරණය කරන්න"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"වෙනත් උපාංගයකින්"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"වෙනස් උපාංගයක් භාවිතා කරන්න"</string>
diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml
index 635f0047..b7c3d2e 100644
--- a/packages/CredentialManager/res/values-sk/strings.xml
+++ b/packages/CredentialManager/res/values-sk/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Pokračovať"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Ďalšie možnosti"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Ďalšie informácie"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Zobraziť heslo"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Skryť heslo"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Bezpečnejšie s prístupovými kľúčmi"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Ak máte prístupové kľúče, nemusíte vytvárať ani si pamätať zložité heslá"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Prístupové kľúče sú šifrované digitálne kľúče, ktoré môžete vytvoriť odtlačkom prsta, tvárou alebo zámkou obrazovky."</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Možnosti prihlásenia"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Pre používateľa <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Správcovia uzamknutých hesiel"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Odomknite klepnutím"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Spravovať prihlasovacie údaje"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Z iného zariadenia"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Použiť iné zariadenie"</string>
diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml
index eeb4a96..3d70707 100644
--- a/packages/CredentialManager/res/values-sl/strings.xml
+++ b/packages/CredentialManager/res/values-sl/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Naprej"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Več možnosti"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Več o tem"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Večja varnost s ključi za dostop"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Po zaslugi ključev za dostop vam ni treba ustvarjati ali si zapomniti zapletenih gesel."</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ključi za dostop so šifrirani digitalni ključi, ki jih ustvarite s prstnim odtisom, obrazom ali načinom zaklepanja zaslona."</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Možnosti prijave"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Zaklenjeni upravitelji gesel"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Dotaknite se, da odklenete"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Upravljanje podatkov za prijavo"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Iz druge naprave"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Uporaba druge naprave"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index 28e8716..4b7ff96 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Vazhdo"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Opsione të tjera"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Mëso më shumë"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Shfaq fjalëkalimin"</string>
+    <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Opsionet e identifikimit"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Për <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Menaxherët e fjalëkalimeve të kyçura"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Trokit për të shkyçur"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Identifikimet e menaxhimit"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Nga një pajisje tjetër"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Përdor një pajisje tjetër"</string>
diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml
index 0474277..6cd5d8d 100644
--- a/packages/CredentialManager/res/values-sr/strings.xml
+++ b/packages/CredentialManager/res/values-sr/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Настави"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Још опција"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Сазнајте више"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Опције за пријављивање"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"За: <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Менаџери закључаних лозинки"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Додирните да бисте откључали"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Управљајте пријављивањима"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Са другог уређаја"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Користи други уређај"</string>
diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml
index fe13124..e061c9b 100644
--- a/packages/CredentialManager/res/values-sv/strings.xml
+++ b/packages/CredentialManager/res/values-sv/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Fortsätt"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Fler alternativ"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Läs mer"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Säkrare med nycklar"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Med nycklar behöver du inte skapa eller komma ihop invecklade lösenord"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Nycklar är krypterade digitala nycklar som du skapar med ditt fingeravtryck, ansikte eller skärmlås"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Inloggningsalternativ"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"För <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Låsta lösenordshanterare"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Tryck för att låsa upp"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Hantera inloggningar"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Via en annan enhet"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Använd en annan enhet"</string>
diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml
index 3c50151..9f30dbb 100644
--- a/packages/CredentialManager/res/values-sw/strings.xml
+++ b/packages/CredentialManager/res/values-sw/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Endelea"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Chaguo zaidi"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Pata maelezo zaidi"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Ni salama ukitumia funguo za siri"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Kwa kutumia funguo za siri, huhitaji kuunda au kukumbuka manenosiri changamano"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Funguo za siri ni funguo dijitali zilizosimbwa kwa njia fiche unazounda kwa kutumia alama yako ya kidole, uso au mbinu ya kufunga skrini"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Chaguo za kuingia katika akaunti"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Kwa ajili ya <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Vidhibiti vya manenosiri vilivyofungwa"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Gusa ili ufungue"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Dhibiti michakato ya kuingia katika akaunti"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Kutoka kwenye kifaa kingine"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Tumia kifaa tofauti"</string>
diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml
index 77beb85..4041066 100644
--- a/packages/CredentialManager/res/values-ta/strings.xml
+++ b/packages/CredentialManager/res/values-ta/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"தொடர்க"</string>
     <string name="string_more_options" msgid="7990658711962795124">"கூடுதல் விருப்பங்கள்"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"மேலும் அறிக"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"உள்நுழைவு விருப்பங்கள்"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g>க்கு"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"பூட்டப்பட்ட கடவுச்சொல் நிர்வாகிகள்"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"அன்லாக் செய்ய தட்டவும்"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"உள்நுழைவுகளை நிர்வகித்தல்"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"மற்றொரு சாதனத்திலிருந்து பயன்படுத்து"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"வேறு சாதனத்தைப் பயன்படுத்து"</string>
diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml
index e62bac9..6dd8204 100644
--- a/packages/CredentialManager/res/values-te/strings.xml
+++ b/packages/CredentialManager/res/values-te/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"కొనసాగించండి"</string>
     <string name="string_more_options" msgid="7990658711962795124">"మరిన్ని ఆప్షన్‌లు"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"మరింత తెలుసుకోండి"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"సైన్ ఇన్ ఆప్షన్‌లు"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> కోసం"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"లాక్ చేయబడిన పాస్‌వర్డ్ మేనేజర్‌లు"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"అన్‌లాక్ చేయడానికి ట్యాప్ చేయండి"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"సైన్‌ ఇన్‌లను మేనేజ్ చేయండి"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"మరొక పరికరం నుండి"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"వేరే పరికరాన్ని ఉపయోగించండి"</string>
diff --git a/packages/CredentialManager/res/values-th/strings.xml b/packages/CredentialManager/res/values-th/strings.xml
index 61144f9..78f89fc 100644
--- a/packages/CredentialManager/res/values-th/strings.xml
+++ b/packages/CredentialManager/res/values-th/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"ต่อไป"</string>
     <string name="string_more_options" msgid="7990658711962795124">"ตัวเลือกเพิ่มเติม"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"ดูข้อมูลเพิ่มเติม"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"แสดงรหัสผ่าน"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"ซ่อนรหัสผ่าน"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"ตัวเลือกการลงชื่อเข้าใช้"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"สำหรับ <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"เครื่องมือจัดการรหัสผ่านที่ล็อกไว้"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"แตะเพื่อปลดล็อก"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"จัดการการลงชื่อเข้าใช้"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"จากอุปกรณ์อื่น"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ใช้อุปกรณ์อื่น"</string>
diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml
index d75ac57..431ce07 100644
--- a/packages/CredentialManager/res/values-tl/strings.xml
+++ b/packages/CredentialManager/res/values-tl/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Magpatuloy"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Higit pang opsyon"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Matuto pa"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Mas ligtas gamit ang mga passkey"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Gamit ang mga passkey, hindi mo na kailangang gumawa o tumanda ng mga komplikadong password"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Ang mga passkey ay mga naka-encrypt na digital na susi na ginagawa mo gamit ang iyong fingerprint, mukha, o lock ng screen"</string>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Mga opsyon sa pag-sign in"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Para kay <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Mga naka-lock na password manager"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"I-tap para i-unlock"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Pamahalaan ang mga sign-in"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Mula sa ibang device"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Gumamit ng ibang device"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index 4ee0b51..0cf5cfd 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Devam"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Diğer seçenekler"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Daha fazla bilgi"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Oturum açma seçenekleri"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> için"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Kilitli şifre yöneticileri"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Kilidi açmak için dokunun"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Oturum açma bilgilerini yönetin"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Başka bir cihazdan"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Farklı bir cihaz kullan"</string>
diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml
index bd10f42..30c085e 100644
--- a/packages/CredentialManager/res/values-uk/strings.xml
+++ b/packages/CredentialManager/res/values-uk/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Продовжити"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Інші опції"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Докладніше"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Опції входу"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Для користувача <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Заблоковані менеджери паролів"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Торкніться, щоб розблокувати"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Керування даними для входу"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"З іншого пристрою"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Використовувати інший пристрій"</string>
diff --git a/packages/CredentialManager/res/values-ur/strings.xml b/packages/CredentialManager/res/values-ur/strings.xml
index 103ea38..e1e530b 100644
--- a/packages/CredentialManager/res/values-ur/strings.xml
+++ b/packages/CredentialManager/res/values-ur/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"جاری رکھیں"</string>
     <string name="string_more_options" msgid="7990658711962795124">"مزید اختیارات"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"مزید جانیں"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"سائن ان کے اختیارات"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> کے لیے"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"مقفل کردہ پاس ورڈ مینیجرز"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"غیر مقفل کرنے کے لیے تھپتھپائیں"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"سائن انز کا نظم کریں"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"دوسرے آلے سے"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"ایک مختلف آلہ استعمال کریں"</string>
diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml
index 43ece9a..96bcbc8 100644
--- a/packages/CredentialManager/res/values-uz/strings.xml
+++ b/packages/CredentialManager/res/values-uz/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Davom etish"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Boshqa parametrlar"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Batafsil"</string>
+    <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Kirish parametrlari"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> uchun"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Qulfli parol menejerlari"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Qulfni ochish uchun bosing"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Hisob maʼlumotlarini boshqarish"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Boshqa qurilmada"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Boshqa qurilmadan foydalanish"</string>
diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml
index f2b9476..61b425e 100644
--- a/packages/CredentialManager/res/values-vi/strings.xml
+++ b/packages/CredentialManager/res/values-vi/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"Tiếp tục"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Tuỳ chọn khác"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Tìm hiểu thêm"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"An toàn hơn nhờ mã xác thực"</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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Tuỳ chọn đăng nhập"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Cho <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Trình quản lý mật khẩu đã khoá"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Nhấn để mở khoá"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Quản lý thông tin đăng nhập"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Từ một thiết bị khác"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Dùng thiết bị khác"</string>
diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml
index daffaca..d03be77 100644
--- a/packages/CredentialManager/res/values-zh-rCN/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"继续"</string>
     <string name="string_more_options" msgid="7990658711962795124">"更多选项"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"了解详情"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"显示密码"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"隐藏密码"</string>
     <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>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"登录选项"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"用户:<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"已锁定的密码管理工具"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"点按即可解锁"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"管理登录信息"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"通过另一台设备"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"使用其他设备"</string>
diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml
index 5255b92..8ddd4be 100644
--- a/packages/CredentialManager/res/values-zh-rHK/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"繼續"</string>
     <string name="string_more_options" msgid="7990658711962795124">"更多選項"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"瞭解詳情"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"登入選項"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> 專用"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"已鎖定的密碼管理工具"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"輕按即可解鎖"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"管理登入資料"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"透過其他裝置"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"使用其他裝置"</string>
diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml
index 274ed21..7e42d56 100644
--- a/packages/CredentialManager/res/values-zh-rTW/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml
@@ -6,6 +6,10 @@
     <string name="string_continue" msgid="1346732695941131882">"繼續"</string>
     <string name="string_more_options" msgid="7990658711962795124">"更多選項"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"瞭解詳情"</string>
+    <!-- no translation found for content_description_show_password (3283502010388521607) -->
+    <skip />
+    <!-- no translation found for content_description_hide_password (6841375971631767996) -->
+    <skip />
     <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>
@@ -55,7 +59,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"登入選項"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> 專用"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"已鎖定的密碼管理工具"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"輕觸即可解鎖"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"管理登入資訊"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"透過其他裝置"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"使用其他裝置"</string>
diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml
index d6624f0..7a40771 100644
--- a/packages/CredentialManager/res/values-zu/strings.xml
+++ b/packages/CredentialManager/res/values-zu/strings.xml
@@ -6,6 +6,8 @@
     <string name="string_continue" msgid="1346732695941131882">"Qhubeka"</string>
     <string name="string_more_options" msgid="7990658711962795124">"Okunye okungakukhethwa kukho"</string>
     <string name="string_learn_more" msgid="4541600451688392447">"Funda kabanzi"</string>
+    <string name="content_description_show_password" msgid="3283502010388521607">"Bonisa iphasiwedi"</string>
+    <string name="content_description_hide_password" msgid="6841375971631767996">"Fihla iphasiwedi"</string>
     <string name="passkey_creation_intro_title" msgid="4251037543787718844">"Iphephe ngokhiye bokudlula"</string>
     <string name="passkey_creation_intro_body_password" msgid="8825872426579958200">"Ngokhiye wokudlula, awudingi ukusungula noma ukukhumbula amaphasiwedi ayinkimbinkimbi"</string>
     <string name="passkey_creation_intro_body_fingerprint" msgid="7331338631826254055">"Okhiye bokungena bangokhiye bedijithali ababethelwe obasungula usebenzisa isigxivizo somunwe sakho, ubuso, noma ukukhiya isikrini"</string>
@@ -55,7 +57,10 @@
     <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Okungakhethwa kukho kokungena ngemvume"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"Okuka-<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Abaphathi bephasiwedi abakhiyiwe"</string>
-    <string name="locked_credential_entry_label_subtext" msgid="9213450912991988691">"Thepha ukuze uvule"</string>
+    <!-- no translation found for locked_credential_entry_label_subtext_tap_to_unlock (6390367581393605009) -->
+    <skip />
+    <!-- no translation found for locked_credential_entry_label_subtext_no_sign_in (8131725029983174901) -->
+    <skip />
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"Phatha ukungena ngemvume"</string>
     <string name="get_dialog_heading_from_another_device" msgid="1166697017046724072">"Kusukela kwenye idivayisi"</string>
     <string name="get_dialog_option_headline_use_a_different_device" msgid="8201578814988047549">"Sebenzisa idivayisi ehlukile"</string>
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index d6909719..9eda82a 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -13,6 +13,10 @@
   <string name="string_more_options">More options</string>
   <!-- This is a label for a button that links to additional information about passkeys. [CHAR LIMIT=20] -->
   <string name="string_learn_more">Learn more</string>
+  <!-- This is a label for content description for show password icon button. -->
+  <string name="content_description_show_password">Show password</string>
+  <!-- This is a label for content description for hide password icon button. -->
+  <string name="content_description_hide_password">Hide password</string>
   <!-- This string introduces passkeys to the users for the first time they use this method. Tip: to avoid gendered language patterns, this header could be translated as if the original string were "More safety with passkeys". [CHAR LIMIT=200] -->
   <string name="passkey_creation_intro_title">Safer with passkeys</string>
   <!-- This string highlight passkey benefits related with the password. [CHAR LIMIT=200] -->
@@ -112,8 +116,10 @@
   <string name="get_dialog_heading_for_username">For <xliff:g id="username" example="becket@gmail.com">%1$s</xliff:g></string>
   <!-- Column heading for displaying locked (that is, the user needs to first authenticate via pin, fingerprint, faceId, etc.) sign-ins. [CHAR LIMIT=80] -->
   <string name="get_dialog_heading_locked_password_managers">Locked password managers</string>
-  <!-- Explanatory sub/body text for an option entry to use a locked (that is, the user needs to first authenticate via pin, fingerprint, faceId, etc.) sign-in. [CHAR LIMIT=120] -->
-  <string name="locked_credential_entry_label_subtext">Tap to unlock</string>
+  <!-- Explanatory label for a button that takes the user to unlock a credential provider by authenticating via pin, fingerprint, faceId, etc. [CHAR LIMIT=120] -->
+  <string name="locked_credential_entry_label_subtext_tap_to_unlock">Tap to unlock</string>
+  <!-- Explanatory label for a disabled button explaining that this option isn't viable because it does not contain any available credential (e.g. password, passkey, etc.) for the user. [CHAR LIMIT=120] -->
+  <string name="locked_credential_entry_label_subtext_no_sign_in">No sign-in info</string>
   <!-- Column heading for displaying action chips for managing sign-ins from each credential provider. [CHAR LIMIT=80] -->
   <string name="get_dialog_heading_manage_sign_ins">Manage sign-ins</string>
   <!-- Column heading for displaying option to use sign-ins saved on a different device. [CHAR LIMIT=80] -->
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index a48cd2b..0723c1a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -16,16 +16,15 @@
 
 package com.android.credentialmanager
 
-import android.app.PendingIntent
 import android.app.slice.Slice
 import android.app.slice.SliceSpec
 import android.content.Context
 import android.content.Intent
-import android.content.pm.SigningInfo
 import android.credentials.CreateCredentialRequest
 import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
-import android.credentials.GetCredentialOption
+import android.credentials.CredentialOption
 import android.credentials.GetCredentialRequest
+import android.credentials.ui.AuthenticationEntry
 import android.credentials.ui.Constants
 import android.credentials.ui.Entry
 import android.credentials.ui.CreateCredentialProviderData
@@ -37,39 +36,44 @@
 import android.credentials.ui.ProviderPendingIntentResponse
 import android.credentials.ui.UserSelectionDialogResult
 import android.net.Uri
+import android.os.IBinder
 import android.os.Binder
 import android.os.Bundle
 import android.os.ResultReceiver
-import android.service.credentials.CredentialProviderService
 import com.android.credentialmanager.createflow.DisabledProviderInfo
 import com.android.credentialmanager.createflow.EnabledProviderInfo
 import com.android.credentialmanager.createflow.RequestDisplayInfo
 import com.android.credentialmanager.getflow.GetCredentialUiState
-import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest.Companion.toCredentialDataBundle
-import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
-import com.android.credentialmanager.jetpack.provider.Action
-import com.android.credentialmanager.jetpack.provider.CreateEntry
-import com.android.credentialmanager.jetpack.provider.CredentialCountInformation
-import com.android.credentialmanager.jetpack.provider.CredentialEntry
+import androidx.credentials.CreateCredentialRequest.DisplayInfo
+import androidx.credentials.CreatePublicKeyCredentialRequest
+import androidx.credentials.CreatePasswordRequest
 
-// Consider repo per screen, similar to view model?
+import java.time.Instant
+
+/**
+ * Client for interacting with Credential Manager. Also holds data inputs from it.
+ *
+ * IMPORTANT: instantiation of the object can fail if the data inputs aren't valid. Callers need
+ * to be equipped to handle this gracefully.
+ */
 class CredentialManagerRepo(
     private val context: Context,
     intent: Intent,
+    userConfigRepo: UserConfigRepo,
 ) {
     val requestInfo: RequestInfo
     private val providerEnabledList: List<ProviderData>
     private val providerDisabledList: List<DisabledProviderData>?
-
     // TODO: require non-null.
     val resultReceiver: ResultReceiver?
 
+    var initialUiState: UiState
+
     init {
         requestInfo = intent.extras?.getParcelable(
             RequestInfo.EXTRA_REQUEST_INFO,
             RequestInfo::class.java
-        ) ?: testCreatePasskeyRequestInfo()
+        ) ?: testGetRequestInfo()
 
         providerEnabledList = when (requestInfo.type) {
             RequestInfo.TYPE_CREATE ->
@@ -83,7 +87,6 @@
                     GetCredentialProviderData::class.java
                 ) ?: testGetCredentialProviderList()
             else -> {
-                // TODO: fail gracefully
                 throw IllegalStateException("Unrecognized request type: ${requestInfo.type}")
             }
         }
@@ -98,6 +101,35 @@
             Constants.EXTRA_RESULT_RECEIVER,
             ResultReceiver::class.java
         )
+
+        initialUiState = when (requestInfo.type) {
+            RequestInfo.TYPE_CREATE -> {
+                val defaultProviderId = userConfigRepo.getDefaultProviderId()
+                val isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse()
+                val providerEnableListUiState = getCreateProviderEnableListInitialUiState()
+                val providerDisableListUiState = getCreateProviderDisableListInitialUiState()
+                val requestDisplayInfoUiState = getCreateRequestDisplayInfoInitialUiState()!!
+                UiState(
+                    createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState(
+                        providerEnableListUiState,
+                        providerDisableListUiState,
+                        defaultProviderId,
+                        requestDisplayInfoUiState,
+                        /** isOnPasskeyIntroStateAlready = */ false,
+                        isPasskeyFirstUse)!!,
+                    getCredentialUiState = null,
+                )
+            }
+            RequestInfo.TYPE_GET -> UiState(
+                createCredentialUiState = null,
+                getCredentialUiState = getCredentialInitialUiState()!!,
+            )
+            else -> throw IllegalStateException("Unrecognized request type: ${requestInfo.type}")
+        }
+    }
+
+    fun initState(): UiState {
+        return initialUiState
     }
 
     // The dialog is canceled by the user.
@@ -115,9 +147,7 @@
     }
 
     fun onCancel(cancelCode: Int) {
-        val resultData = Bundle()
-        BaseDialogResult.addToBundle(BaseDialogResult(requestInfo.token), resultData)
-        resultReceiver?.send(cancelCode, resultData)
+        sendCancellationCode(cancelCode, requestInfo.token, resultReceiver)
     }
 
     fun onOptionSelected(
@@ -134,17 +164,17 @@
             entrySubkey,
             if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null
         )
-        val resultData = Bundle()
-        UserSelectionDialogResult.addToBundle(userSelectionDialogResult, resultData)
+        val resultDataBundle = Bundle()
+        UserSelectionDialogResult.addToBundle(userSelectionDialogResult, resultDataBundle)
         resultReceiver?.send(
             BaseDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION,
-            resultData
+            resultDataBundle
         )
     }
 
-    fun getCredentialInitialUiState(): GetCredentialUiState? {
+    // IMPORTANT: new invocation should be mindful that this method can throw.
+    private fun getCredentialInitialUiState(): GetCredentialUiState? {
         val providerEnabledList = GetFlowUtils.toProviderList(
-            // TODO: handle runtime cast error
             providerEnabledList as List<GetCredentialProviderData>, context
         )
         val requestDisplayInfo = GetFlowUtils.toRequestDisplayInfo(requestInfo, context)
@@ -154,25 +184,39 @@
         )
     }
 
-    fun getCreateProviderEnableListInitialUiState(): List<EnabledProviderInfo> {
+    // IMPORTANT: new invocation should be mindful that this method can throw.
+    private fun getCreateProviderEnableListInitialUiState(): List<EnabledProviderInfo> {
         val providerEnabledList = CreateFlowUtils.toEnabledProviderList(
-            // Handle runtime cast error
             providerEnabledList as List<CreateCredentialProviderData>, context
         )
         return providerEnabledList
     }
 
-    fun getCreateProviderDisableListInitialUiState(): List<DisabledProviderInfo> {
+    private fun getCreateProviderDisableListInitialUiState(): List<DisabledProviderInfo> {
         return CreateFlowUtils.toDisabledProviderList(
             // Handle runtime cast error
             providerDisabledList, context
         )
     }
 
-    fun getCreateRequestDisplayInfoInitialUiState(): RequestDisplayInfo? {
+    private fun getCreateRequestDisplayInfoInitialUiState(): RequestDisplayInfo? {
         return CreateFlowUtils.toRequestDisplayInfo(requestInfo, context)
     }
 
+    companion object {
+        fun sendCancellationCode(
+            cancelCode: Int,
+            requestToken: IBinder?,
+            resultReceiver: ResultReceiver?
+        ) {
+            if (requestToken != null && resultReceiver != null) {
+                val resultData = Bundle()
+                BaseDialogResult.addToBundle(BaseDialogResult(requestToken), resultData)
+                resultReceiver.send(cancelCode, resultData)
+            }
+        }
+    }
+
     // TODO: below are prototype functionalities. To be removed for productionization.
     private fun testCreateCredentialEnabledProviderList(): List<CreateCredentialProviderData> {
         return listOf(
@@ -180,14 +224,14 @@
                 .Builder("io.enpass.app")
                 .setSaveEntries(
                     listOf<Entry>(
-                        newCreateEntry(
+                        CreateTestUtils.newCreateEntry(context,
                             "key1", "subkey-1", "elisa.beckett@gmail.com",
-                            20, 7, 27, 10L,
-                            "Optional footer description"
+                            20, 7, 27, Instant.ofEpochSecond(10L),
+                            "Legal note"
                         ),
-                        newCreateEntry(
+                        CreateTestUtils.newCreateEntry(context,
                             "key1", "subkey-2", "elisa.work@google.com",
-                            20, 7, 27, 12L,
+                            20, 7, 27, Instant.ofEpochSecond(12L),
                             null
                         ),
                     )
@@ -200,14 +244,14 @@
                 .Builder("com.dashlane")
                 .setSaveEntries(
                     listOf<Entry>(
-                        newCreateEntry(
+                        CreateTestUtils.newCreateEntry(context,
                             "key1", "subkey-3", "elisa.beckett@dashlane.com",
-                            20, 7, 27, 11L,
+                            20, 7, 27, Instant.ofEpochSecond(11L),
                             null
                         ),
-                        newCreateEntry(
+                        CreateTestUtils.newCreateEntry(context,
                             "key1", "subkey-4", "elisa.work@dashlane.com",
-                            20, 7, 27, 14L,
+                            20, 7, 27, Instant.ofEpochSecond(14L),
                             null
                         ),
                     )
@@ -227,34 +271,43 @@
         return listOf(
             GetCredentialProviderData.Builder("io.enpass.app")
                 .setCredentialEntries(
-                    listOf<Entry>(
-                        newGetEntry(
-                            "key1", "subkey-1", TYPE_PASSWORD_CREDENTIAL, "Password",
-                            "elisa.family@outlook.com", null, 3L
+                    listOf(
+                        GetTestUtils.newPasswordEntry(
+                            context, "key1", "subkey-1", "elisa.family@outlook.com", null,
+                            Instant.ofEpochSecond(8000L)
                         ),
-                        newGetEntry(
-                            "key1", "subkey-1", TYPE_PUBLIC_KEY_CREDENTIAL, "Passkey",
-                            "elisa.bakery@gmail.com", "Elisa Beckett", 0L
+                        GetTestUtils.newPasskeyEntry(
+                            context, "key1", "subkey-1", "elisa.bakery@gmail.com", "Elisa Beckett",
+                            null
                         ),
-                        newGetEntry(
-                            "key1", "subkey-2", TYPE_PASSWORD_CREDENTIAL, "Password",
-                            "elisa.bakery@gmail.com", null, 10L
+                        GetTestUtils.newPasswordEntry(
+                            context, "key1", "subkey-2", "elisa.bakery@gmail.com", null,
+                            Instant.ofEpochSecond(10000L)
                         ),
-                        newGetEntry(
-                            "key1", "subkey-3", TYPE_PUBLIC_KEY_CREDENTIAL, "Passkey",
-                            "elisa.family@outlook.com", "Elisa Beckett", 1L
+                        GetTestUtils.newPasskeyEntry(
+                            context, "key1", "subkey-3", "elisa.family@outlook.com",
+                            "Elisa Beckett", Instant.ofEpochSecond(500L)
                         ),
                     )
-                ).setAuthenticationEntry(
-                    newAuthenticationEntry("key2", "subkey-1", TYPE_PASSWORD_CREDENTIAL)
+                ).setAuthenticationEntries(
+                    listOf(
+                        GetTestUtils.newAuthenticationEntry(
+                            context, "key2", "subkey-1", "locked-user1@gmail.com",
+                            AuthenticationEntry.STATUS_LOCKED
+                        ),
+                        GetTestUtils.newAuthenticationEntry(
+                            context, "key2", "subkey-2", "locked-user2@gmail.com",
+                            AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
+                        ),
+                    )
                 ).setActionChips(
                     listOf(
-                        newActionEntry(
-                            "key3", "subkey-1", TYPE_PASSWORD_CREDENTIAL,
+                        GetTestUtils.newActionEntry(
+                            context, "key3", "subkey-1",
                             "Open Google Password Manager", "elisa.beckett@gmail.com"
                         ),
-                        newActionEntry(
-                            "key3", "subkey-2", TYPE_PASSWORD_CREDENTIAL,
+                        GetTestUtils.newActionEntry(
+                            context, "key3", "subkey-2",
                             "Open Google Password Manager", "beckett-family@gmail.com"
                         ),
                     )
@@ -264,137 +317,32 @@
             GetCredentialProviderData.Builder("com.dashlane")
                 .setCredentialEntries(
                     listOf<Entry>(
-                        newGetEntry(
-                            "key1", "subkey-2", TYPE_PASSWORD_CREDENTIAL, "Password",
-                            "elisa.family@outlook.com", null, 4L
+                        GetTestUtils.newPasswordEntry(
+                            context, "key1", "subkey-2", "elisa.family@outlook.com", null,
+                            Instant.ofEpochSecond(9000L)
                         ),
-                        newGetEntry(
-                            "key1", "subkey-3", TYPE_PASSWORD_CREDENTIAL, "Password",
-                            "elisa.work@outlook.com", null, 11L
+                        GetTestUtils.newPasswordEntry(
+                            context, "key1", "subkey-3", "elisa.work@outlook.com", null,
+                            Instant.ofEpochSecond(11000L)
                         ),
                     )
-                ).setAuthenticationEntry(
-                    newAuthenticationEntry("key2", "subkey-1", TYPE_PASSWORD_CREDENTIAL)
+                ).setAuthenticationEntries(
+                     listOf(GetTestUtils.newAuthenticationEntry(
+                         context, "key2", "subkey-1", "foo@email.com",
+                         AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT
+                     ))
                 ).setActionChips(
                     listOf(
-                        newActionEntry(
-                            "key3", "subkey-1", TYPE_PASSWORD_CREDENTIAL,
-                            "Open Enpass"
+                        GetTestUtils.newActionEntry(
+                            context, "key3", "subkey-1", "Open Enpass",
+                            "Manage passwords"
                         ),
                     )
                 ).build(),
         )
     }
 
-    private fun newActionEntry(
-        key: String,
-        subkey: String,
-        credentialType: String,
-        text: String,
-        subtext: String? = null,
-    ): Entry {
-        val action = Action(text, subtext, null)
 
-        return Entry(
-            key,
-            subkey,
-            Action.toSlice(action)
-        )
-    }
-
-    private fun newAuthenticationEntry(
-        key: String,
-        subkey: String,
-        credentialType: String,
-    ): Entry {
-        val slice = Slice.Builder(
-            Uri.EMPTY, SliceSpec(credentialType, 1)
-        )
-        return Entry(
-            key,
-            subkey,
-            slice.build()
-        )
-    }
-
-    private fun newGetEntry(
-        key: String,
-        subkey: String,
-        credentialType: String,
-        credentialTypeDisplayName: String,
-        userName: String,
-        userDisplayName: String?,
-        lastUsedTimeMillis: Long?,
-    ): Entry {
-        val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
-            .setPackage("com.androidauth.androidvault")
-        intent.putExtra("provider_extra_sample", "testprovider")
-
-        val pendingIntent = PendingIntent.getActivity(
-            context, 1,
-            intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
-                or PendingIntent.FLAG_ONE_SHOT)
-        )
-
-        val credentialEntry = CredentialEntry(
-            credentialType, credentialTypeDisplayName, userName,
-            userDisplayName, pendingIntent, lastUsedTimeMillis
-                ?: 0L, null, false
-        )
-
-        return Entry(
-            key,
-            subkey,
-            CredentialEntry.toSlice(credentialEntry),
-            Intent()
-        )
-    }
-
-    private fun newCreateEntry(
-        key: String,
-        subkey: String,
-        providerDisplayName: String,
-        passwordCount: Int,
-        passkeyCount: Int,
-        totalCredentialCount: Int,
-        lastUsedTimeMillis: Long,
-        footerDescription: String?,
-    ): Entry {
-        val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
-            .setPackage("com.androidauth.androidvault")
-        intent.putExtra("provider_extra_sample", "testprovider")
-        val pendingIntent = PendingIntent.getActivity(
-            context, 1,
-            intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
-                or PendingIntent.FLAG_ONE_SHOT)
-        )
-        val createPasswordRequest = android.service.credentials.CreateCredentialRequest(
-            android.service.credentials.CallingAppInfo(
-                context.applicationInfo.packageName, SigningInfo()
-            ),
-            TYPE_PASSWORD_CREDENTIAL,
-            toCredentialDataBundle("beckett-bakert@gmail.com", "password123")
-        )
-        val fillInIntent = Intent().putExtra(
-            CredentialProviderService.EXTRA_CREATE_CREDENTIAL_REQUEST,
-            createPasswordRequest
-        )
-
-        val createEntry = CreateEntry(
-            providerDisplayName, pendingIntent,
-            null, lastUsedTimeMillis,
-            listOf(
-                CredentialCountInformation.createPasswordCountInformation(passwordCount),
-                CredentialCountInformation.createPublicKeyCountInformation(passkeyCount),
-            ), footerDescription
-        )
-        return Entry(
-            key,
-            subkey,
-            CreateEntry.toSlice(createEntry),
-            fillInIntent
-        )
-    }
 
     private fun newRemoteEntry(
         key: String,
@@ -451,9 +399,8 @@
         return RequestInfo.newCreateRequestInfo(
             Binder(),
             CreateCredentialRequest(
-                TYPE_PUBLIC_KEY_CREDENTIAL,
+                "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL",
                 credentialData,
-                // TODO: populate with actual data
                 /*candidateQueryData=*/ Bundle(),
                 /*isSystemProviderRequired=*/ false
             ),
@@ -462,14 +409,13 @@
     }
 
     private fun testCreatePasswordRequestInfo(): RequestInfo {
-        val data = toCredentialDataBundle("beckett-bakert@gmail.com", "password123")
+        val request = CreatePasswordRequest("beckett-bakert@gmail.com", "password123")
         return RequestInfo.newCreateRequestInfo(
             Binder(),
             CreateCredentialRequest(
                 TYPE_PASSWORD_CREDENTIAL,
-                data,
-                // TODO: populate with actual data
-                /*candidateQueryData=*/ Bundle(),
+                request.credentialData,
+                request.candidateQueryData,
                 /*isSystemProviderRequired=*/ false
             ),
             "com.google.android.youtube"
@@ -478,6 +424,10 @@
 
     private fun testCreateOtherCredentialRequestInfo(): RequestInfo {
         val data = Bundle()
+        val displayInfo = DisplayInfo("my-username00", "Joe")
+        data.putBundle(
+            "androidx.credentials.BUNDLE_KEY_REQUEST_DISPLAY_INFO",
+            displayInfo.toBundle())
         return RequestInfo.newCreateRequestInfo(
             Binder(),
             CreateCredentialRequest(
@@ -496,9 +446,9 @@
             GetCredentialRequest.Builder(
                 Bundle()
             )
-                .addGetCredentialOption(
-                    GetCredentialOption(
-                        TYPE_PUBLIC_KEY_CREDENTIAL,
+                .addCredentialOption(
+                    CredentialOption(
+                        "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL",
                         Bundle(),
                         Bundle(), /*isSystemProviderRequired=*/
                         false
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index 3b9c02a..bf69ef4 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -17,112 +17,98 @@
 package com.android.credentialmanager
 
 import android.content.Intent
+import android.credentials.ui.BaseDialogResult
 import android.credentials.ui.RequestInfo
 import android.os.Bundle
+import android.os.ResultReceiver
 import android.provider.Settings
 import android.util.Log
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.compose.setContent
 import androidx.activity.result.contract.ActivityResultContracts
+import androidx.activity.viewModels
 import androidx.compose.material.ExperimentalMaterialApi
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
 import androidx.lifecycle.viewmodel.compose.viewModel
 import com.android.credentialmanager.common.Constants
 import com.android.credentialmanager.common.DialogState
 import com.android.credentialmanager.common.ProviderActivityResult
 import com.android.credentialmanager.createflow.CreateCredentialScreen
-import com.android.credentialmanager.createflow.CreateCredentialViewModel
 import com.android.credentialmanager.getflow.GetCredentialScreen
-import com.android.credentialmanager.getflow.GetCredentialViewModel
 import com.android.credentialmanager.ui.theme.CredentialSelectorTheme
 
 @ExperimentalMaterialApi
 class CredentialSelectorActivity : ComponentActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        val credManRepo = CredentialManagerRepo(this, intent)
-        UserConfigRepo.setup(this)
+        Log.d(Constants.LOG_TAG, "Creating new CredentialSelectorActivity")
         try {
+            val userConfigRepo = UserConfigRepo(this)
+            val credManRepo = CredentialManagerRepo(this, intent, userConfigRepo)
             setContent {
                 CredentialSelectorTheme {
-                    CredentialManagerBottomSheet(credManRepo.requestInfo.type, credManRepo)
+                    CredentialManagerBottomSheet(
+                        credManRepo,
+                        userConfigRepo
+                    )
                 }
             }
         } catch (e: Exception) {
-            Log.e(Constants.LOG_TAG, "Failed to show the credential selector", e)
-            reportInstantiationErrorAndFinishActivity(credManRepo)
+            onInitializationError(e, intent)
+        }
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        super.onNewIntent(intent)
+        setIntent(intent)
+        Log.d(Constants.LOG_TAG, "Existing activity received new intent")
+        try {
+            val userConfigRepo = UserConfigRepo(this)
+            val credManRepo = CredentialManagerRepo(this, intent, userConfigRepo)
+            val viewModel: CredentialSelectorViewModel by viewModels()
+            viewModel.onNewCredentialManagerRepo(credManRepo)
+        } catch (e: Exception) {
+            onInitializationError(e, intent)
         }
     }
 
     @ExperimentalMaterialApi
     @Composable
-    fun CredentialManagerBottomSheet(requestType: String, credManRepo: CredentialManagerRepo) {
-        val providerActivityResult = remember { mutableStateOf<ProviderActivityResult?>(null) }
+    fun CredentialManagerBottomSheet(
+        credManRepo: CredentialManagerRepo,
+        userConfigRepo: UserConfigRepo
+    ) {
+        val viewModel: CredentialSelectorViewModel = viewModel {
+            CredentialSelectorViewModel(credManRepo, userConfigRepo)
+        }
         val launcher = rememberLauncherForActivityResult(
             ActivityResultContracts.StartIntentSenderForResult()
         ) {
-            providerActivityResult.value = ProviderActivityResult(it.resultCode, it.data)
+            viewModel.onProviderActivityResult(ProviderActivityResult(it.resultCode, it.data))
         }
-        when (requestType) {
-            RequestInfo.TYPE_CREATE -> {
-                val viewModel: CreateCredentialViewModel = viewModel {
-                    val vm = CreateCredentialViewModel.newInstance(
-                        credManRepo = credManRepo,
-                        providerEnableListUiState =
-                        credManRepo.getCreateProviderEnableListInitialUiState(),
-                        providerDisableListUiState =
-                        credManRepo.getCreateProviderDisableListInitialUiState(),
-                        requestDisplayInfoUiState =
-                        credManRepo.getCreateRequestDisplayInfoInitialUiState()
-                    )
-                    if (vm == null) {
-                        // Input parsing failed. Close the activity.
-                        reportInstantiationErrorAndFinishActivity(credManRepo)
-                        throw IllegalStateException()
-                    } else {
-                        vm
-                    }
-                }
-                LaunchedEffect(viewModel.uiState.dialogState) {
-                    handleDialogState(viewModel.uiState.dialogState)
-                }
-                providerActivityResult.value?.let {
-                    viewModel.onProviderActivityResult(it)
-                    providerActivityResult.value = null
-                }
-                CreateCredentialScreen(
-                    viewModel = viewModel,
-                    providerActivityLauncher = launcher
-                )
-            }
-            RequestInfo.TYPE_GET -> {
-                val viewModel: GetCredentialViewModel = viewModel {
-                    val initialUiState = credManRepo.getCredentialInitialUiState()
-                    if (initialUiState == null) {
-                        // Input parsing failed. Close the activity.
-                        reportInstantiationErrorAndFinishActivity(credManRepo)
-                        throw IllegalStateException()
-                    } else {
-                        GetCredentialViewModel(credManRepo, initialUiState)
-                    }
-                }
-                LaunchedEffect(viewModel.uiState.dialogState) {
-                    handleDialogState(viewModel.uiState.dialogState)
-                }
-                providerActivityResult.value?.let {
-                    viewModel.onProviderActivityResult(it)
-                    providerActivityResult.value = null
-                }
-                GetCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
-            }
-            else -> {
-                Log.d(Constants.LOG_TAG, "Unknown type, not rendering any UI")
-                reportInstantiationErrorAndFinishActivity(credManRepo)
-            }
+        LaunchedEffect(viewModel.uiState.dialogState) {
+            handleDialogState(viewModel.uiState.dialogState)
+        }
+
+        val createCredentialUiState = viewModel.uiState.createCredentialUiState
+        val getCredentialUiState = viewModel.uiState.getCredentialUiState
+        if (createCredentialUiState != null) {
+            CreateCredentialScreen(
+                viewModel = viewModel,
+                createCredentialUiState = createCredentialUiState,
+                providerActivityLauncher = launcher
+            )
+        } else if (getCredentialUiState != null) {
+            GetCredentialScreen(
+                viewModel = viewModel,
+                getCredentialUiState = getCredentialUiState,
+                providerActivityLauncher = launcher
+            )
+        } else {
+            Log.d(Constants.LOG_TAG, "UI wasn't able to render neither get nor create flow")
+            reportInstantiationErrorAndFinishActivity(credManRepo)
         }
     }
 
@@ -142,4 +128,21 @@
             this@CredentialSelectorActivity.finish()
         }
     }
+
+    private fun onInitializationError(e: Exception, intent: Intent) {
+        Log.e(Constants.LOG_TAG, "Failed to show the credential selector", e)
+        val resultReceiver = intent.getParcelableExtra(
+            android.credentials.ui.Constants.EXTRA_RESULT_RECEIVER,
+            ResultReceiver::class.java
+        )
+        val requestInfo = intent.extras?.getParcelable(
+            RequestInfo.EXTRA_REQUEST_INFO,
+            RequestInfo::class.java
+        )
+        CredentialManagerRepo.sendCancellationCode(
+            BaseDialogResult.RESULT_CODE_DATA_PARSING_FAILURE,
+            requestInfo?.token, resultReceiver
+        )
+        this.finish()
+    }
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
new file mode 100644
index 0000000..30b4b86
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager
+
+import android.app.Activity
+import android.util.Log
+import androidx.activity.compose.ManagedActivityResultLauncher
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.IntentSenderRequest
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.lifecycle.ViewModel
+import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.common.Constants
+import com.android.credentialmanager.common.DialogState
+import com.android.credentialmanager.common.ProviderActivityResult
+import com.android.credentialmanager.common.ProviderActivityState
+import com.android.credentialmanager.createflow.ActiveEntry
+import com.android.credentialmanager.createflow.CreateCredentialUiState
+import com.android.credentialmanager.createflow.CreateScreenState
+import com.android.credentialmanager.getflow.GetCredentialUiState
+import com.android.credentialmanager.getflow.GetScreenState
+
+/** One and only one of create or get state can be active at any given time. */
+data class UiState(
+    val createCredentialUiState: CreateCredentialUiState?,
+    val getCredentialUiState: GetCredentialUiState?,
+    val selectedEntry: BaseEntry? = null,
+    val providerActivityState: ProviderActivityState = ProviderActivityState.NOT_APPLICABLE,
+    val dialogState: DialogState = DialogState.ACTIVE,
+)
+
+class CredentialSelectorViewModel(
+    private var credManRepo: CredentialManagerRepo,
+    private val userConfigRepo: UserConfigRepo,
+) : ViewModel() {
+    var uiState by mutableStateOf(credManRepo.initState())
+        private set
+
+    /**************************************************************************/
+    /*****                       Shared Callbacks                         *****/
+    /**************************************************************************/
+    fun onCancel() {
+        credManRepo.onUserCancel()
+        uiState = uiState.copy(dialogState = DialogState.COMPLETE)
+    }
+
+    fun onNewCredentialManagerRepo(credManRepo: CredentialManagerRepo) {
+        this.credManRepo = credManRepo
+        uiState = credManRepo.initState()
+    }
+
+    fun launchProviderUi(
+        launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
+    ) {
+        val entry = uiState.selectedEntry
+        if (entry != null && entry.pendingIntent != null) {
+            Log.d(Constants.LOG_TAG, "Launching provider activity")
+            uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
+            val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
+                .setFillInIntent(entry.fillInIntent).build()
+            launcher.launch(intentSenderRequest)
+        } else {
+            Log.d(Constants.LOG_TAG, "No provider UI to launch")
+            onInternalError()
+        }
+    }
+
+    fun onProviderActivityResult(providerActivityResult: ProviderActivityResult) {
+        val entry = uiState.selectedEntry
+        val resultCode = providerActivityResult.resultCode
+        val resultData = providerActivityResult.data
+        if (resultCode == Activity.RESULT_CANCELED) {
+            // Re-display the CredMan UI if the user canceled from the provider UI.
+            Log.d(Constants.LOG_TAG, "The provider activity was cancelled," +
+                " re-displaying our UI.")
+            uiState = uiState.copy(
+                selectedEntry = null,
+                providerActivityState = ProviderActivityState.NOT_APPLICABLE,
+            )
+        } else {
+            if (entry != null) {
+                Log.d(
+                    Constants.LOG_TAG, "Got provider activity result: {provider=" +
+                    "${entry.providerId}, key=${entry.entryKey}, subkey=${entry.entrySubkey}" +
+                    ", resultCode=$resultCode, resultData=$resultData}"
+                )
+                credManRepo.onOptionSelected(
+                    entry.providerId, entry.entryKey, entry.entrySubkey,
+                    resultCode, resultData,
+                )
+                if (entry.shouldTerminateUiUponSuccessfulProviderResult) {
+                    uiState = uiState.copy(dialogState = DialogState.COMPLETE)
+                }
+            } else {
+                Log.w(Constants.LOG_TAG,
+                    "Illegal state: received a provider result but found no matching entry.")
+                onInternalError()
+            }
+        }
+    }
+
+    private fun onInternalError() {
+        Log.w(Constants.LOG_TAG, "UI closed due to illegal internal state")
+        credManRepo.onParsingFailureCancel()
+        uiState = uiState.copy(dialogState = DialogState.COMPLETE)
+    }
+
+    /**************************************************************************/
+    /*****                      Get Flow Callbacks                        *****/
+    /**************************************************************************/
+    fun getFlowOnEntrySelected(entry: BaseEntry) {
+        Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
+            ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
+        uiState = if (entry.pendingIntent != null) {
+            uiState.copy(
+                selectedEntry = entry,
+                providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
+            )
+        } else {
+            credManRepo.onOptionSelected(entry.providerId, entry.entryKey, entry.entrySubkey)
+            uiState.copy(dialogState = DialogState.COMPLETE)
+        }
+    }
+
+    fun getFlowOnConfirmEntrySelected() {
+        val activeEntry = uiState.getCredentialUiState?.activeEntry
+        if (activeEntry != null) {
+            getFlowOnEntrySelected(activeEntry)
+        } else {
+            Log.d(Constants.LOG_TAG,
+                "Illegal state: confirm is pressed but activeEntry isn't set.")
+            onInternalError()
+        }
+    }
+
+    fun getFlowOnMoreOptionSelected() {
+        Log.d(Constants.LOG_TAG, "More Option selected")
+        uiState = uiState.copy(
+            getCredentialUiState = uiState.getCredentialUiState?.copy(
+                currentScreenState = GetScreenState.ALL_SIGN_IN_OPTIONS
+            )
+        )
+    }
+
+    fun getFlowOnMoreOptionOnSnackBarSelected(isNoAccount: Boolean) {
+        Log.d(Constants.LOG_TAG, "More Option on snackBar selected")
+        uiState = uiState.copy(
+            getCredentialUiState = uiState.getCredentialUiState?.copy(
+                currentScreenState = GetScreenState.ALL_SIGN_IN_OPTIONS,
+                isNoAccount = isNoAccount,
+            )
+        )
+    }
+
+    fun getFlowOnBackToPrimarySelectionScreen() {
+        uiState = uiState.copy(
+            getCredentialUiState = uiState.getCredentialUiState?.copy(
+                currentScreenState = GetScreenState.PRIMARY_SELECTION
+            )
+        )
+    }
+
+    /**************************************************************************/
+    /*****                     Create Flow Callbacks                      *****/
+    /**************************************************************************/
+    fun createFlowOnConfirmIntro() {
+        val prevUiState = uiState.createCredentialUiState
+        if (prevUiState == null) {
+            Log.d(Constants.LOG_TAG, "Encountered unexpected null create ui state")
+            onInternalError()
+            return
+        }
+        val newUiState = CreateFlowUtils.toCreateCredentialUiState(
+            prevUiState.enabledProviders, prevUiState.disabledProviders,
+            userConfigRepo.getDefaultProviderId(), prevUiState.requestDisplayInfo, true,
+            userConfigRepo.getIsPasskeyFirstUse())
+        if (newUiState == null) {
+            Log.d(Constants.LOG_TAG, "Unable to update create ui state")
+            onInternalError()
+            return
+        }
+        uiState = uiState.copy(createCredentialUiState = newUiState)
+        userConfigRepo.setIsPasskeyFirstUse(false)
+    }
+
+    fun createFlowOnMoreOptionsSelectedOnProviderSelection() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.MORE_OPTIONS_SELECTION,
+                isFromProviderSelection = true
+            )
+        )
+    }
+
+    fun createFlowOnMoreOptionsSelectedOnCreationSelection() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.MORE_OPTIONS_SELECTION,
+                isFromProviderSelection = false
+            )
+        )
+    }
+
+    fun createFlowOnBackProviderSelectionButtonSelected() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.PROVIDER_SELECTION,
+            )
+        )
+    }
+
+    fun createFlowOnBackCreationSelectionButtonSelected() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+            )
+        )
+    }
+
+    fun createFlowOnBackPasskeyIntroButtonSelected() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.PASSKEY_INTRO,
+            )
+        )
+    }
+
+    fun createFlowOnEntrySelectedFromMoreOptionScreen(activeEntry: ActiveEntry) {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState =
+                if (activeEntry.activeProvider.id ==
+                    userConfigRepo.getDefaultProviderId())
+                    CreateScreenState.CREATION_OPTION_SELECTION
+                else CreateScreenState.MORE_OPTIONS_ROW_INTRO,
+                activeEntry = activeEntry
+            )
+        )
+    }
+
+    fun createFlowOnEntrySelectedFromFirstUseScreen(activeEntry: ActiveEntry) {
+        val providerId = activeEntry.activeProvider.id
+        createFlowOnDefaultChanged(providerId)
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+                activeEntry = activeEntry
+            )
+        )
+    }
+
+    fun createFlowOnDisabledProvidersSelected() {
+        credManRepo.onSettingLaunchCancel()
+        uiState = uiState.copy(dialogState = DialogState.CANCELED_FOR_SETTINGS)
+    }
+
+    fun createFlowOnLearnMore() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO,
+            )
+        )
+    }
+
+    fun createFlowOnChangeDefaultSelected() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+            )
+        )
+        val providerId = uiState.createCredentialUiState?.activeEntry?.activeProvider?.id
+        createFlowOnDefaultChanged(providerId)
+    }
+
+    fun createFlowOnUseOnceSelected() {
+        uiState = uiState.copy(
+            createCredentialUiState = uiState.createCredentialUiState?.copy(
+                currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
+            )
+        )
+    }
+
+    fun createFlowOnDefaultChanged(providerId: String?) {
+        if (providerId != null) {
+            Log.d(
+                Constants.LOG_TAG, "Default provider changed to: " +
+                " {provider=$providerId")
+            userConfigRepo.setDefaultProvider(providerId)
+        } else {
+            Log.w(Constants.LOG_TAG, "Null provider is being changed")
+        }
+    }
+
+    fun createFlowOnEntrySelected(selectedEntry: BaseEntry) {
+        val providerId = selectedEntry.providerId
+        val entryKey = selectedEntry.entryKey
+        val entrySubkey = selectedEntry.entrySubkey
+        Log.d(
+            Constants.LOG_TAG, "Option selected for entry: " +
+            " {provider=$providerId, key=$entryKey, subkey=$entrySubkey")
+        if (selectedEntry.pendingIntent != null) {
+            uiState = uiState.copy(
+                selectedEntry = selectedEntry,
+                providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
+            )
+        } else {
+            credManRepo.onOptionSelected(
+                providerId,
+                entryKey,
+                entrySubkey
+            )
+            uiState = uiState.copy(dialogState = DialogState.COMPLETE)
+        }
+    }
+
+    fun createFlowOnConfirmEntrySelected() {
+        val selectedEntry = uiState.createCredentialUiState?.activeEntry?.activeEntryInfo
+        if (selectedEntry != null) {
+            createFlowOnEntrySelected(selectedEntry)
+        } else {
+            Log.d(Constants.LOG_TAG,
+                "Unexpected: confirm is pressed but no active entry exists.")
+            onInternalError()
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index 3f705d6..50036e8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -16,18 +16,24 @@
 
 package com.android.credentialmanager
 
+import android.app.slice.Slice
+import android.app.slice.SliceItem
 import android.content.ComponentName
 import android.content.Context
 import android.content.pm.PackageManager
+import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
+import android.credentials.ui.AuthenticationEntry
 import android.credentials.ui.CreateCredentialProviderData
 import android.credentials.ui.DisabledProviderData
 import android.credentials.ui.Entry
 import android.credentials.ui.GetCredentialProviderData
 import android.credentials.ui.RequestInfo
 import android.graphics.drawable.Drawable
+import android.service.credentials.CredentialEntry
 import android.text.TextUtils
 import android.util.Log
 import com.android.credentialmanager.common.Constants
+import com.android.credentialmanager.common.CredentialType
 import com.android.credentialmanager.createflow.ActiveEntry
 import com.android.credentialmanager.createflow.CreateCredentialUiState
 import com.android.credentialmanager.createflow.CreateOptionInfo
@@ -41,17 +47,22 @@
 import com.android.credentialmanager.getflow.CredentialEntryInfo
 import com.android.credentialmanager.getflow.ProviderInfo
 import com.android.credentialmanager.getflow.RemoteEntryInfo
-import com.android.credentialmanager.jetpack.developer.CreateCredentialRequest
-import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest
-import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
-import com.android.credentialmanager.jetpack.provider.Action
-import com.android.credentialmanager.jetpack.provider.AuthenticationAction
-import com.android.credentialmanager.jetpack.provider.CreateEntry
-import com.android.credentialmanager.jetpack.provider.CredentialCountInformation
-import com.android.credentialmanager.jetpack.provider.CredentialEntry
+import androidx.credentials.CreateCredentialRequest
+import androidx.credentials.CreateCustomCredentialRequest
+import androidx.credentials.CreatePasswordRequest
+import androidx.credentials.CreatePublicKeyCredentialRequest
+import androidx.credentials.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
+import androidx.credentials.provider.Action
+import androidx.credentials.provider.AuthenticationAction
+import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+import androidx.credentials.provider.RemoteCreateEntry
+import androidx.credentials.provider.RemoteCredentialEntry
 import org.json.JSONObject
 
+// TODO: remove all !! checks
 private fun getAppLabel(
     pm: PackageManager,
     appPackageName: String
@@ -138,12 +149,11 @@
                         credentialEntryList = getCredentialOptionInfoList(
                             it.providerFlattenedComponentName, it.credentialEntries, context
                         ),
-                        authenticationEntry = getAuthenticationEntry(
+                        authenticationEntryList = getAuthenticationEntryList(
                             it.providerFlattenedComponentName,
                             providerLabel,
                             providerIcon,
-                            it.authenticationEntry
-                        ),
+                            it.authenticationEntries),
                         remoteEntry = getRemoteEntry(
                             it.providerFlattenedComponentName,
                             it.remoteEntry
@@ -168,103 +178,172 @@
         }
 
 
-        /* From service data structure to UI credential entry list representation. */
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun getCredentialOptionInfoList(
             providerId: String,
             credentialEntries: List<Entry>,
             context: Context,
         ): List<CredentialEntryInfo> {
-            return credentialEntries.map {
-                // TODO: handle NPE gracefully
-                val credentialEntry = CredentialEntry.fromSlice(it.slice)!!
+            val result: MutableList<CredentialEntryInfo> = mutableListOf()
+            credentialEntries.forEach {
+                val credentialEntry = parseCredentialEntryFromSlice(it.slice)
+                when (credentialEntry) {
+                    is PasswordCredentialEntry -> {
+                        result.add(CredentialEntryInfo(
+                            providerId = providerId,
+                            entryKey = it.key,
+                            entrySubkey = it.subkey,
+                            pendingIntent = credentialEntry.pendingIntent,
+                            fillInIntent = it.frameworkExtrasIntent,
+                            credentialType = CredentialType.PASSWORD,
+                            credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+                            userName = credentialEntry.username.toString(),
+                            displayName = credentialEntry.displayName?.toString(),
+                            icon = credentialEntry.icon?.loadDrawable(context),
+                            lastUsedTimeMillis = credentialEntry.lastUsedTime,
+                        ))
+                    }
+                    is PublicKeyCredentialEntry -> {
+                        result.add(CredentialEntryInfo(
+                            providerId = providerId,
+                            entryKey = it.key,
+                            entrySubkey = it.subkey,
+                            pendingIntent = credentialEntry.pendingIntent,
+                            fillInIntent = it.frameworkExtrasIntent,
+                            credentialType = CredentialType.PASSKEY,
+                            credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+                            userName = credentialEntry.username.toString(),
+                            displayName = credentialEntry.displayName?.toString(),
+                            icon = credentialEntry.icon?.loadDrawable(context),
+                            lastUsedTimeMillis = credentialEntry.lastUsedTime,
+                        ))
+                    }
+                    is CustomCredentialEntry -> {
+                        result.add(CredentialEntryInfo(
+                            providerId = providerId,
+                            entryKey = it.key,
+                            entrySubkey = it.subkey,
+                            pendingIntent = credentialEntry.pendingIntent,
+                            fillInIntent = it.frameworkExtrasIntent,
+                            credentialType = CredentialType.UNKNOWN,
+                            credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
+                            userName = credentialEntry.title.toString(),
+                            displayName = credentialEntry.subtitle?.toString(),
+                            icon = credentialEntry.icon?.loadDrawable(context),
+                            lastUsedTimeMillis = credentialEntry.lastUsedTime,
+                        ))
+                    }
+                    else -> Log.d(
+                        Constants.LOG_TAG,
+                        "Encountered unrecognized credential entry ${it.slice.spec?.type}"
+                    )
+                }
+            }
+            // TODO: handle empty list due to parsing error.
+            return result
+        }
 
-                // Consider directly move the UI object into the class.
-                return@map CredentialEntryInfo(
-                    providerId = providerId,
-                    entryKey = it.key,
-                    entrySubkey = it.subkey,
-                    pendingIntent = credentialEntry.pendingIntent,
-                    fillInIntent = it.frameworkExtrasIntent,
-                    credentialType = credentialEntry.type,
-                    credentialTypeDisplayName = credentialEntry.typeDisplayName.toString(),
-                    userName = credentialEntry.username.toString(),
-                    displayName = credentialEntry.displayName?.toString(),
-                    // TODO: proper fallback
-                    icon = credentialEntry.icon?.loadDrawable(context),
-                    lastUsedTimeMillis = credentialEntry.lastUsedTimeMillis,
-                )
+        private fun parseCredentialEntryFromSlice(slice: Slice): CredentialEntry? {
+            try {
+                when (slice.spec?.type) {
+                    TYPE_PASSWORD_CREDENTIAL -> return PasswordCredentialEntry.fromSlice(slice)!!
+                    TYPE_PUBLIC_KEY_CREDENTIAL -> return PublicKeyCredentialEntry.fromSlice(slice)!!
+                    else -> return CustomCredentialEntry.fromSlice(slice)!!
+                }
+            } catch (e: Exception) {
+                // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
+                // password / passkey parsing attempt.
+                return CustomCredentialEntry.fromSlice(slice)
             }
         }
 
-        private fun getAuthenticationEntry(
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
+        private fun getAuthenticationEntryList(
             providerId: String,
             providerDisplayName: String,
             providerIcon: Drawable,
-            authEntry: Entry?,
-        ): AuthenticationEntryInfo? {
-            if (authEntry == null) {
-                return null
-            }
-            val authStructuredEntry = AuthenticationAction.fromSlice(
-                authEntry!!.slice
-            )
-            if (authStructuredEntry == null) {
-                return null
-            }
+            authEntryList: List<AuthenticationEntry>,
+        ): List<AuthenticationEntryInfo> {
+            val result: MutableList<AuthenticationEntryInfo> = mutableListOf()
+            authEntryList.forEach { entry ->
+                val structuredAuthEntry =
+                    AuthenticationAction.fromSlice(entry.slice) ?: return@forEach
 
-            return AuthenticationEntryInfo(
-                providerId = providerId,
-                entryKey = authEntry.key,
-                entrySubkey = authEntry.subkey,
-                pendingIntent = authStructuredEntry.pendingIntent,
-                fillInIntent = authEntry.frameworkExtrasIntent,
-                title = providerDisplayName,
-                icon = providerIcon,
-            )
+                // TODO: replace with official jetpack code.
+                val titleItem: SliceItem? = entry.slice.items.firstOrNull {
+                    it.hasHint(
+                        "androidx.credentials.provider.authenticationAction.SLICE_HINT_TITLE")
+                }
+                val title: String = titleItem?.text?.toString() ?: providerDisplayName
+
+                result.add(AuthenticationEntryInfo(
+                    providerId = providerId,
+                    entryKey = entry.key,
+                    entrySubkey = entry.subkey,
+                    pendingIntent = structuredAuthEntry.pendingIntent,
+                    fillInIntent = entry.frameworkExtrasIntent,
+                    title = title,
+                    icon = providerIcon,
+                    isUnlockedAndEmpty = entry.status != AuthenticationEntry.STATUS_LOCKED,
+                    isLastUnlocked =
+                    entry.status == AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
+                ))
+            }
+            return result
         }
 
         private fun getRemoteEntry(providerId: String, remoteEntry: Entry?): RemoteEntryInfo? {
-            // TODO: should also call fromSlice after getting the official jetpack code.
             if (remoteEntry == null) {
                 return null
             }
+            val structuredRemoteEntry = RemoteCredentialEntry.fromSlice(remoteEntry.slice)
+                ?: return null
             return RemoteEntryInfo(
                 providerId = providerId,
                 entryKey = remoteEntry.key,
                 entrySubkey = remoteEntry.subkey,
-                pendingIntent = remoteEntry.pendingIntent,
+                pendingIntent = structuredRemoteEntry.pendingIntent,
                 fillInIntent = remoteEntry.frameworkExtrasIntent,
             )
         }
 
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun getActionEntryList(
             providerId: String,
             actionEntries: List<Entry>,
             providerIcon: Drawable,
         ): List<ActionEntryInfo> {
-            return actionEntries.map {
-                // TODO: handle NPE gracefully
-                val actionEntryUi = Action.fromSlice(it.slice)!!
-
-                return@map ActionEntryInfo(
+            val result: MutableList<ActionEntryInfo> = mutableListOf()
+            actionEntries.forEach {
+                val actionEntryUi = Action.fromSlice(it.slice) ?: return@forEach
+                result.add(ActionEntryInfo(
                     providerId = providerId,
                     entryKey = it.key,
                     entrySubkey = it.subkey,
                     pendingIntent = actionEntryUi.pendingIntent,
                     fillInIntent = it.frameworkExtrasIntent,
                     title = actionEntryUi.title.toString(),
-                    // TODO: gracefully fail
                     icon = providerIcon,
-                    subTitle = actionEntryUi.subTitle?.toString(),
-                )
+                    subTitle = actionEntryUi.subtitle?.toString(),
+                ))
             }
+            // TODO: handle empty list
+            return result
         }
     }
 }
 
 class CreateFlowUtils {
     companion object {
-        // Returns the list (potentially empty) of enabled provider.
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         fun toEnabledProviderList(
             providerDataList: List<CreateCredentialProviderData>,
             context: Context,
@@ -289,7 +368,9 @@
             return providerList
         }
 
-        // Returns the list (potentially empty) of disabled provider.
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         fun toDisabledProviderList(
             providerDataList: List<DisabledProviderData>?,
             context: Context,
@@ -316,22 +397,21 @@
         ): RequestDisplayInfo? {
             val appLabel = getAppLabel(context.packageManager, requestInfo.appPackageName)
                 ?: return null
-            val createCredentialRequest = requestInfo.createCredentialRequest
-            val createCredentialRequestJetpack = createCredentialRequest?.let {
-                CreateCredentialRequest.createFrom(
-                    it.type, it.credentialData, it.candidateQueryData, it.isSystemProviderRequired
+            val createCredentialRequest = requestInfo.createCredentialRequest ?: return null
+            val createCredentialRequestJetpack = CreateCredentialRequest.createFrom(
+                createCredentialRequest.type,
+                createCredentialRequest.credentialData,
+                createCredentialRequest.candidateQueryData,
+                createCredentialRequest.isSystemProviderRequired
+            )
+            return when (createCredentialRequestJetpack) {
+                is CreatePasswordRequest -> RequestDisplayInfo(
+                    createCredentialRequestJetpack.id,
+                    createCredentialRequestJetpack.password,
+                    CredentialType.PASSWORD,
+                    appLabel,
+                    context.getDrawable(R.drawable.ic_password)!!
                 )
-            }
-            when (createCredentialRequestJetpack) {
-                is CreatePasswordRequest -> {
-                    return RequestDisplayInfo(
-                        createCredentialRequestJetpack.id,
-                        createCredentialRequestJetpack.password,
-                        createCredentialRequestJetpack.type,
-                        appLabel,
-                        context.getDrawable(R.drawable.ic_password)!!
-                    )
-                }
                 is CreatePublicKeyCredentialRequest -> {
                     val requestJson = createCredentialRequestJetpack.requestJson
                     val json = JSONObject(requestJson)
@@ -342,24 +422,29 @@
                         name = user.getString("name")
                         displayName = user.getString("displayName")
                     }
-                    return RequestDisplayInfo(
+                    RequestDisplayInfo(
                         name,
                         displayName,
-                        createCredentialRequestJetpack.type,
+                        CredentialType.PASSKEY,
                         appLabel,
                         context.getDrawable(R.drawable.ic_passkey)!!
                     )
                 }
-                // TODO: correctly parsing for other sign-ins
-                else -> {
-                    return RequestDisplayInfo(
-                        "beckett-bakert@gmail.com",
-                        "Elisa Beckett",
-                        "other-sign-ins",
-                        appLabel.toString(),
-                        context.getDrawable(R.drawable.ic_other_sign_in)!!
+                is CreateCustomCredentialRequest -> {
+                    // TODO: directly use the display info once made public
+                    val displayInfo = CreateCredentialRequest.DisplayInfo
+                        .parseFromCredentialDataBundle(createCredentialRequest.credentialData)
+                        ?: return null
+                    RequestDisplayInfo(
+                        title = displayInfo.userId,
+                        subtitle = displayInfo.userDisplayName,
+                        type = CredentialType.UNKNOWN,
+                        appName = appLabel,
+                        typeIcon = displayInfo.credentialTypeIcon?.loadDrawable(context)
+                            ?: context.getDrawable(R.drawable.ic_other_sign_in)!!
                     )
                 }
+                else -> null
             }
         }
 
@@ -398,17 +483,14 @@
                 /*requestDisplayInfo=*/requestDisplayInfo,
                 /*defaultProvider=*/defaultProvider, /*remoteEntry=*/remoteEntry,
                 /*isPasskeyFirstUse=*/isPasskeyFirstUse
-            )
-            if (initialScreenState == null) {
-                return null
-            }
+            ) ?: return null
             return CreateCredentialUiState(
                 enabledProviders = enabledProviders,
                 disabledProviders = disabledProviders,
                 currentScreenState = initialScreenState,
                 requestDisplayInfo = requestDisplayInfo,
                 sortedCreateOptionsPairs = createOptionsPairs.sortedWith(
-                    compareByDescending { it.first.lastUsedTimeMillis }
+                    compareByDescending { it.first.lastUsedTime }
                 ),
                 hasDefaultProvider = defaultProvider != null,
                 activeEntry = toActiveEntry(
@@ -430,7 +512,7 @@
             isPasskeyFirstUse: Boolean,
         ): CreateScreenState? {
             return if (isPasskeyFirstUse && requestDisplayInfo.type ==
-                TYPE_PUBLIC_KEY_CREDENTIAL && !isOnPasskeyIntroStateAlready) {
+                CredentialType.PASSKEY && !isOnPasskeyIntroStateAlready) {
                 CreateScreenState.PASSKEY_INTRO
             } else if ((defaultProvider == null || defaultProvider.createOptions.isEmpty()) &&
                 createOptionSize > 1) {
@@ -474,17 +556,18 @@
             } else null
         }
 
+        /**
+         * Note: caller required handle empty list due to parsing error.
+         */
         private fun toCreationOptionInfoList(
             providerId: String,
             creationEntries: List<Entry>,
             context: Context,
         ): List<CreateOptionInfo> {
-            return creationEntries.map {
-                // TODO: handle NPE gracefully
-                val createEntry = CreateEntry.fromSlice(it.slice)!!
-
-                return@map CreateOptionInfo(
-                    // TODO: remove fallbacks
+            val result: MutableList<CreateOptionInfo> = mutableListOf()
+            creationEntries.forEach {
+                val createEntry = CreateEntry.fromSlice(it.slice) ?: return@forEach
+                result.add(CreateOptionInfo(
                     providerId = providerId,
                     entryKey = it.key,
                     entrySubkey = it.subkey,
@@ -492,32 +575,28 @@
                     fillInIntent = it.frameworkExtrasIntent,
                     userProviderDisplayName = createEntry.accountName.toString(),
                     profileIcon = createEntry.icon?.loadDrawable(context),
-                    passwordCount = CredentialCountInformation.getPasswordCount(
-                        createEntry.credentialCountInformationList
-                    ) ?: 0,
-                    passkeyCount = CredentialCountInformation.getPasskeyCount(
-                        createEntry.credentialCountInformationList
-                    ) ?: 0,
-                    totalCredentialCount = CredentialCountInformation.getTotalCount(
-                        createEntry.credentialCountInformationList
-                    ) ?: 0,
-                    lastUsedTimeMillis = createEntry.lastUsedTimeMillis ?: 0,
-                    footerDescription = createEntry.footerDescription?.toString()
-                )
+                    passwordCount = createEntry.getPasswordCredentialCount(),
+                    passkeyCount = createEntry.getPublicKeyCredentialCount(),
+                    totalCredentialCount = createEntry.getTotalCredentialCount(),
+                    lastUsedTime = createEntry.lastUsedTime,
+                    footerDescription = createEntry.description?.toString()
+                ))
             }
+            return result
         }
 
         private fun toRemoteInfo(
             providerId: String,
             remoteEntry: Entry?,
         ): RemoteInfo? {
-            // TODO: should also call fromSlice after getting the official jetpack code.
             return if (remoteEntry != null) {
+                val structuredRemoteEntry = RemoteCreateEntry.fromSlice(remoteEntry.slice)
+                    ?: return null
                 RemoteInfo(
                     providerId = providerId,
                     entryKey = remoteEntry.key,
                     entrySubkey = remoteEntry.subkey,
-                    pendingIntent = remoteEntry.pendingIntent,
+                    pendingIntent = structuredRemoteEntry.pendingIntent,
                     fillInIntent = remoteEntry.frameworkExtrasIntent,
                 )
             } else null
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
new file mode 100644
index 0000000..eb3d188
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.credentialmanager
+
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.content.Context
+import android.content.Intent
+import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
+import android.credentials.ui.AuthenticationEntry
+import android.credentials.ui.Entry
+import android.net.Uri
+import android.provider.Settings
+import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+
+import java.time.Instant
+
+// TODO: remove once testing is complete
+class GetTestUtils {
+    companion object {
+        internal fun newAuthenticationEntry(
+            context: Context,
+            key: String,
+            subkey: String,
+            title: String,
+            status: Int
+        ): AuthenticationEntry {
+            val slice = Slice.Builder(
+                Uri.EMPTY, SliceSpec("AuthenticationAction", 0)
+            )
+            val intent = Intent(Settings.ACTION_SYNC_SETTINGS)
+            val pendingIntent =
+                PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+            slice.addAction(
+                pendingIntent,
+                Slice.Builder(slice)
+                    .addHints(listOf("androidx.credentials.provider.authenticationAction" +
+                        ".SLICE_HINT_PENDING_INTENT"))
+                    .build(),
+                /*subType=*/null
+            )
+            slice.addText(
+                title,
+                null,
+                listOf("androidx.credentials.provider.authenticationAction.SLICE_HINT_TITLE")
+            )
+            return AuthenticationEntry(
+                key,
+                subkey,
+                slice.build(),
+                status
+            )
+        }
+
+        internal fun newActionEntry(
+            context: Context,
+            key: String,
+            subkey: String,
+            text: String,
+            subtext: String? = null,
+        ): Entry {
+            val intent = Intent(Settings.ACTION_SYNC_SETTINGS)
+            val pendingIntent =
+                PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec("Action", 0))
+                .addText(
+                    text, /*subType=*/null,
+                    listOf("androidx.credentials.provider.action.HINT_ACTION_TITLE")
+                )
+                .addText(
+                    subtext, /*subType=*/null,
+                    listOf("androidx.credentials.provider.action.HINT_ACTION_SUBTEXT")
+                )
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(
+                        listOf("androidx.credentials.provider.action.SLICE_HINT_PENDING_INTENT")
+                    )
+                    .build(),
+                /*subType=*/null
+            )
+            return Entry(
+                key,
+                subkey,
+                sliceBuilder.build()
+            )
+        }
+
+        internal fun newPasswordEntry(
+            context: Context,
+            key: String,
+            subkey: String,
+            userName: String,
+            userDisplayName: String?,
+            lastUsedTime: Instant?,
+        ): Entry {
+            val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
+                .setPackage("com.androidauth.androidvault")
+            intent.putExtra("provider_extra_sample", "testprovider")
+            val pendingIntent = PendingIntent.getActivity(
+                context, 1,
+                intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
+                or PendingIntent.FLAG_ONE_SHOT)
+            )
+            val passwordEntry = PasswordCredentialEntry.Builder(context, userName, pendingIntent)
+                .setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
+            return Entry(key, subkey, passwordEntry.slice, Intent())
+        }
+
+        internal fun newPasskeyEntry(
+            context: Context,
+            key: String,
+            subkey: String,
+            userName: String,
+            userDisplayName: String?,
+            lastUsedTime: Instant?,
+        ): Entry {
+            val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
+                .setPackage("com.androidauth.androidvault")
+            intent.putExtra("provider_extra_sample", "testprovider")
+            val pendingIntent = PendingIntent.getActivity(
+                context, 1,
+                intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
+                or PendingIntent.FLAG_ONE_SHOT)
+            )
+            val passkeyEntry = PublicKeyCredentialEntry.Builder(context, userName, pendingIntent)
+                .setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
+            return Entry(key, subkey, passkeyEntry.slice, Intent())
+        }
+    }
+}
+
+class CreateTestUtils {
+    companion object {
+        private const val TYPE_TOTAL_CREDENTIAL = "TOTAL_CREDENTIAL_COUNT_TYPE"
+        private const val SLICE_HINT_ACCOUNT_NAME =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_USER_PROVIDER_ACCOUNT_NAME"
+        private const val SLICE_HINT_NOTE =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_NOTE"
+        private const val SLICE_HINT_ICON =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_PROFILE_ICON"
+        private const val SLICE_HINT_CREDENTIAL_COUNT_INFORMATION =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_CREDENTIAL_COUNT_INFORMATION"
+        private const val SLICE_HINT_LAST_USED_TIME_MILLIS =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_PENDING_INTENT"
+
+        internal fun newCreateEntry(
+            context: Context,
+            key: String,
+            subkey: String,
+            providerUserDisplayName: String,
+            passwordCount: Int?,
+            passkeyCount: Int?,
+            totalCredentialCount: Int?,
+            lastUsedTime: Instant?,
+            footerDescription: String?,
+        ): Entry {
+            val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD")
+                .setPackage("com.androidauth.androidvault")
+            intent.putExtra("provider_extra_sample", "testprovider")
+            val pendingIntent = PendingIntent.getActivity(
+                context, 1,
+                intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
+                or PendingIntent.FLAG_ONE_SHOT)
+            )
+            val credCountMap = mutableMapOf<String, Int>()
+            passwordCount?.let { credCountMap.put(TYPE_PASSWORD_CREDENTIAL, it) }
+            passkeyCount?.let {
+                credCountMap.put("androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL", it)
+            }
+            totalCredentialCount?.let { credCountMap.put(TYPE_TOTAL_CREDENTIAL, it) }
+            return Entry(
+                key,
+                subkey,
+                CreateEntry.toSlice(
+                    providerUserDisplayName,
+                    null,
+                    footerDescription,
+                    lastUsedTime,
+                    credCountMap,
+                    pendingIntent
+                ),
+                Intent()
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt
index 021dcab..a17f2c8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/UserConfigRepo.kt
@@ -50,21 +50,9 @@
     }
 
     companion object {
-        lateinit var repo: UserConfigRepo
-
         const val DEFAULT_PROVIDER = "default_provider"
         // This first use value only applies to passkeys, not related with if generally
         // credential manager is first use or not
         const val IS_PASSKEY_FIRST_USE = "is_passkey_first_use"
-
-        fun setup(
-            context: Context,
-        ) {
-            repo = UserConfigRepo(context)
-        }
-
-        fun getInstance(): UserConfigRepo {
-            return repo
-        }
     }
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.kt
new file mode 100644
index 0000000..ee36989
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BaseEntry.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.credentialmanager.common
+
+import android.app.PendingIntent
+import android.content.Intent
+
+open class BaseEntry (
+    val providerId: String,
+    val entryKey: String,
+    val entrySubkey: String,
+    val pendingIntent: PendingIntent?,
+    val fillInIntent: Intent?,
+    val shouldTerminateUiUponSuccessfulProviderResult: Boolean,
+)
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.kt
index 497c272..cc92f60 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/CredentialType.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,12 +14,8 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package com.android.credentialmanager.common
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+enum class CredentialType {
+    UNKNOWN, PASSKEY, PASSWORD,
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/material/ModalBottomSheet.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/material/ModalBottomSheet.kt
index f1f453d..58edb25 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/material/ModalBottomSheet.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/material/ModalBottomSheet.kt
@@ -28,6 +28,7 @@
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.sizeIn
 import androidx.compose.foundation.layout.offset
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Surface
@@ -40,6 +41,7 @@
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.saveable.Saver
 import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
@@ -131,7 +133,7 @@
         if (isSkipHalfExpanded) {
             require(initialValue != HalfExpanded) {
                 "The initial value must not be set to HalfExpanded if skipHalfExpanded is set to" +
-                        " true."
+                    " true."
             }
         }
     }
@@ -209,10 +211,10 @@
             message = "Please specify the skipHalfExpanded parameter",
             replaceWith = ReplaceWith(
                 "ModalBottomSheetState.Saver(" +
-                        "animationSpec = animationSpec," +
-                        "skipHalfExpanded = ," +
-                        "confirmStateChange = confirmStateChange" +
-                        ")"
+                    "animationSpec = animationSpec," +
+                    "skipHalfExpanded = ," +
+                    "confirmStateChange = confirmStateChange" +
+                    ")"
             )
         )
         fun Saver(
@@ -339,55 +341,77 @@
                 visible = sheetState.targetValue != Hidden
             )
         }
-        Surface(
-            Modifier
-                .fillMaxWidth()
-                .nestedScroll(sheetState.nestedScrollConnection)
-                .offset {
-                    val y = if (sheetState.anchors.isEmpty()) {
-                        // if we don't know our anchors yet, render the sheet as hidden
-                        fullHeight.roundToInt()
-                    } else {
-                        // if we do know our anchors, respect them
-                        sheetState.offset.value.roundToInt()
-                    }
-                    IntOffset(0, y)
-                }
-                .bottomSheetSwipeable(sheetState, fullHeight, sheetHeightState)
-                .onGloballyPositioned {
-                    sheetHeightState.value = it.size.height.toFloat()
-                }
-                .semantics {
-                    if (sheetState.isVisible) {
-                        dismiss {
-                            if (sheetState.confirmStateChange(Hidden)) {
-                                scope.launch { sheetState.hide() }
-                            }
-                            true
-                        }
-                        if (sheetState.currentValue == HalfExpanded) {
-                            expand {
-                                if (sheetState.confirmStateChange(Expanded)) {
-                                    scope.launch { sheetState.expand() }
-                                }
-                                true
-                            }
-                        } else if (sheetState.hasHalfExpandedState) {
-                            collapse {
-                                if (sheetState.confirmStateChange(HalfExpanded)) {
-                                    scope.launch { sheetState.halfExpand() }
-                                }
-                                true
-                            }
-                        }
-                    }
-                },
-            shape = sheetShape,
-            shadowElevation = sheetElevation,
-            color = sheetBackgroundColor,
-            contentColor = sheetContentColor
+
+        // For large screen, allow enough horizontal scrim space.
+        // Manually calculate the > compact width due to lack of corresponding jetpack dependency.
+        val maxSheetContentWidth: Dp =
+            if (maxWidth >= ModalBottomSheetDefaults.MaxCompactWidth &&
+                maxWidth <= ModalBottomSheetDefaults.MaxCompactWidth +
+                ModalBottomSheetDefaults.StartPadding + ModalBottomSheetDefaults.EndPadding
+            )
+                (maxWidth - ModalBottomSheetDefaults.StartPadding -
+                    ModalBottomSheetDefaults.EndPadding)
+            else ModalBottomSheetDefaults.MaxSheetWidth
+        val maxSheetContentHeight = maxHeight - ModalBottomSheetDefaults.MinScrimHeight
+        Box(
+            Modifier.sizeIn(
+                maxWidth = maxSheetContentWidth,
+                // Allow enough vertical scrim space.
+                maxHeight = maxSheetContentHeight
+            ).align(Alignment.TopCenter)
         ) {
-            Column(content = sheetContent)
+            Surface(
+                Modifier
+                    .fillMaxWidth()
+                    .nestedScroll(sheetState.nestedScrollConnection)
+                    .offset {
+                        val y = if (sheetState.anchors.isEmpty()) {
+                            // if we don't know our anchors yet, render the sheet as hidden
+                            fullHeight.roundToInt()
+                        } else {
+                            // if we do know our anchors, respect them
+                            sheetState.offset.value.roundToInt()
+                        }
+                        IntOffset(0, y)
+                    }
+                    .bottomSheetSwipeable(sheetState, fullHeight, sheetHeightState)
+                    .onGloballyPositioned {
+                        sheetHeightState.value = it.size.height.toFloat()
+                    }
+                    .semantics {
+                        if (sheetState.isVisible) {
+                            dismiss {
+                                if (sheetState.confirmStateChange(Hidden)) {
+                                    scope.launch { sheetState.hide() }
+                                }
+                                true
+                            }
+                            if (sheetState.currentValue == HalfExpanded) {
+                                expand {
+                                    if (sheetState.confirmStateChange(Expanded)) {
+                                        scope.launch { sheetState.expand() }
+                                    }
+                                    true
+                                }
+                            } else if (sheetState.hasHalfExpandedState) {
+                                collapse {
+                                    if (sheetState.confirmStateChange(HalfExpanded)) {
+                                        scope.launch { sheetState.halfExpand() }
+                                    }
+                                    true
+                                }
+                            }
+                        }
+                    },
+                shape = sheetShape,
+                shadowElevation = sheetElevation,
+                color = sheetBackgroundColor,
+                contentColor = sheetContentColor
+            ) {
+                Column(
+                    content = sheetContent
+                )
+            }
         }
     }
 }
@@ -465,6 +489,11 @@
  * Contains useful Defaults for [ModalBottomSheetLayout].
  */
 object ModalBottomSheetDefaults {
+    val MaxCompactWidth = 600.dp
+    val MaxSheetWidth = 640.dp
+    val MinScrimHeight = 56.dp
+    val StartPadding = 56.dp
+    val EndPadding = 56.dp
 
     /**
      * The default elevation used by [ModalBottomSheetLayout].
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt
index d0271ab..984057a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/ActionButton.kt
@@ -16,11 +16,23 @@
 
 package com.android.credentialmanager.common.ui
 
+import com.android.credentialmanager.R
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Visibility
+import androidx.compose.material.icons.outlined.VisibilityOff
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextButton
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
 
 @Composable
 fun ActionButton(text: String, onClick: () -> Unit) {
@@ -32,4 +44,27 @@
     ) {
         Text(text = text)
     }
+}
+
+@Composable
+fun ToggleVisibilityButton(modifier: Modifier = Modifier, onToggle: (Boolean) -> Unit) {
+    // default state is visibility off
+    val toggleState: MutableState<Boolean> = remember { mutableStateOf(false) }
+
+    IconButton(
+        modifier = modifier,
+        onClick = {
+            toggleState.value = !toggleState.value
+            onToggle(toggleState.value)
+        }
+    ) {
+        Icon(
+            imageVector = if (toggleState.value)
+                Icons.Outlined.Visibility else Icons.Outlined.VisibilityOff,
+            contentDescription = if (toggleState.value)
+                stringResource(R.string.content_description_show_password) else
+                stringResource(R.string.content_description_hide_password),
+            tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant
+        )
+    }
 }
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
new file mode 100644
index 0000000..c4d96cc
--- /dev/null
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.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.credentialmanager.common.ui
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import com.android.credentialmanager.common.material.ModalBottomSheetLayout
+import com.android.credentialmanager.common.material.ModalBottomSheetValue
+import com.android.credentialmanager.common.material.rememberModalBottomSheetState
+import com.android.credentialmanager.ui.theme.EntryShape
+
+/** Draws a modal bottom sheet with the same styles and effects shared by various flows. */
+@Composable
+fun ModalBottomSheet(
+    sheetContent: @Composable ColumnScope.() -> Unit,
+    onDismiss: () -> Unit
+) {
+    val state = rememberModalBottomSheetState(
+        initialValue = ModalBottomSheetValue.Expanded,
+        skipHalfExpanded = true
+    )
+    ModalBottomSheetLayout(
+        sheetBackgroundColor = MaterialTheme.colorScheme.surface,
+        modifier = Modifier.background(Color.Transparent),
+        sheetState = state,
+        sheetContent = sheetContent,
+        scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.8f),
+        sheetShape = EntryShape.TopRoundedCorner,
+    ) {}
+    LaunchedEffect(state.currentValue) {
+        if (state.currentValue == ModalBottomSheetValue.Hidden) {
+            onDismiss()
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Cards.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Cards.kt
index aaabce3..85e5c1e 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Cards.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/Cards.kt
@@ -18,9 +18,9 @@
 
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.material3.Card
 import androidx.compose.material3.CardDefaults
-import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
@@ -30,7 +30,6 @@
  * By default the card is filled with surfaceVariant color. This container card instead fills the
  * background color with surface corlor.
  */
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ContainerCard(
     modifier: Modifier = Modifier,
@@ -39,7 +38,7 @@
     content: @Composable ColumnScope.() -> Unit,
 ) {
     Card(
-        modifier = modifier,
+        modifier = modifier.fillMaxWidth(),
         shape = shape,
         border = border,
         colors = CardDefaults.cardColors(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
index 5e432b9..a7f17c8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt
@@ -2,15 +2,17 @@
 
 package com.android.credentialmanager.createflow
 
-import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
 import androidx.activity.compose.ManagedActivityResultLauncher
 import androidx.activity.result.ActivityResult
 import androidx.activity.result.IntentSenderRequest
+import androidx.compose.foundation.isSystemInDarkTheme
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.lazy.LazyColumn
@@ -27,117 +29,123 @@
 import androidx.compose.material.icons.filled.Add
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.input.PasswordVisualTransformation
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.core.graphics.drawable.toBitmap
+import com.android.credentialmanager.CredentialSelectorViewModel
 import com.android.credentialmanager.R
+import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.common.CredentialType
 import com.android.credentialmanager.common.ProviderActivityState
-import com.android.credentialmanager.common.material.ModalBottomSheetLayout
-import com.android.credentialmanager.common.material.ModalBottomSheetValue
-import com.android.credentialmanager.common.material.rememberModalBottomSheetState
 import com.android.credentialmanager.common.ui.ActionButton
 import com.android.credentialmanager.common.ui.ConfirmButton
 import com.android.credentialmanager.common.ui.Entry
+import com.android.credentialmanager.common.ui.ModalBottomSheet
 import com.android.credentialmanager.common.ui.TextOnSurface
 import com.android.credentialmanager.common.ui.TextSecondary
 import com.android.credentialmanager.common.ui.TextOnSurfaceVariant
 import com.android.credentialmanager.common.ui.ContainerCard
-import com.android.credentialmanager.ui.theme.EntryShape
+import com.android.credentialmanager.common.ui.ToggleVisibilityButton
 import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun CreateCredentialScreen(
-    viewModel: CreateCredentialViewModel,
+    viewModel: CredentialSelectorViewModel,
+    createCredentialUiState: CreateCredentialUiState,
     providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
 ) {
-    val state = rememberModalBottomSheetState(
-        initialValue = ModalBottomSheetValue.Expanded,
-        skipHalfExpanded = true
-    )
-    ModalBottomSheetLayout(
-        sheetBackgroundColor = MaterialTheme.colorScheme.surface,
-        sheetState = state,
+    ModalBottomSheet(
         sheetContent = {
-            val uiState = viewModel.uiState
             // Hide the sheet content as opposed to the whole bottom sheet to maintain the scrim
             // background color even when the content should be hidden while waiting for
             // results from the provider app.
-            when (uiState.providerActivityState) {
+            when (viewModel.uiState.providerActivityState) {
                 ProviderActivityState.NOT_APPLICABLE -> {
-                    when (uiState.currentScreenState) {
+                    when (createCredentialUiState.currentScreenState) {
                         CreateScreenState.PASSKEY_INTRO -> ConfirmationCard(
-                            onConfirm = viewModel::onConfirmIntro,
-                            onLearnMore = viewModel::onLearnMore,
+                            onConfirm = viewModel::createFlowOnConfirmIntro,
+                            onLearnMore = viewModel::createFlowOnLearnMore,
                         )
                         CreateScreenState.PROVIDER_SELECTION -> ProviderSelectionCard(
-                            requestDisplayInfo = uiState.requestDisplayInfo,
-                            enabledProviderList = uiState.enabledProviders,
-                            disabledProviderList = uiState.disabledProviders,
-                            sortedCreateOptionsPairs = uiState.sortedCreateOptionsPairs,
-                            onOptionSelected = viewModel::onEntrySelectedFromFirstUseScreen,
+                            requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
+                            enabledProviderList = createCredentialUiState.enabledProviders,
+                            disabledProviderList = createCredentialUiState.disabledProviders,
+                            sortedCreateOptionsPairs =
+                            createCredentialUiState.sortedCreateOptionsPairs,
+                            onOptionSelected =
+                            viewModel::createFlowOnEntrySelectedFromFirstUseScreen,
                             onDisabledProvidersSelected =
-                            viewModel::onDisabledProvidersSelected,
+                            viewModel::createFlowOnDisabledProvidersSelected,
                             onMoreOptionsSelected =
-                            viewModel::onMoreOptionsSelectedOnProviderSelection,
+                            viewModel::createFlowOnMoreOptionsSelectedOnProviderSelection,
                         )
                         CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard(
-                            requestDisplayInfo = uiState.requestDisplayInfo,
-                            enabledProviderList = uiState.enabledProviders,
-                            providerInfo = uiState.activeEntry?.activeProvider!!,
+                            requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
+                            enabledProviderList = createCredentialUiState.enabledProviders,
+                            providerInfo = createCredentialUiState.activeEntry?.activeProvider!!,
+                            hasDefaultProvider = createCredentialUiState.hasDefaultProvider,
                             createOptionInfo =
-                            uiState.activeEntry.activeEntryInfo as CreateOptionInfo,
-                            onOptionSelected = viewModel::onEntrySelected,
-                            onConfirm = viewModel::onConfirmEntrySelected,
+                            createCredentialUiState.activeEntry.activeEntryInfo
+                                as CreateOptionInfo,
+                            onOptionSelected = viewModel::createFlowOnEntrySelected,
+                            onConfirm = viewModel::createFlowOnConfirmEntrySelected,
                             onMoreOptionsSelected =
-                            viewModel::onMoreOptionsSelectedOnCreationSelection,
+                            viewModel::createFlowOnMoreOptionsSelectedOnCreationSelection,
                         )
                         CreateScreenState.MORE_OPTIONS_SELECTION -> MoreOptionsSelectionCard(
-                            requestDisplayInfo = uiState.requestDisplayInfo,
-                            enabledProviderList = uiState.enabledProviders,
-                            disabledProviderList = uiState.disabledProviders,
-                            sortedCreateOptionsPairs = uiState.sortedCreateOptionsPairs,
-                            hasDefaultProvider = uiState.hasDefaultProvider,
-                            isFromProviderSelection = uiState.isFromProviderSelection!!,
+                            requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
+                            enabledProviderList = createCredentialUiState.enabledProviders,
+                            disabledProviderList = createCredentialUiState.disabledProviders,
+                            sortedCreateOptionsPairs =
+                            createCredentialUiState.sortedCreateOptionsPairs,
+                            hasDefaultProvider = createCredentialUiState.hasDefaultProvider,
+                            isFromProviderSelection =
+                            createCredentialUiState.isFromProviderSelection!!,
                             onBackProviderSelectionButtonSelected =
-                            viewModel::onBackProviderSelectionButtonSelected,
+                            viewModel::createFlowOnBackProviderSelectionButtonSelected,
                             onBackCreationSelectionButtonSelected =
-                            viewModel::onBackCreationSelectionButtonSelected,
+                            viewModel::createFlowOnBackCreationSelectionButtonSelected,
                             onOptionSelected =
-                            viewModel::onEntrySelectedFromMoreOptionScreen,
+                            viewModel::createFlowOnEntrySelectedFromMoreOptionScreen,
                             onDisabledProvidersSelected =
-                            viewModel::onDisabledProvidersSelected,
-                            onRemoteEntrySelected = viewModel::onEntrySelected,
+                            viewModel::createFlowOnDisabledProvidersSelected,
+                            onRemoteEntrySelected = viewModel::createFlowOnEntrySelected,
                         )
                         CreateScreenState.MORE_OPTIONS_ROW_INTRO -> MoreOptionsRowIntroCard(
-                            providerInfo = uiState.activeEntry?.activeProvider!!,
-                            onChangeDefaultSelected = viewModel::onChangeDefaultSelected,
-                            onUseOnceSelected = viewModel::onUseOnceSelected,
+                            providerInfo = createCredentialUiState.activeEntry?.activeProvider!!,
+                            onChangeDefaultSelected = viewModel::createFlowOnChangeDefaultSelected,
+                            onUseOnceSelected = viewModel::createFlowOnUseOnceSelected,
                         )
                         CreateScreenState.EXTERNAL_ONLY_SELECTION -> ExternalOnlySelectionCard(
-                            requestDisplayInfo = uiState.requestDisplayInfo,
-                            activeRemoteEntry = uiState.activeEntry?.activeEntryInfo!!,
-                            onOptionSelected = viewModel::onEntrySelected,
-                            onConfirm = viewModel::onConfirmEntrySelected,
+                            requestDisplayInfo = createCredentialUiState.requestDisplayInfo,
+                            activeRemoteEntry =
+                            createCredentialUiState.activeEntry?.activeEntryInfo!!,
+                            onOptionSelected = viewModel::createFlowOnEntrySelected,
+                            onConfirm = viewModel::createFlowOnConfirmEntrySelected,
                         )
                         CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO ->
                             MoreAboutPasskeysIntroCard(
                                 onBackPasskeyIntroButtonSelected =
-                                viewModel::onBackPasskeyIntroButtonSelected,
+                                viewModel::createFlowOnBackPasskeyIntroButtonSelected,
                             )
                     }
                 }
                 ProviderActivityState.READY_TO_LAUNCH -> {
                     // Launch only once per providerActivityState change so that the provider
                     // UI will not be accidentally launched twice.
-                    LaunchedEffect(uiState.providerActivityState) {
+                    LaunchedEffect(viewModel.uiState.providerActivityState) {
                         viewModel.launchProviderUi(providerActivityLauncher)
                     }
                 }
@@ -146,14 +154,8 @@
                 }
             }
         },
-        scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.8f),
-        sheetShape = EntryShape.TopRoundedCorner,
-    ) {}
-    LaunchedEffect(state.currentValue) {
-        if (state.currentValue == ModalBottomSheetValue.Hidden) {
-            viewModel.onCancel()
-        }
-    }
+        onDismiss = viewModel::onCancel
+    )
 }
 
 @OptIn(ExperimentalMaterial3Api::class)
@@ -164,8 +166,16 @@
 ) {
     ContainerCard() {
         Column() {
+            val onboardingImageResource = remember {
+                mutableStateOf(R.drawable.ic_passkeys_onboarding)
+            }
+            if (isSystemInDarkTheme()) {
+                onboardingImageResource.value = R.drawable.ic_passkeys_onboarding_dark
+            } else {
+                onboardingImageResource.value = R.drawable.ic_passkeys_onboarding
+            }
             Image(
-                painter = painterResource(R.drawable.ic_passkeys_onboarding),
+                painter = painterResource(onboardingImageResource.value),
                 contentDescription = null,
                 modifier = Modifier.align(alignment = Alignment.CenterHorizontally)
                     .padding(top = 24.dp, bottom = 12.dp).size(316.dp, 168.dp)
@@ -264,7 +274,6 @@
     }
 }
 
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ProviderSelectionCard(
     requestDisplayInfo: RequestDisplayInfo,
@@ -288,11 +297,11 @@
                 text = stringResource(
                     R.string.choose_provider_title,
                     when (requestDisplayInfo.type) {
-                        TYPE_PUBLIC_KEY_CREDENTIAL ->
+                        CredentialType.PASSKEY ->
                             stringResource(R.string.passkeys)
-                        TYPE_PASSWORD_CREDENTIAL ->
+                        CredentialType.PASSWORD ->
                             stringResource(R.string.passwords)
-                        else -> stringResource(R.string.sign_in_info)
+                        CredentialType.UNKNOWN -> stringResource(R.string.sign_in_info)
                     }),
                 style = MaterialTheme.typography.titleMedium,
                 modifier = Modifier.padding(horizontal = 24.dp)
@@ -351,7 +360,6 @@
                 thickness = 24.dp,
                 color = Color.Transparent
             )
-            // TODO: handle the error situation that if multiple remoteInfos exists
             enabledProviderList.forEach { enabledProvider ->
                 if (enabledProvider.remoteEntry != null) {
                     Row(
@@ -363,6 +371,7 @@
                             onMoreOptionsSelected
                         )
                     }
+                    return@forEach
                 }
             }
             Divider(
@@ -387,7 +396,7 @@
     onBackCreationSelectionButtonSelected: () -> Unit,
     onOptionSelected: (ActiveEntry) -> Unit,
     onDisabledProvidersSelected: () -> Unit,
-    onRemoteEntrySelected: (EntryInfo) -> Unit,
+    onRemoteEntrySelected: (BaseEntry) -> Unit,
 ) {
     ContainerCard() {
         Column() {
@@ -398,11 +407,11 @@
                         stringResource(
                             R.string.save_credential_to_title,
                             when (requestDisplayInfo.type) {
-                                TYPE_PUBLIC_KEY_CREDENTIAL ->
+                                CredentialType.PASSKEY ->
                                     stringResource(R.string.passkey)
-                                TYPE_PASSWORD_CREDENTIAL ->
+                                CredentialType.PASSWORD ->
                                     stringResource(R.string.password)
-                                else -> stringResource(R.string.sign_in_info)
+                                CredentialType.UNKNOWN -> stringResource(R.string.sign_in_info)
                             }),
                         style = MaterialTheme.typography.titleMedium,
                     )
@@ -463,7 +472,6 @@
                             )
                         }
                     }
-                    // TODO: handle the error situation that if multiple remoteInfos exists
                     enabledProviderList.forEach {
                         if (it.remoteEntry != null) {
                             item {
@@ -472,6 +480,7 @@
                                     onRemoteEntrySelected = onRemoteEntrySelected,
                                 )
                             }
+                            return@forEach
                         }
                     }
                 }
@@ -546,9 +555,10 @@
     enabledProviderList: List<EnabledProviderInfo>,
     providerInfo: EnabledProviderInfo,
     createOptionInfo: CreateOptionInfo,
-    onOptionSelected: (EntryInfo) -> Unit,
+    onOptionSelected: (BaseEntry) -> Unit,
     onConfirm: () -> Unit,
     onMoreOptionsSelected: () -> Unit,
+    hasDefaultProvider: Boolean,
 ) {
     ContainerCard() {
         Column() {
@@ -571,15 +581,15 @@
             )
             TextOnSurface(
                 text = when (requestDisplayInfo.type) {
-                    TYPE_PUBLIC_KEY_CREDENTIAL -> stringResource(
+                    CredentialType.PASSKEY -> stringResource(
                         R.string.choose_create_option_passkey_title,
                         requestDisplayInfo.appName
                     )
-                    TYPE_PASSWORD_CREDENTIAL -> stringResource(
+                    CredentialType.PASSWORD -> stringResource(
                         R.string.choose_create_option_password_title,
                         requestDisplayInfo.appName
                     )
-                    else -> stringResource(
+                    CredentialType.UNKNOWN -> stringResource(
                         R.string.choose_create_option_sign_in_title,
                         requestDisplayInfo.appName
                     )
@@ -601,7 +611,6 @@
                     onOptionSelected = onOptionSelected
                 )
             }
-            var shouldShowMoreOptionsButton = false
             var createOptionsSize = 0
             var remoteEntry: RemoteInfo? = null
             enabledProviderList.forEach { enabledProvider ->
@@ -610,8 +619,13 @@
                 }
                 createOptionsSize += enabledProvider.createOptions.size
             }
-            if (createOptionsSize > 1 || remoteEntry != null) {
-                shouldShowMoreOptionsButton = true
+            val shouldShowMoreOptionsButton = if (!hasDefaultProvider) {
+                // User has already been presented with all options on the default provider
+                // selection screen. Don't show them again. Therefore, only show the more option
+                // button if remote option is present.
+                remoteEntry != null
+            } else {
+                createOptionsSize > 1 || remoteEntry != null
             }
             Row(
                 horizontalArrangement =
@@ -655,8 +669,8 @@
 @Composable
 fun ExternalOnlySelectionCard(
     requestDisplayInfo: RequestDisplayInfo,
-    activeRemoteEntry: EntryInfo,
-    onOptionSelected: (EntryInfo) -> Unit,
+    activeRemoteEntry: BaseEntry,
+    onOptionSelected: (BaseEntry) -> Unit,
     onConfirm: () -> Unit,
 ) {
     ContainerCard() {
@@ -803,8 +817,8 @@
 @Composable
 fun PrimaryCreateOptionRow(
     requestDisplayInfo: RequestDisplayInfo,
-    entryInfo: EntryInfo,
-    onOptionSelected: (EntryInfo) -> Unit
+    entryInfo: BaseEntry,
+    onOptionSelected: (BaseEntry) -> Unit
 ) {
     Entry(
         onClick = { onOptionSelected(entryInfo) },
@@ -826,9 +840,8 @@
         },
         label = {
             Column() {
-                // TODO: Add the function to hide/view password when the type is create password
                 when (requestDisplayInfo.type) {
-                    TYPE_PUBLIC_KEY_CREDENTIAL -> {
+                    CredentialType.PASSKEY -> {
                         TextOnSurfaceVariant(
                             text = requestDisplayInfo.title,
                             style = MaterialTheme.typography.titleLarge,
@@ -846,20 +859,46 @@
                             modifier = Modifier.padding(bottom = 16.dp, start = 5.dp),
                         )
                     }
-                    TYPE_PASSWORD_CREDENTIAL -> {
+                    CredentialType.PASSWORD -> {
                         TextOnSurfaceVariant(
                             text = requestDisplayInfo.title,
                             style = MaterialTheme.typography.titleLarge,
                             modifier = Modifier.padding(top = 16.dp, start = 5.dp),
                         )
-                        TextSecondary(
+                        Row(modifier = Modifier.fillMaxWidth().padding(top = 4.dp, bottom = 16.dp,
+                                                                       start = 5.dp),
+                            verticalAlignment = Alignment.CenterVertically) {
+                            val visualTransformation = remember { PasswordVisualTransformation() }
                             // This subtitle would never be null for create password
-                            text = requestDisplayInfo.subtitle ?: "",
-                            style = MaterialTheme.typography.bodyMedium,
-                            modifier = Modifier.padding(bottom = 16.dp, start = 5.dp),
-                        )
+                            val originalPassword by remember {
+                                mutableStateOf(requestDisplayInfo.subtitle ?: "")
+                            }
+                            val displayedPassword = remember {
+                                mutableStateOf(
+                                    visualTransformation.filter(
+                                        AnnotatedString(originalPassword)
+                                    ).text.text
+                                )
+                            }
+                            TextSecondary(
+                                text = displayedPassword.value,
+                                style = MaterialTheme.typography.bodyMedium,
+                                modifier = Modifier.padding(top = 4.dp, bottom = 4.dp),
+                            )
+
+                            ToggleVisibilityButton(modifier = Modifier.padding(start = 4.dp)
+                                .height(24.dp).width(24.dp), onToggle = {
+                                if (it) {
+                                    displayedPassword.value = originalPassword
+                                } else {
+                                    displayedPassword.value = visualTransformation.filter(
+                                        AnnotatedString(originalPassword)
+                                    ).text.text
+                                }
+                            })
+                        }
                     }
-                    else -> {
+                    CredentialType.UNKNOWN -> {
                         if (requestDisplayInfo.subtitle != null) {
                             TextOnSurfaceVariant(
                                 text = requestDisplayInfo.title,
@@ -917,8 +956,8 @@
                         modifier = Modifier.padding(start = 5.dp),
                     )
                 }
-                if (requestDisplayInfo.type == TYPE_PUBLIC_KEY_CREDENTIAL ||
-                    requestDisplayInfo.type == TYPE_PASSWORD_CREDENTIAL) {
+                if (requestDisplayInfo.type == CredentialType.PASSKEY ||
+                    requestDisplayInfo.type == CredentialType.PASSWORD) {
                     if (createOptionInfo.passwordCount != null &&
                         createOptionInfo.passkeyCount != null
                     ) {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
deleted file mode 100644
index 01318b1..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialViewModel.kt
+++ /dev/null
@@ -1,280 +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.credentialmanager.createflow
-
-import android.app.Activity
-import android.util.Log
-import androidx.activity.compose.ManagedActivityResultLauncher
-import androidx.activity.result.ActivityResult
-import androidx.activity.result.IntentSenderRequest
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.lifecycle.ViewModel
-import com.android.credentialmanager.common.Constants
-import com.android.credentialmanager.CreateFlowUtils
-import com.android.credentialmanager.CredentialManagerRepo
-import com.android.credentialmanager.UserConfigRepo
-import com.android.credentialmanager.common.DialogState
-import com.android.credentialmanager.common.ProviderActivityResult
-import com.android.credentialmanager.common.ProviderActivityState
-
-
-class CreateCredentialViewModel(
-    private val credManRepo: CredentialManagerRepo,
-    private val providerEnableListUiState: List<EnabledProviderInfo>,
-    private val providerDisableListUiState: List<DisabledProviderInfo>,
-    private val requestDisplayInfoUiState: RequestDisplayInfo,
-    userConfigRepo: UserConfigRepo = UserConfigRepo.getInstance(),
-) : ViewModel() {
-
-    val defaultProviderId = userConfigRepo.getDefaultProviderId()
-    val isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse()
-
-    var uiState by mutableStateOf(
-        CreateFlowUtils.toCreateCredentialUiState(
-            providerEnableListUiState,
-            providerDisableListUiState,
-            defaultProviderId,
-            requestDisplayInfoUiState,
-            false,
-            isPasskeyFirstUse)!!)
-        private set
-
-    fun onConfirmIntro() {
-        val newUiState = CreateFlowUtils.toCreateCredentialUiState(
-            providerEnableListUiState, providerDisableListUiState, defaultProviderId,
-            requestDisplayInfoUiState, true, isPasskeyFirstUse)
-        if (newUiState == null) {
-            onInternalError()
-            return
-        }
-        uiState = newUiState
-        UserConfigRepo.getInstance().setIsPasskeyFirstUse(false)
-    }
-
-    fun getProviderInfoByName(providerId: String): EnabledProviderInfo {
-        return uiState.enabledProviders.single {
-            it.id == providerId
-        }
-    }
-
-    fun onMoreOptionsSelectedOnProviderSelection() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.MORE_OPTIONS_SELECTION,
-            isFromProviderSelection = true
-        )
-    }
-
-    fun onMoreOptionsSelectedOnCreationSelection() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.MORE_OPTIONS_SELECTION,
-            isFromProviderSelection = false
-        )
-    }
-
-    fun onBackProviderSelectionButtonSelected() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.PROVIDER_SELECTION,
-        )
-    }
-
-    fun onBackCreationSelectionButtonSelected() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
-        )
-    }
-
-    fun onBackPasskeyIntroButtonSelected() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.PASSKEY_INTRO,
-        )
-    }
-
-    fun onEntrySelectedFromMoreOptionScreen(activeEntry: ActiveEntry) {
-        uiState = uiState.copy(
-            currentScreenState =
-            if (activeEntry.activeProvider.id ==
-                UserConfigRepo.getInstance().getDefaultProviderId())
-                CreateScreenState.CREATION_OPTION_SELECTION
-            else CreateScreenState.MORE_OPTIONS_ROW_INTRO,
-            activeEntry = activeEntry
-        )
-    }
-
-    fun onEntrySelectedFromFirstUseScreen(activeEntry: ActiveEntry) {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
-            activeEntry = activeEntry
-        )
-        val providerId = uiState.activeEntry?.activeProvider?.id
-        onDefaultChanged(providerId)
-    }
-
-    fun onDisabledProvidersSelected() {
-        credManRepo.onSettingLaunchCancel()
-        uiState = uiState.copy(dialogState = DialogState.CANCELED_FOR_SETTINGS)
-    }
-
-    // When the view model runs into unexpected illegal state, reports the error back and close
-    // the activity gracefully.
-    private fun onInternalError() {
-        Log.w(Constants.LOG_TAG, "UI closed due to illegal internal state")
-        credManRepo.onParsingFailureCancel()
-        uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-    }
-
-    fun onCancel() {
-        credManRepo.onUserCancel()
-        uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-    }
-
-    fun onLearnMore() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO,
-        )
-    }
-
-    fun onChangeDefaultSelected() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
-        )
-        val providerId = uiState.activeEntry?.activeProvider?.id
-        onDefaultChanged(providerId)
-    }
-
-    fun onUseOnceSelected() {
-        uiState = uiState.copy(
-            currentScreenState = CreateScreenState.CREATION_OPTION_SELECTION,
-        )
-    }
-
-    fun onDefaultChanged(providerId: String?) {
-        if (providerId != null) {
-            Log.d(
-                Constants.LOG_TAG, "Default provider changed to: " +
-                " {provider=$providerId")
-            UserConfigRepo.getInstance().setDefaultProvider(providerId)
-        } else {
-            Log.w(Constants.LOG_TAG, "Null provider is being changed")
-        }
-    }
-
-    fun onEntrySelected(selectedEntry: EntryInfo) {
-        val providerId = selectedEntry.providerId
-        val entryKey = selectedEntry.entryKey
-        val entrySubkey = selectedEntry.entrySubkey
-        Log.d(
-            Constants.LOG_TAG, "Option selected for entry: " +
-            " {provider=$providerId, key=$entryKey, subkey=$entrySubkey")
-        if (selectedEntry.pendingIntent != null) {
-            uiState = uiState.copy(
-                selectedEntry = selectedEntry,
-                providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
-            )
-        } else {
-            credManRepo.onOptionSelected(
-                providerId,
-                entryKey,
-                entrySubkey
-            )
-            uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-        }
-    }
-
-    fun launchProviderUi(
-        launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
-    ) {
-        val entry = uiState.selectedEntry
-        if (entry != null && entry.pendingIntent != null) {
-            uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
-            val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
-                .setFillInIntent(entry.fillInIntent).build()
-            launcher.launch(intentSenderRequest)
-        } else {
-            Log.d(Constants.LOG_TAG, "Unexpected: no provider UI to launch")
-            onInternalError()
-        }
-    }
-
-    fun onConfirmEntrySelected() {
-        val selectedEntry = uiState.activeEntry?.activeEntryInfo
-        if (selectedEntry != null) {
-            onEntrySelected(selectedEntry)
-        } else {
-            Log.d(Constants.LOG_TAG,
-                "Unexpected: confirm is pressed but no active entry exists.")
-            onInternalError()
-        }
-    }
-
-    fun onProviderActivityResult(providerActivityResult: ProviderActivityResult) {
-        val entry = uiState.selectedEntry
-        val resultCode = providerActivityResult.resultCode
-        val resultData = providerActivityResult.data
-        if (resultCode == Activity.RESULT_CANCELED) {
-            // Re-display the CredMan UI if the user canceled from the provider UI.
-            Log.d(Constants.LOG_TAG, "The provider activity was cancelled," +
-                " re-displaying our UI.")
-            uiState = uiState.copy(
-                selectedEntry = null,
-                providerActivityState = ProviderActivityState.NOT_APPLICABLE,
-            )
-        } else {
-            if (entry != null) {
-                val providerId = entry.providerId
-                Log.d(Constants.LOG_TAG, "Got provider activity result: {provider=" +
-                    "$providerId, key=${entry.entryKey}, subkey=${entry.entrySubkey}, " +
-                    "resultCode=$resultCode, resultData=$resultData}"
-                )
-                credManRepo.onOptionSelected(
-                    providerId, entry.entryKey, entry.entrySubkey, resultCode, resultData,
-                )
-                uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-            } else {
-                Log.d(Constants.LOG_TAG,
-                    "Illegal state: received a provider result but found no matching entry.")
-                onInternalError()
-            }
-        }
-    }
-
-    companion object Factory {
-        // Validates the input and returns null if the input is invalid.
-        fun newInstance(
-            credManRepo: CredentialManagerRepo,
-            providerEnableListUiState: List<EnabledProviderInfo>,
-            providerDisableListUiState: List<DisabledProviderInfo>,
-            requestDisplayInfoUiState: RequestDisplayInfo?,
-        ): CreateCredentialViewModel? {
-            if (providerEnableListUiState.isEmpty() || requestDisplayInfoUiState == null) {
-                return null
-            }
-            return try {
-                val result = CreateCredentialViewModel(
-                    credManRepo = credManRepo,
-                    providerEnableListUiState = providerEnableListUiState,
-                    providerDisableListUiState = providerDisableListUiState,
-                    requestDisplayInfoUiState = requestDisplayInfoUiState
-                )
-                result
-            } catch (e: Exception) {
-                null
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
index 12a5085..8d20564 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateModel.kt
@@ -19,8 +19,9 @@
 import android.app.PendingIntent
 import android.content.Intent
 import android.graphics.drawable.Drawable
-import com.android.credentialmanager.common.DialogState
-import com.android.credentialmanager.common.ProviderActivityState
+import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.common.CredentialType
+import java.time.Instant
 
 data class CreateCredentialUiState(
   val enabledProviders: List<EnabledProviderInfo>,
@@ -32,11 +33,7 @@
   // we're showing provider selection page at the beginning
   val hasDefaultProvider: Boolean,
   val activeEntry: ActiveEntry? = null,
-  val selectedEntry: EntryInfo? = null,
-  val providerActivityState: ProviderActivityState =
-    ProviderActivityState.NOT_APPLICABLE,
   val isFromProviderSelection: Boolean? = null,
-  val dialogState: DialogState = DialogState.ACTIVE,
 )
 
 open class ProviderInfo(
@@ -59,28 +56,27 @@
   displayName: String,
 ) : ProviderInfo(icon, id, displayName)
 
-open class EntryInfo (
-  val providerId: String,
-  val entryKey: String,
-  val entrySubkey: String,
-  val pendingIntent: PendingIntent?,
-  val fillInIntent: Intent?,
-)
-
 class CreateOptionInfo(
-  providerId: String,
-  entryKey: String,
-  entrySubkey: String,
-  pendingIntent: PendingIntent?,
-  fillInIntent: Intent?,
-  val userProviderDisplayName: String?,
-  val profileIcon: Drawable?,
-  val passwordCount: Int?,
-  val passkeyCount: Int?,
-  val totalCredentialCount: Int?,
-  val lastUsedTimeMillis: Long?,
-  val footerDescription: String?,
-) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    val userProviderDisplayName: String?,
+    val profileIcon: Drawable?,
+    val passwordCount: Int?,
+    val passkeyCount: Int?,
+    val totalCredentialCount: Int?,
+    val lastUsedTime: Instant?,
+    val footerDescription: String?,
+) : BaseEntry(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
 
 class RemoteInfo(
   providerId: String,
@@ -88,12 +84,19 @@
   entrySubkey: String,
   pendingIntent: PendingIntent?,
   fillInIntent: Intent?,
-) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
+) : BaseEntry(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
 
 data class RequestDisplayInfo(
   val title: String,
   val subtitle: String?,
-  val type: String,
+  val type: CredentialType,
   val appName: String,
   val typeIcon: Drawable,
 )
@@ -104,7 +107,7 @@
  */
 data class ActiveEntry (
   val activeProvider: EnabledProviderInfo,
-  val activeEntryInfo: EntryInfo,
+  val activeEntryInfo: BaseEntry,
 )
 
 /** The name of the current screen. */
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index b30d1ec..438978c 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -16,14 +16,12 @@
 
 package com.android.credentialmanager.getflow
 
-import android.credentials.Credential
 import android.text.TextUtils
 import androidx.activity.compose.ManagedActivityResultLauncher
 import androidx.activity.result.ActivityResult
 import androidx.activity.result.IntentSenderRequest
 
 import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -58,69 +56,64 @@
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.core.graphics.drawable.toBitmap
+import com.android.credentialmanager.CredentialSelectorViewModel
 import com.android.credentialmanager.R
+import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.common.CredentialType
 import com.android.credentialmanager.common.ProviderActivityState
-import com.android.credentialmanager.common.material.ModalBottomSheetLayout
-import com.android.credentialmanager.common.material.ModalBottomSheetValue
-import com.android.credentialmanager.common.material.rememberModalBottomSheetState
 import com.android.credentialmanager.common.ui.ActionButton
 import com.android.credentialmanager.common.ui.ConfirmButton
 import com.android.credentialmanager.common.ui.Entry
+import com.android.credentialmanager.common.ui.ModalBottomSheet
 import com.android.credentialmanager.common.ui.TextOnSurface
 import com.android.credentialmanager.common.ui.TextSecondary
 import com.android.credentialmanager.common.ui.TextOnSurfaceVariant
 import com.android.credentialmanager.common.ui.ContainerCard
 import com.android.credentialmanager.common.ui.TransparentBackgroundEntry
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
 import com.android.credentialmanager.ui.theme.EntryShape
 import com.android.credentialmanager.ui.theme.LocalAndroidColorScheme
 
 @Composable
 fun GetCredentialScreen(
-    viewModel: GetCredentialViewModel,
+    viewModel: CredentialSelectorViewModel,
+    getCredentialUiState: GetCredentialUiState,
     providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
 ) {
-    val state = rememberModalBottomSheetState(
-        initialValue = ModalBottomSheetValue.Expanded,
-        skipHalfExpanded = true
-    )
-    val uiState = viewModel.uiState
-    if (uiState.currentScreenState != GetScreenState.REMOTE_ONLY) {
-        ModalBottomSheetLayout(
-            sheetBackgroundColor = MaterialTheme.colorScheme.surface,
-            modifier = Modifier.background(Color.Transparent),
-            sheetState = state,
+    if (getCredentialUiState.currentScreenState != GetScreenState.REMOTE_ONLY) {
+        ModalBottomSheet(
             sheetContent = {
                 // Hide the sheet content as opposed to the whole bottom sheet to maintain the scrim
                 // background color even when the content should be hidden while waiting for
                 // results from the provider app.
-                when (uiState.providerActivityState) {
+                when (viewModel.uiState.providerActivityState) {
                     ProviderActivityState.NOT_APPLICABLE -> {
-                        if (uiState.currentScreenState == GetScreenState.PRIMARY_SELECTION) {
+                        if (getCredentialUiState.currentScreenState
+                            == GetScreenState.PRIMARY_SELECTION) {
                             PrimarySelectionCard(
-                                requestDisplayInfo = uiState.requestDisplayInfo,
-                                providerDisplayInfo = uiState.providerDisplayInfo,
-                                providerInfoList = uiState.providerInfoList,
-                                activeEntry = uiState.activeEntry,
-                                onEntrySelected = viewModel::onEntrySelected,
-                                onConfirm = viewModel::onConfirmEntrySelected,
-                                onMoreOptionSelected = viewModel::onMoreOptionSelected,
+                                requestDisplayInfo = getCredentialUiState.requestDisplayInfo,
+                                providerDisplayInfo = getCredentialUiState.providerDisplayInfo,
+                                providerInfoList = getCredentialUiState.providerInfoList,
+                                activeEntry = getCredentialUiState.activeEntry,
+                                onEntrySelected = viewModel::getFlowOnEntrySelected,
+                                onConfirm = viewModel::getFlowOnConfirmEntrySelected,
+                                onMoreOptionSelected = viewModel::getFlowOnMoreOptionSelected,
                             )
                         } else {
                             AllSignInOptionCard(
-                                providerInfoList = uiState.providerInfoList,
-                                providerDisplayInfo = uiState.providerDisplayInfo,
-                                onEntrySelected = viewModel::onEntrySelected,
-                                onBackButtonClicked = viewModel::onBackToPrimarySelectionScreen,
+                                providerInfoList = getCredentialUiState.providerInfoList,
+                                providerDisplayInfo = getCredentialUiState.providerDisplayInfo,
+                                onEntrySelected = viewModel::getFlowOnEntrySelected,
+                                onBackButtonClicked =
+                                viewModel::getFlowOnBackToPrimarySelectionScreen,
                                 onCancel = viewModel::onCancel,
-                                isNoAccount = uiState.isNoAccount,
+                                isNoAccount = getCredentialUiState.isNoAccount,
                             )
                         }
                     }
                     ProviderActivityState.READY_TO_LAUNCH -> {
                         // Launch only once per providerActivityState change so that the provider
                         // UI will not be accidentally launched twice.
-                        LaunchedEffect(uiState.providerActivityState) {
+                        LaunchedEffect(viewModel.uiState.providerActivityState) {
                             viewModel.launchProviderUi(providerActivityLauncher)
                         }
                     }
@@ -129,17 +122,11 @@
                     }
                 }
             },
-            scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.8f),
-            sheetShape = EntryShape.TopRoundedCorner,
-        ) {}
-        LaunchedEffect(state.currentValue) {
-            if (state.currentValue == ModalBottomSheetValue.Hidden) {
-                viewModel.onCancel()
-            }
-        }
+            onDismiss = viewModel::onCancel,
+        )
     } else {
         SnackBarScreen(
-            onClick = viewModel::onMoreOptionOnSnackBarSelected,
+            onClick = viewModel::getFlowOnMoreOptionOnSnackBarSelected,
             onCancel = viewModel::onCancel,
         )
     }
@@ -151,8 +138,8 @@
     requestDisplayInfo: RequestDisplayInfo,
     providerDisplayInfo: ProviderDisplayInfo,
     providerInfoList: List<ProviderInfo>,
-    activeEntry: EntryInfo?,
-    onEntrySelected: (EntryInfo) -> Unit,
+    activeEntry: BaseEntry?,
+    onEntrySelected: (BaseEntry) -> Unit,
     onConfirm: () -> Unit,
     onMoreOptionSelected: () -> Unit,
 ) {
@@ -171,7 +158,7 @@
                     ) {
                         if (sortedUserNameToCredentialEntryList.first()
                                 .sortedCredentialEntryList.first().credentialType
-                            == PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL
+                            == CredentialType.PASSKEY
                         ) R.string.get_dialog_title_use_passkey_for
                         else R.string.get_dialog_title_use_sign_in_for
                     } else if (
@@ -280,7 +267,7 @@
 fun AllSignInOptionCard(
     providerInfoList: List<ProviderInfo>,
     providerDisplayInfo: ProviderDisplayInfo,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
     onBackButtonClicked: () -> Unit,
     onCancel: () -> Unit,
     isNoAccount: Boolean,
@@ -379,7 +366,7 @@
 @Composable
 fun ActionChips(
     providerInfoList: List<ProviderInfo>,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     val actionChips = providerInfoList.flatMap { it.actionEntryList }
     if (actionChips.isEmpty()) {
@@ -407,7 +394,7 @@
 @Composable
 fun RemoteEntryCard(
     remoteEntry: RemoteEntryInfo,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     TextSecondary(
         text = stringResource(R.string.get_dialog_heading_from_another_device),
@@ -449,7 +436,7 @@
 @Composable
 fun LockedCredentials(
     authenticationEntryList: List<AuthenticationEntryInfo>,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     TextSecondary(
         text = stringResource(R.string.get_dialog_heading_locked_password_managers),
@@ -474,7 +461,7 @@
 @Composable
 fun PerUserNameCredentials(
     perUserNameCredentialEntryList: PerUserNameCredentialEntryList,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     TextSecondary(
         text = stringResource(
@@ -498,11 +485,10 @@
     }
 }
 
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun CredentialEntryRow(
     credentialEntryInfo: CredentialEntryInfo,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     Entry(
         onClick = { onEntrySelected(credentialEntryInfo) },
@@ -511,15 +497,13 @@
                 Image(
                     modifier = Modifier.padding(start = 10.dp).size(32.dp),
                     bitmap = credentialEntryInfo.icon.toBitmap().asImageBitmap(),
-                    // TODO: add description.
-                    contentDescription = "",
+                    contentDescription = null,
                 )
             } else {
                 Icon(
                     modifier = Modifier.padding(start = 10.dp).size(32.dp),
                     painter = painterResource(R.drawable.ic_other_sign_in),
-                    // TODO: add description.
-                    contentDescription = "",
+                    contentDescription = null,
                     tint = LocalAndroidColorScheme.current.colorAccentPrimaryVariant
                 )
             }
@@ -534,7 +518,7 @@
                 )
                 TextSecondary(
                     text = if (
-                        credentialEntryInfo.credentialType == Credential.TYPE_PASSWORD_CREDENTIAL) {
+                        credentialEntryInfo.credentialType == CredentialType.PASSWORD) {
                         "••••••••••••"
                     } else {
                         if (TextUtils.isEmpty(credentialEntryInfo.displayName))
@@ -558,7 +542,7 @@
 @Composable
 fun AuthenticationEntryRow(
     authenticationEntryInfo: AuthenticationEntryInfo,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     Entry(
         onClick = { onEntrySelected(authenticationEntryInfo) },
@@ -566,8 +550,7 @@
             Image(
                 modifier = Modifier.padding(start = 10.dp).size(32.dp),
                 bitmap = authenticationEntryInfo.icon.toBitmap().asImageBitmap(),
-                // TODO: add description.
-                contentDescription = ""
+                contentDescription = null
             )
         },
         label = {
@@ -576,23 +559,28 @@
                 modifier = Modifier.fillMaxWidth().padding(horizontal = 5.dp),
             ) {
                 Column() {
-                    // TODO: fix the text values.
                     TextOnSurfaceVariant(
                         text = authenticationEntryInfo.title,
                         style = MaterialTheme.typography.titleLarge,
                         modifier = Modifier.padding(top = 16.dp)
                     )
                     TextSecondary(
-                        text = stringResource(R.string.locked_credential_entry_label_subtext),
+                        text = stringResource(
+                            if (authenticationEntryInfo.isUnlockedAndEmpty)
+                                R.string.locked_credential_entry_label_subtext_no_sign_in
+                            else R.string.locked_credential_entry_label_subtext_tap_to_unlock
+                    ),
                         style = MaterialTheme.typography.bodyMedium,
                         modifier = Modifier.padding(bottom = 16.dp)
                     )
                 }
-                Icon(
-                    Icons.Outlined.Lock,
-                    null,
-                    Modifier.align(alignment = Alignment.CenterVertically).padding(end = 10.dp),
-                )
+                if (!authenticationEntryInfo.isUnlockedAndEmpty) {
+                    Icon(
+                        Icons.Outlined.Lock,
+                        null,
+                        Modifier.align(alignment = Alignment.CenterVertically).padding(end = 10.dp),
+                    )
+                }
             }
         }
     )
@@ -602,15 +590,14 @@
 @Composable
 fun ActionEntryRow(
     actionEntryInfo: ActionEntryInfo,
-    onEntrySelected: (EntryInfo) -> Unit,
+    onEntrySelected: (BaseEntry) -> Unit,
 ) {
     TransparentBackgroundEntry(
         icon = {
             Image(
                 modifier = Modifier.padding(start = 10.dp).size(24.dp),
                 bitmap = actionEntryInfo.icon.toBitmap().asImageBitmap(),
-                // TODO: add description.
-                contentDescription = ""
+                contentDescription = null,
             )
         },
         label = {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
deleted file mode 100644
index 7d2f0da..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialViewModel.kt
+++ /dev/null
@@ -1,282 +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.credentialmanager.getflow
-
-import android.app.Activity
-import android.util.Log
-import androidx.activity.compose.ManagedActivityResultLauncher
-import androidx.activity.result.ActivityResult
-import androidx.activity.result.IntentSenderRequest
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.lifecycle.ViewModel
-import com.android.credentialmanager.CredentialManagerRepo
-import com.android.credentialmanager.common.Constants
-import com.android.credentialmanager.common.DialogState
-import com.android.credentialmanager.common.ProviderActivityResult
-import com.android.credentialmanager.common.ProviderActivityState
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
-import com.android.internal.util.Preconditions
-
-data class GetCredentialUiState(
-    val providerInfoList: List<ProviderInfo>,
-    val requestDisplayInfo: RequestDisplayInfo,
-    val currentScreenState: GetScreenState = toGetScreenState(providerInfoList),
-    val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerInfoList),
-    val selectedEntry: EntryInfo? = null,
-    val activeEntry: EntryInfo? = toActiveEntry(providerDisplayInfo),
-    val providerActivityState: ProviderActivityState =
-        ProviderActivityState.NOT_APPLICABLE,
-    val isNoAccount: Boolean = false,
-    val dialogState: DialogState = DialogState.ACTIVE,
-)
-
-class GetCredentialViewModel(
-    private val credManRepo: CredentialManagerRepo,
-    initialUiState: GetCredentialUiState,
-) : ViewModel() {
-
-    var uiState by mutableStateOf(initialUiState)
-        private set
-
-    fun onEntrySelected(entry: EntryInfo) {
-        Log.d(Constants.LOG_TAG, "credential selected: {provider=${entry.providerId}" +
-            ", key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
-        if (entry.pendingIntent != null) {
-            uiState = uiState.copy(
-                selectedEntry = entry,
-                providerActivityState = ProviderActivityState.READY_TO_LAUNCH,
-            )
-        } else {
-            credManRepo.onOptionSelected(entry.providerId, entry.entryKey, entry.entrySubkey)
-            uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-        }
-    }
-
-    fun onConfirmEntrySelected() {
-        val activeEntry = uiState.activeEntry
-        if (activeEntry != null) {
-            onEntrySelected(activeEntry)
-        } else {
-            Log.d(Constants.LOG_TAG,
-                "Illegal state: confirm is pressed but activeEntry isn't set.")
-            onInternalError()
-        }
-    }
-
-    fun launchProviderUi(
-        launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
-    ) {
-        val entry = uiState.selectedEntry
-        if (entry != null && entry.pendingIntent != null) {
-            Log.d(Constants.LOG_TAG, "Launching provider activity")
-            uiState = uiState.copy(providerActivityState = ProviderActivityState.PENDING)
-            val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
-                .setFillInIntent(entry.fillInIntent).build()
-            launcher.launch(intentSenderRequest)
-        } else {
-            Log.d(Constants.LOG_TAG, "No provider UI to launch")
-            onInternalError()
-        }
-    }
-
-    // When the view model runs into unexpected illegal state, reports the error back and close
-    // the activity gracefully.
-    private fun onInternalError() {
-        Log.w(Constants.LOG_TAG, "UI closed due to illegal internal state")
-        credManRepo.onParsingFailureCancel()
-        uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-    }
-
-    fun onProviderActivityResult(providerActivityResult: ProviderActivityResult) {
-        val entry = uiState.selectedEntry
-        val resultCode = providerActivityResult.resultCode
-        val resultData = providerActivityResult.data
-        if (resultCode == Activity.RESULT_CANCELED) {
-            // Re-display the CredMan UI if the user canceled from the provider UI.
-            Log.d(Constants.LOG_TAG, "The provider activity was cancelled," +
-                " re-displaying our UI.")
-            uiState = uiState.copy(
-                selectedEntry = null,
-                providerActivityState = ProviderActivityState.NOT_APPLICABLE,
-            )
-        } else {
-            if (entry != null) {
-                Log.d(
-                    Constants.LOG_TAG, "Got provider activity result: {provider=" +
-                    "${entry.providerId}, key=${entry.entryKey}, subkey=${entry.entrySubkey}" +
-                    ", resultCode=$resultCode, resultData=$resultData}"
-                )
-                credManRepo.onOptionSelected(
-                    entry.providerId, entry.entryKey, entry.entrySubkey,
-                    resultCode, resultData,
-                )
-                uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-            } else {
-                Log.w(Constants.LOG_TAG,
-                    "Illegal state: received a provider result but found no matching entry.")
-                onInternalError()
-            }
-        }
-    }
-
-    fun onMoreOptionSelected() {
-        Log.d(Constants.LOG_TAG, "More Option selected")
-        uiState = uiState.copy(
-            currentScreenState = GetScreenState.ALL_SIGN_IN_OPTIONS
-        )
-    }
-
-    fun onMoreOptionOnSnackBarSelected(isNoAccount: Boolean) {
-        Log.d(Constants.LOG_TAG, "More Option on snackBar selected")
-        uiState = uiState.copy(
-            currentScreenState = GetScreenState.ALL_SIGN_IN_OPTIONS,
-            isNoAccount = isNoAccount,
-        )
-    }
-
-    fun onBackToPrimarySelectionScreen() {
-        uiState = uiState.copy(
-            currentScreenState = GetScreenState.PRIMARY_SELECTION
-        )
-    }
-
-    fun onCancel() {
-        credManRepo.onUserCancel()
-        uiState = uiState.copy(dialogState = DialogState.COMPLETE)
-    }
-}
-
-private fun toProviderDisplayInfo(
-    providerInfoList: List<ProviderInfo>
-): ProviderDisplayInfo {
-
-    val userNameToCredentialEntryMap = mutableMapOf<String, MutableList<CredentialEntryInfo>>()
-    val authenticationEntryList = mutableListOf<AuthenticationEntryInfo>()
-    val remoteEntryList = mutableListOf<RemoteEntryInfo>()
-    providerInfoList.forEach { providerInfo ->
-        if (providerInfo.authenticationEntry != null) {
-            authenticationEntryList.add(providerInfo.authenticationEntry)
-        }
-        if (providerInfo.remoteEntry != null) {
-            remoteEntryList.add(providerInfo.remoteEntry)
-        }
-
-        providerInfo.credentialEntryList.forEach {
-            userNameToCredentialEntryMap.compute(
-                it.userName
-            ) { _, v ->
-                if (v == null) {
-                    mutableListOf(it)
-                } else {
-                    v.add(it)
-                    v
-                }
-            }
-        }
-    }
-    // There can only be at most one remote entry
-    // TODO: fail elegantly
-    Preconditions.checkState(remoteEntryList.size <= 1)
-
-    // Compose sortedUserNameToCredentialEntryList
-    val comparator = CredentialEntryInfoComparatorByTypeThenTimestamp()
-    // Sort per username
-    userNameToCredentialEntryMap.values.forEach {
-        it.sortWith(comparator)
-    }
-    // Transform to list of PerUserNameCredentialEntryLists and then sort across usernames
-    val sortedUserNameToCredentialEntryList = userNameToCredentialEntryMap.map {
-        PerUserNameCredentialEntryList(it.key, it.value)
-    }.sortedWith(
-        compareByDescending { it.sortedCredentialEntryList.first().lastUsedTimeMillis }
-    )
-
-    return ProviderDisplayInfo(
-        sortedUserNameToCredentialEntryList = sortedUserNameToCredentialEntryList,
-        authenticationEntryList = authenticationEntryList,
-        remoteEntry = remoteEntryList.getOrNull(0),
-    )
-}
-
-private fun toActiveEntry(
-    providerDisplayInfo: ProviderDisplayInfo,
-): EntryInfo? {
-    val sortedUserNameToCredentialEntryList =
-        providerDisplayInfo.sortedUserNameToCredentialEntryList
-    val authenticationEntryList = providerDisplayInfo.authenticationEntryList
-    var activeEntry: EntryInfo? = null
-    if (sortedUserNameToCredentialEntryList
-            .size == 1 && authenticationEntryList.isEmpty()
-    ) {
-        activeEntry = sortedUserNameToCredentialEntryList.first().sortedCredentialEntryList.first()
-    } else if (
-        sortedUserNameToCredentialEntryList
-            .isEmpty() && authenticationEntryList.size == 1
-    ) {
-        activeEntry = authenticationEntryList.first()
-    }
-    return activeEntry
-}
-
-private fun toGetScreenState(
-    providerInfoList: List<ProviderInfo>
-): GetScreenState {
-    var noLocalAccount = true
-    var remoteInfo: RemoteEntryInfo? = null
-    providerInfoList.forEach { providerInfo ->
-        if (providerInfo.credentialEntryList.isNotEmpty() ||
-            providerInfo.authenticationEntry != null) {
-            noLocalAccount = false
-        }
-        // TODO: handle the error situation that if multiple remoteInfos exists
-        if (providerInfo.remoteEntry != null) {
-            remoteInfo = providerInfo.remoteEntry
-        }
-    }
-
-    return if (noLocalAccount && remoteInfo != null)
-        GetScreenState.REMOTE_ONLY else GetScreenState.PRIMARY_SELECTION
-}
-
-internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator<CredentialEntryInfo> {
-    override fun compare(p0: CredentialEntryInfo, p1: CredentialEntryInfo): Int {
-        // First prefer passkey type for its security benefits
-        if (p0.credentialType != p1.credentialType) {
-            if (PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL == p0.credentialType) {
-                return -1
-            } else if (PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL == p1.credentialType) {
-                return 1
-            }
-        }
-
-        // Then order by last used timestamp
-        if (p0.lastUsedTimeMillis != null && p1.lastUsedTimeMillis != null) {
-            if (p0.lastUsedTimeMillis < p1.lastUsedTimeMillis) {
-                return 1
-            } else if (p0.lastUsedTimeMillis > p1.lastUsedTimeMillis) {
-                return -1
-            }
-        } else if (p0.lastUsedTimeMillis != null && p0.lastUsedTimeMillis > 0) {
-            return -1
-        } else if (p1.lastUsedTimeMillis != null && p1.lastUsedTimeMillis > 0) {
-            return 1
-        }
-        return 0
-    }
-}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
index 8ce31bd..1a30295 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt
@@ -19,89 +19,126 @@
 import android.app.PendingIntent
 import android.content.Intent
 import android.graphics.drawable.Drawable
+import com.android.credentialmanager.common.BaseEntry
+import com.android.credentialmanager.common.CredentialType
+import com.android.internal.util.Preconditions
+
+import java.time.Instant
+
+data class GetCredentialUiState(
+    val providerInfoList: List<ProviderInfo>,
+    val requestDisplayInfo: RequestDisplayInfo,
+    val currentScreenState: GetScreenState = toGetScreenState(providerInfoList),
+    val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerInfoList),
+    val activeEntry: BaseEntry? = toActiveEntry(providerDisplayInfo),
+    val isNoAccount: Boolean = false,
+)
 
 data class ProviderInfo(
-  /**
-   * Unique id (component name) of this provider.
-   * Not for display purpose - [displayName] should be used for ui rendering.
-   */
-  val id: String,
-  val icon: Drawable,
-  val displayName: String,
-  val credentialEntryList: List<CredentialEntryInfo>,
-  val authenticationEntry: AuthenticationEntryInfo?,
-  val remoteEntry: RemoteEntryInfo?,
-  val actionEntryList: List<ActionEntryInfo>,
+    /**
+     * Unique id (component name) of this provider.
+     * Not for display purpose - [displayName] should be used for ui rendering.
+     */
+    val id: String,
+    val icon: Drawable,
+    val displayName: String,
+    val credentialEntryList: List<CredentialEntryInfo>,
+    val authenticationEntryList: List<AuthenticationEntryInfo>,
+    val remoteEntry: RemoteEntryInfo?,
+    val actionEntryList: List<ActionEntryInfo>,
 )
 
 /** Display-centric data structure derived from the [ProviderInfo]. This abstraction is not grouping
  *  by the provider id but instead focuses on structures convenient for display purposes. */
 data class ProviderDisplayInfo(
-  /**
-   * The credential entries grouped by userName, derived from all entries of the [providerInfoList].
-   * Note that the list order matters to the display order.
-   */
-  val sortedUserNameToCredentialEntryList: List<PerUserNameCredentialEntryList>,
-  val authenticationEntryList: List<AuthenticationEntryInfo>,
-  val remoteEntry: RemoteEntryInfo?
-)
-
-abstract class EntryInfo (
-  /** Unique id combination of this entry. Not for display purpose. */
-  val providerId: String,
-  val entryKey: String,
-  val entrySubkey: String,
-  val pendingIntent: PendingIntent?,
-  val fillInIntent: Intent?,
+    /**
+     * The credential entries grouped by userName, derived from all entries of the [providerInfoList].
+     * Note that the list order matters to the display order.
+     */
+    val sortedUserNameToCredentialEntryList: List<PerUserNameCredentialEntryList>,
+    val authenticationEntryList: List<AuthenticationEntryInfo>,
+    val remoteEntry: RemoteEntryInfo?
 )
 
 class CredentialEntryInfo(
-  providerId: String,
-  entryKey: String,
-  entrySubkey: String,
-  pendingIntent: PendingIntent?,
-  fillInIntent: Intent?,
-  /** Type of this credential used for sorting. Not localized so must not be directly displayed. */
-  val credentialType: String,
-  /** Localized type value of this credential used for display purpose. */
-  val credentialTypeDisplayName: String,
-  val userName: String,
-  val displayName: String?,
-  val icon: Drawable?,
-  val lastUsedTimeMillis: Long?,
-) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    /** Type of this credential used for sorting. Not localized so must not be directly displayed. */
+    val credentialType: CredentialType,
+    /** Localized type value of this credential used for display purpose. */
+    val credentialTypeDisplayName: String,
+    val userName: String,
+    val displayName: String?,
+    val icon: Drawable?,
+    val lastUsedTimeMillis: Instant?,
+) : BaseEntry(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
 
 class AuthenticationEntryInfo(
-  providerId: String,
-  entryKey: String,
-  entrySubkey: String,
-  pendingIntent: PendingIntent?,
-  fillInIntent: Intent?,
-  val title: String,
-  val icon: Drawable,
-) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    val title: String,
+    val icon: Drawable,
+    // The entry had been unlocked and turned out to be empty. Used to determine whether to
+    // show "Tap to unlock" or "No sign-in info" for this entry.
+    val isUnlockedAndEmpty: Boolean,
+    // True if the entry was the last one unlocked. Used to show the no sign-in info snackbar.
+    val isLastUnlocked: Boolean,
+) : BaseEntry(
+    providerId,
+    entryKey, entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = false,
+)
 
 class RemoteEntryInfo(
-  providerId: String,
-  entryKey: String,
-  entrySubkey: String,
-  pendingIntent: PendingIntent?,
-  fillInIntent: Intent?,
-) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+) : BaseEntry(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = true,
+)
 
 class ActionEntryInfo(
-  providerId: String,
-  entryKey: String,
-  entrySubkey: String,
-  pendingIntent: PendingIntent?,
-  fillInIntent: Intent?,
-  val title: String,
-  val icon: Drawable,
-  val subTitle: String?,
-) : EntryInfo(providerId, entryKey, entrySubkey, pendingIntent, fillInIntent)
+    providerId: String,
+    entryKey: String,
+    entrySubkey: String,
+    pendingIntent: PendingIntent?,
+    fillInIntent: Intent?,
+    val title: String,
+    val icon: Drawable,
+    val subTitle: String?,
+) : BaseEntry(
+    providerId,
+    entryKey,
+    entrySubkey,
+    pendingIntent,
+    fillInIntent,
+    shouldTerminateUiUponSuccessfulProviderResult = false,
+)
 
 data class RequestDisplayInfo(
-  val appName: String,
+    val appName: String,
 )
 
 /**
@@ -110,16 +147,135 @@
  *                                     by last used timestamps and then by credential types
  */
 data class PerUserNameCredentialEntryList(
-  val userName: String,
-  val sortedCredentialEntryList: List<CredentialEntryInfo>,
+    val userName: String,
+    val sortedCredentialEntryList: List<CredentialEntryInfo>,
 )
 
 /** The name of the current screen. */
 enum class GetScreenState {
-  /** The primary credential selection page. */
-  PRIMARY_SELECTION,
-  /** The secondary credential selection page, where all sign-in options are listed. */
-  ALL_SIGN_IN_OPTIONS,
-  /** The snackbar only page when there's no account but only a remoteEntry. */
-  REMOTE_ONLY,
+    /** The primary credential selection page. */
+    PRIMARY_SELECTION,
+
+    /** The secondary credential selection page, where all sign-in options are listed. */
+    ALL_SIGN_IN_OPTIONS,
+
+    /** The snackbar only page when there's no account but only a remoteEntry. */
+    REMOTE_ONLY,
 }
+
+// IMPORTANT: new invocation should be mindful that this method will throw if more than 1 remote
+// entry exists
+private fun toProviderDisplayInfo(
+    providerInfoList: List<ProviderInfo>
+): ProviderDisplayInfo {
+
+    val userNameToCredentialEntryMap = mutableMapOf<String, MutableList<CredentialEntryInfo>>()
+    val authenticationEntryList = mutableListOf<AuthenticationEntryInfo>()
+    val remoteEntryList = mutableListOf<RemoteEntryInfo>()
+    providerInfoList.forEach { providerInfo ->
+        authenticationEntryList.addAll(providerInfo.authenticationEntryList)
+        if (providerInfo.remoteEntry != null) {
+            remoteEntryList.add(providerInfo.remoteEntry)
+        }
+        // There can only be at most one remote entry
+        Preconditions.checkState(remoteEntryList.size <= 1)
+
+        providerInfo.credentialEntryList.forEach {
+            userNameToCredentialEntryMap.compute(
+                it.userName
+            ) { _, v ->
+                if (v == null) {
+                    mutableListOf(it)
+                } else {
+                    v.add(it)
+                    v
+                }
+            }
+        }
+    }
+
+    // Compose sortedUserNameToCredentialEntryList
+    val comparator = CredentialEntryInfoComparatorByTypeThenTimestamp()
+    // Sort per username
+    userNameToCredentialEntryMap.values.forEach {
+        it.sortWith(comparator)
+    }
+    // Transform to list of PerUserNameCredentialEntryLists and then sort across usernames
+    val sortedUserNameToCredentialEntryList = userNameToCredentialEntryMap.map {
+        PerUserNameCredentialEntryList(it.key, it.value)
+    }.sortedWith(
+        compareByDescending { it.sortedCredentialEntryList.first().lastUsedTimeMillis }
+    )
+
+    return ProviderDisplayInfo(
+        sortedUserNameToCredentialEntryList = sortedUserNameToCredentialEntryList,
+        authenticationEntryList = authenticationEntryList,
+        remoteEntry = remoteEntryList.getOrNull(0),
+    )
+}
+
+private fun toActiveEntry(
+    providerDisplayInfo: ProviderDisplayInfo,
+): BaseEntry? {
+    val sortedUserNameToCredentialEntryList =
+        providerDisplayInfo.sortedUserNameToCredentialEntryList
+    val authenticationEntryList = providerDisplayInfo.authenticationEntryList
+    var activeEntry: BaseEntry? = null
+    if (sortedUserNameToCredentialEntryList
+            .size == 1 && authenticationEntryList.isEmpty()
+    ) {
+        activeEntry = sortedUserNameToCredentialEntryList.first().sortedCredentialEntryList.first()
+    } else if (
+        sortedUserNameToCredentialEntryList
+            .isEmpty() && authenticationEntryList.size == 1
+    ) {
+        activeEntry = authenticationEntryList.first()
+    }
+    return activeEntry
+}
+
+private fun toGetScreenState(
+    providerInfoList: List<ProviderInfo>
+): GetScreenState {
+    var noLocalAccount = true
+    var remoteInfo: RemoteEntryInfo? = null
+    providerInfoList.forEach { providerInfo ->
+        if (providerInfo.credentialEntryList.isNotEmpty() ||
+            providerInfo.authenticationEntryList.isNotEmpty()) {
+            noLocalAccount = false
+        }
+        if (providerInfo.remoteEntry != null) {
+            remoteInfo = providerInfo.remoteEntry
+        }
+    }
+
+    return if (noLocalAccount && remoteInfo != null)
+        GetScreenState.REMOTE_ONLY else GetScreenState.PRIMARY_SELECTION
+}
+
+internal class CredentialEntryInfoComparatorByTypeThenTimestamp : Comparator<CredentialEntryInfo> {
+    override fun compare(p0: CredentialEntryInfo, p1: CredentialEntryInfo): Int {
+        // First prefer passkey type for its security benefits
+        if (p0.credentialType != p1.credentialType) {
+            if (CredentialType.PASSKEY == p0.credentialType) {
+                return -1
+            } else if (CredentialType.PASSKEY == p1.credentialType) {
+                return 1
+            }
+        }
+
+        // Then order by last used timestamp
+        if (p0.lastUsedTimeMillis != null && p1.lastUsedTimeMillis != null) {
+            if (p0.lastUsedTimeMillis < p1.lastUsedTimeMillis) {
+                return 1
+            } else if (p0.lastUsedTimeMillis > p1.lastUsedTimeMillis) {
+                return -1
+            }
+        } else if (p0.lastUsedTimeMillis != null) {
+            return -1
+        } else if (p1.lastUsedTimeMillis != null) {
+            return 1
+        }
+        return 0
+    }
+}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
deleted file mode 100644
index eaa2ad4..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCredentialRequest.kt
+++ /dev/null
@@ -1,74 +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.credentialmanager.jetpack.developer
-
-import android.credentials.Credential
-import android.os.Bundle
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
-
-/**
- * Base request class for registering a credential.
- *
- * @property type the credential type
- * @property data the request data in the [Bundle] format
- * @property requireSystemProvider true if must only be fulfilled by a system provider and false
- *                              otherwise
- */
-open class CreateCredentialRequest(
-    open val type: String,
-    open val credentialData: Bundle,
-    open val candidateQueryData: Bundle,
-    open val requireSystemProvider: Boolean
-) {
-    companion object {
-        @JvmStatic
-        fun createFrom(
-            type: String,
-            credentialData: Bundle,
-            candidateQueryData: Bundle,
-            requireSystemProvider: Boolean
-        ): CreateCredentialRequest {
-            return try {
-                when (type) {
-                    Credential.TYPE_PASSWORD_CREDENTIAL ->
-                        CreatePasswordRequest.createFrom(credentialData)
-                    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
-                        when (credentialData.getString(BUNDLE_KEY_SUBTYPE)) {
-                            CreatePublicKeyCredentialRequest
-                                .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST ->
-                                CreatePublicKeyCredentialRequest.createFrom(credentialData)
-                            CreatePublicKeyCredentialRequestPrivileged
-                                .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV ->
-                                CreatePublicKeyCredentialRequestPrivileged
-                                    .createFrom(credentialData)
-                            else -> throw FrameworkClassParsingException()
-                        }
-                    else -> throw FrameworkClassParsingException()
-                }
-            } catch (e: FrameworkClassParsingException) {
-                // Parsing failed but don't crash the process. Instead just output a request with
-                // the raw framework values.
-                CreateCustomCredentialRequest(
-                    type,
-                    credentialData,
-                    candidateQueryData,
-                    requireSystemProvider
-                )
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt
deleted file mode 100644
index 50da9a1..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreateCustomCredentialRequest.kt
+++ /dev/null
@@ -1,50 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * Base custom create request class for registering a credential.
- *
- * An application can construct a subtype custom request and call
- * [CredentialManager.executeCreateCredential] to launch framework UI flows to collect consent and
- * any other metadata needed from the user to register a new user credential.
- *
- * @property type the credential type determined by the credential-type-specific subclass for custom
- * use cases
- * @property credentialData the full credential creation request data in the [Bundle] format for
- * custom use cases
- * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
- * the provider during the initial candidate query stage, which should not contain sensitive user
- * credential information
- * @property requireSystemProvider true if must only be fulfilled by a system provider and false
- * otherwise
- * @throws IllegalArgumentException If [type] is empty
- * @throws NullPointerException If [type] or [credentialData] are null
- */
-open class CreateCustomCredentialRequest(
-    final override val type: String,
-    final override val credentialData: Bundle,
-    final override val candidateQueryData: Bundle,
-    @get:JvmName("requireSystemProvider")
-    final override val requireSystemProvider: Boolean
-) : CreateCredentialRequest(type, credentialData, candidateQueryData, requireSystemProvider) {
-    init {
-        require(type.isNotEmpty()) { "type should not be empty" }
-    }
-}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
deleted file mode 100644
index bf0aa8a..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePasswordRequest.kt
+++ /dev/null
@@ -1,76 +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.credentialmanager.jetpack.developer
-
-import android.credentials.Credential
-import android.os.Bundle
-
-/**
- * A request to save the user password credential with their password provider.
- *
- * @property id the user id associated with the password
- * @property password the password
- * @throws NullPointerException If [id] is null
- * @throws NullPointerException If [password] is null
- * @throws IllegalArgumentException If [password] is empty
- */
-class CreatePasswordRequest constructor(
-        val id: String,
-        val password: String,
-) : CreateCredentialRequest(
-        type = Credential.TYPE_PASSWORD_CREDENTIAL,
-        credentialData = toCredentialDataBundle(id, password),
-        // No credential data should be sent during the query phase.
-        candidateQueryData = Bundle(),
-        requireSystemProvider = false,
-) {
-
-    init {
-        require(password.isNotEmpty()) { "password should not be empty" }
-    }
-
-    companion object {
-        const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
-        const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
-
-        @JvmStatic
-        internal fun toCredentialDataBundle(id: String, password: String): Bundle {
-            val bundle = Bundle()
-            bundle.putString(BUNDLE_KEY_ID, id)
-            bundle.putString(BUNDLE_KEY_PASSWORD, password)
-            return bundle
-        }
-
-        @JvmStatic
-        internal fun toCandidateDataBundle(id: String): Bundle {
-            val bundle = Bundle()
-            bundle.putString(BUNDLE_KEY_ID, id)
-            return bundle
-        }
-
-        @JvmStatic
-        internal fun createFrom(data: Bundle): CreatePasswordRequest {
-            try {
-                val id = data.getString(BUNDLE_KEY_ID)
-                val password = data.getString(BUNDLE_KEY_PASSWORD)
-                return CreatePasswordRequest(id!!, password!!)
-            } catch (e: Exception) {
-                throw FrameworkClassParsingException()
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
deleted file mode 100644
index f3d402a..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequest.kt
+++ /dev/null
@@ -1,100 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
-
-/**
-* A request to register a passkey from the user's public key credential provider.
-*
-* @property requestJson the privileged request in JSON format in the standard webauthn web json
-* shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
-* @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
-* immediately when there is no available passkey registration offering instead of falling back to
-* discovering remote options, and false (default) otherwise
-* @throws NullPointerException If [requestJson] is null
-* @throws IllegalArgumentException If [requestJson] is empty
-*/
-class CreatePublicKeyCredentialRequest @JvmOverloads constructor(
-    val requestJson: String,
-    @get:JvmName("preferImmediatelyAvailableCredentials")
-    val preferImmediatelyAvailableCredentials: Boolean = false
-) : CreateCredentialRequest(
-    type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    credentialData = toCredentialDataBundle(requestJson, preferImmediatelyAvailableCredentials),
-    // The whole request data should be passed during the query phase.
-    candidateQueryData = toCredentialDataBundle(requestJson, preferImmediatelyAvailableCredentials),
-    requireSystemProvider = false,
-) {
-
-    init {
-        require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
-    }
-
-    /** @hide */
-    companion object {
-        const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
-            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
-        internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
-        internal const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST =
-            "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST"
-
-        @JvmStatic
-        internal fun toCredentialDataBundle(
-            requestJson: String,
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Bundle {
-            val bundle = Bundle()
-            bundle.putString(BUNDLE_KEY_SUBTYPE,
-                BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
-            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials)
-            return bundle
-        }
-
-        @JvmStatic
-        internal fun toCandidateDataBundle(
-            requestJson: String,
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Bundle {
-            val bundle = Bundle()
-            bundle.putString(BUNDLE_KEY_SUBTYPE,
-                BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST)
-            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials)
-            return bundle
-        }
-
-        @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
-        // boolean value from being returned.
-        @JvmStatic
-        internal fun createFrom(data: Bundle): CreatePublicKeyCredentialRequest {
-            try {
-                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
-                val preferImmediatelyAvailableCredentials =
-                    data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
-                return CreatePublicKeyCredentialRequest(requestJson!!,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean)
-            } catch (e: Exception) {
-                throw FrameworkClassParsingException()
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
deleted file mode 100644
index 85ab2d2..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/CreatePublicKeyCredentialRequestPrivileged.kt
+++ /dev/null
@@ -1,183 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
-
-/**
- * A privileged request to register a passkey from the user’s public key credential provider, where
- * the caller can modify the rp. Only callers with privileged permission, e.g. user’s default
- * brower, caBLE, can use this. These permissions will be introduced in an upcoming release.
- * TODO("Add specific permission info/annotation")
- *
- * @property requestJson the privileged request in JSON format in the standard webauthn web json
- * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
- * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
- * immediately when there is no available passkey registration offering instead of falling back to
- * discovering remote options, and false (default) otherwise
- * @property relyingParty the expected true RP ID which will override the one in the [requestJson],
- * where rp is defined [here](https://w3c.github.io/webauthn/#rp-id)
- * @property clientDataHash a hash that is used to verify the [relyingParty] Identity
- * @throws NullPointerException If any of [requestJson], [relyingParty], or [clientDataHash] is
- * null
- * @throws IllegalArgumentException If any of [requestJson], [relyingParty], or [clientDataHash] is
- * empty
- */
-class CreatePublicKeyCredentialRequestPrivileged @JvmOverloads constructor(
-    val requestJson: String,
-    val relyingParty: String,
-    val clientDataHash: String,
-    @get:JvmName("preferImmediatelyAvailableCredentials")
-    val preferImmediatelyAvailableCredentials: Boolean = false
-) : CreateCredentialRequest(
-    type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    credentialData = toCredentialDataBundle(
-        requestJson,
-        relyingParty,
-        clientDataHash,
-        preferImmediatelyAvailableCredentials
-    ),
-    // The whole request data should be passed during the query phase.
-    candidateQueryData = toCredentialDataBundle(
-        requestJson, relyingParty, clientDataHash, preferImmediatelyAvailableCredentials
-    ),
-    requireSystemProvider = false,
-) {
-
-    init {
-        require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
-        require(relyingParty.isNotEmpty()) { "rp must not be empty" }
-        require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
-    }
-
-    /** A builder for [CreatePublicKeyCredentialRequestPrivileged]. */
-    class Builder(
-        private var requestJson: String,
-        private var relyingParty: String,
-        private var clientDataHash: String
-    ) {
-
-        private var preferImmediatelyAvailableCredentials: Boolean = false
-
-        /**
-         * Sets the privileged request in JSON format.
-         */
-        fun setRequestJson(requestJson: String): Builder {
-            this.requestJson = requestJson
-            return this
-        }
-
-        /**
-         * Sets to true if you prefer the operation to return immediately when there is no available
-         * passkey registration offering instead of falling back to discovering remote options, and
-         * false otherwise.
-         *
-         * The default value is false.
-         */
-        @Suppress("MissingGetterMatchingBuilder")
-        fun setPreferImmediatelyAvailableCredentials(
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Builder {
-            this.preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
-            return this
-        }
-
-        /**
-         * Sets the expected true RP ID which will override the one in the [requestJson].
-         */
-        fun setRelyingParty(relyingParty: String): Builder {
-            this.relyingParty = relyingParty
-            return this
-        }
-
-        /**
-         * Sets a hash that is used to verify the [relyingParty] Identity.
-         */
-        fun setClientDataHash(clientDataHash: String): Builder {
-            this.clientDataHash = clientDataHash
-            return this
-        }
-
-        /** Builds a [CreatePublicKeyCredentialRequestPrivileged]. */
-        fun build(): CreatePublicKeyCredentialRequestPrivileged {
-            return CreatePublicKeyCredentialRequestPrivileged(
-                this.requestJson,
-                this.relyingParty, this.clientDataHash, this.preferImmediatelyAvailableCredentials
-            )
-        }
-    }
-
-    /** @hide */
-    companion object {
-        internal const val BUNDLE_KEY_RELYING_PARTY =
-            "androidx.credentials.BUNDLE_KEY_RELYING_PARTY"
-        internal const val BUNDLE_KEY_CLIENT_DATA_HASH =
-            "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
-        internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
-            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
-
-        internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
-
-        internal const val BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV =
-            "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_" +
-                    "PRIVILEGED"
-
-        @JvmStatic
-        internal fun toCredentialDataBundle(
-            requestJson: String,
-            relyingParty: String,
-            clientDataHash: String,
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Bundle {
-            val bundle = Bundle()
-            bundle.putString(
-                PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
-                BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST_PRIV
-            )
-            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putString(BUNDLE_KEY_RELYING_PARTY, relyingParty)
-            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
-            bundle.putBoolean(
-                BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials
-            )
-            return bundle
-        }
-
-        @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
-        // boolean value from being returned.
-        @JvmStatic
-        internal fun createFrom(data: Bundle): CreatePublicKeyCredentialRequestPrivileged {
-            try {
-                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
-                val rp = data.getString(BUNDLE_KEY_RELYING_PARTY)
-                val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
-                val preferImmediatelyAvailableCredentials =
-                    data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
-                return CreatePublicKeyCredentialRequestPrivileged(
-                    requestJson!!,
-                    rp!!,
-                    clientDataHash!!,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean,
-                )
-            } catch (e: Exception) {
-                throw FrameworkClassParsingException()
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt
deleted file mode 100644
index ee08e9e..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/Credential.kt
+++ /dev/null
@@ -1,27 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * Base class for a credential with which the user consented to authenticate to the app.
- *
- * @property type the credential type
- * @property data the credential data in the [Bundle] format.
- */
-open class Credential(val type: String, val data: Bundle)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
deleted file mode 100644
index fc7b7de..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialOption.kt
+++ /dev/null
@@ -1,68 +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.credentialmanager.jetpack.developer
-
-import android.credentials.Credential
-import android.os.Bundle
-
-/**
- * Base request class for getting a registered credential.
- *
- * @property type the credential type
- * @property data the request data in the [Bundle] format
- * @property requireSystemProvider true if must only be fulfilled by a system provider and false
- *                              otherwise
- */
-open class GetCredentialOption(
-    open val type: String,
-    open val requestData: Bundle,
-    open val candidateQueryData: Bundle,
-    open val requireSystemProvider: Boolean,
-) {
-    companion object {
-        @JvmStatic
-        fun createFrom(
-            type: String,
-            requestData: Bundle,
-            candidateQueryData: Bundle,
-            requireSystemProvider: Boolean
-        ): GetCredentialOption {
-            return try {
-                when (type) {
-                    Credential.TYPE_PASSWORD_CREDENTIAL ->
-                        GetPasswordOption.createFrom(requestData)
-                    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
-                        when (requestData.getString(PublicKeyCredential.BUNDLE_KEY_SUBTYPE)) {
-                            GetPublicKeyCredentialOption
-                                .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION ->
-                                GetPublicKeyCredentialOption.createFrom(requestData)
-                            GetPublicKeyCredentialOptionPrivileged
-                                .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED ->
-                                GetPublicKeyCredentialOptionPrivileged.createFrom(requestData)
-                            else -> throw FrameworkClassParsingException()
-                        }
-                    else -> throw FrameworkClassParsingException()
-                }
-            } catch (e: FrameworkClassParsingException) {
-                // Parsing failed but don't crash the process. Instead just output a request with
-                // the raw framework values.
-                GetCustomCredentialOption(
-                    type, requestData, candidateQueryData, requireSystemProvider)
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
deleted file mode 100644
index 5cb8d3b..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCredentialRequest.kt
+++ /dev/null
@@ -1,75 +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.credentialmanager.jetpack.developer
-
-/**
- * Encapsulates a request to get a user credential.
- *
- * @property getCredentialOptions the list of [GetCredentialOption] from which the user can choose
- * one to authenticate to the app
- * @throws IllegalArgumentException If [getCredentialOptions] is empty
- */
-class GetCredentialRequest constructor(
-    val getCredentialOptions: List<GetCredentialOption>,
-) {
-
-    init {
-        require(getCredentialOptions.isNotEmpty()) { "credentialRequests should not be empty" }
-    }
-
-    /** A builder for [GetCredentialRequest]. */
-    class Builder {
-        private var getCredentialOptions: MutableList<GetCredentialOption> = mutableListOf()
-
-        /** Adds a specific type of [GetCredentialOption]. */
-        fun addGetCredentialOption(getCredentialOption: GetCredentialOption): Builder {
-            getCredentialOptions.add(getCredentialOption)
-            return this
-        }
-
-        /** Sets the list of [GetCredentialOption]. */
-        fun setGetCredentialOptions(getCredentialOptions: List<GetCredentialOption>): Builder {
-            this.getCredentialOptions = getCredentialOptions.toMutableList()
-            return this
-        }
-
-        /**
-         * Builds a [GetCredentialRequest].
-         *
-         * @throws IllegalArgumentException If [getCredentialOptions] is empty
-         */
-        fun build(): GetCredentialRequest {
-            return GetCredentialRequest(getCredentialOptions.toList())
-        }
-    }
-
-    companion object {
-        @JvmStatic
-        fun createFrom(from: android.credentials.GetCredentialRequest): GetCredentialRequest {
-            return GetCredentialRequest(
-                from.getCredentialOptions.map {
-                    GetCredentialOption.createFrom(
-                        it.type,
-                        it.credentialRetrievalData,
-                        it.candidateQueryData,
-                        it.isSystemProviderRequired()
-                    )
-                }
-            )
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCustomCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCustomCredentialOption.kt
deleted file mode 100644
index 803885c..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetCustomCredentialOption.kt
+++ /dev/null
@@ -1,50 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * Allows extending custom versions of GetCredentialOptions for unique use cases.
- *
- * @property type the credential type determined by the credential-type-specific subclass
- * generated for custom use cases
- * @property requestData the request data in the [Bundle] format, generated for custom use cases
- * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
- * the provider during the initial candidate query stage, which should not contain sensitive user
- * information
- * @property requireSystemProvider true if must only be fulfilled by a system provider and false
- * otherwise
- * @throws IllegalArgumentException If [type] is empty
- * @throws NullPointerException If [requestData] or [type] is null
- */
-open class GetCustomCredentialOption(
-    final override val type: String,
-    final override val requestData: Bundle,
-    final override val candidateQueryData: Bundle,
-    @get:JvmName("requireSystemProvider")
-    final override val requireSystemProvider: Boolean
-) : GetCredentialOption(
-    type,
-    requestData,
-    candidateQueryData,
-    requireSystemProvider
-) {
-    init {
-        require(type.isNotEmpty()) { "type should not be empty" }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
deleted file mode 100644
index 2b9cfa3..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPasswordOption.kt
+++ /dev/null
@@ -1,35 +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.credentialmanager.jetpack.developer
-
-import android.credentials.Credential
-import android.os.Bundle
-
-/** A request to retrieve the user's saved application password from their password provider. */
-class GetPasswordOption : GetCredentialOption(
-        Credential.TYPE_PASSWORD_CREDENTIAL,
-        Bundle(),
-        Bundle(),
-        false,
-) {
-    companion object {
-        @JvmStatic
-        fun createFrom(data: Bundle): GetPasswordOption {
-            return GetPasswordOption()
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
deleted file mode 100644
index 2f9b249..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOption.kt
+++ /dev/null
@@ -1,85 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * A request to get passkeys from the user's public key credential provider.
- *
- * @property requestJson the privileged request in JSON format in the standard webauthn web json
- * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
- * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
- * immediately when there is no available credential instead of falling back to discovering remote
- * credentials, and false (default) otherwise
- * @throws NullPointerException If [requestJson] is null
- * @throws IllegalArgumentException If [requestJson] is empty
- */
-class GetPublicKeyCredentialOption @JvmOverloads constructor(
-    val requestJson: String,
-    @get:JvmName("preferImmediatelyAvailableCredentials")
-    val preferImmediatelyAvailableCredentials: Boolean = false,
-) : GetCredentialOption(
-    type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    requestData = toRequestDataBundle(requestJson, preferImmediatelyAvailableCredentials),
-    candidateQueryData = toRequestDataBundle(requestJson, preferImmediatelyAvailableCredentials),
-    requireSystemProvider = false
-) {
-    init {
-        require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
-    }
-
-    /** @hide */
-    companion object {
-        internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
-            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
-        internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
-        internal const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION =
-            "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION"
-
-        @JvmStatic
-        internal fun toRequestDataBundle(
-            requestJson: String,
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Bundle {
-            val bundle = Bundle()
-            bundle.putString(
-                PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
-                BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION
-            )
-            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials)
-            return bundle
-        }
-
-        @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
-        // boolean value from being returned.
-        @JvmStatic
-        internal fun createFrom(data: Bundle): GetPublicKeyCredentialOption {
-            try {
-                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
-                val preferImmediatelyAvailableCredentials =
-                    data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
-                return GetPublicKeyCredentialOption(requestJson!!,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean)
-            } catch (e: Exception) {
-                throw FrameworkClassParsingException()
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
deleted file mode 100644
index 6f4782a..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/GetPublicKeyCredentialOptionPrivileged.kt
+++ /dev/null
@@ -1,182 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * A privileged request to get passkeys from the user's public key credential provider. The caller
- * can modify the RP. Only callers with privileged permission (e.g. user's public browser or caBLE)
- * can use this. These permissions will be introduced in an upcoming release.
- * TODO("Add specific permission info/annotation")
- *
- * @property requestJson the privileged request in JSON format in the standard webauthn web json
- * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
- * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
- * immediately when there is no available credential instead of falling back to discovering remote
- * credentials, and false (default) otherwise
- * @property relyingParty the expected true RP ID which will override the one in the [requestJson],
- * where relyingParty is defined [here](https://w3c.github.io/webauthn/#rp-id) in more detail
- * @property clientDataHash a hash that is used to verify the [relyingParty] Identity
- * @throws NullPointerException If any of [requestJson], [relyingParty], or [clientDataHash]
- * is null
- * @throws IllegalArgumentException If any of [requestJson], [relyingParty], or [clientDataHash] is
- * empty
- */
-class GetPublicKeyCredentialOptionPrivileged @JvmOverloads constructor(
-    val requestJson: String,
-    val relyingParty: String,
-    val clientDataHash: String,
-    @get:JvmName("preferImmediatelyAvailableCredentials")
-    val preferImmediatelyAvailableCredentials: Boolean = false
-) : GetCredentialOption(
-    type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    requestData = toBundle(
-        requestJson,
-        relyingParty,
-        clientDataHash,
-        preferImmediatelyAvailableCredentials
-    ),
-    candidateQueryData = toBundle(
-        requestJson,
-        relyingParty,
-        clientDataHash,
-        preferImmediatelyAvailableCredentials
-    ),
-    requireSystemProvider = false,
-) {
-
-    init {
-        require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
-        require(relyingParty.isNotEmpty()) { "rp must not be empty" }
-        require(clientDataHash.isNotEmpty()) { "clientDataHash must not be empty" }
-    }
-
-    /** A builder for [GetPublicKeyCredentialOptionPrivileged]. */
-    class Builder(
-        private var requestJson: String,
-        private var relyingParty: String,
-        private var clientDataHash: String
-    ) {
-
-        private var preferImmediatelyAvailableCredentials: Boolean = false
-
-        /**
-         * Sets the privileged request in JSON format.
-         */
-        fun setRequestJson(requestJson: String): Builder {
-            this.requestJson = requestJson
-            return this
-        }
-
-        /**
-         * Sets to true if you prefer the operation to return immediately when there is no available
-         * credential instead of falling back to discovering remote credentials, and false
-         * otherwise.
-         *
-         * The default value is false.
-         */
-        @Suppress("MissingGetterMatchingBuilder")
-        fun setPreferImmediatelyAvailableCredentials(
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Builder {
-            this.preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
-            return this
-        }
-
-        /**
-         * Sets the expected true RP ID which will override the one in the [requestJson].
-         */
-        fun setRelyingParty(relyingParty: String): Builder {
-            this.relyingParty = relyingParty
-            return this
-        }
-
-        /**
-         * Sets a hash that is used to verify the [relyingParty] Identity.
-         */
-        fun setClientDataHash(clientDataHash: String): Builder {
-            this.clientDataHash = clientDataHash
-            return this
-        }
-
-        /** Builds a [GetPublicKeyCredentialOptionPrivileged]. */
-        fun build(): GetPublicKeyCredentialOptionPrivileged {
-            return GetPublicKeyCredentialOptionPrivileged(
-                this.requestJson,
-                this.relyingParty, this.clientDataHash, this.preferImmediatelyAvailableCredentials
-            )
-        }
-    }
-
-    /** @hide */
-    companion object {
-        internal const val BUNDLE_KEY_RELYING_PARTY =
-            "androidx.credentials.BUNDLE_KEY_RELYING_PARTY"
-        internal const val BUNDLE_KEY_CLIENT_DATA_HASH =
-            "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
-        internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
-            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
-        internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
-        internal const val BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED =
-            "androidx.credentials.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION" +
-                    "_PRIVILEGED"
-
-        @JvmStatic
-        internal fun toBundle(
-            requestJson: String,
-            relyingParty: String,
-            clientDataHash: String,
-            preferImmediatelyAvailableCredentials: Boolean
-        ): Bundle {
-            val bundle = Bundle()
-            bundle.putString(
-                PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
-                BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION_PRIVILEGED
-            )
-            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putString(BUNDLE_KEY_RELYING_PARTY, relyingParty)
-            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
-            bundle.putBoolean(
-                BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials
-            )
-            return bundle
-        }
-
-        @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
-        // boolean value from being returned.
-        @JvmStatic
-        internal fun createFrom(data: Bundle): GetPublicKeyCredentialOptionPrivileged {
-            try {
-                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
-                val rp = data.getString(BUNDLE_KEY_RELYING_PARTY)
-                val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
-                val preferImmediatelyAvailableCredentials =
-                    data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
-                return GetPublicKeyCredentialOptionPrivileged(
-                    requestJson!!,
-                    rp!!,
-                    clientDataHash!!,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean,
-                )
-            } catch (e: Exception) {
-                throw FrameworkClassParsingException()
-            }
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PasswordCredential.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PasswordCredential.kt
deleted file mode 100644
index 1658858..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PasswordCredential.kt
+++ /dev/null
@@ -1,55 +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.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-class PasswordCredential constructor(
-        val id: String,
-        val password: String,
-) : Credential(android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL, toBundle(id, password)) {
-
-    init {
-        require(password.isNotEmpty()) { "password should not be empty" }
-    }
-
-    /** @hide */
-    companion object {
-
-        const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
-        const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
-
-        @JvmStatic
-        internal fun toBundle(id: String, password: String): Bundle {
-            val bundle = Bundle()
-            bundle.putString(BUNDLE_KEY_ID, id)
-            bundle.putString(BUNDLE_KEY_PASSWORD, password)
-            return bundle
-        }
-
-        @JvmStatic
-        internal fun createFrom(data: Bundle): PasswordCredential {
-            try {
-                val id = data.getString(BUNDLE_KEY_ID)
-                val password = data.getString(BUNDLE_KEY_PASSWORD)
-                return PasswordCredential(id!!, password!!)
-            } catch (e: Exception) {
-                throw FrameworkClassParsingException()
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
deleted file mode 100644
index 6a81167..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/PublicKeyCredential.kt
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.credentialmanager.jetpack.developer
-
-import android.os.Bundle
-
-/**
- * Represents the user's passkey credential granted by the user for app sign-in.
- *
- * @property authenticationResponseJson the public key credential authentication response in
- * JSON format that follows the standard webauthn json format shown at
- * [this w3c link](https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson)
- * @throws NullPointerException If [authenticationResponseJson] is null. This is handled by the
- * kotlin runtime
- * @throws IllegalArgumentException If [authenticationResponseJson] is empty
- *
- * @hide
- */
-class PublicKeyCredential constructor(
-        val authenticationResponseJson: String
-) : Credential(
-        TYPE_PUBLIC_KEY_CREDENTIAL,
-        toBundle(authenticationResponseJson)
-) {
-
-    init {
-        require(authenticationResponseJson.isNotEmpty()) {
-            "authentication response JSON must not be empty" }
-    }
-    companion object {
-        /** The type value for public key credential related operations. */
-        const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
-                "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
-        /** The Bundle key value for the public key credential subtype (privileged or regular). */
-        internal const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
-        const val BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON =
-                "androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"
-
-        @JvmStatic
-        internal fun toBundle(authenticationResponseJson: String): Bundle {
-            val bundle = Bundle()
-            bundle.putString(BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON, authenticationResponseJson)
-            return bundle
-        }
-    }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/Action.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/Action.kt
deleted file mode 100644
index 1abf911..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/Action.kt
+++ /dev/null
@@ -1,100 +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.credentialmanager.jetpack.provider
-
-import android.annotation.SuppressLint
-import android.app.PendingIntent
-import android.app.slice.Slice
-import android.app.slice.SliceSpec
-import android.net.Uri
-import android.util.Log
-import java.util.Collections
-
-/**
- * UI representation for a credential entry used during the get credential flow.
- *
- * TODO: move to jetpack.
- */
-class Action constructor(
-        val title: CharSequence,
-        val subTitle: CharSequence?,
-        val pendingIntent: PendingIntent?,
-) {
-
-  init {
-    require(title.isNotEmpty()) { "title must not be empty" }
-  }
-
-  companion object {
-    private const val TAG = "Action"
-    internal const val SLICE_HINT_TITLE =
-            "androidx.credentials.provider.action.HINT_ACTION_TITLE"
-    internal const val SLICE_HINT_SUBTITLE =
-            "androidx.credentials.provider.action.HINT_ACTION_SUBTEXT"
-    internal const val SLICE_HINT_PENDING_INTENT =
-            "androidx.credentials.provider.action.SLICE_HINT_PENDING_INTENT"
-
-    @JvmStatic
-    fun toSlice(action: Action): Slice {
-      // TODO("Put the right spec and version value")
-      val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec("type", 1))
-              .addText(action.title, /*subType=*/null,
-                      listOf(SLICE_HINT_TITLE))
-              .addText(action.subTitle, /*subType=*/null,
-                      listOf(SLICE_HINT_SUBTITLE))
-      if (action.pendingIntent != null) {
-        sliceBuilder.addAction(action.pendingIntent,
-                Slice.Builder(sliceBuilder)
-                        .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
-                        .build(),
-                /*subType=*/null)
-      }
-      return sliceBuilder.build()
-    }
-
-    /**
-     * Returns an instance of [Action] derived from a [Slice] object.
-     *
-     * @param slice the [Slice] object constructed through [toSlice]
-     */
-    @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
-    @JvmStatic
-    fun fromSlice(slice: Slice): Action? {
-      // TODO("Put the right spec and version value")
-      var title: CharSequence = ""
-      var subTitle: CharSequence? = null
-      var pendingIntent: PendingIntent? = null
-
-      slice.items.forEach {
-        if (it.hasHint(SLICE_HINT_TITLE)) {
-          title = it.text
-        } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {
-          subTitle = it.text
-        } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
-          pendingIntent = it.action
-        }
-      }
-
-      return try {
-        Action(title, subTitle, pendingIntent)
-      } catch (e: Exception) {
-        Log.i(TAG, "fromSlice failed with: " + e.message)
-        null
-      }
-    }
-  }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/AuthenticationAction.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/AuthenticationAction.kt
deleted file mode 100644
index 283c7ba..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/AuthenticationAction.kt
+++ /dev/null
@@ -1,55 +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.credentialmanager.jetpack.provider
-
-import android.app.PendingIntent
-import android.app.slice.Slice
-import android.util.Log
-import androidx.annotation.VisibleForTesting
-
-/**
- * UI representation for a credential entry used during the get credential flow.
- *
- * TODO: move to jetpack.
- */
-class AuthenticationAction constructor(
-        val pendingIntent: PendingIntent
-) {
-
-
-  companion object {
-    private const val TAG = "AuthenticationAction"
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
-    internal const val SLICE_HINT_PENDING_INTENT =
-            "androidx.credentials.provider.authenticationAction.SLICE_HINT_PENDING_INTENT"
-
-    @JvmStatic
-    fun fromSlice(slice: Slice): AuthenticationAction? {
-      slice.items.forEach {
-        if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
-          return try {
-            AuthenticationAction(it.action)
-          } catch (e: Exception) {
-            Log.i(TAG, "fromSlice failed with: " + e.message)
-            null
-          }
-        }
-      }
-      return null
-    }
-  }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt
deleted file mode 100644
index 0ec91d6..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CreateEntry.kt
+++ /dev/null
@@ -1,243 +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.credentialmanager.jetpack.provider
-
-import android.annotation.SuppressLint
-import android.app.PendingIntent
-import android.app.slice.Slice
-import android.app.slice.SliceSpec
-import android.graphics.drawable.Icon
-import android.net.Uri
-import android.os.Bundle
-import android.util.Log
-import java.util.Collections
-
-/**
- * UI representation for a save entry used during the create credential flow.
- *
- * TODO: move to jetpack.
- */
-class CreateEntry internal constructor(
-        val accountName: CharSequence,
-        val pendingIntent: PendingIntent?,
-        val icon: Icon?,
-        val lastUsedTimeMillis: Long,
-        val credentialCountInformationList: List<CredentialCountInformation>,
-        val footerDescription: CharSequence?,
-) {
-
-  init {
-    require(accountName.isNotEmpty()) { "accountName must not be empty" }
-  }
-
-  /**
-   * A builder for [CreateEntry]
-   *
-   * @property accountName the name of the account where the credential will be registered
-   * @property pendingIntent the [PendingIntent] that will be fired when the user selects
-   * this entry
-   *
-   * @hide
-   */
-  class Builder constructor(
-          private val accountName: CharSequence,
-          private val pendingIntent: PendingIntent? = null
-  ) {
-
-    private var credentialCountInformationList: MutableList<CredentialCountInformation> =
-            mutableListOf()
-    private var icon: Icon? = null
-    private var lastUsedTimeMillis: Long = 0
-    private var footerDescription: CharSequence? = null
-
-    /** Adds a [CredentialCountInformation] denoting a given credential
-     * type and the count of credentials that the provider has stored for that
-     * credential type.
-     *
-     * This information will be displayed on the [CreateEntry] to help the user
-     * make a choice.
-     */
-    @Suppress("MissingGetterMatchingBuilder")
-    fun addCredentialCountInformation(info: CredentialCountInformation): Builder {
-      credentialCountInformationList.add(info)
-      return this
-    }
-
-    /** Sets a list of [CredentialCountInformation]. Each item in the list denotes a given
-     * credential type and the count of credentials that the provider has stored of that
-     * credential type.
-     *
-     * This information will be displayed on the [CreateEntry] to help the user
-     * make a choice.
-     */
-    fun setCredentialCountInformationList(infoList: List<CredentialCountInformation>): Builder {
-      credentialCountInformationList = infoList as MutableList<CredentialCountInformation>
-      return this
-    }
-
-    /** Sets an icon to be displayed with the entry on the UI */
-    fun setIcon(icon: Icon?): Builder {
-      this.icon = icon
-      return this
-    }
-
-    /** Sets the last time this account was used */
-    fun setLastUsedTimeMillis(lastUsedTimeMillis: Long): Builder {
-      this.lastUsedTimeMillis = lastUsedTimeMillis
-      return this
-    }
-
-    /** Sets the footer description of this */
-    fun setFooterDescription(footerDescription: CharSequence): Builder {
-      this.footerDescription = footerDescription
-      return this
-    }
-
-    /**
-     * Builds an instance of [CreateEntry]
-     *
-     * @throws IllegalArgumentException If [accountName] is empty
-     */
-    fun build(): CreateEntry {
-      return CreateEntry(accountName, pendingIntent, icon, lastUsedTimeMillis,
-              credentialCountInformationList, footerDescription)
-    }
-  }
-
-  companion object {
-    private const val TAG = "CreateEntry"
-    internal const val SLICE_HINT_ACCOUNT_NAME =
-            "androidx.credentials.provider.createEntry.SLICE_HINT_USER_PROVIDER_ACCOUNT_NAME"
-    internal const val SLICE_HINT_ICON =
-            "androidx.credentials.provider.createEntry.SLICE_HINT_PROFILE_ICON"
-    internal const val SLICE_HINT_CREDENTIAL_COUNT_INFORMATION =
-            "androidx.credentials.provider.createEntry.SLICE_HINT_CREDENTIAL_COUNT_INFORMATION"
-    internal const val SLICE_HINT_LAST_USED_TIME_MILLIS =
-            "androidx.credentials.provider.createEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
-    internal const val SLICE_HINT_PENDING_INTENT =
-            "androidx.credentials.provider.createEntry.SLICE_HINT_PENDING_INTENT"
-    internal const val SLICE_HINT_FOOTER_DESCRIPTION =
-            "androidx.credentials.provider.createEntry.SLICE_HINT_FOOTER_DESCRIPTION"
-
-    @JvmStatic
-    fun toSlice(createEntry: CreateEntry): Slice {
-      // TODO("Use the right type and revision")
-      val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec("type", 1))
-      sliceBuilder.addText(createEntry.accountName, /*subType=*/null,
-              listOf(SLICE_HINT_ACCOUNT_NAME))
-              .addLong(createEntry.lastUsedTimeMillis, /*subType=*/null, listOf(
-                      SLICE_HINT_LAST_USED_TIME_MILLIS))
-      if (createEntry.icon != null) {
-        sliceBuilder.addIcon(createEntry.icon, /*subType=*/null,
-                listOf(SLICE_HINT_ICON))
-      }
-
-      val credentialCountBundle = convertCredentialCountInfoToBundle(
-              createEntry.credentialCountInformationList)
-      if (credentialCountBundle != null) {
-        sliceBuilder.addBundle(convertCredentialCountInfoToBundle(
-                createEntry.credentialCountInformationList), null, listOf(
-                SLICE_HINT_CREDENTIAL_COUNT_INFORMATION))
-      }
-      if (createEntry.pendingIntent != null) {
-        sliceBuilder.addAction(createEntry.pendingIntent,
-                Slice.Builder(sliceBuilder)
-                        .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
-                        .build(),
-                /*subType=*/null)
-      }
-      if (createEntry.footerDescription != null) {
-        sliceBuilder.addText(createEntry.footerDescription, /*subType=*/null,
-                listOf(SLICE_HINT_FOOTER_DESCRIPTION))
-      }
-      return sliceBuilder.build()
-    }
-
-    /**
-     * Returns an instance of [CreateEntry] derived from a [Slice] object.
-     *
-     * @param slice the [Slice] object constructed through [toSlice]
-     */
-    @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
-    @JvmStatic
-    fun fromSlice(slice: Slice): CreateEntry? {
-      // TODO("Put the right spec and version value")
-      var accountName: CharSequence = ""
-      var icon: Icon? = null
-      var pendingIntent: PendingIntent? = null
-      var credentialCountInfo: List<CredentialCountInformation> = listOf()
-      var lastUsedTimeMillis: Long = 0
-      var footerDescription: CharSequence? = null
-
-      slice.items.forEach {
-        if (it.hasHint(SLICE_HINT_ACCOUNT_NAME)) {
-          accountName = it.text
-        } else if (it.hasHint(SLICE_HINT_ICON)) {
-          icon = it.icon
-        } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
-          pendingIntent = it.action
-        } else if (it.hasHint(SLICE_HINT_CREDENTIAL_COUNT_INFORMATION)) {
-          credentialCountInfo = convertBundleToCredentialCountInfo(it.bundle)
-        } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
-          lastUsedTimeMillis = it.long
-        } else if (it.hasHint(SLICE_HINT_FOOTER_DESCRIPTION)) {
-          footerDescription = it.text
-        }
-      }
-
-      return try {
-        CreateEntry(accountName, pendingIntent, icon,
-                lastUsedTimeMillis, credentialCountInfo, footerDescription)
-      } catch (e: Exception) {
-        Log.i(TAG, "fromSlice failed with: " + e.message)
-        null
-      }
-    }
-
-    @JvmStatic
-    internal fun convertBundleToCredentialCountInfo(bundle: Bundle?):
-            List<CredentialCountInformation> {
-      val credentialCountList = ArrayList<CredentialCountInformation>()
-      if (bundle == null) {
-        return credentialCountList
-      }
-      bundle.keySet().forEach {
-        try {
-          credentialCountList.add(
-                  CredentialCountInformation(it, bundle.getInt(it)))
-        } catch (e: Exception) {
-          Log.i(TAG, "Issue unpacking credential count info bundle: " + e.message)
-        }
-      }
-      return credentialCountList
-    }
-
-    @JvmStatic
-    internal fun convertCredentialCountInfoToBundle(
-            credentialCountInformationList: List<CredentialCountInformation>
-    ): Bundle? {
-      if (credentialCountInformationList.isEmpty()) {
-        return null
-      }
-      val bundle = Bundle()
-      credentialCountInformationList.forEach {
-        bundle.putInt(it.type, it.count)
-      }
-      return bundle
-    }
-  }
-}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialCountInformation.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialCountInformation.kt
deleted file mode 100644
index aa77b74..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialCountInformation.kt
+++ /dev/null
@@ -1,61 +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.credentialmanager.jetpack.provider
-
-import android.credentials.Credential
-import com.android.credentialmanager.jetpack.developer.PublicKeyCredential
-
-class CredentialCountInformation constructor(
-        val type: String,
-        val count: Int
-) {
-    companion object {
-        @JvmStatic
-        fun createPasswordCountInformation(count: Int): CredentialCountInformation {
-            return CredentialCountInformation(Credential.TYPE_PASSWORD_CREDENTIAL, count)
-        }
-
-        @JvmStatic
-        fun getPasswordCount(infos: List<CredentialCountInformation>): Int? {
-            return getCountForType(infos, Credential.TYPE_PASSWORD_CREDENTIAL)
-        }
-
-        @JvmStatic
-        fun createPublicKeyCountInformation(count: Int): CredentialCountInformation {
-            return CredentialCountInformation(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL, count)
-        }
-
-        @JvmStatic
-        fun getPasskeyCount(infos: List<CredentialCountInformation>): Int? {
-            return getCountForType(infos, PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
-        }
-
-        @JvmStatic
-        fun createTotalCountInformation(count: Int): CredentialCountInformation {
-            return CredentialCountInformation("TOTAL_COUNT", count)
-        }
-
-        @JvmStatic
-        fun getTotalCount(infos: List<CredentialCountInformation>): Int? {
-            return getCountForType(infos, "TOTAL_COUNT")
-        }
-
-        private fun getCountForType(infos: List<CredentialCountInformation>, type: String): Int? {
-            return infos.firstOrNull { info -> info.type == type }?.count
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntry.kt b/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntry.kt
deleted file mode 100644
index 61a104b..0000000
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/provider/CredentialEntry.kt
+++ /dev/null
@@ -1,150 +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.credentialmanager.jetpack.provider
-
-import android.annotation.SuppressLint
-import android.app.PendingIntent
-import android.app.slice.Slice
-import android.app.slice.SliceSpec
-import android.graphics.drawable.Icon
-import android.net.Uri
-import android.util.Log
-import java.util.Collections
-
-/**
- * UI representation for a credential entry used during the get credential flow.
- *
- * TODO: move to jetpack.
- */
-open class CredentialEntry constructor(
-        // TODO("Add credential type display name for both CredentialEntry & CreateEntry")
-        val type: String,
-        val typeDisplayName: CharSequence,
-        val username: CharSequence,
-        val displayName: CharSequence?,
-        val pendingIntent: PendingIntent?,
-        // TODO("Consider using Instant or other strongly typed time data type")
-        val lastUsedTimeMillis: Long,
-        val icon: Icon?,
-        var autoSelectAllowed: Boolean
-) {
-  init {
-    require(type.isNotEmpty()) { "type must not be empty" }
-    require(username.isNotEmpty()) { "type must not be empty" }
-  }
-
-  companion object {
-    private const val TAG = "CredentialEntry"
-    internal const val SLICE_HINT_TYPE_DISPLAY_NAME =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
-    internal const val SLICE_HINT_USERNAME =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_USER_NAME"
-    internal const val SLICE_HINT_DISPLAYNAME =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_CREDENTIAL_TYPE_DISPLAY_NAME"
-    internal const val SLICE_HINT_LAST_USED_TIME_MILLIS =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
-    internal const val SLICE_HINT_ICON =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PROFILE_ICON"
-    internal const val SLICE_HINT_PENDING_INTENT =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PENDING_INTENT"
-    internal const val SLICE_HINT_AUTO_ALLOWED =
-            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_ALLOWED"
-    internal const val AUTO_SELECT_TRUE_STRING = "true"
-    internal const val AUTO_SELECT_FALSE_STRING = "false"
-
-    @JvmStatic
-    internal fun toSlice(credentialEntry: CredentialEntry): Slice {
-      // TODO("Put the right revision value")
-      val autoSelectAllowed = if (credentialEntry.autoSelectAllowed) {
-        AUTO_SELECT_TRUE_STRING
-      } else {
-        AUTO_SELECT_FALSE_STRING
-      }
-      val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec(
-              credentialEntry.type, 1))
-              .addText(credentialEntry.typeDisplayName, /*subType=*/null,
-                      listOf(SLICE_HINT_TYPE_DISPLAY_NAME))
-              .addText(credentialEntry.username, /*subType=*/null,
-                      listOf(SLICE_HINT_USERNAME))
-              .addText(credentialEntry.displayName, /*subType=*/null,
-                      listOf(SLICE_HINT_DISPLAYNAME))
-              .addLong(credentialEntry.lastUsedTimeMillis, /*subType=*/null,
-                      listOf(SLICE_HINT_LAST_USED_TIME_MILLIS))
-              .addText(autoSelectAllowed, /*subType=*/null,
-                      listOf(SLICE_HINT_AUTO_ALLOWED))
-      if (credentialEntry.icon != null) {
-        sliceBuilder.addIcon(credentialEntry.icon, /*subType=*/null,
-                listOf(SLICE_HINT_ICON))
-      }
-      if (credentialEntry.pendingIntent != null) {
-        sliceBuilder.addAction(credentialEntry.pendingIntent,
-                Slice.Builder(sliceBuilder)
-                        .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
-                        .build(),
-                /*subType=*/null)
-      }
-      return sliceBuilder.build()
-    }
-
-    /**
-     * Returns an instance of [CredentialEntry] derived from a [Slice] object.
-     *
-     * @param slice the [Slice] object constructed through [toSlice]
-     */
-    @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
-    @JvmStatic
-    fun fromSlice(slice: Slice): CredentialEntry? {
-      var typeDisplayName: CharSequence? = null
-      var username: CharSequence? = null
-      var displayName: CharSequence? = null
-      var icon: Icon? = null
-      var pendingIntent: PendingIntent? = null
-      var lastUsedTimeMillis: Long = 0
-      var autoSelectAllowed = false
-
-      slice.items.forEach {
-        if (it.hasHint(SLICE_HINT_TYPE_DISPLAY_NAME)) {
-          typeDisplayName = it.text
-        } else if (it.hasHint(SLICE_HINT_USERNAME)) {
-          username = it.text
-        } else if (it.hasHint(SLICE_HINT_DISPLAYNAME)) {
-          displayName = it.text
-        } else if (it.hasHint(SLICE_HINT_ICON)) {
-          icon = it.icon
-        } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
-          pendingIntent = it.action
-        } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
-          lastUsedTimeMillis = it.long
-        } else if (it.hasHint(SLICE_HINT_AUTO_ALLOWED)) {
-          val autoSelectValue = it.text
-          if (autoSelectValue == AUTO_SELECT_TRUE_STRING) {
-            autoSelectAllowed = true
-          }
-        }
-      }
-
-      return try {
-        CredentialEntry(slice.spec!!.type, typeDisplayName!!, username!!,
-                displayName, pendingIntent,
-                lastUsedTimeMillis, icon, autoSelectAllowed)
-      } catch (e: Exception) {
-        Log.i(TAG, "fromSlice failed with: " + e.message)
-        null
-      }
-    }
-  }
-}
diff --git a/packages/EasterEgg/src/com/android/egg/neko/Cat.java b/packages/EasterEgg/src/com/android/egg/neko/Cat.java
index cd59a73..bf09bc7 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/Cat.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/Cat.java
@@ -258,7 +258,7 @@
 
         Notification.BubbleMetadata bubbs = new Notification.BubbleMetadata.Builder()
                 .setIntent(
-                        PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE))
+                        PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_MUTABLE))
                 .setIcon(notificationIcon)
                 .setSuppressNotification(false)
                 .setDesiredHeight(context.getResources().getDisplayMetrics().heightPixels)
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
index fd2aeb1..72fb5d6 100644
--- a/packages/PackageInstaller/res/values-af/strings.xml
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Program geïnstalleer."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Wil jy hierdie program installeer?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Wil jy hierdie program opdateer?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Opdaterings vir hierdie app word tans deur <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> bestuur.\n\nAs jy opdateer, sal jy toekomstige opdaterings eerder van <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> af ontvang."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Opdaterings vir hierdie app word tans deur <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> bestuur.\n\nWil jy hierdie opdatering vanaf <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> installeer?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Program nie geïnstalleer nie."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Die installering van die pakket is geblokkeer."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Program is nie geïnstalleer nie omdat pakket met \'n bestaande pakket bots."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Deïnstalleer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Deïnstallering is klaar."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Het <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> gedeïnstalleer"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Het <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon uitgevee"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Deïnstallering onsuksesvol."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Kon nie <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deïnstalleer nie."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Vee tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon uit …"</string>
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
index 4ebcd33..378770d 100644
--- a/packages/PackageInstaller/res/values-am/strings.xml
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"መተግበሪያ ተጭኗል።"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ይህን መተግበሪያ መጫን ይፈልጋሉ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ይህን መተግበሪያ ማዘመን ይፈልጋሉ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"የዚህ መተግበሪያ ዝማኔዎች አሁን በ<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> በመተዳደር ላይ ናቸው።\n\nበማዘመንዎ የወደፊት ዝማኔዎችን በምትኩ ከ<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ያገኛሉ።"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"የዚህ መተግበሪያ ዝማኔዎች አሁን በ<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> በመተዳደር ላይ ናቸው።\n\nይህን ዝማኔ ከ<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> መጫን ይፈልጋሉ።"</string>
     <string name="install_failed" msgid="5777824004474125469">"መተግበሪያ አልተጫነም።"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ጥቅሉ እንዳይጫን ታግዷል።"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"እንደ ጥቅል ያልተጫነ መተግበሪያ ከነባር ጥቅል ጋር ይጋጫል።"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በማራገፍ ላይ…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"ማራግፍ ተጠናቅቋል።"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ተራግፏል"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"የተሰረዘ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ብዜት"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"ማራገፍ አልተሳካም።"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን ማራገፍ ስኬታማ አልነበረም።"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"የተባዛ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በመሰረዝ ላይ…"</string>
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index 88fd1a5..c60f950 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"تم تثبيت التطبيق."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"هل تريد تثبيت هذا التطبيق؟"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"هل تريد تحديث هذا التطبيق؟"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"تتم إدارة تحديثات هذا التطبيق حاليًا من قِبل \"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>\".\n\nمن خلال التحديث، ستتلقّى التحديثات المتوفّرة من \"<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>\" بدلاً من ذلك."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"تتم إدارة تحديثات هذا التطبيق حاليًا من قِبل \"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>\".\n\nهل تريد تثبيت هذا التحديث من <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>\"؟"</string>
     <string name="install_failed" msgid="5777824004474125469">"التطبيق ليس مثبتًا."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"تم حظر تثبيت الحزمة."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"جارٍ إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"تمّ إلغاء تثبيت التطبيق."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"تم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"تم حذف النسخة الطبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"تعذّر إلغاء تثبيت التطبيق."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"لم يتم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> بنجاح."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"جارٍ حذف النسخة الطبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml
index 401ffdb..2b41b1e 100644
--- a/packages/PackageInstaller/res/values-as/strings.xml
+++ b/packages/PackageInstaller/res/values-as/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"এপ্ ইনষ্টল কৰা হ’ল।"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"আপুনি এই এপ্‌টো ইনষ্টল কৰিবলৈ বিচাৰেনে?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"আপুনি এই এপ্‌টো আপডে’ট কৰিবলৈ বিচাৰেনে?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"এই এপ্‌টোৰ আপডে’টসমূহ বৰ্তমান <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>এ পৰিচালনা কৰি আছে।\n\nআপডে’ট কৰিলে, আপুনি ইয়াৰ পৰিবৰ্তে <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>ৰ পৰা ভৱিষ্যত আপডে’টসমূহ পাব।"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"এই এপ্‌টোৰ আপডে’টসমূহ বৰ্তমান <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>এ পৰিচালনা কৰি আছে।\n\nআপুনি <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>ৰ পৰা অহা এই আপডে’টটো ইনষ্টল কৰিব বিচাৰেনে?"</string>
     <string name="install_failed" msgid="5777824004474125469">"এপ্ ইনষ্টল কৰা হোৱা নাই।"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"পেকেজটোৰ ইনষ্টল অৱৰোধ কৰা হৈছে।"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"এপ্‌টো ইনষ্টল কৰিব পৰা নগ\'ল কাৰণ ইয়াৰ সৈতে আগৰে পৰা থকা এটা পেকেজৰ সংঘাত হৈছে।"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰি থকা হৈছে…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"আনইনষ্টল কৰা হ’ল।"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰা হ’ল"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ৰ ক্ল’ন মচা হৈছে"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"আনইনষ্টল কৰিব পৰা নগ\'ল।"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰিব পৰা নগ\'ল।"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ৰ ক্ল’ন মচি থকা হৈছে…"</string>
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
index 7d46f9d..9e915e3 100644
--- a/packages/PackageInstaller/res/values-az/strings.xml
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Tətbiq quraşdırılıb."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Bu tətbiqi quraşdırmaq istəyirsiniz?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Bu tətbiqi güncəlləmək istəyirsiniz?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Bu tətbiq üzrə güncəlləmələr hazırda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> tərəfindən idarə olunur.\n\nGüncəlləməklə, <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> adlı mənbədən gələcək güncəlləmələri əldə edəcəksiniz."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Bu tətbiq üzrə güncəlləmələr hazırda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> tərəfindən idarə olunur.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> adlı mənbədən bu güncəlləməni quraşdırmaq istəyirsinizmi."</string>
     <string name="install_failed" msgid="5777824004474125469">"Tətbiq quraşdırılmayıb."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketin quraşdırılması blok edildi."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Bu paketin mövcud paket ilə ziddiyətinə görə tətbiq quraşdırılmadı."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinir…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Sistemdən silindi."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silindi"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klonu silinib"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Sistemdən silinmədi."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinmədi."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kopya silinir…"</string>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index 9837d15..b8dbad5 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Želite da instalirate ovu aplikaciju?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite da ažurirate ovu aplikaciju?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Ažuriranjima ove aplikacije trenutno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAko ažurirate, buduća ažuriranja ćete dobijati od vlasnika <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Ažuriranjima ove aplikacije trenutno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nŽelite li da instalirate ovo ažuriranje vlasnika <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa je blokirano."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Izbrisan je <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klon"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspelo."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Briše se klon aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index 052750f..05c24ff 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Праграма ўсталявана."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Усталяваць гэту праграму?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Абнавіць гэту праграму?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Абнаўленнямі гэтай праграмы цяпер кіруе <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nВыканаўшы гэта абнаўленне, усе наступныя вы будзеце атрымліваць ад <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Абнаўленнямі гэтай праграмы цяпер кіруе <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nВы хочаце ўсталяваць гэта абнаўленне ад <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Праграма не ўсталявана."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Усталяванне пакета заблакіравана."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Праграма не ўсталявана, таму што пакет канфліктуе з існуючым пакетам."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> выдаляецца…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Выдаленне завершана."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Выдалена: <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Выдалена копія \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Не выдалена."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Не ўдалося выдаліць <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Выдаленне клона \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index abbd499..110860b 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Приложението бе инсталирано."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Искате ли да инсталирате това приложение?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Искате ли да актуализирате това приложение?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Актуализациите на това приложение понастоящем се управляват от <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nСлед актуализирането ще получавате бъдещите актуализации от <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Актуализациите на това приложение понастоящем се управляват от <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nИскате ли да инсталирате тази актуализация от <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Приложението не бе инсталирано."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирането на пакета бе блокирано."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Деинсталирането завърши."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Деинсталирахте <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Копието на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> бе изтрито"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирането не бе успешно."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирането на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> не бе успешно."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Копието на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се изтрива…"</string>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index 6104121..16353df 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"অ্যাপটি ইনস্টল করা হয়ে গেছে।"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"আপনি কি এই অ্যাপটি ইনস্টল করতে চান?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"আপনি কি এই অ্যাপটি আপডেট করতে চান?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"এই অ্যাপের আপডেট বর্তমানে <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ম্যানেজ করছেন।\n\nআপডেট করা হলে, আপনি পরিবর্তে <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-এর থেকে ভবিষ্যতের আপডেট পাবেন।"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"বর্তমানে <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> এই অ্যাপের আপডেট ম্যানেজ করছেন।\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> থেকে আসা এই আপডেট ইনস্টল করতে চান।"</string>
     <string name="install_failed" msgid="5777824004474125469">"অ্যাপটি ইনস্টল করা হয়নি।"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ইনস্টল হওয়া থেকে প্যাকেজটিকে ব্লক করা হয়েছে।"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"আগে থেকেই থাকা একটি প্যাকেজের সাথে প্যাকেজটির সমস্যা সৃষ্টি হওয়ায় অ্যাপটি ইনস্টল করা যায়নি।"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হচ্ছে…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"আনইনস্টল করা শেষ হয়েছে।"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হয়ে গেছে"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"ক্লোনের <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> মুছে ফেলা হয়েছে"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"আনইনস্টল করা যায়নি।"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা যায়নি।"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ক্লোন মুছে ফেলা হচ্ছে…"</string>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index 2f03d02..10ed009 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Ažuriranjima ove aplikacije trenutno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAžuriranjem ćete dobivati buduća ažuriranja od <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Ažuriranjima ove aplikacije trenutno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nŽelite li instalirati ažuriranje od <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje ovog paketa je blokirano."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
index 369c33b..337e6d9 100644
--- a/packages/PackageInstaller/res/values-ca/strings.xml
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"S\'ha instal·lat l\'aplicació."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vols instal·lar aquesta aplicació?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vols actualitzar aquesta aplicació?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Actualment, <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> gestiona les actualitzacions d\'aquesta aplicació.\n\nSi l\'actualitzes, obtindràs novetats de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> en el futur."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Actualment, <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> gestiona les actualitzacions d\'aquesta aplicació.\n\nVols instal·lar aquesta actualització de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"No s\'ha instal·lat l\'aplicació."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"El paquet s\'ha bloquejat perquè no es pugui instal·lar."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"L\'aplicació no s\'ha instal·lat perquè el paquet entra en conflicte amb un d\'existent."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"S\'està desinstal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"La desinstal·lació ha finalitzat."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"S\'ha desinstal·lat <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"S\'ha suprimit el clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"No s\'ha pogut desinstal·lar."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"No s\'ha pogut desinstal·lar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"S\'està suprimint el clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 85fcfbe..33ec41c1 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikace je nainstalována."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Chcete tuto aplikaci nainstalovat?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Chcete tuto aplikaci aktualizovat?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Aktualizace této aplikace aktuálně spravuje vlastník <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nPokud ji aktualizujete, budete místo toho v budoucnu dostávat aktualizace od vlastníka <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Aktualizace této aplikace aktuálně spravuje vlastník <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nChcete nainstalovat tuto aktualizaci od vlastníka <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikaci nelze nainstalovat."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instalace balíčku byla zablokována."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikaci nelze nainstalovat, protože balíček je v konfliktu se stávajícím balíčkem."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Odinstalace byla dokončena."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> byl odinstalován"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Byl smazán klon balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Odinstalace se nezdařila."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se nezdařila."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Mazání klonu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index b2219a78..657eccb 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Appen er installeret."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du opdatere denne app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Opdateringer af denne app administreres i øjeblikket af <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nNår du opdaterer, vil du fremover få opdateringer fra <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> i stedet."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Opdateringer af denne app administreres i øjeblikket af <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVil du installere denne opdatering fra <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Appen blev ikke installeret."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Pakken blev forhindret i at blive installeret."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Afinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Afinstallationen er gennemført."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> blev afinstalleret"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klonen af <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> blev slettet"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Appen blev ikke afinstalleret."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kunne ikke afinstalleres."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Sletter klonen af <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index 0e59529..669bae6 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App wurde installiert."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Möchtest du diese App installieren?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Möchtest du diese App aktualisieren?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Updates für diese App werden momentan von <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> verwaltet.\n\nWenn du sie aktualisierst, erhältst du zukünftige Updates stattdessen von <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Updates für diese App werden momentan von <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> verwaltet.\n\nMöchtest du dieses Update von <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> installieren?"</string>
     <string name="install_failed" msgid="5777824004474125469">"App wurde nicht installiert."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Die Installation des Pakets wurde blockiert."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird deinstalliert…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Deinstallation abgeschlossen."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalliert"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Duplikat von „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ gelöscht"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Deinstallation fehlgeschlagen."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstallation von <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> fehlgeschlagen."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-Klon wird gelöscht…"</string>
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index 11cd8f4..ec0cfc7 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Η εφαρμογή εγκαταστάθηκε."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή;"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Θέλετε να ενημερώσετε αυτήν την εφαρμογή;"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Η διαχείριση των ενημερώσεων σε αυτήν την εφαρμογή πραγματοποιείται προς το παρόν από τον κάτοχο <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nΚάνοντας την ενημέρωση, θα λαμβάνετε αντ\' αυτού τις μελλοντικές ενημερώσεις από τον κάτοχο <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Η διαχείριση των ενημερώσεων σε αυτήν την εφαρμογή πραγματοποιείται προς το παρόν από τον κάτοχο <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nΘέλετε να εγκαταστήσετε αυτήν την ενημέρωση από τον κάτοχο <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Η εφαρμογή δεν εγκαταστάθηκε."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Η εγκατάσταση του πακέτου αποκλείστηκε."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή το πακέτο είναι σε διένεξη με κάποιο υπάρχον πακέτο."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Η απεγκατάσταση ολοκληρώθηκε."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Απεγκαταστάθηκε το πακέτο <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Έγινε διαγραφή κλώνου <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Μη επιτυχής απεγκατάσταση."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Μη επιτυχής απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Διαγραφή διπλότυπου εφαρμογής <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
index 7bcc90f..b718868 100644
--- a/packages/PackageInstaller/res/values-en-rAU/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App installed."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nBy updating, you\'ll get future updates from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> instead."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDo you want to install this update from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
index 1c3197d..03f24c9 100644
--- a/packages/PackageInstaller/res/values-en-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App installed."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nBy updating, you\'ll get future updates from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> instead."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDo you want to install this update from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
index 7bcc90f..b718868 100644
--- a/packages/PackageInstaller/res/values-en-rGB/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App installed."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nBy updating, you\'ll get future updates from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> instead."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDo you want to install this update from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
index 7bcc90f..b718868 100644
--- a/packages/PackageInstaller/res/values-en-rIN/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App installed."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Do you want to install this app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Do you want to update this app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nBy updating, you\'ll get future updates from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> instead."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Updates to this app are currently managed by <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDo you want to install this update from <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
index a0aaabb..a095216 100644
--- a/packages/PackageInstaller/res/values-en-rXC/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎App installed.‎‏‎‎‏‎"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎Do you want to install this app?‎‏‎‎‏‎"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎Do you want to update this app?‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎Updates to this app are currently managed by ‎‏‎‎‏‏‎<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎By updating, you\'ll get future updates from ‎‏‎‎‏‏‎<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>‎‏‎‎‏‏‏‎ instead.‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‏‎‎Updates to this app are currently managed by ‎‏‎‎‏‏‎<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Do you want to install this update from ‎‏‎‎‏‏‎<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="install_failed" msgid="5777824004474125469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎App not installed.‎‏‎‎‏‎"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎The package was blocked from being installed.‎‏‎‎‏‎"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎App not installed as package conflicts with an existing package.‎‏‎‎‏‎"</string>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 9808e2a..07485ab 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Se instaló la app."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"¿Deseas instalar esta app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"¿Deseas actualizar esta app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"En este momento, las actualizaciones de esta app están administradas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nSi continúas con la actualización, recibirás actualizaciones futuras de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"En este momento, las actualizaciones de esta app están administradas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\n¿Quieres instalar esta actualización de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"No se instaló la app."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Se bloqueó el paquete para impedir la instalación."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"No se instaló la app debido a un conflicto con un paquete."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Se completó la desinstalación."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Se desinstaló <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Se borró el clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"No se pudo completar la desinstalación."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"No se pudo desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Borrando la clonación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index de337d3..482ccf6 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplicación instalada."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"¿Quieres instalar esta aplicación?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"¿Quieres actualizar esta aplicación?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Las actualizaciones de esta aplicación las gestiona <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nSi actualizas, recibirás las futuras actualizaciones por parte de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Las actualizaciones de esta aplicación las gestiona <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\n¿Quieres instalar esta actualización de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"No se ha instalado la aplicación."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Se ha bloqueado la instalación del paquete."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"La aplicación no se ha instalado debido a un conflicto con un paquete."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Se ha completado la desinstalación."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Se ha desinstalado <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Se ha eliminado el clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"No se ha podido completar la desinstalación."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"No se ha podido desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eliminando clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index 555c8bf..71b22dba 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Rakendus on installitud."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Kas soovite selle rakenduse installida?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Kas soovite seda rakendust värskendada?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Selle rakenduse värskendusi haldab praegu <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVärskendamisel saate tulevasi värskendusi hoopis omanikult <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Selle rakenduse värskendusi haldab praegu <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nKas soovite installida omaniku <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> värskenduse."</string>
     <string name="install_failed" msgid="5777824004474125469">"Rakendus pole installitud."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketi installimine blokeeriti."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Rakendust ei installitud, kuna pakett on olemasoleva paketiga vastuolus."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Desinstallimine on lõpetatud."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Kustutati üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kloon"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Desinstallimine ebaõnnestus."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine ebaõnnestus."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klooni kustutamine …"</string>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index 1a50a26..c571020 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Instalatu da aplikazioa."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Aplikazioa instalatu nahi duzu?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Aplikazioa eguneratu nahi duzu?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> arduratzen da aplikazio hau eguneratzeaz.\n\n Eguneratuz gero, hemendik aurrera <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> arduratuko da eguneratzeez."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> arduratzen da aplikazio hau eguneratzeaz.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> bidez jasotako eguneratze hau instalatu nahi duzu?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Ez da instalatu aplikazioa."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketea instalatzeko aukera blokeatu egin da."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Ez da instalatu aplikazioa, gatazka bat sortu delako lehendik dagoen pakete batekin."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalatzen…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Desinstalatu da."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Ezabatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> paketearen klona"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Ezin izan da desinstalatu."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Ezin izan da desinstalatu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> aplikazioaren klona ezabatzen…"</string>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index 1c636c7..e9775ce 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"برنامه نصب شد."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"می‌خواهید این برنامه را نصب کنید؟"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"می‌خواهید این برنامه را به‌روزرسانی کنید؟"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"درحال‌حاضر <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> به‌روزرسانی‌های این برنامه را مدیریت می‌کند.\n\nبا به‌روز کردن، به‌روزرسانی‌های آتی را به‌جای مالک قبلی از <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> دریافت خواهید کرد."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"درحال‌حاضر <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> به‌روزرسانی‌های این برنامه را مدیریت می‌کند.\n\nمی‌خواهید این به‌روزرسانی را از <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> نصب کنید؟"</string>
     <string name="install_failed" msgid="5777824004474125469">"برنامه نصب نشد."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"از نصب شدن بسته جلوگیری شد."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"درحال حذف نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"حذف نصب انجام شد."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> را حذف نصب کرد"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"همسانه <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> حذف شد"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"حذف نصب انجام نشد."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> باموفقیت حذف نصب شد."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"درحال حذف همسانه <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
index e117dfb..058633b 100644
--- a/packages/PackageInstaller/res/values-fi/strings.xml
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Sovellus on asennettu."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Haluatko asentaa tämän sovelluksen?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Haluatko päivittää tämän sovelluksen?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> hallitsee tämän sovelluksen päivityksiä.\n\nPäivittämisen jälkeen päivityksiä hallitsee <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> hallitsee tämän sovelluksen päivityksiä.\n\nHaluatko ladata tämän päivityksen täältä: <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Sovellusta ei asennettu."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketin asennus estettiin."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Sovellusta ei asennettu, koska paketti on ristiriidassa nykyisen paketin kanssa."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Poistetaan pakettia <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Poisto valmis"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> poistettu"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Kopio (<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>) poistettu"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Poisto epäonnistui."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on poistettu."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Poistetaan kloonia (<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>)…"</string>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index 8e19690..c1c411c 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Application installée."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette application?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette application?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Les mises à jour pour cette application sont actuellement gérées par <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nEn effectuant une mise à jour, vous recevrez plutôt les futures mises à jour de la part de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Les mises à jour de cette application sont actuellement gérées par <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVoulez-vous installer cette mise à jour de la part de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du paquet a été bloquée."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Désinstallation terminée."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a bien été désinstallée"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a été supprimé"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Suppression du clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index b3e76f9..4a61196 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Application installée."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette appli ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette appli ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Les mises à jour de cette appli sont actuellement gérées par <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nEn procédant à la mise à jour, vous recevrez les futures mises à jour de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> à la place."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Les mises à jour de cette appli sont actuellement gérées par <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVoulez-vous installer cette mise à jour de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du package a été bloquée."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le package est en conflit avec un package déjà présent."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Désinstallation terminée."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a été désinstallé"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> supprimé"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Échec de la désinstallation du package <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Suppression du clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index b3d9973..6a37d7b 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Instalouse a aplicación."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Queres instalar esta aplicación?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Queres actualizar esta aplicación?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Actualmente, as actualizacións desta aplicación xestiónaas <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nSe a actualizas, as futuras actualizacións recibiralas de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Actualmente, as actualizacións desta aplicación xestiónaas <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nQueres instalar esta actualización de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Non se instalou a aplicación"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Bloqueouse a instalación do paquete."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"A aplicación non se instalou porque o paquete presenta un conflito cun paquete que xa hai."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Finalizou a desinstalación."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalouse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Eliminouse o clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Produciuse un erro na desinstalación."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"A desinstalación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> non se realizou correctamente."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eliminando clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml
index 0831270..863c1aa 100644
--- a/packages/PackageInstaller/res/values-gu/strings.xml
+++ b/packages/PackageInstaller/res/values-gu/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ઍપ્લિકેશન ઇન્સ્ટૉલ કરી."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"શું તમે આ ઍપ ઇન્સ્ટૉલ કરવા માગો છો?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"શું તમે આ ઍપ અપડેટ કરવા માગો છો?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"આ ઍપની અપડેટને હાલમાં <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> દ્વારા મેનેજ કરવામાં આવે છે.\n\nઅપડેટ કરવાથી, તમને તેના બદલે <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> તરફથી ભવિષ્યની અપડેટ પ્રાપ્ત થશે."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"આ ઍપની અપડેટને હાલમાં <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> દ્વારા મેનેજ કરવામાં આવે છે.\n\nશું તમે <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> તરફથી આ અપડેટ ઇન્સ્ટૉલ કરવા માગો છો."</string>
     <string name="install_failed" msgid="5777824004474125469">"ઍપ્લિકેશન ઇન્સ્ટૉલ કરી નથી."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"પૅકેજને ઇન્સ્ટૉલ થવાથી બ્લૉક કરવામાં આવ્યું હતું."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"પૅકેજનો અસ્તિત્વમાંના પૅકેજ સાથે વિરોધાભાસ હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને અનઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"અનઇન્સ્ટૉલ કરવાનું સમાપ્ત થયું."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> અનઇન્સ્ટૉલ કર્યું"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ની ક્લોન ડિલીટ કરવામાં આવી"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"અનઇન્સ્ટૉલ કરવું નિષ્ફળ રહ્યું."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને અનઇન્સ્ટૉલ કરવું અસફળ રહ્યું."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ની ક્લોન ડિલીટ કરી રહ્યાં છીએ…"</string>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index 43e6e4d..3339d35 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ऐप्लिकेशन इंस्‍टॉल हो गया."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"क्या आपको यह ऐप्लिकेशन इंस्टॉल करना है?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"क्या आप इस ऐप्लिकेशन को अपडेट करना चाहते हैं?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"फ़िलहाल, इस ऐप्लिकेशन के अपडेट <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> मैनेज करता है.\n\nऐप्लिकेशन अपडेट करने के बाद, नए अपडेट <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> से मिलेंगे."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"फ़िलहाल, इस ऐप्लिकेशन के अपडेट <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> मैनेज करता है.\n\nक्या यह अपडेट <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> से करवाना है."</string>
     <string name="install_failed" msgid="5777824004474125469">"ऐप्लिकेशन इंस्‍टॉल नहीं हुआ."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"पैकेज को इंस्टॉल होने से ब्लॉक किया हुआ है."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज का किसी मौजूदा पैकेज से विरोध है."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया जा रहा है…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"अनइंस्टॉल हो गया."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया गया"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> का क्लोन मिटा दिया गया है"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"अनइंस्टॉल नहीं किया जा सका."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को अनइंस्टॉल नहीं किया जा सका."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> का क्लोन मिटाया जा रहा है…"</string>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index 8e7f6fe..8961b851 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Ažuriranjima ove aplikacije trenutačno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAko je ažurirate, buduća ažuriranja primat ćete od vlasnika <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Ažuriranjima ove aplikacije trenutačno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nŽelite li instalirati ažuriranje od vlasnika <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa blokirano je."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
index 79b1f3d..db085ca 100644
--- a/packages/PackageInstaller/res/values-hu/strings.xml
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Alkalmazás telepítve."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Telepíti ezt az alkalmazást?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Frissíti ezt az alkalmazást?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Az alkalmazást érintő frissítéseket jelenleg <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> kezeli.\n\nA mostani frissítés után a jövőbeli frissítéseket helyette tőle érkeznek majd: <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Az alkalmazást érintő frissítéseket jelenleg <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> kezeli.\n\nSzeretné telepíteni a tőle származó frissítést: <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Az alkalmazás nincs telepítve."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"A csomag telepítését letiltotta a rendszer."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"A nem csomagként telepített alkalmazás ütközik egy már létező csomaggal."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása folyamatban van…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Az eltávolítás befejeződött."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása befejeződött"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klónja törölve"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Az eltávolítás sikertelen."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása nem sikerült."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Klónozott <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> törlése…"</string>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index 4b0b549..211d5bc 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Հավելվածը տեղադրված է:"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Տեղադրե՞լ այս հավելվածը:"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Թարմացնե՞լ այս հավելվածը։"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Այս հավելվածի թարմացումները ներկայումս կառավարվում են <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>-ի կողմից։\n\nԹարմացնելով՝ դուք հետագայում թարմացումներ կստանաք <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-ից։"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Այս հավելվածի թարմացումները ներկայումս կառավարվում են <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>-ի կողմից։\n\nՈւզո՞ւմ եք տեղադրել այս թարմացումը <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-ից։"</string>
     <string name="install_failed" msgid="5777824004474125469">"Հավելվածը տեղադրված չէ:"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Փաթեթի տեղադրումն արգելափակվել է:"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթն ունի հակասություն առկա փաթեթի հետ:"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվում է…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Ապատեղադրվեց:"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվեց"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> կլոնը ջնջվել է"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Չհաջողվեց ապատեղադրել:"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Չհաջողվեց ապատեղադրել <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը:"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի կրկնօրինակը ջնջվում է…"</string>
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
index a50bf0c..ed6d23f 100644
--- a/packages/PackageInstaller/res/values-in/strings.xml
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikasi terinstal."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Ingin menginstal aplikasi ini?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Ingin mengupdate aplikasi ini?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Update aplikasi ini sekarang dikelola oleh <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDengan mengupdate, Anda akan mendapatkan update mendatang dari <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Update aplikasi ini sekarang dikelola oleh <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nIngin menginstal update ini dari <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak terinstal."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paket diblokir sehingga tidak dapat diinstal."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikasi tidak diinstal karena paket ini bentrok dengan paket yang sudah ada."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Uninstal selesai."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> di-uninstal"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dihapus"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Uninstal gagal."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Gagal meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Menghapus clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
index 7bfaff4..1da54cb 100644
--- a/packages/PackageInstaller/res/values-is/strings.xml
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Forritið er uppsett."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Viltu setja upp þetta forrit?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Viltu uppfæra þetta forrit?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> stjórnar uppfærslum þessa forrits eins og er.\n\nMeð því að uppfæra færðu síðari uppfærslur frá <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> í staðinn."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> stjórnar uppfærslum þessa forrits eins og er.\n\nViltu setja upp þessa uppfærslu frá <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Forritið er ekki uppsett."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Lokað var á uppsetningu pakkans."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Forritið var ekki sett upp vegna árekstra á milli pakkans og annars pakka."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Fjarlægir <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Forritið hefur verið fjarlægt."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Fjarlægði <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Afriti af <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> var eytt"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Ekki tókst að fjarlægja forritið."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Ekki tókst að fjarlægja <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Eyðir afriti af <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index b3eb19b..c288d96 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App installata."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vuoi installare questa app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vuoi aggiornare questa app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Gli aggiornamenti a questa app sono attualmente gestiti da <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nEseguendo l\'aggiornamento, gli aggiornamenti futuri saranno forniti invece da <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Gli aggiornamenti a questa app sono attualmente gestiti da <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVuoi installare questo aggiornamento da <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"App non installata."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"È stata bloccata l\'installazione del pacchetto."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"App non installata poiché il pacchetto è in conflitto con un pacchetto esistente."</string>
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index 2542f0e..e3893d2 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"האפליקציה הותקנה."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"האם ברצונך להתקין אפליקציה זו?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"האם ברצונך לעדכן אפליקציה זו?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"העדכונים של האפליקציה הזו מנוהלים כרגע על ידי <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nלאחר העדכון הנוכחי, העדכונים העתידיים ינוהלו על ידי <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> במקום זאת."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"העדכונים של האפליקציה הזו מנוהלים כרגע על ידי <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nלהתקין את העדכון הזה של <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"האפליקציה לא הותקנה."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"החבילה נחסמה להתקנה."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"המערכת מסירה את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"הסרת ההתקנה הסתיימה."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> הוסרה"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"מחיקת השכפול של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"לא ניתן היה להסיר את ההתקנה."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"לא ניתן היה להסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"מחיקת השכפול של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> מתבצעת…"</string>
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index cacd022..fd10940 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"アプリをインストールしました。"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"このアプリをインストールしますか?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"このアプリを更新しますか?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"このアプリのアップデートは現在 <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> によって管理されています。\n\n更新すると、今後は代わりに <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> からアップデートを入手するようになります。"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"このアプリのアップデートは現在 <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> によって管理されています。\n\nこのアップデートを <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> からインストールしますか?"</string>
     <string name="install_failed" msgid="5777824004474125469">"アプリはインストールされていません。"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"パッケージのインストールはブロックされています。"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"パッケージが既存のパッケージと競合するため、アプリをインストールできませんでした。"</string>
diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml
index c100740..507a262 100644
--- a/packages/PackageInstaller/res/values-ka/strings.xml
+++ b/packages/PackageInstaller/res/values-ka/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"აპი დაინსტალირებულია."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"გნებავთ ამ აპის დაყენება?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"გსურთ ამ აპის განახლება?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ამ აპის განახლებებს ამჟამად მართავს <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nგანახლებით მომავალ განახლებებს მიიღებთ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-გან."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ამ აპის განახლებებს ამჟამად მართავს <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nგსურთ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-გან განახლების ინსტალაცია?"</string>
     <string name="install_failed" msgid="5777824004474125469">"აპი დაუინსტალირებელია."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ამ პაკეტის ინსტალაცია დაბლოკილია."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"აპი ვერ დაინსტალირდა, რადგან პაკეტი კონფლიქტშია არსებულ პაკეტთან."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"დეინსტალაცია დასრულდა."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> დეინსტალირებულია"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"წაიშალა <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> კლონი"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"დეინსტალაცია ვერ მოხერხდა."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია ვერ მოხერხდა."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> კლონის წაშლა…"</string>
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
index b973362..6e11f2a 100644
--- a/packages/PackageInstaller/res/values-kk/strings.xml
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Қолданба орнатылды."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Бұл қолданбаны орнатқыңыз келе ме?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Бұл қолданбаны жаңартқыңыз келе ме?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Бұл қолданбаны жаңартуды қазір <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> басқарады.\n\nЖаңартсаңыз, келесі жаңартуды <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> беретін болады."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Бұл қолданбаны жаңартуды қазір <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> басқарады.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> беретін жаңартуды пайдаланғыңыз келе ме?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Қолданба орнатылмады."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Пакетті орнатуға тыйым салынды."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Жаңа пакет пен бұрыннан бар пакеттің арасында қайшылық туындағандықтан, қолданба орнатылмады."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылуда…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Жою аяқталды."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылды"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоны жойылды."</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Жою мүмкін болмады."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жою сәтсіз аяқталды."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоны жойылып жатыр…"</string>
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
index 7b65679..46e2914 100644
--- a/packages/PackageInstaller/res/values-km/strings.xml
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"បាន​ដំឡើង​កម្មវិធី។"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"តើ​អ្នក​ចង់​ដំឡើង​កម្មវិធី​នេះ​ដែរទេ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"តើអ្នកចង់ដំឡើងកំណែ​កម្មវិធីនេះដែរទេ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"បច្ចុប្បន្ន ការដំឡើងកំណែកម្មវិធីនេះត្រូវបានគ្រប់គ្រងដោយ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>។\n\nតាមរយៈការដំឡើងកំណែ អ្នកនឹងទទួលបានកំណែថ្មីៗនៅពេលក្រោយពី <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ជំនួសវិញ។"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"បច្ចុប្បន្ន ការដំឡើងកំណែកម្មវិធីនេះត្រូវបានគ្រប់គ្រងដោយ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>។\n\nតើអ្នកចង់ដំឡើងកំណែថ្មីនេះពី <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ឬ។"</string>
     <string name="install_failed" msgid="5777824004474125469">"មិន​បាន​ដំឡើង​កម្មវិធីទេ។"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"កញ្ចប់ត្រូវបានទប់ស្កាត់​មិន​ឱ្យ​ដំឡើង។"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់កម្មវិធីមិនត្រូវគ្នាជាមួយកញ្ចប់ដែលមានស្រាប់។"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"កំពុងលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"បាន​បញ្ចប់​ការ​លុប។"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"បានលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"ក្លូន <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ដែលបានលុប"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"មិន​អាច​លុប​បានទេ។"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"មិនអាចលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> បានទេ។"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"កំពុងលុបក្លូន <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
index ab00502..fe8144e 100644
--- a/packages/PackageInstaller/res/values-kn/strings.xml
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ನೀವು ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ನೀವು ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ಈ ಆ್ಯಪ್‌ನ ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ಪ್ರಸ್ತುತ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ಅವರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ.\n\nಅಪ್‌ಡೇಟ್ ಮಾಡುವುದರಿಂದ, ಬದಲಿಗೆ ನೀವು ಭವಿಷ್ಯದ ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ಅವರಿಂದ ಪಡೆಯುತ್ತೀರಿ."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ಈ ಆ್ಯಪ್‌ನ ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ಪ್ರಸ್ತುತ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ಅವರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ.\n\nನೀವು <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ಅವರ ಈ ಅಪ್‌ಡೇಟ್ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುವಿರಾ."</string>
     <string name="install_failed" msgid="5777824004474125469">"ಆ್ಯಪ್‌ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿಲ್ಲ."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವ ಪ್ಯಾಕೇಜ್‌ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ಪ್ಯಾಕೇಜ್‌ನಂತೆ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿರುವ ಆ್ಯಪ್‌ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಪ್ಯಾಕೇಜ್ ಜೊತೆಗೆ ಸಂಘರ್ಷವಾಗುತ್ತದೆ."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
     <string name="uninstall_done" msgid="439354138387969269">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಪೂರ್ಣಗೊಂಡಿದೆ."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿದೆ"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಕ್ಲೋನ್ ಅನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ವಿಫಲವಾಗಿದೆ."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವಿಕೆ ಯಶಸ್ವಿಯಾಗಿಲ್ಲ."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಕ್ಲೋನ್ ಅನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
index c401430..4bfa3cc 100644
--- a/packages/PackageInstaller/res/values-ko/strings.xml
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"앱이 설치되었습니다."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"이 앱을 설치하시겠습니까?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"이 앱을 업데이트하시겠습니까?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"이 앱 업데이트는 현재 <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>에서 관리합니다.\n\n업데이트할 경우 대신 <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>에서 향후 업데이트를 제공합니다."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"이 앱 업데이트는 현재 <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>에서 관리합니다.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>에서 제공하는 업데이트를 설치하시겠습니까?"</string>
     <string name="install_failed" msgid="5777824004474125469">"앱이 설치되지 않았습니다."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"패키지 설치가 차단되었습니다."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"패키지가 기존 패키지와 충돌하여 앱이 설치되지 않았습니다."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 제거 중…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"제거를 완료했습니다."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>를 제거했습니다."</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론 삭제됨"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"제거하지 못했습니다."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거하지 못했습니다."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론 삭제 중…"</string>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index d3d82c3..5888b7b 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Колдонмо орнотулду."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Бул колдонмону орнотоюн деп жатасызбы?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Бул колдонмону жаңыртайын деп жатасызбы?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Бул колдонмонун жаңыртууларын учурда <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> тескеп жатат.\n\nЖаңыртуу менен келечектеги жаңыртууларды анын ордуна <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> жөнөтүп калат."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Бул колдонмонун жаңыртууларын учурда <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> тескеп жатат.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> жөнөткөн жаңыртуунун чыгарып саласызбы?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Колдонмо орнотулган жок."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Топтомду орнотууга болбойт."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылууда…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Чыгарылып салынды."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылып салынды"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клону өчүрүлдү"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Чыгарылып салынган жок."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылып салынган жок."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клону өчүрүлүүдө…"</string>
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
index 7ab33a9..f9866b0 100644
--- a/packages/PackageInstaller/res/values-lo/strings.xml
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ຕິດຕັ້ງແອັບແລ້ວ."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ທ່ານຕ້ອງການຕິດຕັ້ງແອັບນີ້ບໍ່?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ທ່ານຕ້ອງການອັບເດດແອັບນີ້ບໍ່?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ໃນຕອນນີ້ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ເປັນຜູ້ຈັດການການອັບເດດແອັບນີ້.\n\nຫາກອັບເດດ, ທ່ານຈະໄດ້ຮັບການອັບເດດໃນອະນາຄົດຈາກ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ແທນ."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ໃນຕອນນີ້ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ເປັນຜູ້ຈັດການການອັບເດດແອັບນີ້.\n\nທ່ານຕ້ອງການຕິດຕັ້ງການອັບເດດນີ້ຈາກ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ຫຼືບໍ່."</string>
     <string name="install_failed" msgid="5777824004474125469">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເທື່ອ."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ແພັກ​ເກດ​ຖືກບ​ລັອກ​ບໍ່​ໃຫ້​ໄດ້​ຮັບ​ການ​ຕິດ​ຕັ້ງ."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແພັກເກດຂັດແຍ່ງກັບແພັກເກດທີ່ມີຢູ່ກ່ອນແລ້ວ."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"ກຳລັງຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"ຖອນການຕິດຕັ້ງສຳເລັດແລ້ວ."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ແລ້ວ"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"ລຶບສຳເນົາ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"ຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ບໍ່ສຳເລັດ."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"ກຳລັງລຶບ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ໂຄລນ…"</string>
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
index 9ffa09c..9bf018b 100644
--- a/packages/PackageInstaller/res/values-lt/strings.xml
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Programa įdiegta."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Ar norite įdiegti šią programą?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Ar norite atnaujinti šią programą?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Šios programos naujinius šiuo metu valdo <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAtnaujinę būsimus naujinius gausite iš <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Šios programos naujinius šiuo metu valdo <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAr norite įdiegti šį naujinį iš <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Programa neįdiegta."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketas užblokuotas ir negali būti įdiegtas."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Programa neįdiegta, nes paketas nesuderinamas su esamu paketu."</string>
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
index c3e1a88..823858c 100644
--- a/packages/PackageInstaller/res/values-lv/strings.xml
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Lietotne ir instalēta."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vai vēlaties instalēt šo lietotni?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vai vēlaties atjaunināt šo lietotni?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Šīs lietotnes atjauninājumus pašlaik pārvalda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nJa veiksiet atjaunināšanu, turpmākos atjauninājumus nodrošinās <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Šīs lietotnes atjauninājumus pašlaik pārvalda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVai vēlaties instalēt atjauninājumu, ko nodrošina <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Lietotne nav instalēta."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Pakotnes instalēšana tika bloķēta."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Lietotne netika instalēta, jo pastāv pakotnes konflikts ar esošu pakotni."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Atinstalēšana ir pabeigta."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Lietotne <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ir atinstalēta"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Izdzēsts lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klons"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Atinstalēšana neizdevās."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana nebija sekmīga."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klona dzēšana…"</string>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index e100257..6135e65 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Апликацијата е инсталирана."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Дали сакате да ја инсталирате апликацијава?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Дали сакате да ја ажурирате апликацијава?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Ажурирањата на апликацијава тековно се управуваат од <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nСо ажурирање, ќе добивате ажурирања во иднината од <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Ажурирањата на апликацијава тековно се управуваат од <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nДали сакате да го инсталирате ажурирањево од <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Апликацијата не е инсталирана."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирањето на пакетот е блокирано."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Апликација што не е инсталирана како пакет е во конфликт со постоечки пакет."</string>
diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml
index ca1ae38..43cac7a 100644
--- a/packages/PackageInstaller/res/values-ml/strings.xml
+++ b/packages/PackageInstaller/res/values-ml/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തു."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യണോ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ഈ ആപ്പ് അപ്‌ഡേറ്റ് ചെയ്യണോ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ഈ ആപ്പിലെ അപ്‌ഡേറ്റുകൾ നിലവിൽ മാനേജ് ചെയ്യുന്നത് <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ആണ്.\n\nഅപ്‌ഡേറ്റ് ചെയ്യുന്നതിലൂടെ, പകരം നിങ്ങൾക്ക് ഭാവി അപ്‌ഡേറ്റുകൾ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> എന്നയാളിൽ നിന്ന് ലഭിക്കും."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ഈ ആപ്പിലെ അപ്‌ഡേറ്റുകൾ നിലവിൽ മാനേജ് ചെയ്യുന്നത് <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ആണ്.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> എന്നയാളിൽ നിന്ന് ഈ അപ്ഡേറ്റ് ഇൻസ്‌റ്റാൾ ചെയ്യാൻ നിങ്ങൾ താൽപ്പര്യപ്പെടുന്നുണ്ടോ."</string>
     <string name="install_failed" msgid="5777824004474125469">"ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തിട്ടില്ല."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"പാക്കേജ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് ബ്ലോക്ക് ചെയ്‌തു."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"പാക്കേജിന് നിലവിലുള്ള പാക്കേജുമായി പൊരുത്തക്കേടുള്ളതിനാൽ, ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തില്ല."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"അൺ ഇൻസ്‌റ്റാൾ ചെയ്യൽ പൂർത്തിയായി."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്‌റ്റാൾ ചെയ്‌തു"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ക്ലോൺ ഇല്ലാതാക്കി"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"അൺ ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ക്ലോൺ ചെയ്യൽ ഇല്ലാതാക്കുന്നു…"</string>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index 3be98b5..52bca70 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Аппыг суулгасан."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Та энэ аппыг суулгахыг хүсэж байна уу?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Та энэ аппыг шинэчлэхийг хүсэж байна уу?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Энэ аппын шинэчлэлтийг одоогоор <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>-с удирддаг.\n\nШинэчилснээр та цаашдын шинэчлэлтийг оронд нь <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-с авна."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Энэ аппын шинэчлэлтийг одоогоор <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>-с удирддаг.\n\nТа <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>-н энэ шинэчлэлтийг суулгахыг хүсэж байна уу?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Аппыг суулгаагүй."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Багц суулгахыг блоклосон байна."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Багц одоо байгаа багцтай тохирохгүй байгаа тул аппыг суулгаж чадсангүй."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж байна…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Устгаж дууслаа."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгасан"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоныг устгасан"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Устгах амжилтгүй боллоо."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгах амжилтгүй боллоо."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоныг устгаж байна…"</string>
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index ffd6610..8a4ff44 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"अ‍ॅप इंस्टॉल झाले."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"तुम्हाला हे ॲप इंस्टॉल करायचे आहे का?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"तुम्हाला हे ॲप अपडेट करायचे आहे का?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"या अ‍ॅपसाठीचे अपडेट सध्या <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> द्वारे व्यवस्थापित केले जात आहेत.\n\nत्या ऐवजी, अपडेट केल्याने, तुम्हाला भविष्यातील अपडेट <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> कडून मिळतील."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"या अ‍ॅपसाठीचे अपडेट सध्या <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> द्वारे व्यवस्थापित केले जात आहेत.\n\nतुम्हाला हे अपडेट <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> कडून इंस्टॉल करायचे आहे का."</string>
     <string name="install_failed" msgid="5777824004474125469">"अ‍ॅप इंस्टॉल झाले नाही."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"पॅकेज इंस्टॉल होण्यापासून ब्लॉक केले होते."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अ‍ॅप इंस्टॉल झाले नाही."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करत आहे…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"अनइंस्टॉल पूर्ण झाले."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल केले"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> क्लोन हटवला आहे"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"अनइंस्टॉल करता आले नाही."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करता आले नाही."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"क्लोन <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> हटवत आहे…"</string>
diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml
index 1c369bc..13531bd 100644
--- a/packages/PackageInstaller/res/values-ms/strings.xml
+++ b/packages/PackageInstaller/res/values-ms/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikasi dipasang."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Adakah anda ingin memasang aplikasi ini?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Adakah anda mahu mengemas kini apl ini?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Kemaskinian pada apl ini diuruskan oleh <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> pada masa ini.\n\nDengan membuat pengemaskinian, anda akan mendapat kemaskinian akan datang daripada <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Kemaskinian pada apl ini diuruskan oleh <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> pada masa ini.\n\nAdakah anda mahu memasang kemaskinian ini daripada <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak dipasang."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Pakej ini telah disekat daripada dipasang."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Apl tidak dipasang kerana pakej bercanggah dengan pakej yang sedia ada."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Nyahpasang selesai."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dinyahpasang"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dipadamkan"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Penyahpasangan tidak berjaya."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Tidak berjaya menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Memadamkan klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml
index 08135d2..4dbf3fc 100644
--- a/packages/PackageInstaller/res/values-my/strings.xml
+++ b/packages/PackageInstaller/res/values-my/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"အက်ပ်ထည့်သွင်းပြီးပါပြီ။"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ဤအက်ပ်ကို ထည့်သွင်းလိုသလား။"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ဤအက်ပ်ကို အပ်ဒိတ်လုပ်လိုသလား။"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ဤအက်ပ်ရှိ အပ်ဒိတ်များကို လောလောဆယ်တွင် <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> က စီမံထားသည်။\n\n၎င်းအစား အပ်ဒိတ်လုပ်ခြင်းဖြင့် <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ထံမှ နောက်အပ်ဒိတ်များ ရရှိပါမည်။"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ဤအက်ပ်ရှိ အပ်ဒိတ်များကို လောလောဆယ်တွင် <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> က စီမံထားသည်။\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ထံမှ ဤအပ်ဒိတ်ကို ထည့်သွင်းလိုပါသလား။"</string>
     <string name="install_failed" msgid="5777824004474125469">"အက်ပ်မထည့်သွင်းရသေးပါ"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ပက်ကေ့ဂျ်ထည့်သွင်းခြင်းကို ပိတ်ထားသည်။"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် လက်ရှိပက်ကေ့ဂျ်နှင့် တိုက်နေသည်။"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားနေပါသည်…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"ဖယ်ရှားပြီးပါပြီ။"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားလိုက်ပါပြီ"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ပုံတူပွားကို ဖျက်လိုက်ပါပြီ"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"ဖယ်ရှား၍ မရပါ။"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှား၍မရပါ။"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ပုံတူပွားကို ဖျက်နေသည်…"</string>
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
index ad49d525..8ec94e0 100644
--- a/packages/PackageInstaller/res/values-nb/strings.xml
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Appen er installert."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne appen?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du oppdatere denne appen?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Oppdateringer for denne appen administreres nå av <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVed å oppdatere får du fremtidige oppdateringer fra <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> i stedet."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Oppdateringer for denne appen administreres nå av <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVil du installere denne oppdateringen fra <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Appen ble ikke installert."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Pakken er blokkert fra å bli installert."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Appen ble ikke installert fordi pakken er i konflikt med en eksisterende pakke."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Avinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Avinstalleringen er fullført."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Avinstallerte <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klonen av <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> er slettet"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Avinstalleringen mislyktes."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Kunne ikke avinstallere <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Sletter <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-klonen …"</string>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index 034c6f6..e763ae1 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"एप इन्स्टल गरियो।"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"तपाईं यो एप इन्स्टल गर्न चाहनुहुन्छ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"तपाईं यो एप अपडेट गर्न चाहनुहुन्छ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ले हाल यो एपका अपडेटहरू व्यवस्थापन गर्छ।\n\nतपाईंले अपडेट गर्नुभयो भने तपाईं भविष्यमा <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> बाट अपडेटहरू प्राप्त गर्नु हुने छ।"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ले हाल यो एपका अपडेटहरू व्यवस्थापन गर्छ।\n\nतपाईं <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ले उपलब्ध गराएको यो अपडेट इन्स्टल गर्न चाहनुहुन्छ?"</string>
     <string name="install_failed" msgid="5777824004474125469">"एप स्थापना गरिएन।"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"यो प्याकेज स्थापना गर्ने क्रममा अवरोध गरियो।"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको एप विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्दै…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"स्थापना रद्द गर्ने काम सम्पन्न भयो।"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइन्स्टल गरियो"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> क्लोन मेटाइयो"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"स्थापना रद्द गर्न सकिएन।"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्ने कार्य असफल भयो।"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> क्लोन मेटाइँदै छ…"</string>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index 1a73282..c0a3c8e 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App geïnstalleerd."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Wil je deze app installeren?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Wil je deze app updaten?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Updates voor deze app worden momenteel beheerd door <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAls je updatet, krijg je volgende updates in plaats daarvan van <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Updates voor deze app worden momenteel beheerd door <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nWil je deze update van <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> installeren?"</string>
     <string name="install_failed" msgid="5777824004474125469">"App niet geïnstalleerd."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"De installatie van het pakket is geblokkeerd."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"App die niet is geïnstalleerd als pakket conflicteert met een bestaand pakket."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderen…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Verwijdering voltooid."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderd"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Kloon van <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderd"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Verwijdering mislukt."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kan niet worden verwijderd."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon verwijderen…"</string>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index 95ad470..965c7d8a 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ଆପ ଇନଷ୍ଟଲ ହୋଇଗଲା।"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ଆପଣ ଏହି ଆପକୁ ଇନଷ୍ଟଲ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି କି?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ଆପଣ ଏହି ଆପକୁ ଅପଡେଟ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି କି?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ଏହି ଆପରେ ଅପଡେଟଗୁଡ଼ିକ ବର୍ତ୍ତମାନ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି।\n\nଅପଡେଟ କରି, ଆପଣ ଏହା ପରିବର୍ତ୍ତେ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>ରୁ ଭବିଷ୍ୟତର ଅପଡେଟଗୁଡ଼ିକ ପାଇବେ।"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ଏହି ଆପରେ ଅପଡେଟଗୁଡ଼ିକ ବର୍ତ୍ତମାନ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି।\n\nଆପଣ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>ରୁ ଏହି ଅପଡେଟ ଇନଷ୍ଟଲ କରିବାକୁ ଚାହାଁନ୍ତି?"</string>
     <string name="install_failed" msgid="5777824004474125469">"ଆପ୍‍ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ।"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ଏହି ପ୍ୟାକେଜ୍‌କୁ ଇନଷ୍ଟଲ୍‍ କରାଯିବାରୁ ଅବରୋଧ କରାଯାଇଥିଲା।"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ପୂର୍ବରୁ ଥିବା ପ୍ୟାକେଜ୍‍ ସହ ଏହି ପ୍ୟାକେଜ୍‌ର ସମସ୍ୟା ଉପୁଯିବାରୁ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ ହୋଇପାରିଲା ନାହିଁ।"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଉଛି…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"ଅନଇନଷ୍ଟଲ୍‌ ହୋଇଗଲା।"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>କୁ ଅନଇନଷ୍ଟଲ୍‌ କରାଗଲା"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ର କ୍ଲୋନକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"ଅନଇନଷ୍ଟଲ୍‌ କରିହେଲା ନାହିଁ।"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍‍ କରିବା ସଫଳ ହେଲାନାହିଁ।"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> କ୍ଲୋନକୁ ଡିଲିଟ କରାଯାଉଛି…"</string>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index 9e6b9b8..2a3068c 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ਐਪ ਸਥਾਪਤ ਕੀਤੀ ਗਈ।"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ਫ਼ਿਲਹਾਲ ਇਸ ਐਪ ਦੇ ਅੱਪਡੇਟਾਂ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਅੱਪਡੇਟ ਕਰਨ ਨਾਲ, ਇਸਦੀ ਬਜਾਏ ਤੁਹਾਨੂੰ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ਤੋਂ ਭਵਿੱਖੀ ਅੱਪਡੇਟ ਪ੍ਰਾਪਤ ਹੋਣਗੇ।"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ਫ਼ਿਲਹਾਲ ਇਸ ਐਪ ਦੇ ਅੱਪਡੇਟਾਂ ਦਾ ਪ੍ਰਬੰਧਨ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।\n\nਕੀ ਤੁਸੀਂ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ਵੱਲੋਂ ਇਸ ਅੱਪਡੇਟ ਨੂੰ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ।"</string>
     <string name="install_failed" msgid="5777824004474125469">"ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ਪੈਕੇਜ ਨੂੰ ਸਥਾਪਤ ਹੋਣ ਤੋਂ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ਪੈਕੇਜ ਦੇ ਇੱਕ ਮੌਜੂਦਾ ਪੈਕੇਜ ਨਾਲ ਵਿਵਾਦ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"ਅਣਸਥਾਪਤ ਕਰਨਾ ਮੁਕੰਮਲ ਹੋਇਆ।"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਗਿਆ"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਕਲੋਨ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"ਅਣਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ।"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ।"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਦੇ ਕਲੋਨ ਨੂੰ ਮਿਟਾਇਆ ਜਾ ਰਿਹਾ ਹੈ…"</string>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index 6784325..dc4e0c9 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikacja została zainstalowana."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Zainstalować tę aplikację?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Zaktualizować tę aplikację?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Aktualizacjami tej aplikacji zarządza obecnie <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nJeśli pobierzesz aktualizację, przyszłe aktualizacje będzie zapewniać <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Aktualizacjami tej aplikacji zarządza obecnie <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nChcesz zainstalować tę aktualizację ze źródła <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikacja nie została zainstalowana."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instalacja pakietu została zablokowana."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacja nie została zainstalowana, bo powoduje konflikt z istniejącym pakietem."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalowuję <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Odinstalowywanie zakończone."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Odinstalowano aplikację <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Usunięto klon aplikacji <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Nie udało się odinstalować."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Nie udało się odinstalować pakietu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Usuwam klona aplikacji <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
index 8514aeb..a5ee82b 100644
--- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App instalado."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Quer instalar esse app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Quer atualizar esse app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"No momento, as atualizações deste app são gerenciadas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAo atualizar, você receberá as atualizações futuras de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"No momento, as atualizações deste app são gerenciadas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nGostaria de instalar esta atualização de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"O clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi excluído"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Falha na desinstalação."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Excluindo o clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index 248c366..9e80a97 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App instalada."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Instalar esta app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Pretende atualizar esta app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Atualmente, as atualizações desta app são geridas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAo atualizar, vai obter atualizações futuras de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Atualmente, as atualizações desta app são geridas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nQuer instalar esta atualização de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplicação não instalada."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Foi bloqueada a instalação do pacote."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"A app não foi instalada porque o pacote entra em conflito com um pacote existente."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"A desinstalar a app <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"A app <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi desinstalada"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> apagado"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Desinstalação sem êxito."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha ao desinstalar a app <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"A apagar o clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
index 8514aeb..a5ee82b 100644
--- a/packages/PackageInstaller/res/values-pt/strings.xml
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"App instalado."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Quer instalar esse app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Quer atualizar esse app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"No momento, as atualizações deste app são gerenciadas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAo atualizar, você receberá as atualizações futuras de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"No momento, as atualizações deste app são gerenciadas por <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nGostaria de instalar esta atualização de <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"O clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi excluído"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Falha na desinstalação."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Excluindo o clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
index 2dc2b0c..09693bf 100644
--- a/packages/PackageInstaller/res/values-ro/strings.xml
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplicație instalată."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vrei să instalezi această aplicație?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vrei să actualizezi această aplicație?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Actualizările acestei aplicații sunt gestionate de <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDacă actualizezi, vei primi actualizări de la <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Actualizările acestei aplicații sunt gestionate de <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVrei să instalezi această actualizare de la <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplicația nu a fost instalată."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instalarea pachetului a fost blocată."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplicația nu a fost instalată deoarece pachetul intră în conflict cu un pachet existent."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Se dezinstalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Dezinstalare finalizată."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> s-a dezinstalat"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Clona pentru <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a fost ștearsă"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Dezinstalare nefinalizată."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nu s-a putut dezinstala."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Se șterge clona <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index e811b4e..957f294 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Приложение установлено."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Установить приложение?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Обновить приложение?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"В настоящее время обновлениями этого приложения управляет <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nЕсли вы установите обновление, то все последующие будете получать от <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"В настоящее время обновлениями этого приложения управляет <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nВы хотите установить это обновление от <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Приложение не установлено."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Установка пакета заблокирована."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Приложение не установлено, так как оно конфликтует с другим пакетом."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Удаление приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Удаление завершено."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удалено."</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Клон приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удален."</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"При удалении произошла ошибка."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Не удалось удалить приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Удаление клона пакета \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
index dfd88ef..cfe29cb 100644
--- a/packages/PackageInstaller/res/values-si/strings.xml
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"යෙදුම ස්ථාපනය කර ඇත."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"මෙම යෙදුම ස්ථාපනය කිරීමට ඔබට අවශ්‍යද?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"ඔබට මෙම යෙදුම යාවත්කාලීන කිරීමට අවශ්‍යද?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"මෙම යෙදුම වෙත යාවත්කාලීන කිරීම් දැනට <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> විසින් කළමනාකරණය කරනු ලැබේ.\n\nයාවත්කාලීන කිරීමෙන්, ඔබට <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> වෙතින් අනාගත යාවත්කාලීන ලැබෙනු ඇත."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"මෙම යෙදුම වෙත යාවත්කාලීන කිරීම් දැනට <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> විසින් කළමනාකරණය කරනු ලැබේ.\n\nඔබට <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> වෙතින් මෙම යාවත්කාලීනය ස්ථාපනය කිරීමට අවශ්‍ය ද?"</string>
     <string name="install_failed" msgid="5777824004474125469">"යෙදුම ස්ථාපනය කර නැත."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"මෙම පැකේජය ස්ථාපනය කිරීම අවහිර කරන ලදි."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"පැකේජය දැනට පවතින පැකේජයක් සමග ගැටෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරමින්…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"අස්ථාපනය කිරීම අවසානයි."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරන ලදී"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ක්ලෝනය මකන ලදි"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"අස්ථාපනය කිරිම අසාර්ථක විය."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කිරීම සාර්ථකයි."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ක්ලෝනය මකමින්…"</string>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index 8620d60..f4d5631 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikácia bola nainštalovaná."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Chcete túto aplikáciu nainštalovať?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Chcete túto aplikáciu aktualizovať?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Aktualizácie tejto aplikácie momentálne spravuje vlastník <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nPo aktualizovaní budete namiesto toho získavať budúce aplikácie od vlastníka <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Aktualizácie tejto aplikácie momentálne spravuje vlastník <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nChcete túto aktualizáciu nainštalovať od vlastníka <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikácia nebola nainštalovaná."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Inštalácia balíka bola zablokovaná."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikácia sa nenainštalovala, pretože balík je v konflikte s existujúcim balíkom."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Prebieha odinštalovanie balíka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Odinštalovanie bolo dokončené."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odinštalovaný"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klon balíka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odstránený"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Nepodarilo sa odinštalovať."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa nepodarilo odinštalovať."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa odstraňuje…"</string>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index f083ec2..f12935e 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikacija je nameščena."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Ali želite namestiti to aplikacijo?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Ali želite posodobiti to aplikacijo?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Posodobitve te aplikacije trenutno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nČe posodobite, bo pošiljatelj prihodnjih posodobitev <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Posodobitve te aplikacije trenutno upravlja <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nAli želite namestiti to posodobitev, ki jo je poslal <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikacija ni nameščena."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Namestitev paketa je bila blokirana."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija ni bila nameščena, ker je paket v navzkrižju z obstoječim paketom."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Odstranitev je končana."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena."</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klonirani paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je izbrisan"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Odstranitev ni uspela."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Brisanje kloniranega paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
index 271a7b3..f58efea 100644
--- a/packages/PackageInstaller/res/values-sq/strings.xml
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Aplikacioni u instalua."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Dëshiron ta instalosh këtë aplikacion?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Dëshiron ta përditësosh këtë aplikacion?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Përditësimet për këtë aplikacion menaxhohen aktualisht nga <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDuke e përditësuar, përditësimet në të ardhmen do t\'i marrësh nga <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Përditësimet për këtë aplikacion menaxhohen aktualisht nga <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nDëshiron ta instalosh këtë përditësim nga <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Aplikacioni nuk u instalua."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Instalimi paketës u bllokua."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacioni nuk u instalua pasi paketa është në konflikt me një paketë ekzistuese."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> po çinstalohet…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Çinstalimi përfundoi."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> u çinstalua"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"U fshi kloni i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Çinstalimi nuk pati sukses."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Çinstalimi i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nuk u krye me sukses."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Po fshihet kloni i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
index 3ac1995..2bfcf65 100644
--- a/packages/PackageInstaller/res/values-sr/strings.xml
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Апликација је инсталирана."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Желите да инсталирате ову апликацију?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Желите да ажурирате ову апликацију?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Ажурирањима ове апликације тренутно управља <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nАко ажурирате, будућа ажурирања ћете добијати од власника <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Ажурирањима ове апликације тренутно управља <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nЖелите ли да инсталирате ово ажурирање власника <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Апликација није инсталирана."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирање пакета је блокирано."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Деинсталирање је завршено."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Апликација <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> је деинсталирана"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Избрисан је <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клон"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирање није успело."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирање апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> није успело."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Брише се клон апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index 8681392..cb12c91 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Appen har installerats."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Vill du installera den här appen?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Vill du uppdatera den här appen?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Uppdateringar av den här appen hanteras för närvarande av <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nNär du uppdaterar får du i stället uppdateringar från <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Uppdateringar av den här appen hanteras för närvarande av <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nVill du installera den här uppdateringen från <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Appen har inte installerats."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketet har blockerats för installation."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> avinstalleras …"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Avinstallationen har slutförts."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> har avinstallerats"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klonen <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> har raderats"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Det gick inte att avinstallera."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Det gick inte att avinstallera <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Raderar klonen av <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
index 849a042..64e24f9 100644
--- a/packages/PackageInstaller/res/values-sw/strings.xml
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Imesakinisha programu."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Ungependa kusakinisha programu hii?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Ungependa kusasisha programu hii?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Masasisho ya programu hii kwa sasa yanadhibitiwa na <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nKwa kusasisha, utapata masasisho yajayo kutoka kwa <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> badala yake."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Masasisho ya programu hii kwa sasa yanasimamiwa na <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>\n\nJe, ungependa kusakinisha sasisho hili kutoka kwa <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Imeshindwa kusakinisha programu."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Kifurushi kimezuiwa kisisakinishwe."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Programu haikusakinishwa kwa sababu kifurushi kinakinzana na kifurushi kingine kilichopo."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Inaondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Imeondolewa."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Imeondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Nakala ya <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> imefutwa"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Imeshindwa kuondoa."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Imeshindwa kuondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Inafuta nakala ya <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
index 564606a..71970c4 100644
--- a/packages/PackageInstaller/res/values-ta/strings.xml
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ஆப்ஸ் நிறுவப்பட்டது."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"இந்த ஆப்ஸை நிறுவ வேண்டுமா?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"இந்த ஆப்ஸைப் புதுப்பிக்க வேண்டுமா?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"இந்த ஆப்ஸுக்கான புதுப்பிப்புகள் தற்போது <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> மூலம் நிர்வகிக்கப்படுகின்றன.\n\nபுதுப்பிப்பதன் மூலம் இனிவரும் புதுப்பிப்புகளை <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> மூலம் பெறுவீர்கள்."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"இந்த ஆப்ஸுக்கான புதுப்பிப்புகள் தற்போது <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> மூலம் நிர்வகிக்கப்படுகின்றன.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> மூலம் இந்தப் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா?"</string>
     <string name="install_failed" msgid="5777824004474125469">"ஆப்ஸ் நிறுவப்படவில்லை."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"இந்தத் தொகுப்பு நிறுவப்படுவதிலிருந்து தடுக்கப்பட்டது."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"இந்தத் தொகுப்பு ஏற்கனவே உள்ள தொகுப்புடன் முரண்படுவதால் ஆப்ஸ் நிறுவப்படவில்லை."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குகிறது…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"நிறுவல் நீக்கம் முடிந்தது."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> நிறுவல் நீக்கப்பட்டது"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> குளோன் நீக்கபட்டது"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"நிறுவல் நீக்க இயலவில்லை."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குவதில் தோல்வி."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> குளோனை நீக்குகிறது…"</string>
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index b1662eb..67a15fb 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"యాప్ ఇన్‌స్టాల్ చేయబడింది."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"మీరు ఈ యాప్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"మీరు ఈ యాప్‌ను అప్‌డేట్ చేయాలనుకుంటున్నారా?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ఈ యాప్‌కి అప్‌డేట్‌లు ప్రస్తుతం <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ద్వారా మేనేజ్ చేయబడుతున్నాయి.\n\nఅప్‌డేట్ చేయడం ద్వారా, మీరు అందుకు బదులుగా <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> నుండి భవిష్యత్తు అప్‌డేట్‌లను పొందుతారు."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ఈ యాప్‌కి అప్‌డేట్‌లు ప్రస్తుతం<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ద్వారా మేనేజ్ చేయబడుతున్నాయి.\n\nమీరు <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> నుండి ఈ అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా."</string>
     <string name="install_failed" msgid="5777824004474125469">"యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"ప్యాకేజీ ఇన్‌స్టాల్ కాకుండా బ్లాక్ చేయబడింది."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ప్యాకేజీ, అలాగే ఇప్పటికే ఉన్న ప్యాకేజీ మధ్య వైరుధ్యం ఉన్నందున యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని అన్ఇన్‌స్టాల్ చేస్తోంది…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"అన్‌ఇన్‌స్టాల్ చేయడం ముగిసింది."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> అన్ఇన్‌స్టాల్ చేయబడింది"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"తొలగించబడిన <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> క్లోన్"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"అన్ఇన్‌స్టాల్ చేయడం విజయవంతం కాలేదు."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> అన్ఇన్‌స్టాల్ చేయడంలో విఫలమైంది."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> క్లోన్‌ను తొలగిస్తోంది…"</string>
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
index c0fe2ed..de8f727 100644
--- a/packages/PackageInstaller/res/values-th/strings.xml
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ติดตั้งแอปแล้ว"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"คุณต้องการติดตั้งแอปนี้ไหม"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"คุณต้องการอัปเดตแอปนี้ไหม"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"ขณะนี้ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> เป็นผู้จัดการการอัปเดตแอปนี้\n\nหากอัปเดต คุณจะได้รับการอัปเดตในอนาคตจาก <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> แทน"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"ขณะนี้ <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> เป็นผู้จัดการการอัปเดตแอปนี้\n\nคุณต้องการติดตั้งการอัปเดตนี้จาก <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> ไหม"</string>
     <string name="install_failed" msgid="5777824004474125469">"ไม่ได้ติดตั้งแอป"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"มีการบล็อกแพ็กเกจไม่ให้ติดตั้ง"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ไม่ได้ติดตั้งแอปเพราะแพ็กเกจขัดแย้งกับแพ็กเกจที่มีอยู่"</string>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index f194e86..add4258 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Na-install na ang app."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Gusto mo bang i-install ang app na ito?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Gusto mo bang i-update ang app na ito?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Kasalukuyang pinamamahalaan ng <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ang mga update sa app na ito.\n\nSa pamamagitan ng pag-update, makakakuha ka na lang ng mga update sa hinaharap mula sa <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Kasalukuyang pinamamahalaan ng <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> ang mga update sa app na ito.\n\nGusto mo bang i-install ang update na ito mula sa <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Hindi na-install ang app."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Na-block ang pag-install sa package."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Hindi na-install ang app dahil nagkakaproblema ang package sa isang dati nang package."</string>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index fb64517..a006c06 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Uygulama yüklendi."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Bu uygulamayı yüklemek istiyor musunuz?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Bu uygulamayı güncellemek istiyor musunuz?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Bu uygulamadaki güncellemeler şu anda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> tarafından yönetiliyor.\n\nUygulamayı güncellerseniz bundan sonraki güncellemeleri <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> gönderecektir."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Bu uygulamadaki güncellemeler şu anda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> tarafından yönetiliyor.\n\n<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> tarafından gönderilen bu güncellemeyi yüklemek istiyor musunuz?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Uygulama yüklenmedi."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paketin yüklemesi engellendi."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılıyor…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Yüklemeyi kaldırma işlemi tamamlandı."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırıldı"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klonu silindi"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Yükleme kaldırılamadı."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılamadı."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klonu siliniyor…"</string>
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
index 1b805d3..d8928e5 100644
--- a/packages/PackageInstaller/res/values-uk/strings.xml
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Програму встановлено."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Установити цей додаток?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Оновити цей додаток?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Оновленнями для цього додатка наразі керує <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nОновивши його зараз, ви надалі отримуватимете оновлення від <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Оновленнями для цього додатка наразі керує <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nУстановити це оновлення від <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Програму не встановлено."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Встановлення пакета заблоковано."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Додаток не встановлено, оскільки пакет конфліктує з наявним пакетом."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Видалення додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Видалено."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> видалено"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Копію <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> видалено"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Не видалено."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Не вдалося видалити додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Видалення копії додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
index 03ee46a..ab11cd8 100644
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"ایپ انسٹال ہو گئی۔"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"کیا آپ یہ ایپ انسٹال کرنا چاہتے ہیں؟"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"کیا آپ یہ ایپ اپ ڈیٹ کرنا چاہتے ہیں؟"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"اس ایپس میں اپ ڈیٹس <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> کے زیر انتظام ہیں۔\n\nاپ ڈیٹ کر کے، آپ اس کے بجائے <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> سے مستقبل کی اپ ڈیٹس موصول کر سکتے ہیں۔"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"اس ایپس میں اپ ڈیٹس <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> کے زیر انتظام ہیں۔\n\nآپ یہ اپ ڈیٹ <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> سے انسٹال کرنا چاہتے ہیں۔"</string>
     <string name="install_failed" msgid="5777824004474125469">"ایپ انسٹال نہیں ہوئی۔"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"پیکج کو انسٹال ہونے سے مسدود کر دیا گیا تھا۔"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"ایپ انسٹال نہیں ہوئی کیونکہ پیکج ایک موجودہ پیکیج سے متصادم ہے۔"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو رہا ہے…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"اَن انسٹال مکمل ہو گیا۔"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> اَن انسٹال ہو گیا"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کا کلون حذف کر دیا گیا ہے"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"اَن انسٹال ناکام ہو گیا۔"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو ان انسٹال کرنا ناکام ہو گیا۔"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کلون کو حذف کیا جا رہا ہے…"</string>
diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml
index aeb00cc..bb225bc 100644
--- a/packages/PackageInstaller/res/values-uz/strings.xml
+++ b/packages/PackageInstaller/res/values-uz/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Ilova o‘rnatildi."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Bu ilovani oʻrnatmoqchimisiz?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Bu ilova yangilansinmi?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Bu ilova yangilanishlari hozirda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> boshqaruvida.\n\nYangilanishida kelgusi oʻzgarishlar <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> dan keladi."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Bu ilova yangilanishlari hozirda <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> boshqaruvida.\n\nBu yangilanish <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> dan oʻrnatilsinmi?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Ilova o‘rnatilmadi."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Paket o‘rnatilishga qarshi bloklangan."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Paket mavjud paket bilan zid kelganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirilmoqda…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"O‘chirib tashlandi."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirib tashlandi"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nusxasi oʻchirildi"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"O‘chirib tashlanmadi."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ilovasini o‘chirib bo‘lmadi."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nusxasi oʻchirilmoqda…"</string>
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
index 7fbc74c..1e0df14 100644
--- a/packages/PackageInstaller/res/values-vi/strings.xml
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Ứng dụng đã được cài đặt."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Bạn có muốn cài đặt ứng dụng này không?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Bạn có muốn cập nhật ứng dụng này không?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Hiện tại, <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> đang quản lý các bản cập nhật của ứng dụng này.\n\nBằng việc cập nhật, bạn sẽ nhận được các bản cập nhật sau này của <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Hiện tại, <xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g> đang quản lý các bản cập nhật của ứng dụng này.\n\nBạn có muốn cài đặt bản cập nhật này của <xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> không?"</string>
     <string name="install_failed" msgid="5777824004474125469">"Ứng dụng chưa được cài đặt."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Đã chặn cài đặt gói."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Chưa cài đặt được ứng dụng do gói xung đột với một gói hiện có."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Đang gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Đã gỡ cài đặt xong."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Đã gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Đã xoá bản sao của <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Gỡ cài đặt không thành công."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> không thành công."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Đang xoá bản sao của <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
index b5f3cba..f25da81 100644
--- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"已安装应用。"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"要安装此应用吗?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"要更新此应用吗?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"此应用的更新目前由<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>管理。\n\n更新后,将改由<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>向您提供日后的更新。"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"此应用的更新目前由<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>管理。\n\n要安装这个来自<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>的更新吗?"</string>
     <string name="install_failed" msgid="5777824004474125469">"未安装应用。"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"系统已禁止安装该软件包。"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"应用未安装:软件包与现有软件包存在冲突。"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"正在卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"卸载完成。"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"已卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"已删除<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>克隆"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"卸载失败。"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>失败。"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"正在删除 <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 克隆应用…"</string>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 74e8bea..46f3b9f 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"要安裝此應用程式嗎?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"要更新此應用程式嗎?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"此應用程式的更新目前由「<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>」管理。\n\n更新後將改由「<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>」提供更新。"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"此應用程式的更新目前由「<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>」管理。\n\n是否要安裝這項由「<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>」提供的更新?"</string>
     <string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"套件已遭封鎖,無法安裝。"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"套件與現有的套件發生衝突,無法安裝應用程式。"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"完成解除安裝。"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"已刪除「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」複製本"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"解除安裝失敗。"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」失敗。"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"正在刪除「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」複製本…"</string>
diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
index a338015..cf8cd59 100644
--- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"要安裝這個應用程式嗎?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"要更新這個應用程式嗎?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"這個應用程式的更新目前是由「<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>」管理。\n\n更新後,將改由「<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>」提供更新。"</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"這個應用程式的更新目前是由「<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>」管理。\n\n是否要安裝「<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>」提供的這項更新?"</string>
     <string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"系統已封鎖這個套件,因此無法安裝。"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"應用程式套件與現有套件衝突,因此未能完成安裝。"</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"已順利解除安裝。"</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"已刪除「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」副本"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"無法解除安裝。"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"無法解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」。"</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"正在刪除「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」副本…"</string>
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
index 9298cbd..afdfd82 100644
--- a/packages/PackageInstaller/res/values-zu/strings.xml
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -26,8 +26,6 @@
     <string name="install_done" msgid="5987363587661783896">"Uhlelo lokusebenza olufakiwe."</string>
     <string name="install_confirm_question" msgid="7663733664476363311">"Ingabe ufuna ukufaka le app?"</string>
     <string name="install_confirm_question_update" msgid="3348888852318388584">"Ingabe ufuna ukubuyekeza le app?"</string>
-    <string name="install_confirm_question_update_owner_changed" msgid="4215696609006069124">"Izibuyekezo zale app okwamanje ziphethwe yi-<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nNgokubuyekeza, kunalokho uzothola izibuyekezo zesikhathi esizayo ezivela ku-<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g> esikhundleni."</string>
-    <string name="install_confirm_question_update_owner_reminder" msgid="8778026710268011466">"Izibuyekezo zale app okwamanje ziphethwe yi-<xliff:g id="EXISTING_UPDATE_OWNER">%1$s</xliff:g>.\n\nUyafuna ukufaka lesi sibuyekezo esivela ku-<xliff:g id="NEW_UPDATE_OWNER">%2$s</xliff:g>."</string>
     <string name="install_failed" msgid="5777824004474125469">"Uhlelo lokusebenza alufakiwe."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"Iphakheji livinjiwe kusukela ekufakweni."</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"Uhlelo lokusebenza alufakiwe njengoba ukuphakheja kushayisana nephakheji elikhona."</string>
@@ -70,8 +68,7 @@
     <string name="uninstalling_app" msgid="8866082646836981397">"Ikhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
     <string name="uninstall_done" msgid="439354138387969269">"Ukukhipha kuqedile."</string>
     <string name="uninstall_done_app" msgid="4588850984473605768">"Kukhishwe i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <!-- no translation found for uninstall_done_clone_app (5578308154544195413) -->
-    <skip />
+    <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Sula iclone ye-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"Ukukhipha akuphumelelanga."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"Ukukhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> akuphumelele."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Isula <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> i-clone…"</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index 7338e64..ac32020 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -80,7 +80,10 @@
         final int originatingUid = getOriginatingUid(sourceInfo);
         boolean isTrustedSource = false;
         if (sourceInfo != null && sourceInfo.isPrivilegedApp()) {
-            isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false);
+            isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false) || (
+                    originatingUid != Process.INVALID_UID && checkPermission(
+                            Manifest.permission.INSTALL_PACKAGES, -1 /* pid */, originatingUid)
+                            == PackageManager.PERMISSION_GRANTED);
         }
 
         if (!isTrustedSource && originatingUid != Process.INVALID_UID) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 3ec81aa..fd41f5f 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -246,26 +246,28 @@
 
     @Override
     public void onActivityResult(int request, int result, Intent data) {
-        if (request == REQUEST_TRUST_EXTERNAL_SOURCE && result == RESULT_OK) {
-            // The user has just allowed this package to install other packages (via Settings).
-            mAllowUnknownSources = true;
-
+        if (request == REQUEST_TRUST_EXTERNAL_SOURCE) {
             // Log the fact that the app is requesting an install, and is now allowed to do it
             // (before this point we could only log that it's requesting an install, but isn't
             // allowed to do it yet).
             String appOpStr =
                     AppOpsManager.permissionToOp(Manifest.permission.REQUEST_INSTALL_PACKAGES);
-            mAppOpsManager.noteOpNoThrow(appOpStr, mOriginatingUid, mOriginatingPackage,
-                    mCallingAttributionTag,
+            int appOpMode = mAppOpsManager.noteOpNoThrow(appOpStr, mOriginatingUid,
+                    mOriginatingPackage, mCallingAttributionTag,
                     "Successfully started package installation activity");
-
-            DialogFragment currentDialog =
-                    (DialogFragment) getFragmentManager().findFragmentByTag("dialog");
-            if (currentDialog != null) {
-                currentDialog.dismissAllowingStateLoss();
+            if (appOpMode == AppOpsManager.MODE_ALLOWED) {
+                // The user has just allowed this package to install other packages
+                // (via Settings).
+                mAllowUnknownSources = true;
+                DialogFragment currentDialog =
+                        (DialogFragment) getFragmentManager().findFragmentByTag("dialog");
+                if (currentDialog != null) {
+                    currentDialog.dismissAllowingStateLoss();
+                }
+                initiateInstall();
+            } else {
+                finish();
             }
-
-            initiateInstall();
         } else {
             finish();
         }
@@ -297,6 +299,10 @@
                 return false;
             }
         }
+        if (mSourceInfo != null && checkPermission(Manifest.permission.INSTALL_PACKAGES,
+                -1 /* pid */, mSourceInfo.uid) == PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
         return true;
     }
 
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
index 4ee4323..483a522 100644
--- a/packages/PrintSpooler/res/values-ca/strings.xml
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -56,7 +56,7 @@
     <string name="print_select_printer" msgid="7388760939873368698">"Selecciona una impressora"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"Oblida la impressora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many">S\'han trobat <xliff:g id="COUNT_1">%1$s</xliff:g> impressores</item>
       <item quantity="other">S\'han trobat <xliff:g id="COUNT_1">%1$s</xliff:g> impressores</item>
       <item quantity="one">S\'ha trobat <xliff:g id="COUNT_0">%1$s</xliff:g> impressora</item>
     </plurals>
@@ -77,7 +77,7 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Serveis desactivats"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Tots els serveis"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Instal·la\'l per detectar <xliff:g id="COUNT_1">%1$s</xliff:g> impressores</item>
       <item quantity="other">Instal·la\'l per detectar <xliff:g id="COUNT_1">%1$s</xliff:g> impressores</item>
       <item quantity="one">Instal·la\'l per detectar <xliff:g id="COUNT_0">%1$s</xliff:g> impressora</item>
     </plurals>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
index 90c1937..476614b 100644
--- a/packages/PrintSpooler/res/values-es-rUS/strings.xml
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -56,7 +56,7 @@
     <string name="print_select_printer" msgid="7388760939873368698">"Seleccionar impresora"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"No recordar impresora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many">Se encontraron <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras.</item>
       <item quantity="other">Se encontraron <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras.</item>
       <item quantity="one">Se encontró <xliff:g id="COUNT_0">%1$s</xliff:g> impresora.</item>
     </plurals>
@@ -77,7 +77,7 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Servicios inhabilitados"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Todos los servicios"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Instala para ver <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item>
       <item quantity="other">Instala para ver <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item>
       <item quantity="one">Instala para ver <xliff:g id="COUNT_0">%1$s</xliff:g> impresora</item>
     </plurals>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
index 18e56db..507b2a7 100644
--- a/packages/PrintSpooler/res/values-es/strings.xml
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -56,7 +56,7 @@
     <string name="print_select_printer" msgid="7388760939873368698">"Seleccionar impresora"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"Olvidar impresora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many">Se han encontrado <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item>
       <item quantity="other">Se han encontrado <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item>
       <item quantity="one">Se ha encontrado <xliff:g id="COUNT_0">%1$s</xliff:g> impresora</item>
     </plurals>
@@ -77,7 +77,7 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Servicios inhabilitados"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Todos los servicios"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Instalar para descubrir <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item>
       <item quantity="other">Instalar para descubrir <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item>
       <item quantity="one">Instalar para descubrir <xliff:g id="COUNT_0">%1$s</xliff:g> impresora</item>
     </plurals>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index 082c148..5298f8b 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -57,7 +57,7 @@
     <string name="print_forget_printer" msgid="5035287497291910766">"Supprimer l\'imprimante"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvée</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvées</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvées</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -78,7 +78,7 @@
     <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
       <item quantity="one">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item>
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item>
       <item quantity="other">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> en cours…"</string>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index 560c5dc..4b7e83c 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -57,7 +57,7 @@
     <string name="print_forget_printer" msgid="5035287497291910766">"Supprimer l\'imprimante"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvée</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes trouvées</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes trouvées</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -78,7 +78,7 @@
     <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
       <item quantity="one">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item>
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item>
       <item quantity="other">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
index 569bbc2..2a64d3d 100644
--- a/packages/PrintSpooler/res/values-it/strings.xml
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -56,7 +56,7 @@
     <string name="print_select_printer" msgid="7388760939873368698">"Seleziona stampante"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"Elimina stampante"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> stampanti trovate</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> stampanti trovate</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> stampante trovata</item>
     </plurals>
@@ -77,7 +77,7 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Servizi disattivati"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Tutti i servizi"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Installa per rilevare <xliff:g id="COUNT_1">%1$s</xliff:g> stampanti</item>
       <item quantity="other">Installa per rilevare <xliff:g id="COUNT_1">%1$s</xliff:g> stampanti</item>
       <item quantity="one">Installa per rilevare <xliff:g id="COUNT_0">%1$s</xliff:g> stampante</item>
     </plurals>
diff --git a/packages/PrintSpooler/res/values-or/strings.xml b/packages/PrintSpooler/res/values-or/strings.xml
index 6f215d3..dd29700 100644
--- a/packages/PrintSpooler/res/values-or/strings.xml
+++ b/packages/PrintSpooler/res/values-or/strings.xml
@@ -47,7 +47,7 @@
     <string name="savetopdf_button" msgid="2976186791686924743">"PDFରେ ସେଭ୍‍ କରନ୍ତୁ"</string>
     <string name="print_options_expanded" msgid="6944679157471691859">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ବଡ଼ କରାଯାଇଛି"</string>
     <string name="print_options_collapsed" msgid="7455930445670414332">"ପ୍ରିଣ୍ଟ ବିକଳ୍ପକୁ ଛୋଟ କରାଯାଇଛି"</string>
-    <string name="search" msgid="5421724265322228497">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
+    <string name="search" msgid="5421724265322228497">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
     <string name="all_printers_label" msgid="3178848870161526399">"ସମସ୍ତ ପ୍ରିଣ୍ଟର୍‌"</string>
     <string name="add_print_service_label" msgid="5356702546188981940">"ସେବା ଯୋଗ କରନ୍ତୁ"</string>
     <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ସର୍ଚ୍ଚ ବକ୍ସ ଦେଖାଯାଇଛି"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
index 3b460a1..855701b 100644
--- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml
@@ -57,7 +57,7 @@
     <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -78,7 +78,7 @@
     <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
       <item quantity="one">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
       <item quantity="other">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
index 8c1087e..c9a52a8 100644
--- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -56,7 +56,7 @@
     <string name="print_select_printer" msgid="7388760939873368698">"Selecionar impressora"</string>
     <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
       <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> impressora encontrada</item>
     </plurals>
@@ -77,7 +77,7 @@
     <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string>
     <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Instale para detetar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
       <item quantity="other">Instale para detetar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
       <item quantity="one">Instale para detetar <xliff:g id="COUNT_0">%1$s</xliff:g> impressora</item>
     </plurals>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
index 3b460a1..855701b 100644
--- a/packages/PrintSpooler/res/values-pt/strings.xml
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -57,7 +57,7 @@
     <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> impressoras encontradas</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -78,7 +78,7 @@
     <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
       <item quantity="one">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
+      <item quantity="many">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
       <item quantity="other">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/ActivityEmbedding/Android.bp b/packages/SettingsLib/ActivityEmbedding/Android.bp
index c35fb3b..4b4cfb7 100644
--- a/packages/SettingsLib/ActivityEmbedding/Android.bp
+++ b/packages/SettingsLib/ActivityEmbedding/Android.bp
@@ -30,5 +30,6 @@
     apex_available: [
         "//apex_available:platform",
         "com.android.permission",
+        "com.android.healthconnect",
     ],
 }
diff --git a/packages/SettingsLib/ActivityEmbedding/OWNERS b/packages/SettingsLib/ActivityEmbedding/OWNERS
new file mode 100644
index 0000000..7022402
--- /dev/null
+++ b/packages/SettingsLib/ActivityEmbedding/OWNERS
@@ -0,0 +1,5 @@
+# Default reviewers for this and subdirectories.
+arcwang@google.com
+chiujason@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
index 1407725..f89be9f 100644
--- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
+++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
@@ -23,7 +23,7 @@
 import android.util.Log;
 
 import androidx.core.os.BuildCompat;
-import androidx.window.embedding.SplitController;
+import androidx.window.embedding.ActivityEmbeddingController;
 
 import com.android.settingslib.utils.BuildCompatUtils;
 
@@ -84,7 +84,7 @@
      * @param activity Activity that needs the check
      */
     public static boolean isActivityEmbedded(Activity activity) {
-        return SplitController.getInstance().isActivityEmbedded(activity);
+        return ActivityEmbeddingController.getInstance(activity).isActivityEmbedded(activity);
     }
 
     /**
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index f170ead..af20a4b 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -42,7 +42,7 @@
         "SettingsLibAdaptiveIcon",
         "SettingsLibRadioButtonPreference",
         "SettingsLibSelectorWithWidgetPreference",
-        "SettingsLibDisplayDensityUtils",
+        "SettingsLibDisplayUtils",
         "SettingsLibUtils",
         "SettingsLibEmergencyNumber",
         "SettingsLibTopIntroPreference",
diff --git a/packages/SettingsLib/DisplayDensityUtils/AndroidManifest.xml b/packages/SettingsLib/DisplayDensityUtils/AndroidManifest.xml
deleted file mode 100644
index 0a4e2bb..0000000
--- a/packages/SettingsLib/DisplayDensityUtils/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.settingslib.display">
-
-</manifest>
diff --git a/packages/SettingsLib/DisplayDensityUtils/Android.bp b/packages/SettingsLib/DisplayUtils/Android.bp
similarity index 90%
rename from packages/SettingsLib/DisplayDensityUtils/Android.bp
rename to packages/SettingsLib/DisplayUtils/Android.bp
index b7bfb5f..136f883 100644
--- a/packages/SettingsLib/DisplayDensityUtils/Android.bp
+++ b/packages/SettingsLib/DisplayUtils/Android.bp
@@ -8,7 +8,7 @@
 }
 
 android_library {
-    name: "SettingsLibDisplayDensityUtils",
+    name: "SettingsLibDisplayUtils",
 
     srcs: ["src/**/*.java"],
 
diff --git a/packages/SettingsLib/DisplayUtils/AndroidManifest.xml b/packages/SettingsLib/DisplayUtils/AndroidManifest.xml
new file mode 100644
index 0000000..e064cab
--- /dev/null
+++ b/packages/SettingsLib/DisplayUtils/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.display">
+
+</manifest>
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java b/packages/SettingsLib/DisplayUtils/src/com/android/settingslib/display/BrightnessUtils.java
similarity index 98%
rename from packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java
rename to packages/SettingsLib/DisplayUtils/src/com/android/settingslib/display/BrightnessUtils.java
index 4f86afaa9..66ed1043 100644
--- a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java
+++ b/packages/SettingsLib/DisplayUtils/src/com/android/settingslib/display/BrightnessUtils.java
@@ -18,6 +18,7 @@
 
 import android.util.MathUtils;
 
+/** Utility methods for calculating the display brightness. */
 public class BrightnessUtils {
 
     public static final int GAMMA_SPACE_MIN = 0;
diff --git a/packages/SettingsLib/DisplayDensityUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java b/packages/SettingsLib/DisplayUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java
similarity index 100%
rename from packages/SettingsLib/DisplayDensityUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java
rename to packages/SettingsLib/DisplayUtils/src/com/android/settingslib/display/DisplayDensityConfiguration.java
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index 36315b5..1b3020a 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -1,12 +1,11 @@
 # People who can approve changes for submission
 dsandler@android.com
 edgarwang@google.com
-emilychuang@google.com
 evanlaird@google.com
-hanxu@google.com
 juliacr@google.com
+lijun@google.com
+songchenxi@google.com
 yantingyang@google.com
-ykhung@google.com
 
 # Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
 per-file *.xml=*
diff --git a/packages/SettingsLib/Spa/gallery/build.gradle b/packages/SettingsLib/Spa/gallery/build.gradle
index 7868aff..416a403 100644
--- a/packages/SettingsLib/Spa/gallery/build.gradle
+++ b/packages/SettingsLib/Spa/gallery/build.gradle
@@ -42,11 +42,11 @@
         }
     }
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
     }
     kotlinOptions {
-        jvmTarget = '1.8'
+        jvmTarget = '11'
         freeCompilerArgs = ["-Xjvm-default=all"]
     }
     buildFeatures {
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
index e54e276..c702f59 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/GallerySpaEnvironment.kt
@@ -24,6 +24,9 @@
 import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
 import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider
 import com.android.settingslib.spa.gallery.home.HomePageProvider
+import com.android.settingslib.spa.gallery.itemList.ItemListPageProvider
+import com.android.settingslib.spa.gallery.itemList.ItemOperatePageProvider
+import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
 import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
 import com.android.settingslib.spa.gallery.page.ChartPageProvider
 import com.android.settingslib.spa.gallery.page.FooterPageProvider
@@ -50,6 +53,8 @@
     HOME("home"),
     PREFERENCE("preference"),
     ARGUMENT("argument"),
+    ITEM_LIST("itemList"),
+    ITEM_OP_PAGE("itemOp"),
 
     // Add your SPPs
 }
@@ -76,6 +81,9 @@
                 LoadingBarPageProvider,
                 ChartPageProvider,
                 AlterDialogPageProvider,
+                ItemListPageProvider,
+                ItemOperatePageProvider,
+                OperateListPageProvider,
             ),
             rootPages = listOf(
                 HomePageProvider.createSettingsPage(),
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
index decc292..df1d7d1 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/button/ActionButtonsPage.kt
@@ -24,8 +24,8 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.button.ActionButton
@@ -39,13 +39,24 @@
 object ActionButtonPageProvider : SettingsPageProvider {
     override val name = "ActionButton"
 
+    override fun getTitle(arguments: Bundle?): String {
+        return TITLE
+    }
+
     @Composable
     override fun Page(arguments: Bundle?) {
-        ActionButtonPage()
+        RegularScaffold(title = TITLE) {
+            val actionButtons = listOf(
+                ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {},
+                ActionButton(text = "Uninstall", imageVector = Icons.Outlined.Delete) {},
+                ActionButton(text = "Force stop", imageVector = Icons.Outlined.WarningAmber) {},
+            )
+            ActionButtons(actionButtons)
+        }
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner = createSettingsPage())
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
@@ -55,22 +66,10 @@
     }
 }
 
-@Composable
-fun ActionButtonPage() {
-    RegularScaffold(title = TITLE) {
-        val actionButtons = listOf(
-            ActionButton(text = "Open", imageVector = Icons.Outlined.Launch) {},
-            ActionButton(text = "Uninstall", imageVector = Icons.Outlined.Delete) {},
-            ActionButton(text = "Force stop", imageVector = Icons.Outlined.WarningAmber) {},
-        )
-        ActionButtons(actionButtons)
-    }
-}
-
 @Preview(showBackground = true)
 @Composable
 private fun ActionButtonPagePreview() {
     SettingsTheme {
-        ActionButtonPage()
+        ActionButtonPageProvider.Page(null)
     }
 }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
index 5d26b34..0878fc0 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
@@ -18,6 +18,7 @@
 
 import android.os.Bundle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
@@ -28,6 +29,7 @@
 import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
 import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
 import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider
+import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
 import com.android.settingslib.spa.gallery.page.ArgumentPageModel
 import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
 import com.android.settingslib.spa.gallery.page.ChartPageProvider
@@ -50,6 +52,7 @@
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
         return listOf(
             PreferenceMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
+            OperateListPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
             ArgumentPageProvider.buildInjectEntry("foo")!!.setLink(fromPage = owner).build(),
             SliderPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
             SpinnerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
@@ -71,8 +74,10 @@
 
     @Composable
     override fun Page(arguments: Bundle?) {
-        HomeScaffold(title = getTitle(arguments)) {
-            for (entry in buildEntry(arguments)) {
+        val title = remember { getTitle(arguments) }
+        val entries = remember { buildEntry(arguments) }
+        HomeScaffold(title) {
+            for (entry in entries) {
                 if (entry.owner.isCreateBy(SettingsPageProviderEnum.ARGUMENT.name)) {
                     entry.UiLayout(ArgumentPageModel.buildArgument(intParam = 0))
                 } else {
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/ItemListPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/ItemListPage.kt
new file mode 100644
index 0000000..08e6452
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/ItemListPage.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.settingslib.spa.gallery.itemList
+
+import android.os.Bundle
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.core.os.bundleOf
+import androidx.navigation.NavType
+import androidx.navigation.navArgument
+import com.android.settingslib.spa.framework.common.EntrySearchData
+import com.android.settingslib.spa.framework.common.SettingsEntry
+import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.util.getStringArg
+import com.android.settingslib.spa.framework.util.navLink
+import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.scaffold.RegularScaffold
+
+private const val OPERATOR_PARAM_NAME = "opParam"
+
+object ItemListPageProvider : SettingsPageProvider {
+    override val name = SettingsPageProviderEnum.ITEM_LIST.name
+    override val displayName = SettingsPageProviderEnum.ITEM_LIST.displayName
+    override val parameter = listOf(
+        navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
+    )
+
+    override fun getTitle(arguments: Bundle?): String {
+        val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "NULL"
+        return "Operation: $operation"
+    }
+
+    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
+        if (!ItemOperatePageProvider.isValidArgs(arguments)) return emptyList()
+        val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
+        val owner = createSettingsPage(arguments)
+        return listOf(
+            ItemOperatePageProvider.buildInjectEntry(operation)!!.setLink(fromPage = owner).build(),
+        )
+    }
+
+    fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
+        val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
+        if (!ItemOperatePageProvider.isValidArgs(arguments)) return null
+
+        return SettingsEntryBuilder.createInject(
+            owner = createSettingsPage(arguments),
+            displayName = "ItemList_$opParam",
+        ).setUiLayoutFn {
+            Preference(
+                object : PreferenceModel {
+                    override val title = opParam
+                    override val onClick = navigator(
+                        SettingsPageProviderEnum.ITEM_LIST.name + parameter.navLink(it)
+                    )
+                }
+            )
+        }.setSearchDataFn {
+            EntrySearchData(title = "Operation: $opParam")
+        }
+    }
+
+    @Composable
+    override fun Page(arguments: Bundle?) {
+        val title = remember { getTitle(arguments) }
+        val entries = remember { buildEntry(arguments) }
+        val itemList = remember {
+            // Add logic to get item List during runtime.
+            listOf("itemFoo", "itemBar", "itemToy")
+        }
+        RegularScaffold(title) {
+            for (item in itemList) {
+                val rtArgs = ItemOperatePageProvider.genRuntimeArguments(item)
+                for (entry in entries) {
+                    entry.UiLayout(rtArgs)
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/ItemOperatePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/ItemOperatePage.kt
new file mode 100644
index 0000000..8179356
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/ItemOperatePage.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.spa.gallery.itemList
+
+import android.os.Bundle
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.core.os.bundleOf
+import androidx.navigation.NavType
+import androidx.navigation.navArgument
+import com.android.settingslib.spa.framework.common.SettingsEntry
+import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.util.getStringArg
+import com.android.settingslib.spa.framework.util.navLink
+import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.preference.SwitchPreference
+import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
+
+private const val OPERATOR_PARAM_NAME = "opParam"
+private const val ITEM_NAME_PARAM_NAME = "rt_nameParam"
+private val ALLOWED_OPERATOR_LIST = listOf("opDnD", "opPiP", "opInstall", "opConnect")
+
+object ItemOperatePageProvider : SettingsPageProvider {
+    override val name = SettingsPageProviderEnum.ITEM_OP_PAGE.name
+    override val displayName = SettingsPageProviderEnum.ITEM_OP_PAGE.displayName
+    override val parameter = listOf(
+        navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
+        navArgument(ITEM_NAME_PARAM_NAME) { type = NavType.StringType },
+    )
+
+    override fun getTitle(arguments: Bundle?): String {
+        // Operation name is not a runtime parameter, which should always available
+        val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "opInValid"
+        // Item name is a runtime parameter, which could be missing
+        val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, arguments) ?: "[unset]"
+        return "$operation on $itemName"
+    }
+
+    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
+        if (!isValidArgs(arguments)) return emptyList()
+
+        val owner = createSettingsPage(arguments)
+        val entryList = mutableListOf<SettingsEntry>()
+        entryList.add(
+            SettingsEntryBuilder.create("ItemName", owner)
+                .setUiLayoutFn {
+                    // Item name is a runtime parameter, which needs to be read inside UiLayoutFn
+                    val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
+                    Preference(
+                        object : PreferenceModel {
+                            override val title = "Item $itemName"
+                        }
+                    )
+                }.build()
+        )
+
+        // Operation name is not a runtime parameter, which can be read outside.
+        val opName = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
+        entryList.add(
+            SettingsEntryBuilder.create("ItemOp", owner)
+                .setUiLayoutFn {
+                    val checked = rememberSaveable { mutableStateOf(false) }
+                    SwitchPreference(remember {
+                        object : SwitchPreferenceModel {
+                            override val title = "Item operation: $opName"
+                            override val checked = checked
+                            override val onCheckedChange =
+                                { newChecked: Boolean -> checked.value = newChecked }
+                        }
+                    })
+                }.build(),
+        )
+        return entryList
+    }
+
+    fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
+        val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
+        if (!isValidArgs(arguments)) return null
+
+        return SettingsEntryBuilder.createInject(
+            owner = createSettingsPage(arguments),
+            displayName = "ItemOp_$opParam",
+        ).setUiLayoutFn {
+            // Item name is a runtime parameter, which needs to be read inside UiLayoutFn
+            val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
+            Preference(
+                object : PreferenceModel {
+                    override val title = "item: $itemName"
+                    override val onClick = navigator(
+                        SettingsPageProviderEnum.ITEM_OP_PAGE.name + parameter.navLink(it)
+                    )
+                }
+            )
+        }
+    }
+
+    fun isValidArgs(arguments: Bundle?): Boolean {
+        val opParam = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)
+        return (opParam != null && ALLOWED_OPERATOR_LIST.contains(opParam))
+    }
+
+    fun genRuntimeArguments(itemName: String): Bundle {
+        return bundleOf(ITEM_NAME_PARAM_NAME to itemName)
+    }
+}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/OperateListPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/OperateListPage.kt
new file mode 100644
index 0000000..e0baf86
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/itemList/OperateListPage.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.settingslib.spa.gallery.itemList
+
+import android.os.Bundle
+import com.android.settingslib.spa.framework.common.SettingsEntry
+import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+
+private const val TITLE = "Operate List Main"
+
+object OperateListPageProvider : SettingsPageProvider {
+    override val name = "OpList"
+    private val owner = createSettingsPage()
+
+    override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
+        return listOf(
+            ItemListPageProvider.buildInjectEntry("opPiP")!!.setLink(fromPage = owner).build(),
+            ItemListPageProvider.buildInjectEntry("opInstall")!!.setLink(fromPage = owner).build(),
+            ItemListPageProvider.buildInjectEntry("opDnD")!!.setLink(fromPage = owner).build(),
+            ItemListPageProvider.buildInjectEntry("opConnect")!!.setLink(fromPage = owner).build(),
+        )
+    }
+
+    override fun getTitle(arguments: Bundle?): String {
+        return TITLE
+    }
+
+    fun buildInjectEntry(): SettingsEntryBuilder {
+        return SettingsEntryBuilder.createInject(owner = owner)
+            .setUiLayoutFn {
+                Preference(object : PreferenceModel {
+                    override val title = TITLE
+                    override val onClick = navigator(name)
+                })
+            }
+    }
+}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
index 42ac1ac..eca47b6 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPage.kt
@@ -18,6 +18,7 @@
 
 import android.os.Bundle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
@@ -101,10 +102,13 @@
 
     @Composable
     override fun Page(arguments: Bundle?) {
-        RegularScaffold(title = getTitle(arguments)) {
-            for (entry in buildEntry(arguments)) {
+        val title = remember { getTitle(arguments) }
+        val entries = remember { buildEntry(arguments) }
+        val rtArgNext = remember { ArgumentPageModel.buildNextArgument(arguments) }
+        RegularScaffold(title) {
+            for (entry in entries) {
                 if (entry.toPage != null) {
-                    entry.UiLayout(ArgumentPageModel.buildNextArgument(arguments))
+                    entry.UiLayout(rtArgNext)
                 } else {
                     entry.UiLayout()
                 }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
index 5f15865..5d6aa03 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ArgumentPageModel.kt
@@ -132,7 +132,7 @@
             override val title = PAGE_TITLE
             override val summary = stateOf(summaryArray.joinToString(", "))
             override val onClick = navigator(
-                SettingsPageProviderEnum.ARGUMENT.displayName + parameter.navLink(arguments)
+                SettingsPageProviderEnum.ARGUMENT.name + parameter.navLink(arguments)
             )
         }
     }
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt
index 7f21a4d..69c4705 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ChartPage.kt
@@ -21,8 +21,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.chart.BarChart
@@ -36,7 +36,6 @@
 import com.android.settingslib.spa.widget.chart.PieChartModel
 import com.android.settingslib.spa.widget.preference.Preference
 import com.android.settingslib.spa.widget.preference.PreferenceModel
-import com.android.settingslib.spa.widget.scaffold.RegularScaffold
 import com.github.mikephil.charting.formatter.IAxisValueFormatter
 import java.text.NumberFormat
 
@@ -47,9 +46,13 @@
 
 object ChartPageProvider : SettingsPageProvider {
     override val name = "Chart"
+    private val owner = createSettingsPage()
+
+    override fun getTitle(arguments: Bundle?): String {
+        return TITLE
+    }
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create("Line Chart", owner)
@@ -133,7 +136,7 @@
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
@@ -141,15 +144,6 @@
                 })
             }
     }
-
-    @Composable
-    override fun Page(arguments: Bundle?) {
-        RegularScaffold(title = TITLE) {
-            for (entry in buildEntry(arguments)) {
-                entry.UiLayout(arguments)
-            }
-        }
-    }
 }
 
 @Preview(showBackground = true)
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt
index 9f24ea9..9c7e0ce 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/FooterPage.kt
@@ -23,8 +23,8 @@
 import com.android.settingslib.spa.framework.common.EntrySearchData
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.stateOf
 import com.android.settingslib.spa.framework.theme.SettingsTheme
@@ -37,9 +37,9 @@
 
 object FooterPageProvider : SettingsPageProvider {
     override val name = "Footer"
+    private val owner = createSettingsPage()
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "Some Preference", owner)
@@ -58,7 +58,7 @@
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt
index 44f0343..ee22b96 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt
@@ -21,8 +21,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.gallery.R
@@ -36,9 +36,9 @@
 
 object IllustrationPageProvider : SettingsPageProvider {
     override val name = "Illustration"
+    private val owner = createSettingsPage()
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "Lottie Illustration", owner)
@@ -71,7 +71,7 @@
     }
 
      fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt
index 4332a81..247990c 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/LoadingBarPage.kt
@@ -29,8 +29,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.preference.Preference
@@ -45,7 +45,7 @@
     override val name = "LoadingBar"
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner = createSettingsPage())
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt
index 20d90dd..9026a24 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/ProgressBarPage.kt
@@ -28,8 +28,8 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.preference.Preference
@@ -47,7 +47,7 @@
     override val name = "ProgressBar"
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner = createSettingsPage())
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt
index c0d0abc..dc45e6d 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SettingsPagerPage.kt
@@ -23,8 +23,8 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.preference.Preference
@@ -39,7 +39,7 @@
     override val name = "SettingsPager"
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner = createSettingsPage())
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
index a62ec7b..1051549 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
@@ -29,8 +29,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.preference.SliderPreference
@@ -42,9 +42,9 @@
 
 object SliderPageProvider : SettingsPageProvider {
     override val name = "Slider"
+    private val owner = createSettingsPage()
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create("Simple Slider", owner)
@@ -104,7 +104,7 @@
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt
index 67e35dc..442ace8 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt
@@ -24,8 +24,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.stateOf
 import com.android.settingslib.spa.framework.theme.SettingsTheme
@@ -38,9 +38,9 @@
 
 object MainSwitchPreferencePageProvider : SettingsPageProvider {
     override val name = "MainSwitchPreference"
+    private val owner = createSettingsPage()
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "MainSwitchPreference", owner)
@@ -59,7 +59,7 @@
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt
index 067911c..b67e066 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/SwitchPreferencePage.kt
@@ -27,8 +27,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.stateOf
 import com.android.settingslib.spa.framework.theme.SettingsTheme
@@ -43,9 +43,9 @@
 
 object SwitchPreferencePageProvider : SettingsPageProvider {
     override val name = "SwitchPreference"
+    private val owner = createSettingsPage()
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "SwitchPreference", owner)
@@ -82,7 +82,7 @@
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt
index 33e5e8d..a2cd283 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/TwoTargetSwitchPreferencePage.kt
@@ -25,8 +25,8 @@
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntry
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.compose.stateOf
 import com.android.settingslib.spa.framework.theme.SettingsTheme
@@ -40,9 +40,9 @@
 
 object TwoTargetSwitchPreferencePageProvider : SettingsPageProvider {
     override val name = "TwoTargetSwitchPreference"
+    private val owner = createSettingsPage()
 
     override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
-        val owner = SettingsPage.create(name)
         val entryList = mutableListOf<SettingsEntry>()
         entryList.add(
             SettingsEntryBuilder.create( "TwoTargetSwitchPreference", owner)
@@ -73,7 +73,7 @@
     }
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner)
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
index 8fdc22f..aeba6ea 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
@@ -26,8 +26,8 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.tooling.preview.Preview
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.framework.compose.navigator
 import com.android.settingslib.spa.framework.theme.SettingsTheme
 import com.android.settingslib.spa.widget.preference.Preference
@@ -42,7 +42,7 @@
     override val name = "Spinner"
 
     fun buildInjectEntry(): SettingsEntryBuilder {
-        return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
+        return SettingsEntryBuilder.createInject(owner = createSettingsPage())
             .setUiLayoutFn {
                 Preference(object : PreferenceModel {
                     override val title = TITLE
diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle
index e035615..6f1b41c 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle
+++ b/packages/SettingsLib/Spa/spa/build.gradle
@@ -48,11 +48,11 @@
         }
     }
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
     }
     kotlinOptions {
-        jvmTarget = '1.8'
+        jvmTarget = '11'
         freeCompilerArgs = ["-Xjvm-default=all"]
     }
     buildFeatures {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugProvider.kt
index 838c0cf..494e3cc 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugProvider.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/DebugProvider.kt
@@ -161,7 +161,7 @@
                 .add(ColumnEnum.PAGE_ROUTE.id, page.buildRoute())
                 .add(ColumnEnum.PAGE_INTENT_URI.id, intent.toUri(URI_INTENT_SCHEME))
                 .add(ColumnEnum.PAGE_ENTRY_COUNT.id, pageWithEntry.entries.size)
-                .add(ColumnEnum.HAS_RUNTIME_PARAM.id, if (page.hasRuntimeParam()) 1 else 0)
+                .add(ColumnEnum.PAGE_BROWSABLE.id, if (page.isBrowsable()) 1 else 0)
         }
         return cursor
     }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/ProviderColumn.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/ProviderColumn.kt
index bb9a134..fc6160e 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/ProviderColumn.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/debug/ProviderColumn.kt
@@ -28,7 +28,7 @@
     PAGE_ROUTE("pageRoute"),
     PAGE_INTENT_URI("pageIntent"),
     PAGE_ENTRY_COUNT("entryCount"),
-    HAS_RUNTIME_PARAM("hasRuntimeParam"),
+    PAGE_BROWSABLE("pageBrowsable"),
     PAGE_START_ADB("pageStartAdb"),
 
     // Columns related to entry
@@ -67,7 +67,7 @@
             ColumnEnum.PAGE_ROUTE,
             ColumnEnum.PAGE_INTENT_URI,
             ColumnEnum.PAGE_ENTRY_COUNT,
-            ColumnEnum.HAS_RUNTIME_PARAM,
+            ColumnEnum.PAGE_BROWSABLE,
         )
     ),
 
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
index a8432d6..f1b1abd 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
@@ -39,7 +39,7 @@
 import androidx.navigation.NavGraph.Companion.findStartDestination
 import com.android.settingslib.spa.R
 import com.android.settingslib.spa.framework.common.LogCategory
-import com.android.settingslib.spa.framework.common.SettingsPage
+import com.android.settingslib.spa.framework.common.NullPageProvider
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
 import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
 import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
@@ -106,14 +106,13 @@
 
 @Composable
 private fun NavControllerWrapperImpl.NavContent(allProvider: Collection<SettingsPageProvider>) {
-    val nullPage = SettingsPage.createNull()
     AnimatedNavHost(
         navController = navController,
-        startDestination = nullPage.sppName,
+        startDestination = NullPageProvider.name,
     ) {
         val slideEffect = tween<IntOffset>(durationMillis = 300)
         val fadeEffect = tween<Float>(durationMillis = 300)
-        composable(nullPage.sppName) {}
+        composable(NullPageProvider.name) {}
         for (spp in allProvider) {
             composable(
                 route = spp.name + spp.parameter.navRoute(),
@@ -139,9 +138,7 @@
                     ) + fadeOut(animationSpec = fadeEffect)
                 },
             ) { navBackStackEntry ->
-                val page = remember(navBackStackEntry.arguments) {
-                    spp.createSettingsPage(navBackStackEntry.arguments)
-                }
+                val page = remember { spp.createSettingsPage(navBackStackEntry.arguments) }
                 page.PageWithEvent()
             }
         }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt
index 44714ab..b92729d 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntry.kt
@@ -25,9 +25,6 @@
 import androidx.compose.runtime.remember
 import com.android.settingslib.spa.framework.compose.LocalNavController
 
-private const val INJECT_ENTRY_NAME = "INJECT"
-private const val ROOT_ENTRY_NAME = "ROOT"
-
 interface EntryData {
     val pageId: String?
         get() = null
@@ -163,148 +160,3 @@
         }
     }
 }
-
-/**
- * The helper to build a Settings Entry instance.
- */
-class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) {
-    private var displayName = name
-    private var fromPage: SettingsPage? = null
-    private var toPage: SettingsPage? = null
-
-    // Attributes
-    private var isAllowSearch: Boolean = false
-    private var isSearchDataDynamic: Boolean = false
-    private var hasMutableStatus: Boolean = false
-    private var hasSliceSupport: Boolean = false
-
-    // Functions
-    private var uiLayoutFn: UiLayerRenderer = { }
-    private var statusDataFn: StatusDataGetter = { null }
-    private var searchDataFn: SearchDataGetter = { null }
-    private var sliceDataFn: SliceDataGetter = { _: Uri, _: Bundle? -> null }
-
-    fun build(): SettingsEntry {
-        val page = fromPage ?: owner
-        val isEnabled = page.isEnabled()
-        return SettingsEntry(
-            id = id(),
-            name = name,
-            owner = owner,
-            displayName = displayName,
-
-            // linking data
-            fromPage = fromPage,
-            toPage = toPage,
-
-            // attributes
-            // TODO: set isEnabled & (isAllowSearch, hasSliceSupport) separately
-            isAllowSearch = isEnabled && isAllowSearch,
-            isSearchDataDynamic = isSearchDataDynamic,
-            hasMutableStatus = hasMutableStatus,
-            hasSliceSupport = isEnabled && hasSliceSupport,
-
-            // functions
-            statusDataImpl = statusDataFn,
-            searchDataImpl = searchDataFn,
-            sliceDataImpl = sliceDataFn,
-            uiLayoutImpl = uiLayoutFn,
-        )
-    }
-
-    fun setDisplayName(displayName: String): SettingsEntryBuilder {
-        this.displayName = displayName
-        return this
-    }
-
-    fun setLink(
-        fromPage: SettingsPage? = null,
-        toPage: SettingsPage? = null
-    ): SettingsEntryBuilder {
-        if (fromPage != null) this.fromPage = fromPage
-        if (toPage != null) this.toPage = toPage
-        return this
-    }
-
-    fun setIsSearchDataDynamic(isDynamic: Boolean): SettingsEntryBuilder {
-        this.isSearchDataDynamic = isDynamic
-        return this
-    }
-
-    fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder {
-        this.hasMutableStatus = hasMutableStatus
-        return this
-    }
-
-    fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder {
-        setStatusDataFn { fn(it).getStatusData() }
-        setSearchDataFn { fn(it).getSearchData() }
-        setUiLayoutFn {
-            val macro = remember { fn(it) }
-            macro.UiLayout()
-        }
-        return this
-    }
-
-    fun setStatusDataFn(fn: StatusDataGetter): SettingsEntryBuilder {
-        this.statusDataFn = fn
-        return this
-    }
-
-    fun setSearchDataFn(fn: SearchDataGetter): SettingsEntryBuilder {
-        this.searchDataFn = fn
-        this.isAllowSearch = true
-        return this
-    }
-
-    fun clearSearchDataFn(): SettingsEntryBuilder {
-        this.searchDataFn = { null }
-        this.isAllowSearch = false
-        return this
-    }
-
-    fun setSliceDataFn(fn: SliceDataGetter): SettingsEntryBuilder {
-        this.sliceDataFn = fn
-        this.hasSliceSupport = true
-        return this
-    }
-
-    fun setUiLayoutFn(fn: UiLayerRenderer): SettingsEntryBuilder {
-        this.uiLayoutFn = fn
-        return this
-    }
-
-    // The unique id of this entry, which is computed by name + owner + fromPage + toPage.
-    private fun id(): String {
-        return "$name:${owner.id}(${fromPage?.id}-${toPage?.id})".toHashId()
-    }
-
-    companion object {
-        fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
-            return SettingsEntryBuilder(entryName, owner)
-        }
-
-        fun createLinkFrom(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
-            return create(entryName, owner).setLink(fromPage = owner)
-        }
-
-        fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
-            return create(entryName, owner).setLink(toPage = owner)
-        }
-
-        fun create(owner: SettingsPage, entryName: String, displayName: String? = null):
-            SettingsEntryBuilder {
-            return SettingsEntryBuilder(entryName, owner).setDisplayName(displayName ?: entryName)
-        }
-
-        fun createInject(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder {
-            val name = displayName ?: "${INJECT_ENTRY_NAME}_${owner.displayName}"
-            return createLinkTo(INJECT_ENTRY_NAME, owner).setDisplayName(name)
-        }
-
-        fun createRoot(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder {
-            val name = displayName ?: "${ROOT_ENTRY_NAME}_${owner.displayName}"
-            return createLinkTo(ROOT_ENTRY_NAME, owner).setDisplayName(name)
-        }
-    }
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.kt
new file mode 100644
index 0000000..67f9ea5
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryBuilder.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.settingslib.spa.framework.common
+
+import android.net.Uri
+import android.os.Bundle
+import androidx.compose.runtime.remember
+import com.android.settingslib.spa.framework.util.genEntryId
+
+private const val INJECT_ENTRY_NAME = "INJECT"
+private const val ROOT_ENTRY_NAME = "ROOT"
+
+/**
+ * The helper to build a Settings Entry instance.
+ */
+class SettingsEntryBuilder(private val name: String, private val owner: SettingsPage) {
+    private var displayName = name
+    private var fromPage: SettingsPage? = null
+    private var toPage: SettingsPage? = null
+
+    // Attributes
+    private var isAllowSearch: Boolean = false
+    private var isSearchDataDynamic: Boolean = false
+    private var hasMutableStatus: Boolean = false
+    private var hasSliceSupport: Boolean = false
+
+    // Functions
+    private var uiLayoutFn: UiLayerRenderer = { }
+    private var statusDataFn: StatusDataGetter = { null }
+    private var searchDataFn: SearchDataGetter = { null }
+    private var sliceDataFn: SliceDataGetter = { _: Uri, _: Bundle? -> null }
+
+    fun build(): SettingsEntry {
+        val page = fromPage ?: owner
+        val isEnabled = page.isEnabled()
+        return SettingsEntry(
+            id = genEntryId(name, owner, fromPage, toPage),
+            name = name,
+            owner = owner,
+            displayName = displayName,
+
+            // linking data
+            fromPage = fromPage,
+            toPage = toPage,
+
+            // attributes
+            // TODO: set isEnabled & (isAllowSearch, hasSliceSupport) separately
+            isAllowSearch = isEnabled && isAllowSearch,
+            isSearchDataDynamic = isSearchDataDynamic,
+            hasMutableStatus = hasMutableStatus,
+            hasSliceSupport = isEnabled && hasSliceSupport,
+
+            // functions
+            statusDataImpl = statusDataFn,
+            searchDataImpl = searchDataFn,
+            sliceDataImpl = sliceDataFn,
+            uiLayoutImpl = uiLayoutFn,
+        )
+    }
+
+    fun setDisplayName(displayName: String): SettingsEntryBuilder {
+        this.displayName = displayName
+        return this
+    }
+
+    fun setLink(
+        fromPage: SettingsPage? = null,
+        toPage: SettingsPage? = null
+    ): SettingsEntryBuilder {
+        if (fromPage != null) this.fromPage = fromPage
+        if (toPage != null) this.toPage = toPage
+        return this
+    }
+
+    fun setIsSearchDataDynamic(isDynamic: Boolean): SettingsEntryBuilder {
+        this.isSearchDataDynamic = isDynamic
+        return this
+    }
+
+    fun setHasMutableStatus(hasMutableStatus: Boolean): SettingsEntryBuilder {
+        this.hasMutableStatus = hasMutableStatus
+        return this
+    }
+
+    fun setMacro(fn: (arguments: Bundle?) -> EntryMacro): SettingsEntryBuilder {
+        setStatusDataFn { fn(it).getStatusData() }
+        setSearchDataFn { fn(it).getSearchData() }
+        setUiLayoutFn {
+            val macro = remember { fn(it) }
+            macro.UiLayout()
+        }
+        return this
+    }
+
+    fun setStatusDataFn(fn: StatusDataGetter): SettingsEntryBuilder {
+        this.statusDataFn = fn
+        return this
+    }
+
+    fun setSearchDataFn(fn: SearchDataGetter): SettingsEntryBuilder {
+        this.searchDataFn = fn
+        this.isAllowSearch = true
+        return this
+    }
+
+    fun clearSearchDataFn(): SettingsEntryBuilder {
+        this.searchDataFn = { null }
+        this.isAllowSearch = false
+        return this
+    }
+
+    fun setSliceDataFn(fn: SliceDataGetter): SettingsEntryBuilder {
+        this.sliceDataFn = fn
+        this.hasSliceSupport = true
+        return this
+    }
+
+    fun setUiLayoutFn(fn: UiLayerRenderer): SettingsEntryBuilder {
+        this.uiLayoutFn = fn
+        return this
+    }
+
+    companion object {
+        fun create(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
+            return SettingsEntryBuilder(entryName, owner)
+        }
+
+        fun createLinkFrom(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
+            return create(entryName, owner).setLink(fromPage = owner)
+        }
+
+        fun createLinkTo(entryName: String, owner: SettingsPage): SettingsEntryBuilder {
+            return create(entryName, owner).setLink(toPage = owner)
+        }
+
+        fun create(owner: SettingsPage, entryName: String, displayName: String? = null):
+            SettingsEntryBuilder {
+            return SettingsEntryBuilder(entryName, owner).setDisplayName(displayName ?: entryName)
+        }
+
+        fun createInject(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder {
+            val name = displayName ?: "${INJECT_ENTRY_NAME}_${owner.displayName}"
+            return createLinkTo(INJECT_ENTRY_NAME, owner).setDisplayName(name)
+        }
+
+        fun createRoot(owner: SettingsPage, displayName: String? = null): SettingsEntryBuilder {
+            val name = displayName ?: "${ROOT_ENTRY_NAME}_${owner.displayName}"
+            return createLinkTo(ROOT_ENTRY_NAME, owner).setDisplayName(name)
+        }
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt
index 14b1629..429f97b 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsEntryRepository.kt
@@ -30,14 +30,10 @@
     val injectEntry: SettingsEntry,
 )
 
-private fun SettingsPage.getTitle(sppRepository: SettingsPageProviderRepository): String {
-    return sppRepository.getProviderOrNull(sppName)!!.getTitle(arguments)
-}
-
 /**
  * The repository to maintain all Settings entries
  */
-class SettingsEntryRepository(private val sppRepository: SettingsPageProviderRepository) {
+class SettingsEntryRepository(sppRepository: SettingsPageProviderRepository) {
     // Map of entry unique Id to entry
     private val entryMap: Map<String, SettingsEntry>
 
@@ -49,7 +45,7 @@
         entryMap = mutableMapOf()
         pageWithEntryMap = mutableMapOf()
 
-        val nullPage = SettingsPage.createNull()
+        val nullPage = NullPageProvider.createSettingsPage()
         val entryQueue = LinkedList<SettingsEntry>()
         for (page in sppRepository.getAllRootPages()) {
             val rootEntry =
@@ -66,6 +62,9 @@
             if (page == null || pageWithEntryMap.containsKey(page.id)) continue
             val spp = sppRepository.getProviderOrNull(page.sppName) ?: continue
             val newEntries = spp.buildEntry(page.arguments)
+            // The page id could be existed already, if there are 2+ pages go to the same one.
+            // For now, override the previous ones, which means only the last from-page is kept.
+            // TODO: support multiple from-pages if necessary.
             pageWithEntryMap[page.id] = SettingsPageWithEntry(
                 page = page,
                 entries = newEntries,
@@ -123,7 +122,7 @@
             if (it.toPage == null)
                 defaultTitle
             else {
-                it.toPage.getTitle(sppRepository)
+                it.toPage.getTitle()
             }
         }
     }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt
index 8bbeb62..724588f 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPage.kt
@@ -19,11 +19,9 @@
 import android.os.Bundle
 import androidx.compose.runtime.Composable
 import androidx.navigation.NamedNavArgument
+import com.android.settingslib.spa.framework.util.genPageId
 import com.android.settingslib.spa.framework.util.isRuntimeParam
 import com.android.settingslib.spa.framework.util.navLink
-import com.android.settingslib.spa.framework.util.normalize
-
-private const val NULL_PAGE_NAME = "NULL"
 
 /**
  * Defines data to identify a Settings page.
@@ -45,10 +43,7 @@
     val arguments: Bundle? = null,
 ) {
     companion object {
-        fun createNull(): SettingsPage {
-            return create(NULL_PAGE_NAME)
-        }
-
+        // TODO: cleanup it once all its usage in Settings are switched to Spp.createSettingsPage
         fun create(
             name: String,
             displayName: String? = null,
@@ -56,23 +51,13 @@
             arguments: Bundle? = null
         ): SettingsPage {
             return SettingsPage(
-                id = id(name, parameter, arguments),
+                id = genPageId(name, parameter, arguments),
                 sppName = name,
                 displayName = displayName ?: name,
                 parameter = parameter,
                 arguments = arguments
             )
         }
-
-        // The unique id of this page, which is computed by name + normalized(arguments)
-        private fun id(
-            name: String,
-            parameter: List<NamedNavArgument> = emptyList(),
-            arguments: Bundle? = null
-        ): String {
-            val normArguments = parameter.normalize(arguments, eraseRuntimeValues = true)
-            return "$name:${normArguments?.toString()}".toHashId()
-        }
     }
 
     // Returns if this Settings Page is created by the given Spp.
@@ -84,42 +69,24 @@
         return sppName + parameter.navLink(arguments)
     }
 
-    fun hasRuntimeParam(): Boolean {
-        for (navArg in parameter) {
-            if (navArg.isRuntimeParam()) return true
-        }
-        return false
-    }
-
     fun isBrowsable(): Boolean {
-        return !isCreateBy(NULL_PAGE_NAME) && !hasRuntimeParam()
-    }
-
-    private fun getProvider(): SettingsPageProvider? {
-        if (!SpaEnvironmentFactory.isReady()) return null
-        val pageProviderRepository by SpaEnvironmentFactory.instance.pageProviderRepository
-        return pageProviderRepository.getProviderOrNull(sppName)
+        if (sppName == NullPageProvider.name) return false
+        for (navArg in parameter) {
+            if (navArg.isRuntimeParam()) return false
+        }
+        return true
     }
 
     fun isEnabled(): Boolean {
-        return getProvider()?.isEnabled(arguments) ?: false
+        return getPageProvider(sppName)?.isEnabled(arguments) ?: false
+    }
+
+    fun getTitle(): String {
+        return getPageProvider(sppName)?.getTitle(arguments) ?: ""
     }
 
     @Composable
     fun UiLayout() {
-        getProvider()?.Page(arguments)
+        getPageProvider(sppName)?.Page(arguments)
     }
 }
-
-fun SettingsPageProvider.createSettingsPage(arguments: Bundle? = null): SettingsPage {
-    return SettingsPage.create(
-        name = name,
-        displayName = displayName,
-        parameter = parameter,
-        arguments = arguments
-    )
-}
-
-fun String.toHashId(): String {
-    return this.hashCode().toUInt().toString(36)
-}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt
index 42e5f7e..18f964e 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SettingsPageProvider.kt
@@ -18,9 +18,14 @@
 
 import android.os.Bundle
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.navigation.NamedNavArgument
+import com.android.settingslib.spa.framework.util.genPageId
+import com.android.settingslib.spa.framework.util.normalizeArgList
 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
 
+private const val NULL_PAGE_NAME = "NULL"
+
 /**
  * An SettingsPageProvider which is used to create Settings page instances.
  */
@@ -52,10 +57,33 @@
     /** The [Composable] used to render this page. */
     @Composable
     fun Page(arguments: Bundle?) {
-        RegularScaffold(title = getTitle(arguments)) {
-            for (entry in buildEntry(arguments)) {
+        val title = remember { getTitle(arguments) }
+        val entries = remember { buildEntry(arguments) }
+        RegularScaffold(title) {
+            for (entry in entries) {
                 entry.UiLayout()
             }
         }
     }
 }
+
+fun SettingsPageProvider.createSettingsPage(arguments: Bundle? = null): SettingsPage {
+    return SettingsPage(
+        id = genPageId(name, parameter, arguments),
+        sppName = name,
+        displayName = displayName + parameter.normalizeArgList(arguments, eraseRuntimeValues = true)
+            .joinToString("") { arg -> "/$arg" },
+        parameter = parameter,
+        arguments = arguments,
+    )
+}
+
+object NullPageProvider : SettingsPageProvider {
+    override val name = NULL_PAGE_NAME
+}
+
+fun getPageProvider(sppName: String): SettingsPageProvider? {
+    if (!SpaEnvironmentFactory.isReady()) return null
+    val pageProviderRepository by SpaEnvironmentFactory.instance.pageProviderRepository
+    return pageProviderRepository.getProviderOrNull(sppName)
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt
index be303f0..f0eeb13 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/Parameter.kt
@@ -29,8 +29,16 @@
 }
 
 fun List<NamedNavArgument>.navLink(arguments: Bundle? = null): String {
+    return normalizeArgList(arguments).joinToString("") { arg -> "/$arg" }
+}
+
+fun List<NamedNavArgument>.normalizeArgList(
+    arguments: Bundle? = null,
+    eraseRuntimeValues: Boolean = false
+): List<String> {
     val argsArray = mutableListOf<String>()
     for (navArg in this) {
+        if (eraseRuntimeValues && navArg.isRuntimeParam()) continue
         if (arguments == null || !arguments.containsKey(navArg.name)) {
             argsArray.add(UNSET_PARAM_VALUE)
             continue
@@ -44,7 +52,7 @@
             }
         }
     }
-    return argsArray.joinToString("") { arg -> "/$arg" }
+    return argsArray
 }
 
 fun List<NamedNavArgument>.normalize(
@@ -55,7 +63,7 @@
     val normArgs = Bundle()
     for (navArg in this) {
         // Erase value of runtime parameters.
-        if (navArg.isRuntimeParam() && eraseRuntimeValues) {
+        if (eraseRuntimeValues && navArg.isRuntimeParam()) {
             normArgs.putString(navArg.name, null)
             continue
         }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/UniqueId.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/UniqueId.kt
new file mode 100644
index 0000000..3b0ff7d
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/util/UniqueId.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.spa.framework.util
+
+import android.os.Bundle
+import androidx.navigation.NamedNavArgument
+import com.android.settingslib.spa.framework.common.SettingsPage
+
+fun genPageId(
+    sppName: String,
+    parameter: List<NamedNavArgument> = emptyList(),
+    arguments: Bundle? = null
+): String {
+    val normArguments = parameter.normalize(arguments, eraseRuntimeValues = true)
+    return "$sppName:${normArguments?.toString()}".toHashId()
+}
+
+fun genEntryId(
+    name: String,
+    owner: SettingsPage,
+    fromPage: SettingsPage? = null,
+    toPage: SettingsPage? = null
+): String {
+    return "$name:${owner.id}(${fromPage?.id}-${toPage?.id})".toHashId()
+}
+
+// TODO: implement a better hash function
+private fun String.toHashId(): String {
+    return this.hashCode().toUInt().toString(36)
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
index 32b283e..62189dc 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
@@ -24,7 +24,12 @@
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.composed
+import androidx.compose.ui.draw.scale
+import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.LayoutDirection
 import com.android.settingslib.spa.framework.compose.LocalNavController
 
 /** Action that navigates back to last page. */
@@ -50,6 +55,7 @@
         Icon(
             imageVector = Icons.Outlined.ArrowBack,
             contentDescription = contentDescription,
+            modifier = Modifier.autoMirrored(),
         )
     }
 }
@@ -75,3 +81,10 @@
         )
     }
 }
+
+private fun Modifier.autoMirrored() = composed {
+    when (LocalLayoutDirection.current) {
+        LayoutDirection.Rtl -> scale(scaleX = -1f, scaleY = 1f)
+        else -> this
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
index e8b5b19..f6bb3cc 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
@@ -119,7 +119,6 @@
         actions = actions,
         colors = topAppBarColors(),
         windowInsets = TopAppBarDefaults.windowInsets,
-        maxHeightWithoutTitle = 120.dp,
         pinnedHeight = ContainerHeight,
         scrollBehavior = scrollBehavior,
     )
@@ -261,7 +260,7 @@
  * A two-rows top app bar that is designed to be called by the Large and Medium top app bar
  * composables.
  *
- * @throws [IllegalArgumentException] if the given [maxHeightWithoutTitle] is equal or smaller than
+ * @throws [IllegalArgumentException] if the given [MaxHeightWithoutTitle] is equal or smaller than
  * the [pinnedHeight]
  */
 @OptIn(ExperimentalMaterial3Api::class)
@@ -277,11 +276,10 @@
     actions: @Composable RowScope.() -> Unit,
     windowInsets: WindowInsets,
     colors: TopAppBarColors,
-    maxHeightWithoutTitle: Dp,
     pinnedHeight: Dp,
     scrollBehavior: TopAppBarScrollBehavior?
 ) {
-    if (maxHeightWithoutTitle <= pinnedHeight) {
+    if (MaxHeightWithoutTitle <= pinnedHeight) {
         throw IllegalArgumentException(
             "A TwoRowsTopAppBar max height should be greater than its pinned height"
         )
@@ -289,7 +287,7 @@
     val pinnedHeightPx: Float
     val density = LocalDensity.current
     val maxHeightPx = density.run {
-        remember { mutableStateOf((maxHeightWithoutTitle + pinnedHeight).toPx()) }
+        remember { mutableStateOf((MaxHeightWithoutTitle + DefaultTitleHeight).toPx()) }
     }
     val titleBottomPaddingPx: Int
     density.run {
@@ -380,7 +378,7 @@
                     Box(modifier = Modifier.onGloballyPositioned { coordinates ->
                         density.run {
                             maxHeightPx.value =
-                                maxHeightWithoutTitle.toPx() + coordinates.size.height.toFloat()
+                                MaxHeightWithoutTitle.toPx() + coordinates.size.height.toFloat()
                         }
                     }) { title() }
                 },
@@ -610,6 +608,8 @@
 // Medium or Large app bar.
 private val TopTitleAlphaEasing = CubicBezierEasing(.8f, 0f, .8f, .15f)
 
+private val MaxHeightWithoutTitle = 124.dp
+private val DefaultTitleHeight = 52.dp
 private val ContainerHeight = 56.dp
 private val LargeTitleBottomPadding = 28.dp
 private val TopAppBarHorizontalPadding = 4.dp
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt
index c0b7464..379b9a7 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryRepositoryTest.kt
@@ -19,12 +19,12 @@
 import android.content.Context
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.framework.util.genEntryId
+import com.android.settingslib.spa.framework.util.genPageId
 import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
 import com.android.settingslib.spa.tests.testutils.SppHome
 import com.android.settingslib.spa.tests.testutils.SppLayer1
 import com.android.settingslib.spa.tests.testutils.SppLayer2
-import com.android.settingslib.spa.tests.testutils.getUniqueEntryId
-import com.android.settingslib.spa.tests.testutils.getUniquePageId
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -41,18 +41,18 @@
         val pageWithEntry = entryRepository.getAllPageWithEntry()
         assertThat(pageWithEntry.size).isEqualTo(3)
         assertThat(
-            entryRepository.getPageWithEntry(getUniquePageId("SppHome"))
+            entryRepository.getPageWithEntry(genPageId("SppHome"))
                 ?.entries?.size
         ).isEqualTo(1)
         assertThat(
-            entryRepository.getPageWithEntry(getUniquePageId("SppLayer1"))
+            entryRepository.getPageWithEntry(genPageId("SppLayer1"))
                 ?.entries?.size
         ).isEqualTo(3)
         assertThat(
-            entryRepository.getPageWithEntry(getUniquePageId("SppLayer2"))
+            entryRepository.getPageWithEntry(genPageId("SppLayer2"))
                 ?.entries?.size
         ).isEqualTo(2)
-        assertThat(entryRepository.getPageWithEntry(getUniquePageId("SppWithParam"))).isNull()
+        assertThat(entryRepository.getPageWithEntry(genPageId("SppWithParam"))).isNull()
     }
 
     @Test
@@ -61,17 +61,17 @@
         assertThat(entry.size).isEqualTo(7)
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId(
+                genEntryId(
                     "ROOT",
                     SppHome.createSettingsPage(),
-                    SettingsPage.createNull(),
+                    NullPageProvider.createSettingsPage(),
                     SppHome.createSettingsPage(),
                 )
             )
         ).isNotNull()
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId(
+                genEntryId(
                     "INJECT",
                     SppLayer1.createSettingsPage(),
                     SppHome.createSettingsPage(),
@@ -81,7 +81,7 @@
         ).isNotNull()
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId(
+                genEntryId(
                     "INJECT",
                     SppLayer2.createSettingsPage(),
                     SppLayer1.createSettingsPage(),
@@ -91,45 +91,46 @@
         ).isNotNull()
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId("Layer1Entry1", SppLayer1.createSettingsPage())
+                genEntryId("Layer1Entry1", SppLayer1.createSettingsPage())
             )
         ).isNotNull()
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId("Layer1Entry2", SppLayer1.createSettingsPage())
+                genEntryId("Layer1Entry2", SppLayer1.createSettingsPage())
             )
         ).isNotNull()
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId("Layer2Entry1", SppLayer2.createSettingsPage())
+                genEntryId("Layer2Entry1", SppLayer2.createSettingsPage())
             )
         ).isNotNull()
         assertThat(
             entryRepository.getEntry(
-                getUniqueEntryId("Layer2Entry2", SppLayer2.createSettingsPage())
+                genEntryId("Layer2Entry2", SppLayer2.createSettingsPage())
             )
         ).isNotNull()
     }
 
     @Test
     fun testGetEntryPath() {
+        SpaEnvironmentFactory.reset(spaEnvironment)
         assertThat(
             entryRepository.getEntryPathWithDisplayName(
-                getUniqueEntryId("Layer2Entry1", SppLayer2.createSettingsPage())
+                genEntryId("Layer2Entry1", SppLayer2.createSettingsPage())
             )
         ).containsExactly("Layer2Entry1", "INJECT_SppLayer2", "INJECT_SppLayer1", "ROOT_SppHome")
             .inOrder()
 
         assertThat(
             entryRepository.getEntryPathWithTitle(
-                getUniqueEntryId("Layer2Entry2", SppLayer2.createSettingsPage()),
+                genEntryId("Layer2Entry2", SppLayer2.createSettingsPage()),
                 "entryTitle"
             )
         ).containsExactly("entryTitle", "SppLayer2", "TitleLayer1", "TitleHome").inOrder()
 
         assertThat(
             entryRepository.getEntryPathWithDisplayName(
-                getUniqueEntryId(
+                genEntryId(
                     "INJECT",
                     SppLayer1.createSettingsPage(),
                     SppHome.createSettingsPage(),
@@ -140,7 +141,7 @@
 
         assertThat(
             entryRepository.getEntryPathWithTitle(
-                getUniqueEntryId(
+                genEntryId(
                     "INJECT",
                     SppLayer2.createSettingsPage(),
                     SppLayer1.createSettingsPage(),
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt
index 6de1ae5..5754c9b 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsEntryTest.kt
@@ -23,11 +23,12 @@
 import androidx.core.os.bundleOf
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.framework.util.genEntryId
+import com.android.settingslib.spa.framework.util.genPageId
 import com.android.settingslib.spa.slice.appendSpaParams
 import com.android.settingslib.spa.slice.getEntryId
 import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
-import com.android.settingslib.spa.tests.testutils.getUniqueEntryId
-import com.android.settingslib.spa.tests.testutils.getUniquePageId
+import com.android.settingslib.spa.tests.testutils.createSettingsPage
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
@@ -64,9 +65,9 @@
 
     @Test
     fun testBuildBasic() {
-        val owner = SettingsPage.create("mySpp")
+        val owner = createSettingsPage("mySpp")
         val entry = SettingsEntryBuilder.create(owner, "myEntry").build()
-        assertThat(entry.id).isEqualTo(getUniqueEntryId("myEntry", owner))
+        assertThat(entry.id).isEqualTo(genEntryId("myEntry", owner))
         assertThat(entry.displayName).isEqualTo("myEntry")
         assertThat(entry.owner.sppName).isEqualTo("mySpp")
         assertThat(entry.owner.displayName).isEqualTo("mySpp")
@@ -80,19 +81,19 @@
 
     @Test
     fun testBuildWithLink() {
-        val owner = SettingsPage.create("mySpp")
-        val fromPage = SettingsPage.create("fromSpp")
-        val toPage = SettingsPage.create("toSpp")
+        val owner = createSettingsPage("mySpp")
+        val fromPage = createSettingsPage("fromSpp")
+        val toPage = createSettingsPage("toSpp")
         val entryFrom =
             SettingsEntryBuilder.createLinkFrom("myEntry", owner).setLink(toPage = toPage).build()
-        assertThat(entryFrom.id).isEqualTo(getUniqueEntryId("myEntry", owner, owner, toPage))
+        assertThat(entryFrom.id).isEqualTo(genEntryId("myEntry", owner, owner, toPage))
         assertThat(entryFrom.displayName).isEqualTo("myEntry")
         assertThat(entryFrom.fromPage!!.sppName).isEqualTo("mySpp")
         assertThat(entryFrom.toPage!!.sppName).isEqualTo("toSpp")
 
         val entryTo =
             SettingsEntryBuilder.createLinkTo("myEntry", owner).setLink(fromPage = fromPage).build()
-        assertThat(entryTo.id).isEqualTo(getUniqueEntryId("myEntry", owner, fromPage, owner))
+        assertThat(entryTo.id).isEqualTo(genEntryId("myEntry", owner, fromPage, owner))
         assertThat(entryTo.displayName).isEqualTo("myEntry")
         assertThat(entryTo.fromPage!!.sppName).isEqualTo("fromSpp")
         assertThat(entryTo.toPage!!.sppName).isEqualTo("mySpp")
@@ -100,10 +101,10 @@
 
     @Test
     fun testBuildInject() {
-        val owner = SettingsPage.create("mySpp")
+        val owner = createSettingsPage("mySpp")
         val entryInject = SettingsEntryBuilder.createInject(owner).build()
         assertThat(entryInject.id).isEqualTo(
-            getUniqueEntryId(
+            genEntryId(
                 INJECT_ENTRY_NAME_TEST, owner, toPage = owner
             )
         )
@@ -114,10 +115,10 @@
 
     @Test
     fun testBuildRoot() {
-        val owner = SettingsPage.create("mySpp")
+        val owner = createSettingsPage("mySpp")
         val entryInject = SettingsEntryBuilder.createRoot(owner, "myRootEntry").build()
         assertThat(entryInject.id).isEqualTo(
-            getUniqueEntryId(
+            genEntryId(
                 ROOT_ENTRY_NAME_TEST, owner, toPage = owner
             )
         )
@@ -129,7 +130,7 @@
     @Test
     fun testSetAttributes() {
         SpaEnvironmentFactory.reset(spaEnvironment)
-        val owner = SettingsPage.create("SppHome")
+        val owner = createSettingsPage("SppHome")
         val entryBuilder =
             SettingsEntryBuilder.create(owner, "myEntry")
                 .setDisplayName("myEntryDisplay")
@@ -138,7 +139,7 @@
                 .setSearchDataFn { null }
                 .setSliceDataFn { _, _ -> null }
         val entry = entryBuilder.build()
-        assertThat(entry.id).isEqualTo(getUniqueEntryId("myEntry", owner))
+        assertThat(entry.id).isEqualTo(genEntryId("myEntry", owner))
         assertThat(entry.displayName).isEqualTo("myEntryDisplay")
         assertThat(entry.fromPage).isNull()
         assertThat(entry.toPage).isNull()
@@ -148,7 +149,7 @@
         assertThat(entry.hasSliceSupport).isTrue()
 
         // Test disabled Spp
-        val ownerDisabled = SettingsPage.create("SppDisabled")
+        val ownerDisabled = createSettingsPage("SppDisabled")
         val entryBuilderDisabled =
             SettingsEntryBuilder.create(ownerDisabled, "myEntry")
                 .setDisplayName("myEntryDisplay")
@@ -157,7 +158,7 @@
                 .setSearchDataFn { null }
                 .setSliceDataFn { _, _ -> null }
         val entryDisabled = entryBuilderDisabled.build()
-        assertThat(entryDisabled.id).isEqualTo(getUniqueEntryId("myEntry", ownerDisabled))
+        assertThat(entryDisabled.id).isEqualTo(genEntryId("myEntry", ownerDisabled))
         assertThat(entryDisabled.displayName).isEqualTo("myEntryDisplay")
         assertThat(entryDisabled.fromPage).isNull()
         assertThat(entryDisabled.toPage).isNull()
@@ -173,7 +174,7 @@
         // Clear SppHome in spa environment
         SpaEnvironmentFactory.reset()
         val entry3 = entryBuilder.build()
-        assertThat(entry3.id).isEqualTo(getUniqueEntryId("myEntry", owner))
+        assertThat(entry3.id).isEqualTo(genEntryId("myEntry", owner))
         assertThat(entry3.displayName).isEqualTo("myEntryDisplay")
         assertThat(entry3.fromPage).isNull()
         assertThat(entry3.toPage).isNull()
@@ -186,12 +187,12 @@
     @Test
     fun testSetMarco() {
         SpaEnvironmentFactory.reset(spaEnvironment)
-        val owner = SettingsPage.create("SppHome", arguments = bundleOf("param" to "v1"))
+        val owner = createSettingsPage("SppHome", arguments = bundleOf("param" to "v1"))
         val entry = SettingsEntryBuilder.create(owner, "myEntry").setMacro {
             assertThat(it?.getString("param")).isEqualTo("v1")
             assertThat(it?.getString("rtParam")).isEqualTo("v2")
             assertThat(it?.getString("unknown")).isNull()
-            MacroForTest(getUniquePageId("SppHome"), getUniqueEntryId("myEntry", owner))
+            MacroForTest(genPageId("SppHome"), genEntryId("myEntry", owner))
         }.build()
 
         val rtArguments = bundleOf("rtParam" to "v2")
@@ -211,8 +212,8 @@
     @Test
     fun testSetSliceDataFn() {
         SpaEnvironmentFactory.reset(spaEnvironment)
-        val owner = SettingsPage.create("SppHome")
-        val entryId = getUniqueEntryId("myEntry", owner)
+        val owner = createSettingsPage("SppHome")
+        val entryId = genEntryId("myEntry", owner)
         val emptySliceData = EntrySliceData()
 
         val entryBuilder = SettingsEntryBuilder.create(owner, "myEntry").setSliceDataFn { uri, _ ->
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt
index 6c0c652..8576573 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageProviderRepositoryTest.kt
@@ -17,6 +17,7 @@
 package com.android.settingslib.spa.framework.common
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.tests.testutils.createSettingsPage
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -29,13 +30,14 @@
         assertThat(sppRepoEmpty.getDefaultStartPage()).isEqualTo("")
         assertThat(sppRepoEmpty.getAllRootPages()).isEmpty()
 
+        val nullPage = NullPageProvider.createSettingsPage()
         val sppRepoNull =
-            SettingsPageProviderRepository(emptyList(), listOf(SettingsPage.createNull()))
+            SettingsPageProviderRepository(emptyList(), listOf(nullPage))
         assertThat(sppRepoNull.getDefaultStartPage()).isEqualTo("NULL")
-        assertThat(sppRepoNull.getAllRootPages()).contains(SettingsPage.createNull())
+        assertThat(sppRepoNull.getAllRootPages()).contains(nullPage)
 
-        val rootPage1 = SettingsPage.create(name = "Spp1", displayName = "Spp1")
-        val rootPage2 = SettingsPage.create(name = "Spp2", displayName = "Spp2")
+        val rootPage1 = createSettingsPage(sppName = "Spp1", displayName = "Spp1")
+        val rootPage2 = createSettingsPage(sppName = "Spp2", displayName = "Spp2")
         val sppRepo = SettingsPageProviderRepository(emptyList(), listOf(rootPage1, rootPage2))
         val allRoots = sppRepo.getAllRootPages()
         assertThat(sppRepo.getDefaultStartPage()).isEqualTo("Spp1")
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt
index 1f5de2d..dc74a10 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/common/SettingsPageTest.kt
@@ -22,8 +22,9 @@
 import androidx.navigation.navArgument
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.framework.util.genPageId
 import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
-import com.android.settingslib.spa.tests.testutils.getUniquePageId
+import com.android.settingslib.spa.tests.testutils.createSettingsPage
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,27 +36,25 @@
 
     @Test
     fun testNullPage() {
-        val page = SettingsPage.createNull()
-        assertThat(page.id).isEqualTo(getUniquePageId("NULL"))
+        val page = NullPageProvider.createSettingsPage()
+        assertThat(page.id).isEqualTo(genPageId("NULL"))
         assertThat(page.sppName).isEqualTo("NULL")
         assertThat(page.displayName).isEqualTo("NULL")
         assertThat(page.buildRoute()).isEqualTo("NULL")
         assertThat(page.isCreateBy("NULL")).isTrue()
         assertThat(page.isCreateBy("Spp")).isFalse()
-        assertThat(page.hasRuntimeParam()).isFalse()
         assertThat(page.isBrowsable()).isFalse()
     }
 
     @Test
     fun testRegularPage() {
-        val page = SettingsPage.create("mySpp", "SppDisplayName")
-        assertThat(page.id).isEqualTo(getUniquePageId("mySpp"))
+        val page = createSettingsPage("mySpp", "SppDisplayName")
+        assertThat(page.id).isEqualTo(genPageId("mySpp"))
         assertThat(page.sppName).isEqualTo("mySpp")
         assertThat(page.displayName).isEqualTo("SppDisplayName")
         assertThat(page.buildRoute()).isEqualTo("mySpp")
         assertThat(page.isCreateBy("NULL")).isFalse()
         assertThat(page.isCreateBy("mySpp")).isTrue()
-        assertThat(page.hasRuntimeParam()).isFalse()
         assertThat(page.isBrowsable()).isTrue()
     }
 
@@ -67,7 +66,7 @@
         )
         val page = spaEnvironment.createPage("SppWithParam", arguments)
         assertThat(page.id).isEqualTo(
-            getUniquePageId(
+            genPageId(
                 "SppWithParam", listOf(
                     navArgument("string_param") { type = NavType.StringType },
                     navArgument("int_param") { type = NavType.IntType },
@@ -75,10 +74,9 @@
             )
         )
         assertThat(page.sppName).isEqualTo("SppWithParam")
-        assertThat(page.displayName).isEqualTo("SppWithParam")
+        assertThat(page.displayName).isEqualTo("SppWithParam/myStr/10")
         assertThat(page.buildRoute()).isEqualTo("SppWithParam/myStr/10")
         assertThat(page.isCreateBy("SppWithParam")).isTrue()
-        assertThat(page.hasRuntimeParam()).isFalse()
         assertThat(page.isBrowsable()).isTrue()
     }
 
@@ -91,7 +89,7 @@
         )
         val page = spaEnvironment.createPage("SppWithRtParam", arguments)
         assertThat(page.id).isEqualTo(
-            getUniquePageId(
+            genPageId(
                 "SppWithRtParam", listOf(
                     navArgument("string_param") { type = NavType.StringType },
                     navArgument("int_param") { type = NavType.IntType },
@@ -100,10 +98,9 @@
             )
         )
         assertThat(page.sppName).isEqualTo("SppWithRtParam")
-        assertThat(page.displayName).isEqualTo("SppWithRtParam")
+        assertThat(page.displayName).isEqualTo("SppWithRtParam/myStr/10")
         assertThat(page.buildRoute()).isEqualTo("SppWithRtParam/myStr/10/rtStr")
         assertThat(page.isCreateBy("SppWithRtParam")).isTrue()
-        assertThat(page.hasRuntimeParam()).isTrue()
         assertThat(page.isBrowsable()).isFalse()
     }
 }
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/SpaIntentTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/SpaIntentTest.kt
index 1854728..f974cca 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/SpaIntentTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/SpaIntentTest.kt
@@ -19,9 +19,10 @@
 import android.content.Context
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.framework.common.NullPageProvider
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
-import com.android.settingslib.spa.framework.common.SettingsPage
 import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
+import com.android.settingslib.spa.framework.common.createSettingsPage
 import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
 import com.google.common.truth.Truth
 import org.junit.Before
@@ -40,7 +41,7 @@
 
     @Test
     fun testCreateIntent() {
-        val nullPage = SettingsPage.createNull()
+        val nullPage = NullPageProvider.createSettingsPage()
         Truth.assertThat(nullPage.createIntent()).isNull()
         Truth.assertThat(SettingsEntryBuilder.createInject(nullPage).build().createIntent())
             .isNull()
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/UniqueIdTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/UniqueIdTest.kt
new file mode 100644
index 0000000..c17f83b
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/util/UniqueIdTest.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.settingslib.spa.framework.util
+
+import androidx.core.os.bundleOf
+import androidx.navigation.NavType
+import androidx.navigation.navArgument
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.tests.testutils.createSettingsPage
+import com.google.common.truth.Truth
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class UniqueIdTest {
+    @Test
+    fun testUniquePageId() {
+        Truth.assertThat(genPageId("mySpp")).isEqualTo("1byojwa")
+
+        val parameter = listOf(
+            navArgument("string_param") { type = NavType.StringType },
+            navArgument("int_param") { type = NavType.IntType },
+        )
+        val arguments = bundleOf(
+            "string_param" to "myStr",
+            "int_param" to 10,
+        )
+        Truth.assertThat(genPageId("mySppWithParam", parameter, arguments)).isEqualTo("1sz4pbq")
+
+        val parameter2 = listOf(
+            navArgument("string_param") { type = NavType.StringType },
+            navArgument("int_param") { type = NavType.IntType },
+            navArgument("rt_param") { type = NavType.StringType },
+        )
+        val arguments2 = bundleOf(
+            "string_param" to "myStr",
+            "int_param" to 10,
+            "rt_param" to "myRtStr",
+        )
+        Truth.assertThat(genPageId("mySppWithRtParam", parameter2, arguments2)).isEqualTo("ts6d8k")
+    }
+
+    @Test
+    fun testUniqueEntryId() {
+        val owner = createSettingsPage("mySpp")
+        val fromPage = createSettingsPage("fromSpp")
+        val toPage = createSettingsPage("toSpp")
+
+        Truth.assertThat(genEntryId("myEntry", owner)).isEqualTo("145pppn")
+        Truth.assertThat(genEntryId("myEntry", owner, fromPage = fromPage, toPage = toPage))
+            .isEqualTo("1m7jzew")
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt
index 530d2ed..341a4a5 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/slice/SettingsSliceDataRepositoryTest.kt
@@ -25,10 +25,10 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
 import com.android.settingslib.spa.framework.common.createSettingsPage
+import com.android.settingslib.spa.framework.util.genEntryId
 import com.android.settingslib.spa.tests.testutils.SpaEnvironmentForTest
 import com.android.settingslib.spa.tests.testutils.SppHome
 import com.android.settingslib.spa.tests.testutils.SppLayer2
-import com.android.settingslib.spa.tests.testutils.getUniqueEntryId
 import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
@@ -52,7 +52,7 @@
 
         // Slice supported
         val page = SppLayer2.createSettingsPage()
-        val entryId = getUniqueEntryId("Layer2Entry1", page)
+        val entryId = genEntryId("Layer2Entry1", page)
         val sliceUri = Uri.Builder().appendSpaParams(page.buildRoute(), entryId).build()
         assertThat(sliceUri.getDestination()).isEqualTo("SppLayer2")
         assertThat(sliceUri.getSliceId()).isEqualTo("${entryId}_Bundle[{}]")
@@ -61,7 +61,7 @@
         assertThat(sliceDataRepository.getOrBuildSliceData(sliceUri)).isSameInstanceAs(sliceData)
 
         // Slice unsupported
-        val entryId2 = getUniqueEntryId("Layer2Entry2", page)
+        val entryId2 = genEntryId("Layer2Entry2", page)
         val sliceUri2 = Uri.Builder().appendSpaParams(page.buildRoute(), entryId2).build()
         assertThat(sliceUri2.getDestination()).isEqualTo("SppLayer2")
         assertThat(sliceUri2.getSliceId()).isEqualTo("${entryId2}_Bundle[{}]")
@@ -73,7 +73,7 @@
         SpaEnvironmentFactory.reset(spaEnvironment)
 
         val page = SppLayer2.createSettingsPage()
-        val entryId = getUniqueEntryId("Layer2Entry1", page)
+        val entryId = genEntryId("Layer2Entry1", page)
         val sliceUri = Uri.Builder().appendSpaParams(page.buildRoute(), entryId).build()
 
         // build slice data first
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SettingsPageHelper.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SettingsPageHelper.kt
new file mode 100644
index 0000000..caf4136
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/SettingsPageHelper.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.spa.tests.testutils
+
+import android.os.Bundle
+import androidx.navigation.NamedNavArgument
+import com.android.settingslib.spa.framework.common.SettingsPage
+import com.android.settingslib.spa.framework.util.genPageId
+
+fun createSettingsPage(
+    sppName: String,
+    displayName: String? = null,
+    parameter: List<NamedNavArgument> = emptyList(),
+    arguments: Bundle? = null
+): SettingsPage {
+    return SettingsPage(
+        id = genPageId(sppName, parameter, arguments),
+        sppName = sppName,
+        displayName = displayName ?: sppName,
+        parameter = parameter,
+        arguments = arguments
+    )
+}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/UniqueIdHelper.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/UniqueIdHelper.kt
deleted file mode 100644
index ce9b791..0000000
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/tests/testutils/UniqueIdHelper.kt
+++ /dev/null
@@ -1,48 +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.settingslib.spa.tests.testutils
-
-import android.os.Bundle
-import androidx.navigation.NamedNavArgument
-import com.android.settingslib.spa.framework.common.SettingsPage
-import com.android.settingslib.spa.framework.common.toHashId
-import com.android.settingslib.spa.framework.util.normalize
-
-fun getUniquePageId(
-    name: String,
-    parameter: List<NamedNavArgument> = emptyList(),
-    arguments: Bundle? = null
-): String {
-    val normArguments = parameter.normalize(arguments, eraseRuntimeValues = true)
-    return "$name:${normArguments?.toString()}".toHashId()
-}
-
-fun getUniquePageId(page: SettingsPage): String {
-    return getUniquePageId(page.sppName, page.parameter, page.arguments)
-}
-
-fun getUniqueEntryId(
-    name: String,
-    owner: SettingsPage,
-    fromPage: SettingsPage? = null,
-    toPage: SettingsPage? = null
-): String {
-    val ownerId = getUniquePageId(owner)
-    val fromId = if (fromPage == null) "null" else getUniquePageId(fromPage)
-    val toId = if (toPage == null) "null" else getUniquePageId(toPage)
-    return "$name:$ownerId($fromId-$toId)".toHashId()
-}
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle
index dd7058d..536829e 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle
+++ b/packages/SettingsLib/Spa/testutils/build.gradle
@@ -20,6 +20,7 @@
 }
 
 android {
+    namespace 'com.android.settingslib.spa.testutils'
     compileSdk TARGET_SDK
     buildToolsVersion = BUILD_TOOLS_VERSION
 
@@ -37,11 +38,11 @@
         }
     }
     compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_8
-        targetCompatibility JavaVersion.VERSION_1_8
+        sourceCompatibility JavaVersion.VERSION_11
+        targetCompatibility JavaVersion.VERSION_11
     }
     kotlinOptions {
-        jvmTarget = '1.8'
+        jvmTarget = '11'
         freeCompilerArgs = ["-Xjvm-default=all"]
     }
     buildFeatures {
@@ -55,7 +56,7 @@
 dependencies {
     api project(":spa")
 
-    api "androidx.arch.core:core-testing:2.1.0"
+    api "androidx.arch.core:core-testing:2.2.0-alpha01"
     api "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version"
     api "com.google.truth:truth:1.1.3"
     api "org.mockito:mockito-core:2.21.0"
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppStorageSize.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppStorageSize.kt
index 037b737..1a3c0ab 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppStorageSize.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppStorageSize.kt
@@ -43,5 +43,5 @@
 private fun ApplicationInfo.calculateSizeBytes(context: Context): Long {
     val storageStatsManager = context.storageStatsManager
     val stats = storageStatsManager.queryStatsForPackage(storageUuid, packageName, userHandle)
-    return stats.codeBytes + stats.dataBytes + stats.cacheBytes
+    return stats.codeBytes + stats.dataBytes
 }
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt
index 066e28a..fcacc34 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppStorageSizeTest.kt
@@ -75,7 +75,7 @@
             }
         }
 
-        composeTestRule.waitUntil { storageSize.value == "123 B" }
+        composeTestRule.waitUntil { storageSize.value == "120 B" }
     }
 
     companion object {
diff --git a/packages/SettingsLib/res/drawable/ic_media_avr_device.xml b/packages/SettingsLib/res/drawable/ic_media_avr_device.xml
new file mode 100644
index 0000000..3de0d84
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_avr_device.xml
@@ -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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:pathData="M18.918,7C18.963,7 19,7.037 19,7.082V14.918C19,14.963 18.963,15 18.918,15H3.082C3.037,15 3,14.963 3,14.918V7.082C3,7.037 3.037,7 3.082,7H18.918ZM18.918,5H3.082C1.932,5 1,5.932 1,7.082V14.918C1,16.068 1.932,17 3.082,17H18.918C20.068,17 21,16.068 21,14.918V7.082C21,5.932 20.068,5 18.918,5Z"
+        android:fillColor="#ffffff"/>
+    <path
+        android:pathData="M18,15H17C16.448,15 16,15.448 16,16V17C16,17.552 16.448,18 17,18H18C18.552,18 19,17.552 19,17V16C19,15.448 18.552,15 18,15Z"
+        android:fillColor="#ffffff"/>
+    <path
+        android:pathData="M5,15H4C3.448,15 3,15.448 3,16V17C3,17.552 3.448,18 4,18H5C5.552,18 6,17.552 6,17V16C6,15.448 5.552,15 5,15Z"
+        android:fillColor="#ffffff"/>
+    <path
+        android:pathData="M15.5,12.5C16.328,12.5 17,11.828 17,11C17,10.172 16.328,9.5 15.5,9.5C14.672,9.5 14,10.172 14,11C14,11.828 14.672,12.5 15.5,12.5Z"
+        android:fillColor="#ffffff"/>
+    <path
+        android:pathData="M15.5,10C16.052,10 16.5,10.448 16.5,11C16.5,11.552 16.052,12 15.5,12C14.948,12 14.5,11.552 14.5,11C14.5,10.448 14.948,10 15.5,10ZM15.5,9C14.397,9 13.5,9.897 13.5,11C13.5,12.103 14.397,13 15.5,13C16.603,13 17.5,12.103 17.5,11C17.5,9.897 16.603,9 15.5,9Z"
+        android:fillColor="#ffffff"/>
+    <path
+        android:pathData="M5,9h7v4h-7z"
+        android:fillColor="#ffffff"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 978f745..b1f2cee 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Hierdie foon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Hierdie tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Hierdie foon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Gradeer rekening op om oor te skakel"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan nie aflaaie hier speel nie"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Probeer weer ná die advertensie"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kan nie koppel nie. Skakel toestel af en weer aan"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedrade oudiotoestel"</string>
     <string name="help_label" msgid="3528360748637781274">"Hulp en terugvoer"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellingteruggebaaranimasies"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktiveer stelselanimasies vir voorspellingteruggebaar."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Hierdie instelling aktiveer stelselanimasies vir voorspellinggebaaranimasie. Dit vereis dat enableOnBackInvokedCallback per program op waar gestel word in die manifeslêer."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Skuif links"</item>
+    <item msgid="5425394847942513942">"Skuif af"</item>
+    <item msgid="7728484337962740316">"Skuif regs"</item>
+    <item msgid="324200556467459329">"Skuif op"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 8f1a2a9..cf4b62d 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"የግምት ጀርባ እነማዎች"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ለግምት ጀርባ የስርዓት እንማዎችን ያንቁ።"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ይህ ቅንብር የስርዓት እነማዎችን ለመገመት የምልክት እነማን ያነቃል። በዝርዝር ሰነድ ፋይሉ ውስጥ በእያንዳንዱ መተግበሪያ enableOnBackInvokedCallbackን ወደ እውነት ማቀናበር ያስፈልገዋል።"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ወደ ግራ ውሰድ"</item>
+    <item msgid="5425394847942513942">"ወደ ታች ውሰድ"</item>
+    <item msgid="7728484337962740316">"ወደ ቀኝ ውሰድ"</item>
+    <item msgid="324200556467459329">"ወደ ላይ ውሰድ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 669f85f..1b4b521 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"صور متحركة تعرض إيماءة الرجوع إلى الخلف التنبؤية"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"فعِّل الصور المتحركة في النظام لإيماءة الرجوع إلى الخلف التنبؤية."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏يفعّل هذا الإعداد الصور المتحركة في النظام للصور المتحركة التي تعرض إيماءة الرجوع إلى الخلف التنبؤية. يتطلب الإعداد ضبط enableOnBackInvokedCallback إلى true لكل تطبيق في ملف البيان."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"نقل لليسار"</item>
+    <item msgid="5425394847942513942">"نقل للأسفل"</item>
+    <item msgid="7728484337962740316">"نقل لليمين"</item>
+    <item msgid="324200556467459329">"نقل للأعلى"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index f9745e0..454c6ed 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"প্ৰেডিক্টিভ বেক এনিমেশ্বন"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"প্ৰেডিক্টিভ বেকৰ বাবে ছিষ্টেম এনিমেশ্বন সক্ষম কৰক।"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"এই ছেটিংটোৱে প্ৰেডিক্টিভ বেক এনিমেশ্বনৰ বাবে ছিষ্টেম এনিমেশ্বন সক্ষম কৰে। ইয়াৰ বাবে মেনিফেষ্ট ফাইলত প্ৰতি এপত enableOnBackInvokedCallback সত্য বুলি ছেট কৰাৰ প্ৰয়োজন।"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"বাওঁফাললৈ নিয়ক"</item>
+    <item msgid="5425394847942513942">"তললৈ নিয়ক"</item>
+    <item msgid="7728484337962740316">"সোঁফাললৈ নিয়ক"</item>
+    <item msgid="324200556467459329">"ওপৰলৈ নিয়ক"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index efcc0bc..fa7af3b 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Bu telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Bu planşet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Keçirmək üçün hesabı təkmilləşdirin"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Burada endirmələri oxutmaq mümkün deyil"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamdan sonra yenidən cəhd edin"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Qoşulmaqla bağlı problem. Cihazı deaktiv edin, sonra yenidən aktiv edin"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio cihaz"</string>
     <string name="help_label" msgid="3528360748637781274">"Yardım və rəy"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Proqnozlaşdırılan geri animasiyalar"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Proqnozlaşdırıcı geri jest üçün sistem animasiyalarını aktiv edin."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu ayar proqnozlaşdırıcı jest animasiyası üçün sistem animasiyalarını aktiv edir. Bu, manifest faylında hər bir tətbiq üçün enableOnBackInvokedCallback-in doğru kimi ayarlanmasını tələb edir."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Sola köçürün"</item>
+    <item msgid="5425394847942513942">"Aşağı köçürün"</item>
+    <item msgid="7728484337962740316">"Sağa köçürün"</item>
+    <item msgid="324200556467459329">"Yuxarı köçürün"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index c8955e8..ef74b68 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite nalog radi prebacivanja"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Preuzimanja ne mogu da se puštaju ovde"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Probajte ponovo posle oglasa"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka sa predviđanjem"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućite animacije sistema za pokret povratka sa predviđanjem."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ovo podešavanje omogućava animacije sistema za pokret povratka sa predviđanjem. Zahteva podešavanje dozvole enableOnBackInvokedCallback po aplikaciji na true u fajlu manifesta."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Pomerite nalevo"</item>
+    <item msgid="5425394847942513942">"Pomerite nadole"</item>
+    <item msgid="7728484337962740316">"Pomerite nadesno"</item>
+    <item msgid="324200556467459329">"Pomerite nagore"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index cd7b198..0c75f26 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Анімацыя падказкі для жэста вяртання"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Уключыць сістэмную анімацыю падказкі для жэстаў вяртання."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Гэта налада ўключае сістэмную анімацыю падказкі для жэста вяртання. Для гэтага неабходна задаць у файле маніфеста для параметра enableOnBackInvokedCallback значэнне \"True\" для кожнай праграмы."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Перамясціць улева"</item>
+    <item msgid="5425394847942513942">"Перамясціць уніз"</item>
+    <item msgid="7728484337962740316">"Перамясціць управа"</item>
+    <item msgid="324200556467459329">"Перамясціць уверх"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index a337429..cd5572a 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Анимации за предвиждащия жест за връщане назад"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Активиране на системните анимации за предвиждащия жест за връщане назад."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Тази настройка активира системните анимации за предвиждащите жестове. За целта във файла на манифеста трябва да зададете enableOnBackInvokedCallback на true за отделните приложения."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Преместване наляво"</item>
+    <item msgid="5425394847942513942">"Преместване надолу"</item>
+    <item msgid="7728484337962740316">"Преместване надясно"</item>
+    <item msgid="324200556467459329">"Преместване нагоре"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 28a1598..423309f 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ফিরে যাওয়ার পূর্বাভাস সংক্রান্ত অ্যানিমেশন"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ফিরে যাওয়া সংক্রান্ত পূর্বাভাসের জন্য সিস্টেম অ্যানিমেশন চালু করুন।"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"জেসচারের পূর্বাভাস সংক্রান্ত অ্যানিমেশন দেখাতে এই সেটিং সিস্টেম অ্যানিমেশন চালু করে। এই সেটিংয়ে \'ম্যানিফেস্ট\' ফাইলে প্রত্যেক অ্যাপে enableOnBackInvokedCallback অ্যাট্রিবিউটকে \'ট্রু\' (true) হিসেবে সেট করতে হয়।"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"বাঁদিকে সরান"</item>
+    <item msgid="5425394847942513942">"নিচে নামান"</item>
+    <item msgid="7728484337962740316">"ডানদিকে সরান"</item>
+    <item msgid="324200556467459329">"উপরে সরান"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index e24c68d..574fa9d 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite račun da promijenite"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Nije moguće reproducirati preuzimanja ovdje"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Pokušajte ponovo nakon oglasa"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Došlo je do problema prilikom povezivanja. Isključite, pa ponovo uključite uređaj"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije predvidljivog pokreta unazad"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogućite animacije sistema za predvidljivi pokret unazad."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ova postavka omogućava animacije sistema za animaciju predvidljivih pokreta. Potrebno je po aplikaciji postaviti vrijednost za enableOnBackInvokedCallback na tačno u fajlu deklaracije."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Pomjeranje ulijevo"</item>
+    <item msgid="5425394847942513942">"Pomjeranje nadolje"</item>
+    <item msgid="7728484337962740316">"Pomjeranje udesno"</item>
+    <item msgid="324200556467459329">"Pomjeranje nagore"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index b6f1590..3062e7d 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -232,7 +232,7 @@
     <item msgid="8612549335720461635">"4K (segur)"</item>
     <item msgid="7322156123728520872">"4K (ampliat)"</item>
     <item msgid="7735692090314849188">"4K (ampliat, segur)"</item>
-    <item msgid="7346816300608639624">"720p, 1080p (pantalla doble)"</item>
+    <item msgid="7346816300608639624">"720p, 1080p (pantalla dual)"</item>
   </string-array>
   <string-array name="enable_opengl_traces_entries">
     <item msgid="4433736508877934305">"Cap"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 2abdf00..0ccd82a 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Aquest telèfon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Aquesta tauleta"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Aquest telèfon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualitza el compte per canviar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Les baixades no es poden reproduir aquí"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Torna-ho a provar després de l\'anunci"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Apaga el dispositiu i torna\'l a encendre."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositiu d\'àudio amb cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda i suggeriments"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacions de retrocés predictiu"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activa animacions del sistema de retrocés predictiu."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Aquesta configuració activa animacions del sistema per a accions gestuals predictives. Requereix definir enableOnBackInvokedCallback com a \"true\" en cada aplicació al fitxer de manifest."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mou cap a l\'esquerra"</item>
+    <item msgid="5425394847942513942">"Mou cap avall"</item>
+    <item msgid="7728484337962740316">"Mou cap a la dreta"</item>
+    <item msgid="324200556467459329">"Mou cap amunt"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index d82b472..f2bf000 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Tento telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tento tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Pokud chcete přejít, upgradujte účet"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Stažený obsah zde nelze přehrát"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Zkuste to znovu po reklamě"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problém s připojením. Vypněte zařízení a znovu jej zapněte"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kabelové audiozařízení"</string>
     <string name="help_label" msgid="3528360748637781274">"Nápověda a zpětná vazba"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Prediktivní animace gesta Zpět"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Povolit systémové animace prediktivního gesta Zpět"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Toto nastavení aktivuje systémové prediktivní animace gest. Vyžaduje, aby v souborech manifestu jednotlivých aplikací byl nastaven atribut enableOnBackInvokedCallback na hodnotu True."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Přesunout doleva"</item>
+    <item msgid="5425394847942513942">"Přesunout dolů"</item>
+    <item msgid="7728484337962740316">"Přesunout doprava"</item>
+    <item msgid="324200556467459329">"Přesunout nahoru"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 9726f8c..9671f5e 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
     <string name="help_label" msgid="3528360748637781274">"Hjælp og feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Foreslåede animationer for Tilbage"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivér systemanimationer for foreslåede animationer for Tilbage."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Denne indstilling aktiverer systemanimationer for de foreslåede animationer for bevægelsen Tilbage. Dette forudsætter konfiguration af enableOnBackInvokedCallback som sand for hver app i manifestfilen."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Flyt til venstre"</item>
+    <item msgid="5425394847942513942">"Flyt ned"</item>
+    <item msgid="7728484337962740316">"Flyt til højre"</item>
+    <item msgid="324200556467459329">"Flyt op"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 68199dd..9e77007 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Dieses Smartphone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Dieses Tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Dieses Smartphone"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Zum Umstellen Kontoupgrade durchführen"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Downloads können hier nicht abgespielt werden"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Nach Werbung noch einmal versuchen"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus &amp; und wieder ein."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string>
     <string name="help_label" msgid="3528360748637781274">"Hilfe und Feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animationen für intelligente „Zurück“-Touch-Geste"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Du kannst Systemanimationen für die intelligente „Zurück“-Touch-Geste aktivieren."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Diese Einstellung aktiviert Systemanimationen für intelligente Touch-Gesten. Dazu muss in der Manifestdatei enableOnBackInvokedCallback auf App-Ebene auf „true“ gesetzt werden."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Nach links"</item>
+    <item msgid="5425394847942513942">"Nach unten"</item>
+    <item msgid="7728484337962740316">"Nach rechts"</item>
+    <item msgid="324200556467459329">"Nach oben"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 974c998..2ca882d 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Αυτό το τηλέφωνο"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Αυτό το tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Αυτό το τηλέφωνο"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Κινούμ. εικόνες μετάβασης προς τα πίσω με πρόβλεψη"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ενεργοποίηση κινούμενων εικόνων συστήματος για μετάβαση προς τα πίσω με πρόβλεψη."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Αυτή η ρύθμιση ενεργοποιεί τις κινούμενες εικόνες συστήματος για τις κινούμενες εικόνες κινήσεων με πρόβλεψη. Απαιτεί τη ρύθμιση της παραμέτρου enableOnBackInvokedCallback ως αληθούς σε κάθε εφαρμογή στο αρχείο μανιφέστου."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Μετακίνηση αριστερά"</item>
+    <item msgid="5425394847942513942">"Μετακίνηση προς τα κάτω"</item>
+    <item msgid="7728484337962740316">"Μετακίνηση δεξιά"</item>
+    <item msgid="324200556467459329">"Μετακίνηση προς τα επάνω"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index c6443bd..fa40a7b 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -540,6 +540,13 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Try again after the ad"</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Wake up device to play here"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Device not approved to play"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Can\'t play this media here"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
@@ -666,4 +673,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Move left"</item>
+    <item msgid="5425394847942513942">"Move down"</item>
+    <item msgid="7728484337962740316">"Move right"</item>
+    <item msgid="324200556467459329">"Move up"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 03475be..1ed09ef 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -540,6 +540,13 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Cant play on this device"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Cant play downloads here"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Try again after the ad"</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Wake up device to play here"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Device not approved to play"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Cant play this media here"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off &amp; back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
@@ -666,4 +673,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Move left"</item>
+    <item msgid="5425394847942513942">"Move down"</item>
+    <item msgid="7728484337962740316">"Move right"</item>
+    <item msgid="324200556467459329">"Move up"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index c6443bd..fa40a7b 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -540,6 +540,13 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Try again after the ad"</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Wake up device to play here"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Device not approved to play"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Can\'t play this media here"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
@@ -666,4 +673,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Move left"</item>
+    <item msgid="5425394847942513942">"Move down"</item>
+    <item msgid="7728484337962740316">"Move right"</item>
+    <item msgid="324200556467459329">"Move up"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index c6443bd..fa40a7b 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -540,6 +540,13 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"This tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"This phone"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Can\'t play on this device"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade account to switch"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Can\'t play downloads here"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Try again after the ad"</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"Wake up device to play here"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"Device not approved to play"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"Can\'t play this media here"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
@@ -666,4 +673,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Predictive back animations"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Enable system animations for predictive back."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Move left"</item>
+    <item msgid="5425394847942513942">"Move down"</item>
+    <item msgid="7728484337962740316">"Move right"</item>
+    <item msgid="324200556467459329">"Move up"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 113ea19..11797d5 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -540,6 +540,13 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎This phone‎‏‎‎‏‎"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎This tablet‎‏‎‎‏‎"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎This phone‎‏‎‎‏‎"</string>
+    <string name="media_output_status_unknown_error" msgid="5098565887497902222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎Cant play on this device‎‏‎‎‏‎"</string>
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎Upgrade account to switch‎‏‎‎‏‎"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎Cant play downloads here‎‏‎‎‏‎"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎Try again after the ad‎‏‎‎‏‎"</string>
+    <string name="media_output_status_device_in_low_power_mode" msgid="8184631698321758451">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‏‎Wake up device to play here‎‏‎‎‏‎"</string>
+    <string name="media_output_status_unauthorized" msgid="5880222828273853838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎Device not approved to play‎‏‎‎‏‎"</string>
+    <string name="media_output_status_track_unsupported" msgid="5576313219317709664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎Cant play this media here‎‏‎‎‏‎"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‎Problem connecting. Turn device off &amp; back on‎‏‎‎‏‎"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎Wired audio device‎‏‎‎‏‎"</string>
     <string name="help_label" msgid="3528360748637781274">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎Help &amp; feedback‎‏‎‎‏‎"</string>
@@ -666,4 +673,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎Predictive back animations‎‏‎‎‏‎"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎Enable system animations for predictive back.‎‏‎‎‏‎"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎This setting enables system animations for predictive gesture animation. It requires setting per-app enableOnBackInvokedCallback to true in the manifest file.‎‏‎‎‏‎"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎Move left‎‏‎‎‏‎"</item>
+    <item msgid="5425394847942513942">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‎Move down‎‏‎‎‏‎"</item>
+    <item msgid="7728484337962740316">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎Move right‎‏‎‎‏‎"</item>
+    <item msgid="324200556467459329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎Move up‎‏‎‎‏‎"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 220ca44..3e97c32 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este teléfono"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Esta tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir las descargas aquí"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Vuelve a intentarlo después del anuncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Error al establecer la conexión. Apaga el dispositivo y vuelve a encenderlo."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animaciones de retroceso predictivas"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Habilitar animaciones del sistema para gestos de retroceso predictivos."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuración habilita las animaciones del sistema para la animación de gestos predictiva. Se requiere la configuración por app de enableOnBackInvokedCallback en verdadero en el archivo de manifiesto."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mover hacia la izquierda"</item>
+    <item msgid="5425394847942513942">"Mover hacia abajo"</item>
+    <item msgid="7728484337962740316">"Mover hacia la derecha"</item>
+    <item msgid="324200556467459329">"Mover hacia arriba"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index bdd1ff2..eb176a9 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este teléfono"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Actualiza la cuenta para cambiar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"No se pueden reproducir descargas aquí"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Prueba de nuevo después del anuncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
@@ -579,7 +590,7 @@
     <string name="user_need_lock_message" msgid="4311424336209509301">"Para poder crear un perfil restringido, debes configurar una pantalla de bloqueo que proteja tus aplicaciones y datos personales."</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"Establecer bloqueo"</string>
     <string name="user_switch_to_user" msgid="6975428297154968543">"Cambiar a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
-    <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario…"</string>
+    <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Creando usuario nuevo…"</string>
     <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Creando nuevo invitado…"</string>
     <string name="add_user_failed" msgid="4809887794313944872">"No se ha podido crear el usuario"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"No se ha podido crear un nuevo invitado"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animaciones para acciones de retorno predictivas"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Habilitar animaciones del sistema para acciones de retorno predictivas."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Este ajuste habilita animaciones del sistema para acciones gestuales predictivas. Exige definir el valor de enableOnBackInvokedCallback en \"verdadero\" para cada aplicación en el archivo de manifiesto."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Muévete hacia la izquierda"</item>
+    <item msgid="5425394847942513942">"Muévete hacia abajo"</item>
+    <item msgid="7728484337962740316">"Muévete hacia la derecha"</item>
+    <item msgid="324200556467459329">"Muévete hacia arriba"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index cdc5051..3f0a6ed 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"See telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"See tahvelarvuti"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"See telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Lülitamiseks täiendage kontot"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Siin ei saa allalaaditud faile esitada"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Proovige pärast reklaami uuesti"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem ühendamisel. Lülitage seade välja ja uuesti sisse"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Juhtmega heliseade"</string>
     <string name="help_label" msgid="3528360748637781274">"Abi ja tagasiside"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Tagasiliigutuse prognoosi animatsioon"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Lubage süsteemi animatsioonid, et näha prognoositud tagasiliigutusi."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"See seade võimaldab süsteemi animatsioonidel prognoosida tagasiliigutusi. See nõuab manifestifailis rakendusepõhise atribuudi enableOnBackInvokedCallback määramist tõeseks."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Liiguta vasakule"</item>
+    <item msgid="5425394847942513942">"Liiguta alla"</item>
+    <item msgid="7728484337962740316">"Liiguta paremale"</item>
+    <item msgid="324200556467459329">"Liiguta üles"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 9d6a10a..4fe2e23 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Telefono hau"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tableta hau"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefono hau"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Aldatzeko, bertsio-berritu kontua"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Deskargak ezin dira hemen erreproduzitu"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Saiatu berriro iragarkiaren ondoren"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Arazo bat izan da konektatzean. Itzali gailua eta pitz ezazu berriro."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
     <string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Atzera egiteko keinuaren animazio-igarleak"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Gaitu atzera egiteko keinuaren sistemaren animazio-igarleak."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Atzera egiteko keinuaren sistemaren animazio-igarleak gaitzen ditu ezarpenak. enableOnBackInvokedCallback-ek egiazko gisa ezarrita egon behar du aplikazio bakoitzaren manifestu-fitxategian."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Eraman ezkerrera"</item>
+    <item msgid="5425394847942513942">"Eraman behera"</item>
+    <item msgid="7728484337962740316">"Eraman eskuinera"</item>
+    <item msgid="324200556467459329">"Eraman gora"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index b922640..c7f01af 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -183,7 +183,7 @@
     <string name="tts_lang_use_system" msgid="6312945299804012406">"استفاده از زبان سیستم"</string>
     <string name="tts_lang_not_selected" msgid="7927823081096056147">"زبان انتخاب نشده است"</string>
     <string name="tts_default_lang_summary" msgid="9042620014800063470">"صدای خاص یک زبان را برای متن گفتاری تنظیم می‌کند"</string>
-    <string name="tts_play_example_title" msgid="1599468547216481684">"به نمونه‌ای گوش کنید"</string>
+    <string name="tts_play_example_title" msgid="1599468547216481684">"شنیدن نمونه"</string>
     <string name="tts_play_example_summary" msgid="634044730710636383">"قسمت کوتاهی از ترکیب گفتار پخش شود"</string>
     <string name="tts_install_data_title" msgid="1829942496472751703">"نصب داده‌های صوتی"</string>
     <string name="tts_install_data_summary" msgid="3608874324992243851">"نصب داده‌های صوتی مورد نیاز برای ترکیب گفتار"</string>
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"پویانمایی‌های اشاره برگشت پیش‌گویانه"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"پویانمایی‌های سیستم را برای اشاره برگشت پیش‌گویانه فعال کنید."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏این تنظیم پویانمایی‌های سیستم را برای پویانمایی اشاره برگشت پیش‌بینانه فعال می‌کند. این تنظیم مستلزم تنظیم شدن enableOnBackInvokedCallback مربوط به هر برنامه روی صحیح در فایل مانیفست است."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"انتقال به‌چپ"</item>
+    <item msgid="5425394847942513942">"انتقال به‌پایین"</item>
+    <item msgid="7728484337962740316">"انتقال به‌راست"</item>
+    <item msgid="324200556467459329">"انتقال به‌بالا"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 1bebe1c..a81c176 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Tämä puhelin"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tämä tabletti"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tämä puhelin"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Vaihda päivittämällä tili"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Latauksia ei voi toistaa täällä"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Kokeile uudelleen mainoksen jälkeen"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Yhteysvirhe. Sammuta laite ja käynnistä se uudelleen."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Langallinen äänilaite"</string>
     <string name="help_label" msgid="3528360748637781274">"Ohje ja palaute"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Takaisin siirtymisen ennakoivat animaatiot"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ota käyttöön takaisin siirtymisen ennakoivat järjestelmäanimaatiot."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Asetus ottaa järjestelmäanimaatiot käyttöön ennakoiville eleanimaatioille. Se edellyttää, että enableOnBackInvokedCallback-arvo on Tosi sovelluksen manifestitiedostossa."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Siirrä vasemmalle"</item>
+    <item msgid="5425394847942513942">"Siirrä alas"</item>
+    <item msgid="7728484337962740316">"Siirrä oikealle"</item>
+    <item msgid="324200556467459329">"Siirrä ylös"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 5721d0b..6e1d09e 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ce téléphone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Cette tablette"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à jour le compte pour passer à la version payante"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Lecture des téléchargements impossible ici"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Réessayez après l\'annonce"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteingez et rallumez l\'appareil"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio à câble"</string>
     <string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animations pour le retour prédictif"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activer les animations système pour le retour prédictif."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre permet d\'activer les animations du système pour l\'animation des gestes prédictifs. Cela exige de définir le paramètre enableOnBackInvokedCallback à Vrai pour chaque application dans le fichier de configuration."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Déplacez vers la gauche"</item>
+    <item msgid="5425394847942513942">"Déplacez vers le bas"</item>
+    <item msgid="7728484337962740316">"Déplacez vers la droite"</item>
+    <item msgid="324200556467459329">"Déplacez vers le haut"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 2088854..f74b2bb 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ce téléphone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Cette tablette"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ce téléphone"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Mettez à niveau le compte pour changer"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Impossible de lire les téléchargements ici"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Réessayez après l\'annonce"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez l\'appareil, puis rallumez-le"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio filaire"</string>
     <string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animations pour prévisualiser le retour en arrière"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activer les animations système pour la prévisualisation du geste de retour."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre active les animations système pour la prévisualisation du geste de retour. Pour cela, enableOnBackInvokedCallback doit être défini sur \"True\" dans le fichier manifeste de chaque appli."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Déplacer vers la gauche"</item>
+    <item msgid="5425394847942513942">"Déplacer vers le bas"</item>
+    <item msgid="7728484337962740316">"Déplacer vers la droite"</item>
+    <item msgid="324200556467459329">"Déplacer vers le haut"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index fec8a71..d1d6afe 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -180,7 +180,7 @@
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"Ton"</string>
     <string name="tts_default_pitch_summary" msgid="9132719475281551884">"Afecta ao ton da voz sintetizada"</string>
     <string name="tts_default_lang_title" msgid="4698933575028098940">"Idioma"</string>
-    <string name="tts_lang_use_system" msgid="6312945299804012406">"Utiliza o idioma do sistema"</string>
+    <string name="tts_lang_use_system" msgid="6312945299804012406">"Utilizar o idioma do sistema"</string>
     <string name="tts_lang_not_selected" msgid="7927823081096056147">"Idioma non seleccionado"</string>
     <string name="tts_default_lang_summary" msgid="9042620014800063470">"Define a voz específica do idioma para o texto falado"</string>
     <string name="tts_play_example_title" msgid="1599468547216481684">"Escoitar un exemplo"</string>
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este teléfono"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Esta tableta"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Cambia a conta a un plan superior para facer a modificación"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Non se poden reproducir as descargas neste dispositivo"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Téntao de novo despois de que remate o anuncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Produciuse un problema coa conexión. Apaga e acende o dispositivo."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Axuda e comentarios"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacións de retroceso preditivo"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activa as animacións do sistema para o retroceso preditivo."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta opción de configuración activa as animacións xestuais preditivas. É preciso definir enableOnBackInvokedCallback como True (verdadeiro) para cada aplicación no ficheiro de manifesto."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mover cara á esquerda"</item>
+    <item msgid="5425394847942513942">"Mover cara abaixo"</item>
+    <item msgid="7728484337962740316">"Mover cara á dereita"</item>
+    <item msgid="324200556467459329">"Mover cara arriba"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 0feef07..00435d8 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"પાછળના પૂર્વાનુમાનિત ઍનિમેશન્સ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"પાછળના પૂર્વાનુમાનિત સંકેત માટે સિસ્ટમ ઍનિમેશન ચાલુ કરો."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"આ સેટિંગ પૂર્વાનુમાનિત સંકેત ઍનિમેશન માટે સિસ્ટમ ઍનિમેશન ચાલુ કરે છે. તેના માટે દરેક ઍપ માટે મેનિફેસ્ટ ફાઇલમાં enableOnBackInvokedCallbackને true પર સેટ કરવાની જરૂર પડે છે."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ડાબે ખસેડો"</item>
+    <item msgid="5425394847942513942">"નીચે ખસેડો"</item>
+    <item msgid="7728484337962740316">"જમણે ખસેડો"</item>
+    <item msgid="324200556467459329">"ઉપર ખસેડો"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index ea8d4d45..b5bee94 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"प्रिडिक्टिव बैक ऐनिमेशन"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"प्रिडिक्टिव बैक के लिए सिस्टम ऐनिमेशन चालू करें."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"यह सेटिंग, सिस्टम के ऐनिमेशन को प्रिडिक्टिव जेस्चर ऐनिमेशन के लिए चालू कर देती है. मेनिफ़ेस्ट फ़ाइल में enableOnBackInvokedCallback की सेटिंग को हर ऐप्लिकेशन के हिसाब से \'सही\' पर सेट होना चाहिए."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"बाईं ओर ले जाएं"</item>
+    <item msgid="5425394847942513942">"नीचे ले जाएं"</item>
+    <item msgid="7728484337962740316">"दाईं ओर ले जाएं"</item>
+    <item msgid="324200556467459329">"ऊपर की ओर ले जाएं"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index bccb9d7..bf6ee8b 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ovaj tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ovaj telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nadogradite račun radi prebacivanja"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Preuzimanja se ne mogu reproducirati ovdje"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Pokušajte ponovo nakon oglasa"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem s povezivanjem. Isključite i ponovo uključite uređaj"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audiouređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije za pokret povratka s predviđanjem"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogući animaciju kad korisnik napravi povratnu kretnju."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ova postavka omogućuje animacije sustava za animaciju pokreta s predviđanjem. Zahtijeva postavljanje dopuštenja enableOnBackInvokedCallback po aplikaciji na True u datoteci manifesta."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Pomicanje ulijevo"</item>
+    <item msgid="5425394847942513942">"Pomicanje prema dolje"</item>
+    <item msgid="7728484337962740316">"Pomicanje udesno"</item>
+    <item msgid="324200556467459329">"Pomicanje prema gore"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 5af85ea..327acde 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ez a telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ez a táblagép"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ez a telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"A váltáshoz frissítse fiókját magasabb kategóriára"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Itt nem lehet lejátszani a letöltött elemeket"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Próbálja újra a hirdetés után"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sikertelen csatlakozás. Kapcsolja ki az eszközt, majd kapcsolja be újra."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vezetékes audioeszköz"</string>
     <string name="help_label" msgid="3528360748637781274">"Súgó és visszajelzés"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Prediktív „vissza” kézmozdulat-animációk"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Rendszeranimációk engedélyezése prediktív „vissza” kézmozdulatok esetén."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"A beállítás engedélyezi a rendszeranimációkat a prediktív kézmozdulat-animációk esetén. A használatukhoz az enableOnBackInvokedCallback beállítást true értékre kell állítani az egyes alkalmazások manifestfájljaiban."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mozgatás balra"</item>
+    <item msgid="5425394847942513942">"Mozgatás lefelé"</item>
+    <item msgid="7728484337962740316">"Mozgatás jobbra"</item>
+    <item msgid="324200556467459329">"Mozgatás felfelé"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 2d01b37..1e584f9 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"«Հետ» ժեստի հուշման շարժանկարներ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Միացնել համակարգի անիմացիաները «Հետ» ժեստի հուշման համար"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Այս կարգավորման միջոցով կարելի է միացնել համակարգային շարժանկարները ժեստի հուշման համար։ Կարգավորումը պահանջում է մանիֆեստի ֆայլում սահմանել true արժեքը per-app enableOnBackInvokedCallback հատկության համար։"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Տեղափոխել ձախ"</item>
+    <item msgid="5425394847942513942">"Տեղափոխել ներքև"</item>
+    <item msgid="7728484337962740316">"Տեղափոխել աջ"</item>
+    <item msgid="324200556467459329">"Տեղափոխել վերև"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index e78b339..acedc1c 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ponsel ini"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tablet ini"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ponsel ini"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade akun untuk beralih"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memutar hasil download di sini"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Coba lagi setelah iklan"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ada masalah saat menghubungkan. Nonaktifkan perangkat &amp; aktifkan kembali"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Perangkat audio berkabel"</string>
     <string name="help_label" msgid="3528360748637781274">"Bantuan &amp; masukan"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animasi kembali prediktif"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktifkan animasi sistem untuk kembali prediktif."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Setelan ini mengaktifkan animasi sistem untuk animasi gestur prediktif. Setelan ini mewajibkan enableOnBackInvokedCallback per-aplikasi disetel ke benar (true) dalam file manifes."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Pindahkan ke kiri"</item>
+    <item msgid="5425394847942513942">"Pindahkan ke bawah"</item>
+    <item msgid="7728484337962740316">"Pindahkan ke kanan"</item>
+    <item msgid="324200556467459329">"Pindahkan ke atas"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 9094af6..cf9d475 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Þessi sími"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Þessi spjaldtölva"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Þessi sími"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Uppfærðu reikninginn til að skipta"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Ekki er hægt að spila niðurhal hér"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reyndu aftur eftir auglýsinguna"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Vandamál í tengingu. Slökktu og kveiktu á tækinu"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Snúrutengt hljómtæki"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjálp og ábendingar"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Hreyfimyndir flýtiritunar við bendinguna „til baka“"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Kveikja á hreyfimyndum í kerfinu til að sýna hreyfimyndir þegar bendingin „til baka“ er gerð."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Þessi stilling kveikir á hreyfimyndum í kerfinu til að sýna hreyfimyndir flýtiritunar með bendingum. Stillingin krefst þess að kveikt sé á enableOnBackInvokedCallback í upplýsingaskránni fyrir hvert forrit."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Færa til vinstri"</item>
+    <item msgid="5425394847942513942">"Færa niður"</item>
+    <item msgid="7728484337962740316">"Færa til hægri"</item>
+    <item msgid="324200556467459329">"Færa upp"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 138f341..524e83d 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Questo telefono"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Questo tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Questo telefono"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Esegui l\'upgrade dell\'account per cambiare"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Qui non è possibile riprodurre i download"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Riprova dopo l\'annuncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema di connessione. Spegni e riaccendi il dispositivo"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo audio cablato"</string>
     <string name="help_label" msgid="3528360748637781274">"Guida e feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animazioni predittive per Indietro"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Attiva le animazioni di sistema per il gesto Indietro predittivo."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Questa impostazione attiva le animazioni di sistema per il gesto Indietro predittivo. Richiede di impostare il metodo enableOnBackInvokedCallback su true nel file manifest di tutte le app."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Sposta a sinistra"</item>
+    <item msgid="5425394847942513942">"Sposta in basso"</item>
+    <item msgid="7728484337962740316">"Sposta a destra"</item>
+    <item msgid="324200556467459329">"Sposta in alto"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 58fede9..c1a2a4c 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"חיזוי אנימציה של תנועת החזרה"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"הפעלת אנימציות מערכת עבור חיזוי של תנועת החזרה."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏ההגדרה הזו מפעילה אנימציות מערכת עבור חיזוי אנימציה של תנועת החזרה. היא מחייבת הגדרה בכל אפליקציה של ערך true בשדה enableOnBackInvokedCallback בקובץ המניפסט."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"הזזה שמאלה"</item>
+    <item msgid="5425394847942513942">"הזזה למטה"</item>
+    <item msgid="7728484337962740316">"הזזה ימינה"</item>
+    <item msgid="324200556467459329">"הזזה למעלה"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index a2c59ff..7143f47 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"接続エラーです。デバイスを OFF にしてから ON に戻してください"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線オーディオ デバイス"</string>
     <string name="help_label" msgid="3528360748637781274">"ヘルプとフィードバック"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"予測型「戻る」アニメーション"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"予測型「戻る」のシステム アニメーションを有効にする。"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"この設定は、予測型操作のシステム アニメーションを有効にします。アプリごとにマニフェスト ファイルで enableOnBackInvokedCallback を true に設定する必要があります。"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"左に移動"</item>
+    <item msgid="5425394847942513942">"下に移動"</item>
+    <item msgid="7728484337962740316">"右に移動"</item>
+    <item msgid="324200556467459329">"上に移動"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index cc04f56..61bad37 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"უკან დაბრუნების ანიმაციის პროგნოზირება"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"უკან დაბრუნების პროგნოზირებადი ანიმაციისთვის სისტემის ანიმაციების ჩართვა."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ეს პარამეტრი ჩართავს სისტემის ანიმაციებს ჟესტების პროგნოზირებადი ანიმაციებისთვის. საჭიროა, რომ აღწერის ფაილში აპის enableOnBackInvokedCallback პარამეტრი იყოს ჭეშმარიტი."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"მარცხნივ გადატანა"</item>
+    <item msgid="5425394847942513942">"ქვემოთ გადატანა"</item>
+    <item msgid="7728484337962740316">"მარჯვნივ გადატანა"</item>
+    <item msgid="324200556467459329">"ზემოთ გადატანა"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 43a72db..111c6c2 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"\"Артқа\" қимылына арналған тұспал анимациясы"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"\"Артқа\" қимылына арналған жүйелік тұспал анимацияларын іске қосу."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Бұл параметр қимылға арналған жүйелік тұспал анимацияларын іске қосады. Ол үшін әр қолданбаның манифест файлында enableOnBackInvokedCallback үшін \"True\" мәні қойылуы керек."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Солға жылжыту"</item>
+    <item msgid="5425394847942513942">"Төмен жылжыту"</item>
+    <item msgid="7728484337962740316">"Оңға жылжыту"</item>
+    <item msgid="324200556467459329">"Жоғары жылжыту"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index a340188..36769b9 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ចលនា​ថយក្រោយ​ដែល​ព្យាករ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"បើក​ចលនា​ប្រព័ន្ធ​សម្រាប់​ការ​ថយក្រោយ​ព្យាករ។"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ការ​កំណត់នេះ​បើក​ចលនា​ប្រព័ន្ធ​សម្រាប់​ចលនាព្យាករ។ ចលនា​នេះ​ទាមទារ​ការ​កំណត់ enableOnBackInvokedCallback នៅ​ក្នុងកម្មវិធី​ទៅពិត​នៅ​ក្នុង​ឯកសារ​មេនីហ្វេសថ៍។"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ផ្លាស់ទី​ទៅ​ឆ្វេង"</item>
+    <item msgid="5425394847942513942">"ផ្លាស់ទី​ចុះ​ក្រោម"</item>
+    <item msgid="7728484337962740316">"ផ្លាស់ទីទៅ​ស្តាំ"</item>
+    <item msgid="324200556467459329">"ផ្លាស់ទី​ឡើង​លើ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 0348795..42749bf 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ಮುನ್ಸೂಚಕ ಬ್ಯಾಕ್ ಆ್ಯನಿಮೇಶನ್‌ಗಳು"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ಮುನ್ಸೂಚಕ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್‌ಗಾಗಿ ಸಿಸ್ಟಂ ಆ್ಯನಿಮೇಶನ್‌ಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ಮುನ್ನೋಟದ ಗೆಸ್ಚರ್ ಆ್ಯನಿಮೇಶನ್‌ಗಾಗಿ ಸಿಸ್ಟಂ ಆ್ಯನಿಮೇಶನ್‌ಗಳನ್ನು ಈ ಸೆಟ್ಟಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸುತ್ತವೆ. ಇದನ್ನು ಮಾಡಲು, ಪ್ರತಿ ಆ್ಯಪ್‌ನ ಮ್ಯಾನಿಫೆಸ್ಟ್ ಫೈಲ್‌ನಲ್ಲಿರುವ enableOnBackInvokedCallback ಪ್ಯಾರಾಮೀಟರ್ ಅನ್ನು ಸರಿ ಎಂದು ಹೊಂದಿಸಬೇಕು."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</item>
+    <item msgid="5425394847942513942">"ಕೆಳಕ್ಕೆ ಸರಿಸಿ"</item>
+    <item msgid="7728484337962740316">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</item>
+    <item msgid="324200556467459329">"ಮೇಲಕ್ಕೆ ಸರಿಸಿ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 73de9bb..a65afb1 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"예측된 뒤로 동작 애니메이션"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"예측된 뒤로 동작에 시스템 애니메이션을 사용하도록 설정합니다."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"이 설정은 예측된 동작 애니메이션에 시스템 애니메이션을 사용하도록 합니다. 매니페스트 파일에서 앱별 enableOnBackInvokedCallback을 True로 설정해야 합니다."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"왼쪽으로 이동"</item>
+    <item msgid="5425394847942513942">"아래로 이동"</item>
+    <item msgid="7728484337962740316">"오른쪽으로 이동"</item>
+    <item msgid="324200556467459329">"위로 이동"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index b2a8459..f893fa4 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Божомолдонгон анимациялар"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Божомолдоп билүү үчүн системанын анимацияларын иштетиңиз."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Бул параметр жаңсоо анимациясын божомолдоп билүү үчүн системанын анимацияларын иштетет. Ал үчүн манифест файлындагы enableOnBackInvokedCallback параметри ар бир колдонмо үчүн \"true\" деп коюлушу керек."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Солго жылдыруу"</item>
+    <item msgid="5425394847942513942">"Төмөн жылдыруу"</item>
+    <item msgid="7728484337962740316">"Оңго жылдыруу"</item>
+    <item msgid="324200556467459329">"Жогору жылдыруу"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index fcc4f04..37ef733 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ອະນິເມຊັນກັບຫຼັງແບບຄາດເດົາ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ເປີດການນຳໃຊ້ອະນິເມຊັນລະບົບສຳລັບການກັບຫຼັງແບບຄາດເດົາ."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ການຕັ້ງຄ່ານີ້ຈະເປີດການນຳໃຊ້ອະນິເມຊັນລະບົບສຳລັບອະນິເມຊັນທ່າທາງແບບຄາດເດົາ. ມັນຕ້ອງໃຊ້ການຕັ້ງຄ່າຕໍ່ແອັບ enableOnBackInvokedCallback ເປັນ true ໃນໄຟລ໌ manifest."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ຍ້າຍໄປຊ້າຍ"</item>
+    <item msgid="5425394847942513942">"ຍ້າຍລົງ"</item>
+    <item msgid="7728484337962740316">"ຍ້າຍໄປຂວາ"</item>
+    <item msgid="324200556467459329">"ຍ້າຍຂຶ້ນ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 5b8b93f..05c65c4 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Šis telefonas"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Šis planšetinis kompiuteris"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis telefonas"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Jei norite perjungti, naujovinkite paskyrą"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Čia negalima paleisti atsisiuntimų"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Bandykite dar kartą po skelbimo"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Prisijungiant kilo problema. Išjunkite įrenginį ir vėl jį įjunkite"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Laidinis garso įrenginys"</string>
     <string name="help_label" msgid="3528360748637781274">"Pagalba ir atsiliepimai"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Numatomos grįžimo atgal gestų animacijos"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Įgalinkite sistemos animacijas, kad būtų galima naudoti numatomus grįžimo atgal gestus."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Šis nustatymas įgalina numatomų grįžimo atgal gestų sistemos animacijas. Aprašo faile programos lauką „enableOnBackInvokedCallback“ reikia nustatyti į vertę „true“."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Perkelti kairėn"</item>
+    <item msgid="5425394847942513942">"Perkelti žemyn"</item>
+    <item msgid="7728484337962740316">"Perkelti dešinėn"</item>
+    <item msgid="324200556467459329">"Perkelti aukštyn"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 59c3b0f..b125b40 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Šis tālrunis"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Šis planšetdators"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Šis tālrunis"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Lai pārslēgtu, jauniniet kontu"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Šeit nevar atskaņot lejupielādes"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Mēģiniet vēlreiz, kad beigsies reklāma"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Radās problēma ar savienojuma izveidi. Izslēdziet un atkal ieslēdziet ierīci."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vadu audioierīce"</string>
     <string name="help_label" msgid="3528360748637781274">"Palīdzība un atsauksmes"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animāciju prognozēšana pāriešanai atpakaļ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Iespējot sistēmas animācijas prognozētam žestam pāriešanai atpakaļ."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Šis iestatījums iespējo sistēmas animācijas prognozēto žestu animācijām. Lai to varētu izmantot, parametram “enableOnBackInvokedCallback” lietotnes manifesta failā jāiestata vērtība “true”."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Pārvietojiet pirkstu pa kreisi"</item>
+    <item msgid="5425394847942513942">"Pārvietojiet pirkstu lejup"</item>
+    <item msgid="7728484337962740316">"Pārvietojiet pirkstu pa labi"</item>
+    <item msgid="324200556467459329">"Pārvietojiet pirkstu augšup"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 4a010d3..a843ea1 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Анимации за движењето за враќање"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Овозможете системски анимации за движењето за враќање."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Поставкава ги овозможува системските анимации за предвидливи движења. Поставката треба да се постави на „точно“ преку апликација enableOnBackInvokedCallback во датотеката за манифест."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Преместете налево"</item>
+    <item msgid="5425394847942513942">"Преместете надолу"</item>
+    <item msgid="7728484337962740316">"Преместете надесно"</item>
+    <item msgid="324200556467459329">"Преместете нагоре"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 46ffa9f..da27136 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"പ്രെഡിക്റ്റീവ് ബാക്ക് ആനിമേഷനുകൾ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"പ്രെഡിക്റ്റീവ് ബാക്കിനായി സിസ്റ്റം ആനിമേഷനുകൾ പ്രവർത്തനക്ഷമമാക്കുക."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ഈ ക്രമീകരണം പ്രെഡിക്റ്റീവ് ജെസ്ച്ചർ ആനിമേഷന് വേണ്ടി സിസ്റ്റം ആനിമേഷനുകളെ പ്രവർത്തനക്ഷമമാക്കുന്നു. ഇതിന് ഓരോ ആപ്പിലും enableOnBackInvokedCallback എന്നത് മാനിഫെസ്റ്റ് ഫയലിൽ ശരി എന്ന് സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ഇടത്തേക്ക് നീക്കുക"</item>
+    <item msgid="5425394847942513942">"താഴേക്ക് നീക്കുക"</item>
+    <item msgid="7728484337962740316">"വലത്തേക്ക് നീക്കുക"</item>
+    <item msgid="324200556467459329">"മുകളിലേക്ക് നീക്കുക"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 0a4e4ae..0af5596 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Таамаглах боломжтой буцаах анимаци"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Таамаглах боломжтой буцаах зангаанд системийн анимацийг идэвхжүүлнэ үү."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Энэ тохиргоо нь таамаглах боломжтой зангааны анимацид системийн анимацийг идэвхжүүлнэ. Үүнд апп бүрд тодорхойлогч файлл enableOnBackInvokedCallback-г үнэн болгож тохируулахыг шаардана."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Зүүн тийш зөөх"</item>
+    <item msgid="5425394847942513942">"Доош зөөх"</item>
+    <item msgid="7728484337962740316">"Баруун тийш зөөх"</item>
+    <item msgid="324200556467459329">"Дээш зөөх"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index f74cd54..9773ecf 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"पूर्वानुमानित मागे जाण्याचे अ‍ॅनिमेशन"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"पूर्वानुमानित मागे जाण्यासाठीचे सिस्टीम अ‍ॅनिमेशन सुरू करा."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"हे सेटिंग पूर्वानुमानित जेश्चर ॲनिमेशनसाठी सिस्टीम ॲनिमेशन सुरू करते. यासाठी मॅनिफेस्ट फाइलमध्ये प्रति ॲप enableOnBackInvokedCallback सत्य वर सेट करणे आवश्यक आहे."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"डावीकडे हलवा"</item>
+    <item msgid="5425394847942513942">"खाली हलवा"</item>
+    <item msgid="7728484337962740316">"उजवीकडे हलवा"</item>
+    <item msgid="324200556467459329">"वरती हलवा"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index f6350b3..6e7d430 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Telefon ini"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tablet ini"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Telefon ini"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Tingkatkan akaun untuk bertukar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tidak dapat memainkan muat turun di sini"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Cuba lagi selepas iklan"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Masalah penyambungan. Matikan &amp; hidupkan kembali peranti"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Peranti audio berwayar"</string>
     <string name="help_label" msgid="3528360748637781274">"Bantuan &amp; maklum balas"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animasi kembali ramalan"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Dayakan animasi sistem untuk kembali ramalan."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Tetapan ini mendayakan animasi sistem untuk animasi gerak isyarat ramalan. Animasi sistem memerlukan tetapan enableOnBackInvokedCallback untuk setiap apl kepada benar dalam fail manifes."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Alih ke kiri"</item>
+    <item msgid="5425394847942513942">"Alih ke bawah"</item>
+    <item msgid="7728484337962740316">"Alih ke kanan"</item>
+    <item msgid="324200556467459329">"Alih ke atas"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index c148eba..197143a 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"နောက်ခလုတ်၏ ရှေ့ပြေးလှုပ်ရှားသက်ဝင်ပုံ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"နောက်ခလုတ်ရှေ့ပြေးအတွက် စနစ်လှုပ်ရှားသက်ဝင်ပုံများကို ဖွင့်ပါသည်။"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ဤဆက်တင်သည် လက်ဟန် ရှေ့ပြေးလှုပ်ရှားသက်ဝင်ပုံအတွက် စနစ်လှုပ်ရှားသက်ဝင်ပုံများကို ဖွင့်ပါသည်။ အက်ပ်တစ်ခုစီ၏ ဆက်တင်အတွက် enableOnBackInvokedCallback ကို မန်နီးဖက်စ် (manifest) ဖိုင်၌ ဖွင့်ထားရန်လိုအပ်သည်။"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ဘယ်သို့ရွှေ့ရန်"</item>
+    <item msgid="5425394847942513942">"အောက်သို့ရွှေ့ရန်"</item>
+    <item msgid="7728484337962740316">"ညာသို့ရွှေ့ရန်"</item>
+    <item msgid="324200556467459329">"အပေါ်သို့ရွှေ့ရန်"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 4f70669..d021702 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Denne telefonen"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Dette nettbrettet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Denne telefonen"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Oppgrader kontoen for å bytte"</string>
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -566,7 +577,7 @@
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Når du legger til en ny bruker, må hen konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
     <string name="user_grant_admin_title" msgid="5565796912475193314">"Gi administratorrettigheter?"</string>
     <string name="user_grant_admin_message" msgid="7925257971286380976">"Som administrator kan hen administrere andre brukere, endre enhetsinnstillinger og tilbakestille enheten til fabrikkstandard."</string>
-    <string name="user_setup_dialog_title" msgid="8037342066381939995">"Konfigurere brukeren nå?"</string>
+    <string name="user_setup_dialog_title" msgid="8037342066381939995">"Vil du konfigurere brukeren?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Sørg for at brukeren er tilgjengelig for å konfigurere området sitt på enheten"</string>
     <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Vil du konfigurere profilen nå?"</string>
     <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Konfigurer nå"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Tilbake-animasjoner med forslag"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Slå på systemanimasjoner for tilbakebevegelser med forslag."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Denne innstillingen slår på systemanimasjoner for bevegelsesanimasjoner med forslag. Den krever at enableOnBackInvokedCallback settes til sann i manifestfilen for hver app."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Flytt til venstre"</item>
+    <item msgid="5425394847942513942">"Flytt ned"</item>
+    <item msgid="7728484337962740316">"Flytt til høyre"</item>
+    <item msgid="324200556467459329">"Flytt opp"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 703ee0a..c024503 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"पूर्वानुमानयुक्त ब्याक एनिमेसनहरू"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"पूर्वानुमानयुक्त ब्याक एनिमेसनका हकमा सिस्टम एनिमेसनहरू लागू गर्नुहोस्।"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"यो सेटिङले पूर्वानुमानयुक्त जेस्चर एनिमेसनका हकमा सिस्टम एनिमेनसहरू लागू गर्छ। म्यानिफेस्ट फाइलमा हरेक एपका हकमा enableOnBackInvokedCallback सेट गरी TRUE बनाएपछि मात्र यो सेटिङ अन गर्न मिल्छ।"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"बायाँतिर सार्नुहोस्"</item>
+    <item msgid="5425394847942513942">"तलतिर सार्नुहोस्"</item>
+    <item msgid="7728484337962740316">"दायाँतिर सार्नुहोस्"</item>
+    <item msgid="324200556467459329">"माथितिर सार्नुहोस्"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 344cf01..3090990 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Deze telefoon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Deze tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Deze telefoon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Upgrade het account om te schakelen"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan hier geen downloads afspelen"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Probeer het na de advertentie nog een keer"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem bij verbinding maken. Zet het apparaat uit en weer aan."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedraad audioapparaat"</string>
     <string name="help_label" msgid="3528360748637781274">"Hulp en feedback"</string>
@@ -563,7 +574,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Beperkt profiel"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Nieuwe gebruiker toevoegen?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Je kunt dit apparaat met anderen delen door extra gebruikers te maken. Elke gebruiker heeft een eigen profiel met zelf gekozen apps, achtergrond, enzovoort. Gebruikers kunnen ook apparaatinstellingen aanpassen die van invloed zijn op alle gebruikers, zoals wifi.\n\nWanneer je een nieuwe gebruiker toevoegt, moet die persoon een eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers. Toegankelijkheidsinstellingen en -services worden mogelijk niet overgezet naar de nieuwe gebruiker."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Wanneer je een nieuwe gebruiker toevoegt, moet die persoon diens eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Wanneer je een nieuwe gebruiker toevoegt, moet die persoon hun eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
     <string name="user_grant_admin_title" msgid="5565796912475193314">"Deze gebruiker beheerdersrechten geven?"</string>
     <string name="user_grant_admin_message" msgid="7925257971286380976">"Als beheerder kan deze persoon andere gebruikers beheren, apparaatinstellingen aanpassen en het apparaat terugzetten op de fabrieksinstellingen."</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Gebruiker nu instellen?"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Voorspellende animaties voor gebaren voor terug"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Systeemanimaties aanzetten voor voorspellende animaties voor gebaren voor terug."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Met deze instelling zet je systeemanimaties aan voor voorspellende gebaaranimaties. Je moet enableOnBackInvokedCallback per app instellen op True in het manifestbestand."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Naar links verplaatsen"</item>
+    <item msgid="5425394847942513942">"Omlaag verplaatsen"</item>
+    <item msgid="7728484337962740316">"Naar rechts verplaatsen"</item>
+    <item msgid="324200556467459329">"Omhoog verplaatsen"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 445942d..a509f31 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ପ୍ରେଡିକ୍ଟିଭ ବ୍ୟାକ ଆନିମେସନ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ପ୍ରେଡିକ୍ଟିଭ ବ୍ୟାକ ପାଇଁ ସିଷ୍ଟମ ଆନିମେସନଗୁଡ଼ିକୁ ସକ୍ଷମ କରନ୍ତୁ।"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ଏହି ସେଟିଂ ପ୍ରେଡିକ୍ଟିଭ ଜେଶ୍ଚର ଆନିମେସନ ପାଇଁ ସିଷ୍ଟମ ଆନିମେସନଗୁଡ଼ିକୁ ସକ୍ଷମ କରେ। ଏଥିପାଇଁ ମାନିଫେଷ୍ଟ ଫାଇଲରେ ପ୍ରତି-ଆପ enableOnBackInvokedCallbackକୁ \"ଠିକ\"ରେ ସେଟ କରିବା ଆବଶ୍ୟକ।"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ବାମକୁ ମୁଭ କରନ୍ତୁ"</item>
+    <item msgid="5425394847942513942">"ତଳକୁ ମୁଭ କରନ୍ତୁ"</item>
+    <item msgid="7728484337962740316">"ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</item>
+    <item msgid="324200556467459329">"ଉପରକୁ ମୁଭ କରନ୍ତୁ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 36694db..dcff45c 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ਪਿਛਲੇ ਐਨੀਮੇਸ਼ਨਾਂ ਦਾ ਪੂਰਵ-ਅਨੁਮਾਨ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ਪੂਰਵ-ਅਨੁਮਾਨ ਵਾਪਸੀ ਲਈ ਸਿਸਟਮ ਐਨੀਮੇਸ਼ਨਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ਇਹ ਸੈਟਿੰਗ ਪੂਰਵ-ਅਨੁਮਾਨ ਇਸ਼ਾਰਾ ਐਨੀਮੇਸ਼ਨ ਲਈ ਸਿਸਟਮ ਐਨੀਮੇਸ਼ਨਾਂ ਨੂੰ ਚਾਲੂ ਕਰਦੀ ਹੈ। ਮੈਨੀਫ਼ੈਸਟ ਫ਼ਾਈਲ ਵਿੱਚ enableOnBackInvokedCallback ਸੈਟਿੰਗ ਨੂੰ ਪ੍ਰਤੀ-ਐਪ \'ਸਹੀ\' \'ਤੇ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ਖੱਬੇ ਲਿਜਾਓ"</item>
+    <item msgid="5425394847942513942">"ਹੇਠਾਂ ਲਿਜਾਓ"</item>
+    <item msgid="7728484337962740316">"ਸੱਜੇ ਲਿਜਾਓ"</item>
+    <item msgid="324200556467459329">"ਉੱਪਰ ਲਿਜਾਓ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index debc6c9..0f51432 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ten telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ten tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ten telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Uaktualnij konto, aby przełączyć"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tutaj nie można odtworzyć pobranych plików"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Spróbuj ponownie po reklamie"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem z połączeniem. Wyłącz i ponownie włącz urządzenie"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Przewodowe urządzenie audio"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoc i opinie"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacje przewidywanego przejścia wstecz"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Włącz animacje systemowe dla przewidywanego przejścia wstecz."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"To ustawienie uruchamia animacje systemowe dla przewidywanych gestów. Wymaga ustawienia w pliku manifestu wartości true w polu enableOnBackInvokedCallback dla każdej aplikacji."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Przenieś w lewo"</item>
+    <item msgid="5425394847942513942">"Przenieś w dół"</item>
+    <item msgid="7728484337962740316">"Przenieś w prawo"</item>
+    <item msgid="324200556467459329">"Przenieś w górę"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index c0c1c72..14f2e60 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este smartphone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este smartphone"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Faça upgrade da conta para trocar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível abrir os downloads aqui"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Tente de novo depois do anúncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos \"Voltar\" preditivos"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ativar animações do sistema para gestos \"Voltar\" preditivos."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuração ativa animações do sistema para gestos preditivos. Ela requer que a política enableOnBackInvokedCallback por app seja definida como verdadeira no arquivo de manifesto."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mover para esquerda"</item>
+    <item msgid="5425394847942513942">"Mover para baixo"</item>
+    <item msgid="7728484337962740316">"Mover para direita"</item>
+    <item msgid="324200556467459329">"Mover para cima"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 69245dc..c6cb7ae 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este telemóvel"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Atualize a conta para mudar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível reproduzir as transferências aqui"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Tente novamente depois do anúncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fios"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e comentários"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos para voltar preditivos"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ative as animações do sistema para gestos para voltar preditivos."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta definição ativa animações do sistema para a animação de gestos preditivos. Requer a definição do atributo enableOnBackInvokedCallback por app como verdadeiro no ficheiro de manifesto."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mover para a esquerda"</item>
+    <item msgid="5425394847942513942">"Mover para baixo"</item>
+    <item msgid="7728484337962740316">"Mover para a direita"</item>
+    <item msgid="324200556467459329">"Mover para cima"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index c0c1c72..14f2e60 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Este smartphone"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Este tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este smartphone"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Faça upgrade da conta para trocar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Não é possível abrir os downloads aqui"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Tente de novo depois do anúncio"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animações de gestos \"Voltar\" preditivos"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ativar animações do sistema para gestos \"Voltar\" preditivos."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuração ativa animações do sistema para gestos preditivos. Ela requer que a política enableOnBackInvokedCallback por app seja definida como verdadeira no arquivo de manifesto."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Mover para esquerda"</item>
+    <item msgid="5425394847942513942">"Mover para baixo"</item>
+    <item msgid="7728484337962740316">"Mover para direita"</item>
+    <item msgid="324200556467459329">"Mover para cima"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 9edca36..23e6459 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Acest telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Această tabletă"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Acest telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Fă upgrade contului pentru a comuta"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Aici nu se pot reda descărcări"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Încearcă din nou după anunț"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problemă la conectare. Oprește și repornește dispozitivul."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispozitiv audio cu fir"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajutor și feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animații pentru gestul înapoi predictiv"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activează animațiile de sistem pentru gestul înapoi predictiv."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Această setare activează animațiile de sistem pentru animația gesturilor predictive. Necesită setarea valorii true în cazul atributului enableOnBackInvokedCallback pentru fiecare aplicație în fișierul manifest."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Deplasează la stânga"</item>
+    <item msgid="5425394847942513942">"Deplasează în jos"</item>
+    <item msgid="7728484337962740316">"Deplasează la dreapta"</item>
+    <item msgid="324200556467459329">"Deplasează în sus"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 98a8e88..a437153 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Анимации подсказки для жеста \"Назад\""</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Включить системную анимацию подсказки для жеста \"Назад\"."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"С помощью этого параметра можно включить системные анимации подсказок для жестов. Для этого нужно установить значение true для enableOnBackInvokedCallback в файле манифеста приложения."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Переместите палец влево"</item>
+    <item msgid="5425394847942513942">"Переместите палец вниз"</item>
+    <item msgid="7728484337962740316">"Переместите палец вправо"</item>
+    <item msgid="324200556467459329">"Переместите палец вверх"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index f5437fe..9887eb7 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"සම්බන්ධ කිරීමේ ගැටලුවකි උපාංගය ක්‍රියාවිරහිත කර &amp; ආපසු ක්‍රියාත්මක කරන්න"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"රැහැන්ගත කළ ඕඩියෝ උපාංගය"</string>
     <string name="help_label" msgid="3528360748637781274">"උදවු &amp; ප්‍රතිපෝෂණ"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"පුරෝකථනමය පසු සජීවිකරණ"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"පුරෝකථනමය ආපසු සඳහා පද්ධති සජීවිකරණ සබල කරන්න."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"මෙම සැකසීම පුරෝකථනමය ඉංගිත සජීවිකරණය සඳහා පද්ධති සජීවිකරණ සබල කරයි. එයට මැනිෆෙස්ට් ගොනුව තුළ එක් යෙදුමකට enableOnBackInvokedCallback සත්‍ය ලෙස සැකසීම අවශ්‍ය වේ."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"වමට ගෙන යන්න"</item>
+    <item msgid="5425394847942513942">"පහළට ගෙන යන්න"</item>
+    <item msgid="7728484337962740316">"දකුණට ගෙන යන්න"</item>
+    <item msgid="324200556467459329">"ඉහළට ගෙන යන්න"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index fb46ed9b..e4c2b20 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Tento telefón"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Tento tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefón"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Inovujte účet a prejdite naň"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Tu sa nedajú prehrať stiahnuté súbory"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Skúste to znova po reklame"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio zariadenie s káblom"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomocník a spätná väzba"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Prediktívne animácie gesta Späť"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Povoľte animácie v systéme pre prediktívne gesto Späť"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Toto nastavenie povoľuje animácie v systéme na účely prediktívnej animácie gest. Vyžaduje nastavenie povolenia enableOnBackInvokedCallback na pravdu v súbore manifestu konkrétnej aplikácie."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Posuňte doľava"</item>
+    <item msgid="5425394847942513942">"Posuňte nadol"</item>
+    <item msgid="7728484337962740316">"Posuňte doprava"</item>
+    <item msgid="324200556467459329">"Presuňte nahor"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index c9f8692..02991c4 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ta telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ta tablični računalnik"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ta telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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_try_after_ad" msgid="8312579066856015441">"Poskusite znova po oglasu"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žična zvočna naprava"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoč in povratne informacije"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacije poteze za nazaj s predvidevanjem"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Omogoči sistemske animacije za potezo za nazaj s predvidevanjem."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ta nastavitev omogoča sistemske animacije za animacijo poteze s predvidevanjem. V datoteki manifesta mora biti parameter »enableOnBackInvokedCallback« za posamezno aplikacijo nastavljen na »true«."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Premaknite se levo"</item>
+    <item msgid="5425394847942513942">"Premaknite se navzdol"</item>
+    <item msgid="7728484337962740316">"Premaknite se desno"</item>
+    <item msgid="324200556467459329">"Premaknite se navzgor"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 73b52de..9ff415d 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ky telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ky tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ky telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Përmirëso llogarinë për të ndryshuar"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Shkarkimet nuk mund të luhen këtu"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Provo përsëri pas reklamës"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem me lidhjen. Fike dhe ndize përsëri pajisjen"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Pajisja audio me tel"</string>
     <string name="help_label" msgid="3528360748637781274">"Ndihma dhe komentet"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animacionet për gjestin e parashikuar të kthimit prapa"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivizo animacionet e sistemit për gjestin e parashikuar të kthimit prapa."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ky cilësim aktivizon animacionet e sistemit për animacionin e gjestit të parashikuar. Ai kërkon që enableOnBackInvokedCallback për aplikacionin të jetë caktuar si i vërtetë në skedarin e manifestit."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Lëvize majtas"</item>
+    <item msgid="5425394847942513942">"Lëvize poshtë"</item>
+    <item msgid="7728484337962740316">"Lëvize djathtas"</item>
+    <item msgid="324200556467459329">"Lëvize lart"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 957c243..4d2352d 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Анимације за покрет повратка са предвиђањем"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Омогућите анимације система за покрет повратка са предвиђањем."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ово подешавање омогућава анимације система за покрет повратка са предвиђањем. Захтева подешавање дозволе enableOnBackInvokedCallback по апликацији на true у фајлу манифеста."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Померите налево"</item>
+    <item msgid="5425394847942513942">"Померите надоле"</item>
+    <item msgid="7728484337962740316">"Померите надесно"</item>
+    <item msgid="324200556467459329">"Померите нагоре"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 4e10e54..d8dc9f6 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
     <string name="help_label" msgid="3528360748637781274">"Hjälp och feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Förhandsanimationer för bakåtrörelser"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Aktivera systemanimationer som förhandsvisar bakåtrörelser."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Den här inställningen aktiverar systemanimationer som förhandsvisar vart rörelserna leder. Du måste ställa in enableOnBackInvokedCallback som sant per app i manifestfilen."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Flytta åt vänster"</item>
+    <item msgid="5425394847942513942">"Flytta nedåt"</item>
+    <item msgid="7728484337962740316">"Flytta åt höger"</item>
+    <item msgid="324200556467459329">"Flytta uppåt"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 2c4166a..414c218 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Simu hii"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Kompyuta kibao hii"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Simu hii"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Pata toleo jipya la akaunti ili ubadilishe"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Imeshindwa kucheza maudhui yaliyopakuliwa hapa"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Jaribu tena baada ya tangazo"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kuna tatizo la kuunganisha kwenye Intaneti. Zima kisha uwashe kifaa"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kifaa cha sauti kinachotumia waya"</string>
     <string name="help_label" msgid="3528360748637781274">"Usaidizi na maoni"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Uhuishaji wa utabiri wa kurudi nyuma"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Ruhusu uhuishaji wa mfumo wa utabiri wa kurudi nyuma."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Mipangilio hii inaruhusu uhuishaji wa mfumo wa uhuishaji wa utabiri wa ishara. Inahitaji kuweka mipangilio kwa kila programu enableOnBackInvokedCallback kuwa true katika faili ya maelezo."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Sogeza kushoto"</item>
+    <item msgid="5425394847942513942">"Sogeza chini"</item>
+    <item msgid="7728484337962740316">"Sogeza kulia"</item>
+    <item msgid="324200556467459329">"Sogeza juu"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index eb2b7b2..3b11cab 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"கணிக்கக்கூடிய பின்செல் சைகைக்கான அனிமேஷன்கள்"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"கணிக்கக்கூடிய பின்செல் சைகைக்காகச் சிஸ்டம் அனிமேஷன்களை இயக்கும்."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"கணிக்கக்கூடிய சைகைக்கான அனிமேஷனுக்காக இந்த அமைப்பு சிஸ்டம் அனிமேஷன்களை இயக்கும். மெனிஃபெஸ்ட் ஃபைலில் ஒவ்வொரு ஆப்ஸுக்கும் enableOnBackInvokedCallbackகை \'சரி\' என அமைக்க வேண்டும்."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"இடதுபுறம் நகர்த்துங்கள்"</item>
+    <item msgid="5425394847942513942">"கீழே நகர்த்துங்கள்"</item>
+    <item msgid="7728484337962740316">"வலதுபுறம் நகர்த்துங்கள்"</item>
+    <item msgid="324200556467459329">"மேலே நகர்த்துங்கள்"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 9d6c29d..d539a3d 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"ఊహించదగిన బ్యాక్ యానిమేషన్‌లు"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"ఊహించదగిన బ్యాక్ యానిమేషన్‌ల కోసం సిస్టమ్ యానిమేషన్‌లను ఎనేబుల్ చేయండి."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"ఊహించదగిన సంజ్ఞ యానిమేషన్ కోసం ఈ సెట్టింగ్ సిస్టమ్ యానిమేషన్‌లను ఎనేబుల్ చేస్తుంది. దీనికి మ్యానిఫెస్ట్ ఫైల్‌లో ఒక్కో యాప్‌లో enableOnBackInvokedCallback సెట్టింగ్‌ను ఒప్పునకు సెట్ చేయవలసి ఉంటుంది."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ఎడమ వైపుగా జరపండి"</item>
+    <item msgid="5425394847942513942">"కిందికి జరపండి"</item>
+    <item msgid="7728484337962740316">"కుడి వైపుగా జరపండి"</item>
+    <item msgid="324200556467459329">"పైకి జరపండి"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 6dc2608..beabce4 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"การเคลื่อนไหวย้อนกลับแบบคาดเดา"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"เปิดใช้การเคลื่อนไหวของระบบสำหรับท่าทางสัมผัสย้อนกลับแบบคาดเดา"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"การตั้งค่านี้จะเปิดใช้การเคลื่อนไหวของระบบสำหรับการเคลื่อนไหวจากท่าทางสัมผัสแบบคาดเดา โดยต้องตั้งค่า enableOnBackInvokedCallback สำหรับแต่ละแอปให้เป็น \"จริง\" ในไฟล์ Manifest"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"ย้ายไปทางซ้าย"</item>
+    <item msgid="5425394847942513942">"ย้ายลง"</item>
+    <item msgid="7728484337962740316">"ย้ายไปทางขวา"</item>
+    <item msgid="324200556467459329">"ย้ายขึ้น"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 71b1fdc..53b6d8e 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Ang teleponong ito"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Ang tablet na ito"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ang teleponong ito"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"I-upgrade ang account para lumipat"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Hindi mape-play ang mga download dito"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Subukan ulit pagkatapos ng ad"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Nagkaproblema sa pagkonekta. I-off at pagkatapos ay i-on ang device"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired na audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Tulong at feedback"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Mga animation ng predictive na pagbalik"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"I-enable ang mga animation ng system para sa predictive na pagbalik."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ine-enable ng setting na ito ang mga animation ng system para sa animation ng predictive na galaw. Kinakailangan nitong itakda sa true ang enableOnBackInvokedCallback sa bawat app sa manifest file."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Ilipat pakaliwa"</item>
+    <item msgid="5425394847942513942">"Ilipat pababa"</item>
+    <item msgid="7728484337962740316">"Ilipat pakanan"</item>
+    <item msgid="324200556467459329">"Ilipat pataas"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 76449d5..7110381 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Bu telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Bu tablet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Bu telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Geçiş yapmak için hesabı yükseltin"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"İndirilenler burada oynatılamıyor"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamdan sonra tekrar deneyin"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Bağlanırken sorun oluştu. Cihazı kapatıp tekrar açın"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kablolu ses cihazı"</string>
     <string name="help_label" msgid="3528360748637781274">"Yardım ve geri bildirim"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Tahmine dayalı geri hareketi animasyonları"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Tahmine dayalı geri hareketi için sistem animasyonlarını etkinleştirin"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu ayar, tahmine dayalı hareket animasyonu için sistem animasyonlarını etkinleştirir. Her uygulamanın manifest dosyasında enableOnBackInvokedCallback\'in doğru değerine ayarlanması gerekir."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Sola taşı"</item>
+    <item msgid="5425394847942513942">"Aşağı taşı"</item>
+    <item msgid="7728484337962740316">"Sağa taşı"</item>
+    <item msgid="324200556467459329">"Yukarı taşı"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index e23dae7..54ef3a4a 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Анімації з підказками для жесту \"Назад\""</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Увімкніть системну анімацію з підказками для жесту \"Назад\"."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Якщо вибрати це налаштування, для жесту \"Назад\" відображатиметься анімація з підказками. У файлі маніфесту атрибуту enableOnBackInvokedCallback додатка потрібно присвоїти значення true."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Перемістіть палець ліворуч"</item>
+    <item msgid="5425394847942513942">"Перемістіть палець униз"</item>
+    <item msgid="7728484337962740316">"Перемістіть палець праворуч"</item>
+    <item msgid="324200556467459329">"Перемістіть палець угору"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 452cf77..b1bd695 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"پیچھے جانے کے اشارے کی پیش گوئی والی اینیمیشنز"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"پیچھے جانے کے پیش گوئی والے اشارے کے لیے سسٹم اینیمیشنز فعال کریں۔"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"‏یہ ترتیب پیش گوئی والی اشارے کی اینیمیشن کے لیے سسٹم کی اینیمیشنز کو فعال کرتی ہے۔ اس کے لیے manifest فائل میں فی ایپ enableOnBackInvokedCallback کو درست پر سیٹ کرنے کی ضرورت ہے۔"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"دائيں منتقل کریں"</item>
+    <item msgid="5425394847942513942">"نیچے منتقل کریں"</item>
+    <item msgid="7728484337962740316">"بائيں منتقل کریں"</item>
+    <item msgid="324200556467459329">"اوپر منتقل کریں"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index e55c40e..2df56d7 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Shu telefon"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Shu planshet"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Shu telefon"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Oʻtish uchun hisobingizni yangilang"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Yuklab olingan fayllar ijro etilmaydi"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Reklamadan keyin qayta urining"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
     <string name="help_label" msgid="3528360748637781274">"Yordam/fikr-mulohaza"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Taxminiy qaytish animatsiyalari"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Taxminiy qaytish uchun tizim animatsiyalarini yoqish."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Bu sozlamalar taxminiy qaytish animatsiyalari uchun tizim animatsiyalarini faollashtiradi. Buning uchun har bir ilovaning manifest faylida enableOnBackInvokedCallback parametri “true” qiymatida boʻlishi lozim."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Chapga siljitish"</item>
+    <item msgid="5425394847942513942">"Pastga siljitish"</item>
+    <item msgid="7728484337962740316">"Oʻngga siljitish"</item>
+    <item msgid="324200556467459329">"Tepaga siljitish"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 359fab9..e4f392f 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -315,7 +315,7 @@
     <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Chọn cấu hình USB"</string>
     <string name="allow_mock_location" msgid="2102650981552527884">"Cho phép vị trí mô phỏng"</string>
     <string name="allow_mock_location_summary" msgid="179780881081354579">"Cho phép vị trí mô phỏng"</string>
-    <string name="debug_view_attributes" msgid="3539609843984208216">"Cho phép kiểm tra thuộc tính của chế độ xem"</string>
+    <string name="debug_view_attributes" msgid="3539609843984208216">"Cho phép kiểm tra thuộc tính khung hiển thị"</string>
     <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Luôn bật dữ liệu di động ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Sử dụng tính năng tăng tốc phần cứng khi chia sẻ Internet nếu có"</string>
     <string name="adb_warning_title" msgid="7708653449506485728">"Cho phép gỡ lỗi qua USB?"</string>
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Điện thoại này"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Máy tính bảng này"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Điện thoại này"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Nâng cấp tài khoản để chuyển đổi"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Không thể phát các tệp đã tải xuống tại đây"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Thử lại sau quảng cáo"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sự cố kết nối. Hãy tắt thiết bị rồi bật lại"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Thiết bị âm thanh có dây"</string>
     <string name="help_label" msgid="3528360748637781274">"Trợ giúp và phản hồi"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Ảnh xem trước thao tác quay lại"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Bật ảnh của hệ thống để xem trước thao tác quay lại"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Cài đặt này cho phép sử dụng ảnh động hệ thống cho ảnh động cử chỉ dự đoán. Nó yêu cầu cài đặt cho mỗi ứng dụng chuyển enableOnBackInvokedCallback thành lệnh true trong tệp kê khai."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Di chuyển sang trái"</item>
+    <item msgid="5425394847942513942">"Di chuyển xuống"</item>
+    <item msgid="7728484337962740316">"Di chuyển sang phải"</item>
+    <item msgid="324200556467459329">"Di chuyển lên"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 73c5a97..1cf0acf 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"预见式返回动画"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"启用系统动画作为预见式返回动画。"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"此设置将启用系统动画作为预测性手势动画。这要求在清单文件中将单个应用的 enableOnBackInvokedCallback 设为 true。"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"左移"</item>
+    <item msgid="5425394847942513942">"下移"</item>
+    <item msgid="7728484337962740316">"右移"</item>
+    <item msgid="324200556467459329">"上移"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 36267e2..d195cf8 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"預測返回手勢動畫"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"為預測返回手勢啟用系統動畫。"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"此設定會啟用系統動畫作為預測手勢動畫。這必須在資訊清單檔案中將個別應用程式的 enableOnBackInvokedCallback 設定為 true。"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"向左移"</item>
+    <item msgid="5425394847942513942">"向下移"</item>
+    <item msgid="7728484337962740316">"向右移"</item>
+    <item msgid="324200556467459329">"向上移"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 24bf57e..9511db8 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -540,6 +540,17 @@
     <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>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <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>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <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>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"預測返回操作動畫"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"為預測返回操作啟用系統動畫。"</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"這項設定會啟用系統動畫做為預測手勢動畫。這必須在資訊清單檔案中將個別應用程式的 enableOnBackInvokedCallback 設為 true。"</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"向左移"</item>
+    <item msgid="5425394847942513942">"向下移"</item>
+    <item msgid="7728484337962740316">"向右移"</item>
+    <item msgid="324200556467459329">"向上移"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 4413d3a..e921efc 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -540,6 +540,17 @@
     <string name="media_transfer_this_device_name" product="default" msgid="2357329267148436433">"Le foni"</string>
     <string name="media_transfer_this_device_name" product="tablet" msgid="3714653244000242800">"Le thebulethi"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Le foni"</string>
+    <!-- no translation found for media_output_status_unknown_error (5098565887497902222) -->
+    <skip />
+    <string name="media_output_status_require_premium" msgid="8411255800047014822">"Thuthukisa i-akhawunti ukuze ushintshe"</string>
+    <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Awukwazi ukudlala okudawunilodiwe lapha"</string>
+    <string name="media_output_status_try_after_ad" msgid="8312579066856015441">"Zama futhi ngemva kwesikhangiso"</string>
+    <!-- no translation found for media_output_status_device_in_low_power_mode (8184631698321758451) -->
+    <skip />
+    <!-- no translation found for media_output_status_unauthorized (5880222828273853838) -->
+    <skip />
+    <!-- no translation found for media_output_status_track_unsupported (5576313219317709664) -->
+    <skip />
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Inkinga yokuxhumeka. Vala idivayisi futhi uphinde uyivule"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Idivayisi yomsindo enentambo"</string>
     <string name="help_label" msgid="3528360748637781274">"Usizo nempendulo"</string>
@@ -666,4 +677,10 @@
     <string name="back_navigation_animation" msgid="8105467568421689484">"Ukubikezelwa kwasemuva kopopayi"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Nika amandla ukubikezela emuva kopopayi besistimu."</string>
     <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Leli sethingi livumela opopayi besistimu mayelana nokuthinta okubikezelwayo kopopayi. Idinga ukusetha i-app ngayinye ku-enableOnBackInvokedCallback ukuze iqinisekise ifayela le-manifest."</string>
+  <string-array name="udfps_accessibility_touch_hints">
+    <item msgid="1737722959616802157">"Yisa kwesokunxele"</item>
+    <item msgid="5425394847942513942">"Yehlisa"</item>
+    <item msgid="7728484337962740316">"Yisa kwesokudla"</item>
+    <item msgid="324200556467459329">"Khuphula"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 179573b..00a58f2 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -616,4 +616,16 @@
     <!-- Content descriptions for each of the images in the avatar_images array. -->
     <string-array name="avatar_image_descriptions"/>
 
+    <!-- NOTE: if you change this, you must also add the corresponding scale key and lookup table to
+     frameworks/base/core/java/android/content/res/FontScaleLookupTableFactory.java -->
+    <string-array name="entryvalues_font_size" translatable="false">
+        <item>0.85</item>
+        <item>1.0</item>
+        <item>1.15</item>
+        <item>1.30</item>
+        <item>1.50</item>
+        <item>1.80</item>
+        <item>2.0</item>
+    </string-array>
+
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 8508878..b92b3d6 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1315,6 +1315,20 @@
     <string name="media_transfer_this_device_name" product="tablet">This tablet</string>
     <!-- Name of the phone device with an active remote session. [CHAR LIMIT=30] -->
     <string name="media_transfer_this_phone">This phone</string>
+    <!-- Sub status indicates device is not available due to an unknown error. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_unknown_error">Can\’t play on this device</string>
+    <!-- Sub status indicates device need premium account. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_require_premium">Upgrade account to switch</string>
+    <!-- Sub status indicates device not support download content. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_not_support_downloads">Can\’t play downloads here</string>
+    <!-- Sub status indicates device need to wait after ad. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_try_after_ad">Try again after the ad</string>
+    <!-- Sub status indicates device is in low-power mode. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_device_in_low_power_mode">Wake up device to play here</string>
+    <!-- Sub status indicates the device does not authorize the user. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_unauthorized">Device not approved to play</string>
+    <!-- Sub status indicates the device does not support the current media track. [CHAR LIMIT=NONE] -->
+    <string name="media_output_status_track_unsupported">Can\’t play this media here</string>
 
     <!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] -->
     <string name="profile_connect_timeout_subtext">Problem connecting. Turn device off &amp; back on</string>
@@ -1626,4 +1640,12 @@
     <string name="back_navigation_animation_summary">Enable system animations for predictive back.</string>
     <!-- Developer setting: enable animations when a back gesture is executed, full explanation[CHAR LIMIT=NONE] -->
     <string name="back_navigation_animation_dialog">This setting enables system animations for predictive gesture animation. It requires setting per-app "enableOnBackInvokedCallback" to true in the manifest file.</string>
+
+    <!-- [CHAR LIMIT=NONE] Messages shown when users press outside of udfps region during -->
+    <string-array name="udfps_accessibility_touch_hints">
+        <item>Move left</item>
+        <item>Move down</item>
+        <item>Move right</item>
+        <item>Move up</item>
+    </string-array>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 21e7d81..48d449d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -101,6 +101,9 @@
     @VisibleForTesting
     static ApplicationsState sInstance;
 
+    // Whether the app icon cache mechanism is enabled or not.
+    private static boolean sAppIconCacheEnabled = false;
+
     public static ApplicationsState getInstance(Application app) {
         return getInstance(app, AppGlobals.getPackageManager());
     }
@@ -115,6 +118,11 @@
         }
     }
 
+    /** Set whether the app icon cache mechanism is enabled or not. */
+    public static void setAppIconCacheEnabled(boolean enabled) {
+        sAppIconCacheEnabled = enabled;
+    }
+
     final Context mContext;
     final PackageManager mPm;
     final IPackageManager mIpm;
@@ -776,7 +784,8 @@
     }
 
     private static boolean isAppIconCacheEnabled(Context context) {
-        return SETTING_PKG.equals(context.getPackageName());
+        return SETTING_PKG.equals(context.getPackageName())
+                || sAppIconCacheEnabled;
     }
 
     void rebuildActiveSessions() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index a82f070..96e875b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -70,6 +70,8 @@
             "com.android.settings.category.ia.smart_battery_settings";
     public static final String CATEGORY_COMMUNAL_SETTINGS =
             "com.android.settings.category.ia.communal";
+    public static final String CATEGORY_MORE_SECURITY_PRIVACY_SETTINGS =
+            "com.android.settings.category.ia.more_security_privacy_settings";
 
     public static final Map<String, String> KEY_COMPAT_MAP;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index 8b68a09..e0588ee 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -53,6 +53,12 @@
     public final int maxChargingWattage;
     public final boolean present;
 
+    public static BatteryStatus create(Context context) {
+        final Intent batteryChangedIntent = BatteryUtils.getBatteryIntent(context);
+        return batteryChangedIntent == null
+                ? null : new BatteryStatus(batteryChangedIntent);
+    }
+
     public BatteryStatus(int status, int level, int plugged, int health,
             int maxChargingWattage, boolean present) {
         this.status = status;
@@ -87,11 +93,7 @@
         }
     }
 
-    /**
-     * Determine whether the device is plugged in (USB, power, wireless or dock).
-     *
-     * @return true if the device is plugged in.
-     */
+    /** Determine whether the device is plugged. */
     public boolean isPluggedIn() {
         return plugged == BatteryManager.BATTERY_PLUGGED_AC
                 || plugged == BatteryManager.BATTERY_PLUGGED_USB
@@ -99,30 +101,19 @@
                 || plugged == BatteryManager.BATTERY_PLUGGED_DOCK;
     }
 
-    /**
-     * Determine whether the device is plugged in (USB, power).
-     *
-     * @return true if the device is plugged in wired (as opposed to wireless)
-     */
+    /** Determine whether the device is plugged in (USB, power). */
     public boolean isPluggedInWired() {
         return plugged == BatteryManager.BATTERY_PLUGGED_AC
                 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
     }
 
     /**
-     * Determine whether the device is plugged in wireless.
-     *
-     * @return true if the device is plugged in wireless
-     */
+     * Determine whether the device is plugged in wireless. */
     public boolean isPluggedInWireless() {
         return plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
     }
 
-    /**
-     * Determine whether the device is plugged in dock.
-     *
-     * @return true if the device is plugged in dock
-     */
+    /** Determine whether the device is plugged in dock. */
     public boolean isPluggedInDock() {
         return plugged == BatteryManager.BATTERY_PLUGGED_DOCK;
     }
@@ -131,36 +122,22 @@
      * Whether or not the device is charged. Note that some devices never return 100% for
      * battery level, so this allows either battery level or status to determine if the
      * battery is charged.
-     *
-     * @return true if the device is charged
      */
     public boolean isCharged() {
         return isCharged(status, level);
     }
 
-    /**
-     * Whether battery is low and needs to be charged.
-     *
-     * @return true if battery is low
-     */
+    /** Whether battery is low and needs to be charged. */
     public boolean isBatteryLow() {
         return level < LOW_BATTERY_THRESHOLD;
     }
 
-    /**
-     * Whether battery is overheated.
-     *
-     * @return true if battery is overheated
-     */
+    /** Whether battery is overheated. */
     public boolean isOverheated() {
         return health == BATTERY_HEALTH_OVERHEAT;
     }
 
-    /**
-     * Return current chargin speed is fast, slow or normal.
-     *
-     * @return the charing speed
-     */
+    /** Return current chargin speed is fast, slow or normal. */
     public final int getChargingSpeed(Context context) {
         final int slowThreshold = context.getResources().getInteger(
                 R.integer.config_chargingSlowlyThreshold);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java
new file mode 100644
index 0000000..ad9886e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryUtils.java
@@ -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.settingslib.fuelgauge;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public final class BatteryUtils {
+
+    /** Gets the latest sticky battery intent from the Android system. */
+    public static Intent getBatteryIntent(Context context) {
+        return context.registerReceiver(
+                /*receiver=*/ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/OWNERS b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/OWNERS
new file mode 100644
index 0000000..09e7991
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/OWNERS
@@ -0,0 +1,5 @@
+# Default reviewers for this and subdirectories.
+emilychuang@google.com
+ykhung@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/ComplexMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/ComplexMediaDevice.java
new file mode 100644
index 0000000..c38dfe3
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/ComplexMediaDevice.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.media;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.media.MediaRoute2Info;
+import android.media.MediaRouter2Manager;
+import android.media.RouteListingPreference;
+
+import com.android.settingslib.R;
+
+/**
+ * ComplexMediaDevice extends MediaDevice to represents device with signals from a number of
+ * sources.
+ */
+public class ComplexMediaDevice extends MediaDevice {
+
+    private final String mSummary = "";
+
+    ComplexMediaDevice(Context context, MediaRouter2Manager routerManager,
+            MediaRoute2Info info, String packageName,
+            RouteListingPreference.Item item) {
+        super(context, routerManager, info, packageName, item);
+    }
+
+    // MediaRoute2Info.getName was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
+    @Override
+    public String getName() {
+        return mRouteInfo.getName().toString();
+    }
+
+    @Override
+    public String getSummary() {
+        return mSummary;
+    }
+
+    @Override
+    public Drawable getIcon() {
+        return mContext.getDrawable(R.drawable.ic_media_avr_device);
+    }
+
+    @Override
+    public Drawable getIconWithoutBackground() {
+        return mContext.getDrawable(R.drawable.ic_media_avr_device);
+    }
+
+    @Override
+    public String getId() {
+        return MediaDeviceUtils.getId(mRouteInfo);
+    }
+
+    public boolean isConnected() {
+        return true;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index 6fb5555..c036fdb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -73,6 +73,8 @@
     }
 
     @VisibleForTesting
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     int getDrawableResId() {
         int resId;
         switch (mRouteInfo.getType()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 2bdbb16..684a9aa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -22,6 +22,7 @@
 import static android.media.MediaRoute2Info.TYPE_GROUP;
 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_SPEAKER;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
 import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
@@ -34,10 +35,12 @@
 
 import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_SELECTED;
 
+import android.annotation.Nullable;
 import android.annotation.TargetApi;
 import android.app.Notification;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
 import android.content.Context;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
@@ -103,6 +106,15 @@
         mMediaDevices.clear();
         mRouterManager.registerCallback(mExecutor, mMediaRouterCallback);
         mRouterManager.registerScanRequest();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+                && !TextUtils.isEmpty(mPackageName)) {
+            RouteListingPreference routeListingPreference =
+                    mRouterManager.getRouteListingPreference(mPackageName);
+            if (routeListingPreference != null) {
+                Api34Impl.onRouteListingPreferenceUpdated(null, routeListingPreference,
+                        mPreferenceItemMap);
+            }
+        }
         refreshDevices();
     }
 
@@ -191,6 +203,14 @@
                 && Api34Impl.preferRouteListingOrdering(mRouterManager, mPackageName);
     }
 
+    @Nullable
+    ComponentName getLinkedItemComponentName() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+            return null;
+        }
+        return Api34Impl.getLinkedItemComponentName(mRouterManager, mPackageName);
+    }
+
     /**
      * Remove a {@code device} from current media.
      *
@@ -433,6 +453,8 @@
         dispatchDeviceListAdded();
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     private void buildAllRoutes() {
         for (MediaRoute2Info route : mRouterManager.getAllRoutes()) {
             if (DEBUG) {
@@ -452,6 +474,8 @@
         return infos;
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     private synchronized void buildAvailableRoutes() {
         for (MediaRoute2Info route : getAvailableRoutes(mPackageName)) {
             if (DEBUG) {
@@ -485,7 +509,8 @@
                 infos.add(transferableRoute);
             }
         }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+                && !TextUtils.isEmpty(mPackageName)) {
             RouteListingPreference routeListingPreference =
                     mRouterManager.getRouteListingPreference(mPackageName);
             if (routeListingPreference != null) {
@@ -493,7 +518,7 @@
                         Api34Impl.composePreferenceRouteListing(
                                 routeListingPreference);
                 infos = Api34Impl.arrangeRouteListByPreference(selectedRouteInfos,
-                                infos,
+                                mRouterManager.getAvailableRoutes(packageName),
                                 preferenceRouteListing);
             }
             return Api34Impl.filterDuplicatedIds(infos);
@@ -502,6 +527,8 @@
         }
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     @VisibleForTesting
     void addMediaDevice(MediaRoute2Info route) {
         //TODO(b/258141461): Attach flag and disable reason in MediaDevice
@@ -546,6 +573,9 @@
                             route, mPackageName);
                 }
                 break;
+            case TYPE_REMOTE_AUDIO_VIDEO_RECEIVER:
+                mediaDevice = new ComplexMediaDevice(mContext, mRouterManager, route,
+                        mPackageName, mPreferenceItemMap.get(route.getId()));
             default:
                 Log.w(TAG, "addMediaDevice() unknown device type : " + deviceType);
                 break;
@@ -613,6 +643,7 @@
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                 Api34Impl.onRouteListingPreferenceUpdated(packageName, routeListingPreference,
                         mPreferenceItemMap);
+                refreshDevices();
             }
         }
     }
@@ -625,8 +656,8 @@
             List<RouteListingPreference.Item> finalizedItemList = new ArrayList<>();
             List<RouteListingPreference.Item> itemList = routeListingPreference.getItems();
             for (RouteListingPreference.Item item : itemList) {
-                //Put suggested devices on the top first before further organization
-                if (item.getFlags() == RouteListingPreference.Item.FLAG_SUGGESTED_ROUTE) {
+                // Put suggested devices on the top first before further organization
+                if ((item.getFlags() & RouteListingPreference.Item.FLAG_SUGGESTED) != 0) {
                     finalizedItemList.add(0, item);
                 } else {
                     finalizedItemList.add(item);
@@ -675,6 +706,9 @@
         @DoNotInline
         static boolean preferRouteListingOrdering(MediaRouter2Manager mediaRouter2Manager,
                 String packageName) {
+            if (TextUtils.isEmpty(packageName)) {
+                return false;
+            }
             RouteListingPreference routeListingPreference =
                     mediaRouter2Manager.getRouteListingPreference(packageName);
             return routeListingPreference != null
@@ -682,6 +716,19 @@
         }
 
         @DoNotInline
+        @Nullable
+        static ComponentName getLinkedItemComponentName(
+                MediaRouter2Manager mediaRouter2Manager, String packageName) {
+            if (TextUtils.isEmpty(packageName)) {
+                return null;
+            }
+            RouteListingPreference routeListingPreference =
+                    mediaRouter2Manager.getRouteListingPreference(packageName);
+            return routeListingPreference == null ? null
+                    : routeListingPreference.getLinkedItemComponentName();
+        }
+
+        @DoNotInline
         static void onRouteListingPreferenceUpdated(
                 String packageName,
                 RouteListingPreference routeListingPreference,
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index aec1767..24acf8a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -20,6 +20,7 @@
 import android.app.Notification;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
@@ -217,6 +218,16 @@
     }
 
     /**
+     * Returns required component name for system to take the user back to the app by launching an
+     * intent with the returned {@link ComponentName}, using action {@link #ACTION_TRANSFER_MEDIA},
+     * with the extra {@link #EXTRA_ROUTE_ID}.
+     */
+    @Nullable
+    public ComponentName getLinkedItemComponentName() {
+        return mInfoMediaManager.getLinkedItemComponentName();
+    }
+
+    /**
      * Start scan connected MediaDevice
      */
     public void startScan() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 17ef283..6b9866b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -30,8 +30,19 @@
 import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
 import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
 import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
-import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED_ROUTE;
+import static android.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION;
+import static android.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION_MANAGED;
+import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED;
+import static android.media.RouteListingPreference.Item.SELECTION_BEHAVIOR_TRANSFER;
+import static android.media.RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED;
+import static android.media.RouteListingPreference.Item.SUBTEXT_CUSTOM;
+import static android.media.RouteListingPreference.Item.SUBTEXT_DEVICE_LOW_POWER;
+import static android.media.RouteListingPreference.Item.SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED;
+import static android.media.RouteListingPreference.Item.SUBTEXT_ERROR_UNKNOWN;
 import static android.media.RouteListingPreference.Item.SUBTEXT_NONE;
+import static android.media.RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED;
+import static android.media.RouteListingPreference.Item.SUBTEXT_TRACK_UNSUPPORTED;
+import static android.media.RouteListingPreference.Item.SUBTEXT_UNAUTHORIZED;
 
 import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_SELECTED;
 
@@ -51,6 +62,8 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settingslib.R;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -106,6 +119,8 @@
         setType(info);
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     private void setType(MediaRoute2Info info) {
         if (info == null) {
             mType = MediaDeviceType.TYPE_BLUETOOTH_DEVICE;
@@ -194,29 +209,69 @@
     public abstract String getId();
 
     /**
-     * Get disabled reason of device
+     * Get selection behavior of device
      *
-     * @return disabled reason of device
+     * @return selection behavior of device
      */
     @RouteListingPreference.Item.SubText
-    public int getDisableReason() {
+    public int getSelectionBehavior() {
         return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && mItem != null
-                ? mItem.getSubText()
-                : -1;
+                ? mItem.getSelectionBehavior() : SELECTION_BEHAVIOR_TRANSFER;
     }
 
     /**
-     * Checks if device is has disabled reason
+     * Checks if device is has subtext
      *
-     * @return true if device has disabled reason
+     * @return true if device has subtext
      */
-    public boolean hasDisabledReason() {
+    public boolean hasSubtext() {
         return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
                 && mItem != null
                 && mItem.getSubText() != SUBTEXT_NONE;
     }
 
     /**
+     * Get subtext of device
+     *
+     * @return subtext of device
+     */
+    @RouteListingPreference.Item.SubText
+    public int getSubtext() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && mItem != null
+                ? mItem.getSubText() : SUBTEXT_NONE;
+    }
+
+    /**
+     * Returns subtext string for current route.
+     *
+     * @return subtext string for this route
+     */
+    public String getSubtextString() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && mItem != null
+                ? Api34Impl.composeSubtext(mItem, mContext) : null;
+    }
+
+    /**
+     * Checks if device has ongoing shared session, which allow user to join
+     *
+     * @return true if device has ongoing session
+     */
+    public boolean hasOngoingSession() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+                && Api34Impl.hasOngoingSession(mItem);
+    }
+
+    /**
+     * Checks if device is the host for ongoing shared session, which allow user to adjust volume
+     *
+     * @return true if device is the host for ongoing shared session
+     */
+    public boolean isHostForOngoingSession() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+                && Api34Impl.isHostForOngoingSession(mItem);
+    }
+
+    /**
      * Checks if device is suggested device from application
      *
      * @return true if device is suggested device
@@ -297,6 +352,8 @@
      *
      * @return true if the RouteInfo equals TYPE_BLE_HEADSET.
      */
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     public boolean isBLEDevice() {
         return mRouteInfo.getType() == TYPE_BLE_HEADSET;
     }
@@ -512,8 +569,43 @@
     @RequiresApi(34)
     private static class Api34Impl {
         @DoNotInline
+        static boolean isHostForOngoingSession(RouteListingPreference.Item item) {
+            int flags = item != null ? item.getFlags() : 0;
+            return (flags & FLAG_ONGOING_SESSION) != 0
+                    && (flags & FLAG_ONGOING_SESSION_MANAGED) != 0;
+        }
+
+        @DoNotInline
         static boolean isSuggestedDevice(RouteListingPreference.Item item) {
-            return item != null && item.getFlags() == FLAG_SUGGESTED_ROUTE;
+            return item != null && (item.getFlags() & FLAG_SUGGESTED) != 0;
+        }
+
+        @DoNotInline
+        static boolean hasOngoingSession(RouteListingPreference.Item item) {
+            return item != null && (item.getFlags() & FLAG_ONGOING_SESSION) != 0;
+        }
+
+        @DoNotInline
+        static String composeSubtext(RouteListingPreference.Item item, Context context) {
+            switch (item.getSubText()) {
+                case SUBTEXT_ERROR_UNKNOWN:
+                    return context.getString(R.string.media_output_status_unknown_error);
+                case SUBTEXT_SUBSCRIPTION_REQUIRED:
+                    return context.getString(R.string.media_output_status_require_premium);
+                case SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED:
+                    return context.getString(R.string.media_output_status_not_support_downloads);
+                case SUBTEXT_AD_ROUTING_DISALLOWED:
+                    return context.getString(R.string.media_output_status_try_after_ad);
+                case SUBTEXT_DEVICE_LOW_POWER:
+                    return context.getString(R.string.media_output_status_device_in_low_power_mode);
+                case SUBTEXT_UNAUTHORIZED:
+                    return context.getString(R.string.media_output_status_unauthorized);
+                case SUBTEXT_TRACK_UNSUPPORTED:
+                    return context.getString(R.string.media_output_status_track_unsupported);
+                case SUBTEXT_CUSTOM:
+                    return (String) item.getCustomSubtextMessage();
+            }
+            return "";
         }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index de16d4a..1c82be9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -56,6 +56,8 @@
         initDeviceRecord();
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     @Override
     public String getName() {
         CharSequence name;
@@ -94,11 +96,15 @@
         return mContext.getDrawable(getDrawableResId());
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     @VisibleForTesting
     int getDrawableResId() {
         return mDeviceIconUtil.getIconResIdFromMediaRouteType(mRouteInfo.getType());
     }
 
+    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
+    @SuppressWarnings("NewApi")
     @Override
     public String getId() {
         String id;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsOverlayParams.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
rename to packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsOverlayParams.kt
index 7f3846c..d55a027 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsOverlayParams.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.biometrics
+package com.android.settingslib.udfps
 
 import android.graphics.Rect
 import android.view.Surface
diff --git a/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsUtils.java b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsUtils.java
new file mode 100644
index 0000000..dc8a862
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/udfps/UdfpsUtils.java
@@ -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.settingslib.udfps;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.util.DisplayUtils;
+import android.util.Log;
+import android.util.RotationUtils;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.MotionEvent;
+import android.view.Surface;
+
+import com.android.settingslib.R;
+
+/** Utility class for working with udfps. */
+public class UdfpsUtils {
+    private static final String TAG = "UdfpsUtils";
+
+    /**
+     * Gets the scale factor representing the user's current resolution / the stable (default)
+     * resolution.
+     *
+     * @param displayInfo The display information.
+     */
+    public float getScaleFactor(DisplayInfo displayInfo) {
+        Display.Mode maxDisplayMode =
+                DisplayUtils.getMaximumResolutionDisplayMode(displayInfo.supportedModes);
+        float scaleFactor =
+                DisplayUtils.getPhysicalPixelDisplaySizeRatio(
+                        maxDisplayMode.getPhysicalWidth(),
+                        maxDisplayMode.getPhysicalHeight(),
+                        displayInfo.getNaturalWidth(),
+                        displayInfo.getNaturalHeight()
+                );
+        return (scaleFactor == Float.POSITIVE_INFINITY) ? 1f : scaleFactor;
+    }
+
+    /**
+     * Gets the touch in native coordinates. Map the touch to portrait mode if the device is in
+     * landscape mode.
+     *
+     * @param idx                The pointer identifier.
+     * @param event              The MotionEvent object containing full information about the event.
+     * @param udfpsOverlayParams The [UdfpsOverlayParams] used.
+     * @return The mapped touch event.
+     */
+    public Point getTouchInNativeCoordinates(int idx, MotionEvent event,
+            UdfpsOverlayParams udfpsOverlayParams) {
+        Point portraitTouch = new Point((int) event.getRawX(idx), (int) event.getRawY(idx));
+        int rot = udfpsOverlayParams.getRotation();
+        if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
+            RotationUtils.rotatePoint(
+                    portraitTouch,
+                    RotationUtils.deltaRotation(rot, Surface.ROTATION_0),
+                    udfpsOverlayParams.getLogicalDisplayWidth(),
+                    udfpsOverlayParams.getLogicalDisplayHeight()
+            );
+        }
+
+        // Scale the coordinates to native resolution.
+        float scale = udfpsOverlayParams.getScaleFactor();
+        portraitTouch.x = (int) (portraitTouch.x / scale);
+        portraitTouch.y = (int) (portraitTouch.y / scale);
+        return portraitTouch;
+    }
+
+    /**
+     * This function computes the angle of touch relative to the sensor and maps the angle to a list
+     * of help messages which are announced if accessibility is enabled.
+     *
+     * @return Whether the announcing string is null
+     */
+    public String onTouchOutsideOfSensorArea(boolean touchExplorationEnabled,
+            Context context, int touchX, int touchY, UdfpsOverlayParams udfpsOverlayParams) {
+        if (!touchExplorationEnabled) {
+            return null;
+        }
+
+        String[] touchHints = context.getResources().getStringArray(
+                R.array.udfps_accessibility_touch_hints);
+        if (touchHints.length != 4) {
+            Log.e(TAG, "expected exactly 4 touch hints, got " + touchHints.length + "?");
+            return null;
+        }
+
+        // Scale the coordinates to native resolution.
+        float scale = udfpsOverlayParams.getScaleFactor();
+        float scaledSensorX = udfpsOverlayParams.getSensorBounds().centerX() / scale;
+        float scaledSensorY = udfpsOverlayParams.getSensorBounds().centerY() / scale;
+        String theStr =
+                onTouchOutsideOfSensorAreaImpl(
+                        touchHints,
+                        touchX,
+                        touchY,
+                        scaledSensorX,
+                        scaledSensorY,
+                        udfpsOverlayParams.getRotation()
+                );
+        Log.v(TAG, "Announcing touch outside : $theStr");
+        return theStr;
+    }
+
+    /**
+     * This function computes the angle of touch relative to the sensor and maps the angle to a list
+     * of help messages which are announced if accessibility is enabled.
+     *
+     * There are 4 quadrants of the circle (90 degree arcs)
+     *
+     * [315, 360] && [0, 45) -> touchHints[0] = "Move Fingerprint to the left" [45, 135) ->
+     * touchHints[1] = "Move Fingerprint down" And so on.
+     */
+    private String onTouchOutsideOfSensorAreaImpl(String[] touchHints, float touchX,
+            float touchY, float sensorX, float sensorY, int rotation) {
+        float xRelativeToSensor = touchX - sensorX;
+        // Touch coordinates are with respect to the upper left corner, so reverse
+        // this calculation
+        float yRelativeToSensor = sensorY - touchY;
+        double angleInRad = Math.atan2(yRelativeToSensor, xRelativeToSensor);
+        // If the radians are negative, that means we are counting clockwise.
+        // So we need to add 360 degrees
+        if (angleInRad < 0.0) {
+            angleInRad += 2.0 * Math.PI;
+        }
+        // rad to deg conversion
+        double degrees = Math.toDegrees(angleInRad);
+        double degreesPerBucket = 360.0 / touchHints.length;
+        double halfBucketDegrees = degreesPerBucket / 2.0;
+        // The mapping should be as follows
+        // [315, 360] && [0, 45] -> 0
+        // [45, 135]             -> 1
+        int index = (int) ((degrees + halfBucketDegrees) % 360 / degreesPerBucket);
+        index %= touchHints.length;
+
+        // A rotation of 90 degrees corresponds to increasing the index by 1.
+        if (rotation == Surface.ROTATION_90) {
+            index = (index + 1) % touchHints.length;
+        }
+        if (rotation == Surface.ROTATION_270) {
+            index = (index + 3) % touchHints.length;
+        }
+        return touchHints[index];
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index 2c8aa26..f63c06a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.Mockito.when;
 
 import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
 import android.content.Context;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
@@ -88,6 +89,8 @@
     private MediaManager.MediaDeviceCallback mCallback;
     @Mock
     private MediaSessionManager mMediaSessionManager;
+    @Mock
+    private ComponentName mComponentName;
 
     private InfoMediaManager mInfoMediaManager;
     private Context mContext;
@@ -256,8 +259,10 @@
         ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
                 Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
         final List<RouteListingPreference.Item> preferenceItemList = new ArrayList<>();
-        RouteListingPreference.Item item1 = new RouteListingPreference.Item.Builder(
-                TEST_ID_4).setFlags(RouteListingPreference.Item.FLAG_SUGGESTED_ROUTE).build();
+        RouteListingPreference.Item item1 =
+                new RouteListingPreference.Item.Builder(TEST_ID_4)
+                        .setFlags(RouteListingPreference.Item.FLAG_SUGGESTED)
+                        .build();
         RouteListingPreference.Item item2 = new RouteListingPreference.Item.Builder(
                 TEST_ID_3).build();
         preferenceItemList.add(item1);
@@ -284,42 +289,42 @@
         when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME)).thenReturn(routingSessionInfos);
         when(sessionInfo.getSelectedRoutes()).thenReturn(ImmutableList.of(TEST_ID));
 
-        setTransferableRoutesList();
+        setAvailableRoutesList();
 
         mInfoMediaManager.mRouterManager = mRouterManager;
         mInfoMediaManager.mMediaRouterCallback.onRouteListingPreferenceUpdated(TEST_PACKAGE_NAME,
                 routeListingPreference);
         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
 
+        assertThat(mInfoMediaManager.mMediaDevices).hasSize(3);
         assertThat(mInfoMediaManager.mMediaDevices.get(0).getId()).isEqualTo(TEST_ID);
         assertThat(mInfoMediaManager.mMediaDevices.get(1).getId()).isEqualTo(TEST_ID_4);
         assertThat(mInfoMediaManager.mMediaDevices.get(1).isSuggestedDevice()).isTrue();
         assertThat(mInfoMediaManager.mMediaDevices.get(2).getId()).isEqualTo(TEST_ID_3);
-        assertThat(mInfoMediaManager.mMediaDevices).hasSize(3);
     }
 
-    private List<MediaRoute2Info> setTransferableRoutesList() {
-        final List<MediaRoute2Info> transferableRoutes = new ArrayList<>();
-        final MediaRoute2Info transferableInfo1 = mock(MediaRoute2Info.class);
-        when(transferableInfo1.getId()).thenReturn(TEST_ID_2);
-        when(transferableInfo1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        when(transferableInfo1.getType()).thenReturn(TYPE_REMOTE_TV);
-        transferableRoutes.add(transferableInfo1);
+    private List<MediaRoute2Info> setAvailableRoutesList() {
+        final List<MediaRoute2Info> availableRoutes = new ArrayList<>();
+        final MediaRoute2Info availableInfo1 = mock(MediaRoute2Info.class);
+        when(availableInfo1.getId()).thenReturn(TEST_ID_2);
+        when(availableInfo1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(availableInfo1.getType()).thenReturn(TYPE_REMOTE_TV);
+        availableRoutes.add(availableInfo1);
 
-        final MediaRoute2Info transferableInfo2 = mock(MediaRoute2Info.class);
-        when(transferableInfo2.getId()).thenReturn(TEST_ID_3);
-        when(transferableInfo2.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        transferableRoutes.add(transferableInfo2);
+        final MediaRoute2Info availableInfo2 = mock(MediaRoute2Info.class);
+        when(availableInfo2.getId()).thenReturn(TEST_ID_3);
+        when(availableInfo2.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        availableRoutes.add(availableInfo2);
 
-        final MediaRoute2Info transferableInfo3 = mock(MediaRoute2Info.class);
-        when(transferableInfo3.getId()).thenReturn(TEST_ID_4);
-        when(transferableInfo3.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        transferableRoutes.add(transferableInfo3);
+        final MediaRoute2Info availableInfo3 = mock(MediaRoute2Info.class);
+        when(availableInfo3.getId()).thenReturn(TEST_ID_4);
+        when(availableInfo3.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        availableRoutes.add(availableInfo3);
 
-        when(mRouterManager.getTransferableRoutes(TEST_PACKAGE_NAME)).thenReturn(
-                transferableRoutes);
+        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(
+                availableRoutes);
 
-        return transferableRoutes;
+        return availableRoutes;
     }
 
     @Test
@@ -372,6 +377,24 @@
         assertThat(mInfoMediaManager.preferRouteListingOrdering()).isFalse();
     }
 
+    @Test
+    public void getInAppOnlyItemRoutingReceiver_oldSdkVersion_returnsNull() {
+        assertThat(mInfoMediaManager.getLinkedItemComponentName()).isNull();
+    }
+
+    @Test
+    public void getInAppOnlyItemRoutingReceiver_newSdkVersionWithReceiverExist_returns() {
+        ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT",
+                Build.VERSION_CODES.UPSIDE_DOWN_CAKE);
+        when(mRouterManager.getRouteListingPreference(any())).thenReturn(
+                new RouteListingPreference.Builder().setItems(
+                        ImmutableList.of()).setUseSystemOrdering(
+                        false).setLinkedItemComponentName(mComponentName).build());
+        mInfoMediaManager.mRouterManager = mRouterManager;
+
+        assertThat(mInfoMediaManager.getLinkedItemComponentName()).isEqualTo(mComponentName);
+    }
+
     private List<MediaRoute2Info> getRoutesListWithDuplicatedIds() {
         final List<MediaRoute2Info> routes = new ArrayList<>();
         final MediaRoute2Info info = mock(MediaRoute2Info.class);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/udfps/UdfpsUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/udfps/UdfpsUtilsTest.java
new file mode 100644
index 0000000..f4f0ef9
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/udfps/UdfpsUtilsTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.udfps;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.Surface;
+
+import com.android.settingslib.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+
+@RunWith(RobolectricTestRunner.class)
+public class UdfpsUtilsTest {
+    @Rule
+    public final MockitoRule rule = MockitoJUnit.rule();
+
+    private Context mContext;
+    private String[] mTouchHints;
+    private UdfpsUtils mUdfpsUtils;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mTouchHints = mContext.getResources().getStringArray(
+                R.array.udfps_accessibility_touch_hints);
+        mUdfpsUtils = new UdfpsUtils();
+    }
+
+    @Test
+    public void testTouchOutsideAreaNoRotation() {
+        int rotation = Surface.ROTATION_0;
+        // touch at 0 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, 0/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[0]);
+        // touch at 90 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, -1/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[1]);
+        // touch at 180 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        -1 /* touchX */, 0/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[2]);
+        // touch at 270 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, 1/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[3]);
+    }
+
+
+    @Test
+    public void testTouchOutsideAreaNoRotation90Degrees() {
+        int rotation = Surface.ROTATION_90;
+        // touch at 0 degrees -> 90 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, 0 /* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[1]);
+        // touch at 90 degrees -> 180 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, -1 /* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[2]);
+        // touch at 180 degrees -> 270 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        -1 /* touchX */, 0 /* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[3]);
+        // touch at 270 degrees -> 0 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, 1/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[0]);
+    }
+
+
+    @Test
+    public void testTouchOutsideAreaNoRotation270Degrees() {
+        int rotation = Surface.ROTATION_270;
+        // touch at 0 degrees -> 270 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, 0/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[3]);
+        // touch at 90 degrees -> 0 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, -1/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[0]);
+        // touch at 180 degrees -> 90 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        -1 /* touchX */, 0/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[1]);
+        // touch at 270 degrees -> 180 degrees
+        assertThat(
+                mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
+                        0 /* touchX */, 1/* touchY */,
+                        new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation)
+                )
+        ).isEqualTo(mTouchHints[2]);
+    }
+}
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index 4a10427..1ac20471 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -33,7 +33,7 @@
     static_libs: [
         "junit",
         "SettingsLibDeviceStateRotationLock",
-        "SettingsLibDisplayDensityUtils",
+        "SettingsLibDisplayUtils",
     ],
     platform_apis: true,
     certificate: "platform",
@@ -57,7 +57,7 @@
         "androidx.test.rules",
         "mockito-target-minus-junit4",
         "SettingsLibDeviceStateRotationLock",
-        "SettingsLibDisplayDensityUtils",
+        "SettingsLibDisplayUtils",
         "platform-test-annotations",
         "truth-prebuilt",
     ],
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index c0818a8..7cd8d70 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -99,5 +99,7 @@
         Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS,
         Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER,
         Settings.Global.Wearable.DYNAMIC_COLOR_THEME_ENABLED,
+        Settings.Global.HDR_CONVERSION_MODE,
+        Settings.Global.HDR_FORCE_CONVERSION_TYPE,
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index c133097..dcddde4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -130,6 +130,7 @@
         Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS,
         Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
         Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
+        Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
         Settings.Secure.VR_DISPLAY_MODE,
         Settings.Secure.NOTIFICATION_BADGING,
         Settings.Secure.NOTIFICATION_DISMISS_RTL,
@@ -210,6 +211,8 @@
         Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE,
         Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY,
         Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED,
+        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
+        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED,
         Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED,
         Settings.Secure.NOTIFICATION_BUBBLES,
         Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
@@ -227,6 +230,11 @@
         Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE,
         Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME,
         Settings.Secure.CUSTOM_BUGREPORT_HANDLER_APP,
-        Settings.Secure.CUSTOM_BUGREPORT_HANDLER_USER
+        Settings.Secure.CUSTOM_BUGREPORT_HANDLER_USER,
+        Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED,
+        Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
+        Settings.Secure.HEARING_AID_CALL_ROUTING,
+        Settings.Secure.HEARING_AID_MEDIA_ROUTING,
+        Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index 673a3ab..8de0f0dc 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -16,6 +16,9 @@
 
 package android.provider.settings.validators;
 
+import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_FORCE;
+import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_PASSTHROUGH;
+import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_SYSTEM;
 import static android.media.AudioFormat.SURROUND_SOUND_ENCODING;
 import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.ANY_STRING_VALIDATOR;
@@ -26,6 +29,11 @@
 import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR;
 import static android.provider.settings.validators.SettingsValidators.PERCENTAGE_INTEGER_VALIDATOR;
 import static android.view.Display.HdrCapabilities.HDR_TYPES;
+import static android.view.Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION;
+import static android.view.Display.HdrCapabilities.HDR_TYPE_HDR10;
+import static android.view.Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS;
+import static android.view.Display.HdrCapabilities.HDR_TYPE_HLG;
+import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID;
 
 import android.os.BatteryManager;
 import android.provider.Settings.Global;
@@ -288,6 +296,19 @@
                                 String.valueOf(Global.Wearable.LOCK_SCREEN_STATE_PIN),
                                 String.valueOf(Global.Wearable.LOCK_SCREEN_STATE_PATTERN)
                         }));
+        VALIDATORS.put(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_TYPE,
+                new DiscreteValueValidator(new String[]{
+                        String.valueOf(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_TYPE_DIGIT),
+                        String.valueOf(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_TYPE_TERSE)}));
+        VALIDATORS.put(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED,
+                new DiscreteValueValidator(new String[]{String.valueOf(
+                        Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED_VERY_SLOW),
+                        String.valueOf(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED_SLOW),
+                        String.valueOf(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED_MEDIUM),
+                        String.valueOf(Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED_FAST),
+                        String.valueOf(
+                                Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED_VERY_FAST)}));
         VALIDATORS.put(
                 Global.Wearable.PAIRED_DEVICE_OS_TYPE,
                 new DiscreteValueValidator(
@@ -346,6 +367,20 @@
         VALIDATORS.put(Global.USER_PREFERRED_REFRESH_RATE, NON_NEGATIVE_FLOAT_VALIDATOR);
         VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_HEIGHT, ANY_INTEGER_VALIDATOR);
         VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR);
+        VALIDATORS.put(Global.HDR_CONVERSION_MODE,  new DiscreteValueValidator(
+                new String[] {
+                        String.valueOf(HDR_CONVERSION_PASSTHROUGH),
+                        String.valueOf(HDR_CONVERSION_SYSTEM),
+                        String.valueOf(HDR_CONVERSION_FORCE)
+                }));
+        VALIDATORS.put(Global.HDR_FORCE_CONVERSION_TYPE, new DiscreteValueValidator(
+                new String[] {
+                        String.valueOf(HDR_TYPE_INVALID),
+                        String.valueOf(HDR_TYPE_DOLBY_VISION),
+                        String.valueOf(HDR_TYPE_HDR10),
+                        String.valueOf(HDR_TYPE_HLG),
+                        String.valueOf(HDR_TYPE_HDR10_PLUS)
+                }));
         VALIDATORS.put(Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED,
                        new DiscreteValueValidator(new String[]{"0", "1"}));
         VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 03921e1..1c5e6ea 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -189,6 +189,8 @@
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
                 ANY_STRING_VALIDATOR);
+        VALIDATORS.put(Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
+                ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
@@ -295,6 +297,8 @@
                         Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
                         Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL));
         VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(
                 Secure.ACCESSIBILITY_BUTTON_TARGETS,
                 ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
@@ -359,5 +363,14 @@
         VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.CUSTOM_BUGREPORT_HANDLER_APP, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.CUSTOM_BUGREPORT_HANDLER_USER, ANY_INTEGER_VALIDATOR);
+        VALIDATORS.put(Secure.LOCK_SCREEN_WEATHER_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.HEARING_AID_RINGTONE_ROUTING,
+                new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+        VALIDATORS.put(Secure.HEARING_AID_CALL_ROUTING,
+                new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+        VALIDATORS.put(Secure.HEARING_AID_MEDIA_ROUTING,
+                new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+        VALIDATORS.put(Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
+                new DiscreteValueValidator(new String[] {"0", "1", "2"}));
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 7aeba95..fb3c313 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1832,6 +1832,26 @@
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED,
                 SecureSettingsProto.Accessibility
                         .ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
+                SecureSettingsProto.Accessibility
+                        .ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED,
+                SecureSettingsProto.Accessibility
+                        .ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED);
+        dumpSetting(s, p,
+                Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
+                SecureSettingsProto.Accessibility.HEARING_AID_RINGTONE_ROUTING);
+        dumpSetting(s, p,
+                Settings.Secure.HEARING_AID_CALL_ROUTING,
+                SecureSettingsProto.Accessibility.HEARING_AID_CALL_ROUTING);
+        dumpSetting(s, p,
+                Settings.Secure.HEARING_AID_MEDIA_ROUTING,
+                SecureSettingsProto.Accessibility.HEARING_AID_MEDIA_ROUTING);
+        dumpSetting(s, p,
+                Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
+                SecureSettingsProto.Accessibility.HEARING_AID_SYSTEM_SOUNDS_ROUTING);
         p.end(accessibilityToken);
 
         final long adaptiveSleepToken = p.start(SecureSettingsProto.ADAPTIVE_SLEEP);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index a9c0f00..f1413e5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -33,6 +33,7 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.util.AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM;
 import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX;
 
 import android.Manifest;
@@ -107,6 +108,7 @@
 import android.util.SparseBooleanArray;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.accessibility.util.AccessibilityUtils;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
@@ -3712,7 +3714,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 213;
+            private static final int SETTINGS_VERSION = 214;
 
             private final int mUserId;
 
@@ -5646,6 +5648,27 @@
                     currentVersion = 213;
                 }
 
+                if (currentVersion == 213) {
+                    final ComponentName accessibilityMenuToMigrate =
+                            AccessibilityUtils.getAccessibilityMenuComponentToMigrate(
+                                    getContext().getPackageManager(), userId);
+                    if (accessibilityMenuToMigrate != null) {
+                        final SettingsState secureSettings = getSecureSettingsLocked(userId);
+                        final String toRemove = accessibilityMenuToMigrate.flattenToString();
+                        final String toAdd = ACCESSIBILITY_MENU_IN_SYSTEM.flattenToString();
+                        // Migrate the accessibility shortcuts and enabled state.
+                        migrateColonDelimitedStringSettingLocked(secureSettings,
+                                Secure.ACCESSIBILITY_BUTTON_TARGETS, toRemove, toAdd);
+                        migrateColonDelimitedStringSettingLocked(secureSettings,
+                                Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT, toRemove, toAdd);
+                        migrateColonDelimitedStringSettingLocked(secureSettings,
+                                Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, toRemove, toAdd);
+                        migrateColonDelimitedStringSettingLocked(secureSettings,
+                                Secure.ENABLED_ACCESSIBILITY_SERVICES, toRemove, toAdd);
+                    }
+                    currentVersion = 214;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
@@ -5867,6 +5890,22 @@
             return items;
         }
 
+        @GuardedBy("mLock")
+        private void migrateColonDelimitedStringSettingLocked(SettingsState settingsState,
+                String setting, String toRemove, String toAdd) {
+            final Set<String> componentNames = transformColonDelimitedStringToSet(
+                    settingsState.getSettingLocked(setting).getValue());
+            if (componentNames != null && componentNames.contains(toRemove)) {
+                componentNames.remove(toRemove);
+                componentNames.add(toAdd);
+                settingsState.insertSettingLocked(
+                        setting,
+                        TextUtils.join(":", componentNames),
+                        null /* tag */, false /* makeDefault */,
+                        SettingsState.SYSTEM_PACKAGE_NAME);
+            }
+        }
+
         private boolean isAccessibilityButtonInNavigationBarOn(SettingsState secureSettings) {
             return hasValueInA11yButtonTargets(secureSettings) && !isGestureNavigateEnabled();
         }
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index f1ea482..42f2371 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -663,7 +663,10 @@
                     Settings.Global.Wearable.BEDTIME_HARD_MODE,
                     Settings.Global.Wearable.EARLY_UPDATES_STATUS,
                     Settings.Global.Wearable.RSB_WAKE_ENABLED,
-                    Settings.Global.Wearable.LOCK_SCREEN_STATE);
+                    Settings.Global.Wearable.LOCK_SCREEN_STATE,
+                    Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_ENABLED,
+                    Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_TYPE,
+                    Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED);
 
     private static final Set<String> BACKUP_DENY_LIST_SECURE_SETTINGS =
              newHashSet(
@@ -776,7 +779,7 @@
                  Settings.Secure.SLEEP_TIMEOUT,
                  Settings.Secure.SMS_DEFAULT_APPLICATION,
                  Settings.Secure.SPELL_CHECKER_ENABLED,  // Intentionally removed in Q
-                 Settings.Secure.STYLUS_BUTTONS_DISABLED,
+                 Settings.Secure.STYLUS_BUTTONS_ENABLED,
                  Settings.Secure.TRUST_AGENTS_INITIALIZED,
                  Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED,
                  Settings.Secure.TV_APP_USES_NON_SYSTEM_INPUTS,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index f305981..9d46961 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -223,6 +223,45 @@
     path: "tests/utils/src",
 }
 
+filegroup {
+    name: "SystemUI-tests-robolectric-pilots",
+    srcs: [
+        // data
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt",
+        "tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt",
+        // domain
+        "tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+        "tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
+        // ui
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt",
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt",
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt",
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt",
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt",
+        "tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt",
+    ],
+    path: "tests/src",
+}
+
 java_library {
     name: "SystemUI-tests-concurrency",
     srcs: [
@@ -337,8 +376,16 @@
     defaults: [
         "platform_app_defaults",
         "SystemUI_app_defaults",
+        "SystemUI_compose_defaults",
     ],
     manifest: "tests/AndroidManifest-base.xml",
+
+    srcs: [
+        "src/**/*.kt",
+        "src/**/*.java",
+        "src/**/I*.aidl",
+        ":ReleaseJavaFiles",
+    ],
     static_libs: [
         "SystemUI-tests-base",
     ],
@@ -352,6 +399,9 @@
     certificate: "platform",
     privileged: true,
     resource_dirs: [],
+    kotlincflags: ["-Xjvm-default=all"],
+
+    plugins: ["dagger2-compiler"],
 }
 
 android_robolectric_test {
@@ -359,6 +409,13 @@
     srcs: [
         "tests/robolectric/src/**/*.kt",
         "tests/robolectric/src/**/*.java",
+        ":SystemUI-tests-utils",
+        ":SystemUI-tests-robolectric-pilots",
+    ],
+    static_libs: [
+        "androidx.test.uiautomator_uiautomator",
+        "androidx.test.ext.junit",
+        "inline-mockito-robolectric-prebuilt",
     ],
     libs: [
         "android.test.runner",
@@ -366,7 +423,9 @@
         "android.test.mock",
         "truth-prebuilt",
     ],
-    kotlincflags: ["-Xjvm-default=enable"],
+
+    upstream: true,
+
     instrumentation_for: "SystemUIRobo-stub",
     java_resource_dirs: ["tests/robolectric/config"],
 }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 8e98d2d..4e18222 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -68,6 +68,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
@@ -418,6 +419,34 @@
                  android:permission="com.android.systemui.permission.SELF"
                  android:exported="false" />
 
+        <activity android:name=".screenshot.AppClipsTrampolineActivity"
+            android:theme="@style/AppClipsTrampolineActivity"
+            android:label="@string/screenshot_preview_description"
+            android:permission="android.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE"
+            android:exported="true">
+            <intent-filter android:priority="1">
+                <action android:name="android.intent.action.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".screenshot.AppClipsActivity"
+            android:theme="@style/AppClipsActivity"
+            android:process=":appclips.screenshot"
+            android:label="@string/screenshot_preview_description"
+            android:permission="com.android.systemui.permission.SELF"
+            android:excludeFromRecents="true"
+            android:exported="false"
+            android:noHistory="true" />
+
+        <service android:name=".screenshot.appclips.AppClipsScreenshotHelperService"
+            android:permission="com.android.systemui.permission.SELF"
+            android:exported="false" />
+
+        <service android:name=".screenshot.appclips.AppClipsService"
+            android:permission="android.permission.LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE"
+            android:exported="true" />
+
         <service android:name=".screenrecord.RecordingService"
                  android:foregroundServiceType="systemExempted"/>
 
@@ -915,7 +944,7 @@
                   android:showWhenLocked="true"
                   android:showForAllUsers="true"
                   android:finishOnTaskLaunch="true"
-                  android:launchMode="singleInstance"
+                  android:lockTaskMode="if_whitelisted"
                   android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
                   android:visibleToInstantApps="true">
         </activity>
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index 333aeba..bdd941d 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -49,13 +49,16 @@
     },
     {
       // Permission indicators
-      "name": "CtsPermission4TestCases",
+      "name": "CtsPermission3TestCases",
       "options": [
         {
           "exclude-annotation": "org.junit.Ignore"
         },
         {
           "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "include-filter": "android.permission3.cts.CameraMicIndicatorsPermissionTest"
         }
       ]
     },
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
index 46c604b..140c10d 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/Android.bp
@@ -24,10 +24,19 @@
     static_libs: [
         "androidx.coordinatorlayout_coordinatorlayout",
         "androidx.core_core",
+        "androidx.preference_preference",
         "androidx.viewpager_viewpager",
-        "SettingsLib",
+        "SettingsLibDisplayUtils",
     ],
 
+    optimize: {
+        enabled: true,
+        optimize: true,
+        shrink: true,
+        shrink_resources: true,
+        proguard_compatibility: false,
+    },
+
     uses_libs: [
         "org.apache.http.legacy",
     ],
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
index 77412d9..82ddf38 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
@@ -33,5 +33,27 @@
                 android:name="android.accessibilityservice"
                 android:resource="@xml/accessibilitymenu_service"/>
         </service>
+
+        <!-- Accessibility Menu Settings -->
+        <activity
+            android:name="com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity"
+            android:exported="true"
+            android:label="@string/accessibility_menu_settings_name"
+            android:launchMode="singleTop"
+            android:theme="@style/AccessibilityMenuSettings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+
+                <category android:name="android.accessibilityservice.SERVICE_SETTINGS"/>
+            </intent-filter>
+        </activity>
     </application>
+
+    <queries>
+        <intent>
+            <action android:name="android.intent.action.VIEW" />
+            <category android:name="android.intent.category.BROWSABLE" />
+            <data android:scheme="https" />
+        </intent>
+    </queries>
 </manifest>
\ No newline at end of file
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values/donottranslate.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values/donottranslate.xml
index 0c25ec4..01758e87 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values/donottranslate.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values/donottranslate.xml
@@ -1,11 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-  <!-- user customized shortcuts preference -->
-  <string name="pref_user_shortcuts">accessibility_menu_user_shortcuts</string>
-  <!-- key for user customized shortcuts -->
-  <string name="pref_user_shortcuts_key">pref_user_shortcuts_key</string>
-  <!-- value for empty shortcut -->
-  <string name="pref_user_shortcuts_value_empty">[]</string>
   <!-- empty string for shortcut label -->
   <string name="empty_content"></string>
 
@@ -14,4 +8,6 @@
   <!-- key for Help&feedback settings [CHAR_LIMIT=NONE] -->
   <string name="pref_help">pref_help</string>
 
+  <!-- url for help page -->
+  <string name="help_url">https://support.google.com/accessibility/android/answer/9078941</string>
 </resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml
index a2cf267..2009cd1 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml
@@ -17,7 +17,7 @@
 
 <resources>
   <!--The theme is for preference CollapsingToolbarBaseActivity settings-->
-  <style name="AccessibilityMenuSettings" parent="android:Theme.DeviceDefault.Light" />
+  <style name="AccessibilityMenuSettings" parent="android:Theme.DeviceDefault.DayNight" />
 
   <!--Adds the theme to support SnackBar component and user configurable theme. -->
   <style name="ServiceTheme" parent="android:Theme.DeviceDefault.Light">
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml
new file mode 100644
index 0000000..3b79287
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml
@@ -0,0 +1,33 @@
+<?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.
+  -->
+
+<androidx.preference.PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <SwitchPreference
+        android:defaultValue="false"
+        android:key="@string/pref_large_buttons"
+        android:persistent="true"
+        android:summary="@string/accessibility_menu_large_buttons_summary"
+        android:title="@string/accessibility_menu_large_buttons_title"/>
+
+    <Preference
+        android:key="@string/pref_help"
+        android:title="@string/pref_help_and_feedback_title"/>
+
+</androidx.preference.PreferenceScreen>
\ No newline at end of file
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_service.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_service.xml
index 3dbbb1a..569de3d 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_service.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_service.xml
@@ -21,4 +21,5 @@
     android:intro="@string/accessibility_menu_intro"
     android:animatedImageDrawable="@drawable/a11ymenu_intro"
     android:isAccessibilityTool="true"
+    android:settingsActivity="com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity"
 />
\ No newline at end of file
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index ca6c332..ff73736 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -22,6 +22,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
@@ -38,6 +40,8 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 
+import androidx.preference.PreferenceManager;
+
 import com.android.settingslib.display.BrightnessUtils;
 import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut.ShortcutId;
 import com.android.systemui.accessibility.accessibilitymenu.view.A11yMenuOverlayLayout;
@@ -62,6 +66,7 @@
     public static final long BUTTON_CLICK_TIMEOUT = 200;
 
     private A11yMenuOverlayLayout mA11yMenuLayout;
+    private SharedPreferences mPrefs;
 
     private static boolean sInitialized = false;
 
@@ -90,6 +95,25 @@
         }
     };
 
+    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mA11yMenuLayout.hideMenu();
+        }
+    };
+
+    /**
+     * Update a11y menu layout when large button setting is changed.
+     */
+    private final OnSharedPreferenceChangeListener mSharedPreferenceChangeListener =
+            (SharedPreferences prefs, String key) -> {
+                {
+                    if (key.equals(getString(R.string.pref_large_buttons))) {
+                        mA11yMenuLayout.configureLayout();
+                    }
+                }
+            };
+
     // Update layout.
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Runnable mOnConfigChangedRunnable = new Runnable() {
@@ -110,6 +134,7 @@
     @Override
     public void onCreate() {
         super.onCreate();
+        setTheme(R.style.ServiceTheme);
 
         getAccessibilityButtonController().registerAccessibilityButtonCallback(
                 new AccessibilityButtonController.AccessibilityButtonCallback() {
@@ -147,12 +172,11 @@
     protected void onServiceConnected() {
         mA11yMenuLayout = new A11yMenuOverlayLayout(this);
 
-        registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                mA11yMenuLayout.hideMenu();
-            }}, new IntentFilter(Intent.ACTION_SCREEN_OFF)
-        );
+        registerReceiver(mBroadcastReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+        mPrefs.registerOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
+
 
         mDisplayManager = getSystemService(DisplayManager.class);
         mDisplayManager.registerDisplayListener(mDisplayListener, null);
@@ -286,6 +310,14 @@
     }
 
     @Override
+    public boolean onUnbind(Intent intent) {
+        unregisterReceiver(mBroadcastReceiver);
+        mPrefs.unregisterOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
+        sInitialized = false;
+        return super.onUnbind(intent);
+    }
+
+    @Override
     protected boolean onKeyEvent(KeyEvent event) {
         if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
             mA11yMenuLayout.hideMenu();
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
new file mode 100644
index 0000000..8f29348
--- /dev/null
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.accessibilitymenu.activity;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.provider.Settings;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceManager;
+
+import com.android.systemui.accessibility.accessibilitymenu.R;
+
+/**
+ * Settings activity for AccessibilityMenu.
+ */
+public class A11yMenuSettingsActivity extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getSupportFragmentManager()
+                .beginTransaction()
+                .replace(android.R.id.content, new A11yMenuPreferenceFragment())
+                .commit();
+    }
+
+    /**
+     * Settings/preferences fragment for AccessibilityMenu.
+     */
+    public static class A11yMenuPreferenceFragment extends PreferenceFragmentCompat {
+        @Override
+        public void onCreatePreferences(Bundle bundle, String s) {
+            setPreferencesFromResource(R.xml.accessibilitymenu_preferences, s);
+            initializeHelpAndFeedbackPreference();
+        }
+
+        /**
+         * Returns large buttons settings state.
+         *
+         * @param context The parent context
+         * @return {@code true} large button is enabled; {@code false} large button is disabled
+         */
+        public static boolean isLargeButtonsEnabled(Context context) {
+            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+            String key = context.getResources().getString(R.string.pref_large_buttons);
+            return prefs.getBoolean(key, false);
+        }
+
+        private void initializeHelpAndFeedbackPreference() {
+            final Preference prefHelp = findPreference(getString(R.string.pref_help));
+            if (prefHelp != null) {
+                prefHelp.setTitle(R.string.pref_help_title);
+
+                // Do not allow access to web during setup.
+                if (Settings.Secure.getInt(
+                        getContext().getContentResolver(),
+                        Settings.Secure.USER_SETUP_COMPLETE, 0) != 1) {
+                    return;
+                }
+
+                // Configure preference to open the help page in the default web browser.
+                // If the system has no browser, hide the preference.
+                Uri uri = Uri.parse(getResources().getString(R.string.help_url));
+                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
+                if (getActivity().getPackageManager().queryIntentActivities(
+                        intent, PackageManager.ResolveInfoFlags.of(0)).isEmpty()) {
+                    prefHelp.setVisible(false);
+                    return;
+                }
+                prefHelp.setIntent(intent);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java
index 337814e..6f0fe37 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java
@@ -27,6 +27,7 @@
 
 import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService;
 import com.android.systemui.accessibility.accessibilitymenu.R;
+import com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity.A11yMenuPreferenceFragment;
 import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut;
 import com.android.systemui.accessibility.accessibilitymenu.utils.ShortcutDrawableUtils;
 
@@ -124,7 +125,12 @@
         ImageButton shortcutIconButton = convertView.findViewById(R.id.shortcutIconBtn);
         TextView shortcutLabel = convertView.findViewById(R.id.shortcutLabel);
 
-        // TODO: Enlarge shortcut icon & label when large button setting is on.
+        if (A11yMenuPreferenceFragment.isLargeButtonsEnabled(mService)) {
+            ViewGroup.LayoutParams params = shortcutIconButton.getLayoutParams();
+            params.width = (int) (params.width * LARGE_BUTTON_SCALE);
+            params.height = (int) (params.height * LARGE_BUTTON_SCALE);
+            shortcutLabel.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, mLargeTextSize);
+        }
 
         if (shortcutItem.getId() == A11yMenuShortcut.ShortcutId.UNSPECIFIED_ID_VALUE.ordinal()) {
             // Sets empty shortcut icon and label when the shortcut is ADD_ITEM.
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index 7bdb8f9..dd0a4f0 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -24,6 +24,7 @@
 import android.graphics.Insets;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.view.Display;
@@ -43,6 +44,7 @@
 
 import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService;
 import com.android.systemui.accessibility.accessibilitymenu.R;
+import com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity.A11yMenuPreferenceFragment;
 import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut;
 
 import java.util.ArrayList;
@@ -71,8 +73,27 @@
         A11yMenuShortcut.ShortcutId.ID_SCREENSHOT_VALUE.ordinal()
     };
 
+    /** Predefined default shortcuts when large button setting is on. */
+    private static final int[] LARGE_SHORTCUT_LIST_DEFAULT = {
+            A11yMenuShortcut.ShortcutId.ID_ASSISTANT_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_A11YSETTING_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_POWER_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_RECENT_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_VOLUME_DOWN_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_VOLUME_UP_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_BRIGHTNESS_DOWN_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_BRIGHTNESS_UP_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_LOCKSCREEN_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_QUICKSETTING_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_NOTIFICATION_VALUE.ordinal(),
+            A11yMenuShortcut.ShortcutId.ID_SCREENSHOT_VALUE.ordinal()
+    };
+
+
+
     private final AccessibilityMenuService mService;
     private final WindowManager mWindowManager;
+    private final DisplayManager mDisplayManager;
     private ViewGroup mLayout;
     private WindowManager.LayoutParams mLayoutParameter;
     private A11yMenuViewPager mA11yMenuViewPager;
@@ -82,6 +103,7 @@
     public A11yMenuOverlayLayout(AccessibilityMenuService service) {
         mService = service;
         mWindowManager = mService.getSystemService(WindowManager.class);
+        mDisplayManager = mService.getSystemService(DisplayManager.class);
         configureLayout();
         mHandler = new Handler(Looper.getMainLooper());
         mAccessibilityManager = mService.getSystemService(AccessibilityManager.class);
@@ -153,7 +175,10 @@
      */
     private List<A11yMenuShortcut> createShortcutList() {
         List<A11yMenuShortcut> shortcutList = new ArrayList<>();
-        for (int shortcutId : SHORTCUT_LIST_DEFAULT) {
+
+        for (int shortcutId :
+                (A11yMenuPreferenceFragment.isLargeButtonsEnabled(mService)
+                        ? LARGE_SHORTCUT_LIST_DEFAULT : SHORTCUT_LIST_DEFAULT)) {
             shortcutList.add(new A11yMenuShortcut(shortcutId));
         }
         return shortcutList;
@@ -161,9 +186,9 @@
 
     /** Updates a11y menu layout position by configuring layout params. */
     private void updateLayoutPosition() {
-        Display display = mLayout.getDisplay();
+        final Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
         final int orientation = mService.getResources().getConfiguration().orientation;
-        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+        if (display != null && orientation == Configuration.ORIENTATION_LANDSCAPE) {
             switch (display.getRotation()) {
                 case Surface.ROTATION_90:
                 case Surface.ROTATION_180:
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
index cec503c..0a349e5 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
@@ -33,6 +33,7 @@
 
 import com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService;
 import com.android.systemui.accessibility.accessibilitymenu.R;
+import com.android.systemui.accessibility.accessibilitymenu.activity.A11yMenuSettingsActivity.A11yMenuPreferenceFragment;
 import com.android.systemui.accessibility.accessibilitymenu.model.A11yMenuShortcut;
 import com.android.systemui.accessibility.accessibilitymenu.view.A11yMenuFooter.A11yMenuFooterCallBack;
 
@@ -65,9 +66,6 @@
         /** The number of columns in the grid view when large button settings is on. */
         public static final int LARGE_GRID_COLUMN_COUNT = 2;
 
-        /** Temporary measure to test both item types. */
-        private static final boolean USE_LARGE_ITEMS = false;
-
         /**
          * Returns the number of items in the grid view.
          *
@@ -75,7 +73,7 @@
          * @return Grid item count
          */
         public static int getGridItemCount(Context context) {
-            return USE_LARGE_ITEMS
+            return A11yMenuPreferenceFragment.isLargeButtonsEnabled(context)
                    ? LARGE_GRID_ITEM_COUNT
                    : GRID_ITEM_COUNT;
         }
@@ -87,7 +85,7 @@
          * @return Grid column count
          */
         public static int getGridColumnCount(Context context) {
-            return USE_LARGE_ITEMS
+            return A11yMenuPreferenceFragment.isLargeButtonsEnabled(context)
                    ? LARGE_GRID_COLUMN_COUNT
                    : GRID_COLUMN_COUNT;
         }
@@ -99,7 +97,7 @@
          * @return Grid row count
          */
         public static int getGridRowCount(Context context) {
-            return USE_LARGE_ITEMS
+            return A11yMenuPreferenceFragment.isLargeButtonsEnabled(context)
                    ? (LARGE_GRID_ITEM_COUNT / LARGE_GRID_COLUMN_COUNT)
                    : (GRID_ITEM_COUNT / GRID_COLUMN_COUNT);
         }
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 8acc2f8..978ab5d 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -35,7 +35,6 @@
     ],
 
     static_libs: [
-        "PluginCoreLib",
         "androidx.core_core-animation-nodeps",
         "androidx.core_core-ktx",
         "androidx.annotation_annotation",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index b8d78fb..42a8636 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -33,13 +33,9 @@
 import android.view.WindowManager
 import android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
 import android.widget.FrameLayout
-import android.window.OnBackInvokedDispatcher
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.jank.InteractionJankMonitor.CujType
-import com.android.systemui.animation.back.BackAnimationSpec
-import com.android.systemui.animation.back.applyTo
-import com.android.systemui.animation.back.floatingSystemSurfacesForSysUi
-import com.android.systemui.animation.back.onBackAnimationCallbackFrom
+import com.android.systemui.util.registerAnimationOnBackInvoked
 import java.lang.IllegalArgumentException
 import kotlin.math.roundToInt
 
@@ -304,10 +300,16 @@
     ) {
         val view =
             openedDialogs.firstOrNull { it.dialog == animateFrom }?.dialogContentWithBackground
-                ?: throw IllegalStateException(
-                    "The animateFrom dialog was not animated using " +
-                        "DialogLaunchAnimator.showFrom(View|Dialog)"
-                )
+        if (view == null) {
+            Log.w(
+                TAG,
+                "Showing dialog $dialog normally as the dialog it is shown from was not shown " +
+                    "using DialogLaunchAnimator"
+            )
+            dialog.show()
+            return
+        }
+
         showFromView(
             dialog,
             view,
@@ -792,7 +794,7 @@
 
         if (featureFlags.isPredictiveBackQsDialogAnim) {
             // TODO(b/265923095) Improve animations for QS dialogs on configuration change
-            registerOnBackInvokedCallback(targetView = dialogContentWithBackground)
+            dialog.registerAnimationOnBackInvoked(targetView = dialogContentWithBackground)
         }
 
         // Show the dialog.
@@ -800,35 +802,6 @@
         moveSourceDrawingToDialog()
     }
 
-    private fun registerOnBackInvokedCallback(targetView: View) {
-        val metrics = targetView.resources.displayMetrics
-
-        val onBackAnimationCallback =
-            onBackAnimationCallbackFrom(
-                backAnimationSpec = BackAnimationSpec.floatingSystemSurfacesForSysUi(metrics),
-                displayMetrics = metrics, // TODO(b/265060720): We could remove this
-                onBackProgressed = { backTransformation -> backTransformation.applyTo(targetView) },
-                onBackInvoked = { dialog.dismiss() },
-            )
-
-        val dispatcher = dialog.onBackInvokedDispatcher
-        targetView.addOnAttachStateChangeListener(
-            object : View.OnAttachStateChangeListener {
-                override fun onViewAttachedToWindow(v: View) {
-                    dispatcher.registerOnBackInvokedCallback(
-                        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
-                        onBackAnimationCallback
-                    )
-                }
-
-                override fun onViewDetachedFromWindow(v: View) {
-                    targetView.removeOnAttachStateChangeListener(this)
-                    dispatcher.unregisterOnBackInvokedCallback(onBackAnimationCallback)
-                }
-            }
-        )
-    }
-
     private fun moveSourceDrawingToDialog() {
         if (decorView.viewRootImpl == null) {
             // Make sure that we have access to the dialog view root to move the drawing to the
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
index 33d14b1..8740d14 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
@@ -16,15 +16,21 @@
 
 package com.android.systemui.animation.back
 
+import android.annotation.IntRange
 import android.util.DisplayMetrics
+import android.view.View
 import android.window.BackEvent
 import android.window.OnBackAnimationCallback
+import android.window.OnBackInvokedDispatcher
+import android.window.OnBackInvokedDispatcher.Priority
 
 /**
  * Generates an [OnBackAnimationCallback] given a [backAnimationSpec]. [onBackProgressed] will be
  * called on each update passing the current [BackTransformation].
  *
  * Optionally, you can specify [onBackStarted], [onBackInvoked], and [onBackCancelled] callbacks.
+ *
+ * @sample com.android.systemui.util.registerAnimationOnBackInvoked
  */
 fun onBackAnimationCallbackFrom(
     backAnimationSpec: BackAnimationSpec,
@@ -64,3 +70,34 @@
         }
     }
 }
+
+/**
+ * Register [OnBackAnimationCallback] when View is attached and unregister it when View is detached
+ *
+ * @sample com.android.systemui.util.registerAnimationOnBackInvoked
+ */
+fun View.registerOnBackInvokedCallbackOnViewAttached(
+    onBackInvokedDispatcher: OnBackInvokedDispatcher,
+    onBackAnimationCallback: OnBackAnimationCallback,
+    @Priority @IntRange(from = 0) priority: Int = OnBackInvokedDispatcher.PRIORITY_DEFAULT,
+) {
+    addOnAttachStateChangeListener(
+        object : View.OnAttachStateChangeListener {
+            override fun onViewAttachedToWindow(v: View) {
+                onBackInvokedDispatcher.registerOnBackInvokedCallback(
+                    priority,
+                    onBackAnimationCallback
+                )
+            }
+
+            override fun onViewDetachedFromWindow(v: View) {
+                removeOnAttachStateChangeListener(this)
+                onBackInvokedDispatcher.unregisterOnBackInvokedCallback(onBackAnimationCallback)
+            }
+        }
+    )
+
+    if (isAttachedToWindow) {
+        onBackInvokedDispatcher.registerOnBackInvokedCallback(priority, onBackAnimationCallback)
+    }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
index 7897934..442c6fa 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
@@ -66,11 +66,28 @@
     fun isPlaying(): Boolean = animator.isRunning
 
     private fun applyConfigToShader() {
-        rippleShader.setCenter(config.centerX, config.centerY)
-        rippleShader.setMaxSize(config.maxWidth, config.maxHeight)
-        rippleShader.rippleFill = config.shouldFillRipple
-        rippleShader.pixelDensity = config.pixelDensity
-        rippleShader.color = ColorUtils.setAlphaComponent(config.color, config.opacity)
-        rippleShader.sparkleStrength = config.sparkleStrength
+        with(rippleShader) {
+            setCenter(config.centerX, config.centerY)
+            setMaxSize(config.maxWidth, config.maxHeight)
+            pixelDensity = config.pixelDensity
+            color = ColorUtils.setAlphaComponent(config.color, config.opacity)
+            sparkleStrength = config.sparkleStrength
+
+            assignFadeParams(baseRingFadeParams, config.baseRingFadeParams)
+            assignFadeParams(sparkleRingFadeParams, config.sparkleRingFadeParams)
+            assignFadeParams(centerFillFadeParams, config.centerFillFadeParams)
+        }
+    }
+
+    private fun assignFadeParams(
+        destFadeParams: RippleShader.FadeParams,
+        srcFadeParams: RippleShader.FadeParams?
+    ) {
+        srcFadeParams?.let {
+            destFadeParams.fadeInStart = it.fadeInStart
+            destFadeParams.fadeInEnd = it.fadeInEnd
+            destFadeParams.fadeOutStart = it.fadeOutStart
+            destFadeParams.fadeOutEnd = it.fadeOutEnd
+        }
     }
 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
index 773ac55..1786d13 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
@@ -20,8 +20,11 @@
     val pixelDensity: Float = 1f,
     var color: Int = Color.WHITE,
     val opacity: Int = RIPPLE_DEFAULT_ALPHA,
-    val shouldFillRipple: Boolean = false,
     val sparkleStrength: Float = RIPPLE_SPARKLE_STRENGTH,
+    // Null means it uses default fade parameter values.
+    val baseRingFadeParams: RippleShader.FadeParams? = null,
+    val sparkleRingFadeParams: RippleShader.FadeParams? = null,
+    val centerFillFadeParams: RippleShader.FadeParams? = null,
     val shouldDistort: Boolean = true
 ) {
     companion object {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
index c764d53..61ca90a 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
@@ -82,12 +82,12 @@
                 vec2 p_distorted = distort(p, in_time, in_distort_radial, in_distort_xy);
                 float radius = in_size.x * 0.5;
                 float sparkleRing = soften(circleRing(p_distorted-in_center, radius), in_blur);
-                float inside = soften(sdCircle(p_distorted-in_center, radius * 1.2), in_blur);
+                float inside = soften(sdCircle(p_distorted-in_center, radius * 1.25), in_blur);
                 float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time * 0.00175)
                     * (1.-sparkleRing) * in_fadeSparkle;
 
                 float rippleInsideAlpha = (1.-inside) * in_fadeFill;
-                float rippleRingAlpha = (1.-sparkleRing) * in_fadeRing * in_sparkle_strength;
+                float rippleRingAlpha = (1.-sparkleRing) * in_fadeRing;
                 float rippleAlpha = max(rippleInsideAlpha, rippleRingAlpha) * in_color.a;
                 vec4 ripple = vec4(in_color.rgb, 1.0) * rippleAlpha;
                 return mix(ripple, vec4(sparkle), sparkle * in_sparkle_strength);
@@ -270,38 +270,6 @@
     var currentHeight: Float = 0f
         private set
 
-    /**
-     * True if the ripple should stayed filled in as it expands to give a filled-in circle effect.
-     * False for a ring effect.
-     *
-     * <p>You must reset fade params after changing this.
-     *
-     * TODO(b/265326983): Remove this and only expose fade params.
-     */
-    var rippleFill: Boolean = false
-        set(value) {
-            if (value) {
-                baseRingFadeParams.fadeOutStart = 1f
-                baseRingFadeParams.fadeOutEnd = 1f
-
-                centerFillFadeParams.fadeInStart = 0f
-                centerFillFadeParams.fadeInEnd = 0f
-                centerFillFadeParams.fadeOutStart = 1f
-                centerFillFadeParams.fadeOutEnd = 1f
-            } else {
-                // Set back to the original fade parameters.
-                // Ideally this should be set by the client as they know the initial value.
-                baseRingFadeParams.fadeOutStart = DEFAULT_BASE_RING_FADE_OUT_START
-                baseRingFadeParams.fadeOutEnd = DEFAULT_FADE_OUT_END
-
-                centerFillFadeParams.fadeInStart = DEFAULT_FADE_IN_START
-                centerFillFadeParams.fadeInEnd = DEFAULT_CENTER_FILL_FADE_IN_END
-                centerFillFadeParams.fadeOutStart = DEFAULT_CENTER_FILL_FADE_OUT_START
-                centerFillFadeParams.fadeOutEnd = DEFAULT_CENTER_FILL_FADE_OUT_END
-            }
-            field = value
-        }
-
     /** Parameters that are used to fade in/ out of the sparkle ring. */
     val sparkleRingFadeParams =
         FadeParams(
@@ -324,12 +292,7 @@
             DEFAULT_FADE_OUT_END
         )
 
-    /**
-     * Parameters that are used to fade in/ out of the center fill.
-     *
-     * <p>Note that if [rippleFill] is set to true, those will be ignored and the center fill will
-     * be always full alpha.
-     */
+    /** Parameters that are used to fade in/ out of the center fill. */
     val centerFillFadeParams =
         FadeParams(
             DEFAULT_FADE_IN_START,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
index bc4796a..3c9328c 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
@@ -117,15 +117,6 @@
         rippleShader.color = ColorUtils.setAlphaComponent(color, alpha)
     }
 
-    /**
-     * Set whether the ripple should remain filled as the ripple expands.
-     *
-     * See [RippleShader.rippleFill].
-     */
-    fun setRippleFill(rippleFill: Boolean) {
-        rippleShader.rippleFill = rippleFill
-    }
-
     /** Set the intensity of the sparkles. */
     fun setSparkleStrength(strength: Float) {
         rippleShader.sparkleStrength = strength
diff --git a/packages/SystemUI/animation/src/com/android/systemui/util/Dialog.kt b/packages/SystemUI/animation/src/com/android/systemui/util/Dialog.kt
new file mode 100644
index 0000000..428856d
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/util/Dialog.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.app.Dialog
+import android.view.View
+import android.window.OnBackInvokedDispatcher
+import com.android.systemui.animation.back.BackAnimationSpec
+import com.android.systemui.animation.back.BackTransformation
+import com.android.systemui.animation.back.applyTo
+import com.android.systemui.animation.back.floatingSystemSurfacesForSysUi
+import com.android.systemui.animation.back.onBackAnimationCallbackFrom
+import com.android.systemui.animation.back.registerOnBackInvokedCallbackOnViewAttached
+
+/**
+ * Register on the Dialog's [OnBackInvokedDispatcher] an animation using the [BackAnimationSpec].
+ * The [BackTransformation] will be applied on the [targetView].
+ */
+@JvmOverloads
+fun Dialog.registerAnimationOnBackInvoked(
+    targetView: View,
+    backAnimationSpec: BackAnimationSpec =
+        BackAnimationSpec.floatingSystemSurfacesForSysUi(
+            displayMetrics = targetView.resources.displayMetrics,
+        ),
+) {
+    targetView.registerOnBackInvokedCallbackOnViewAttached(
+        onBackInvokedDispatcher = onBackInvokedDispatcher,
+        onBackAnimationCallback =
+            onBackAnimationCallbackFrom(
+                backAnimationSpec = backAnimationSpec,
+                displayMetrics = targetView.resources.displayMetrics,
+                onBackProgressed = { backTransformation -> backTransformation.applyTo(targetView) },
+                onBackInvoked = { dismiss() },
+            ),
+    )
+}
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 a523cf1..ed6e619 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
@@ -13,11 +13,13 @@
  */
 package com.android.systemui.shared.clocks
 
+import android.app.ActivityManager
+import android.app.UserSwitchObserver
 import android.content.Context
 import android.database.ContentObserver
 import android.graphics.drawable.Drawable
 import android.net.Uri
-import android.os.Handler
+import android.os.UserHandle
 import android.provider.Settings
 import android.util.Log
 import androidx.annotation.OpenForTesting
@@ -29,17 +31,23 @@
 import com.android.systemui.plugins.ClockSettings
 import com.android.systemui.plugins.PluginListener
 import com.android.systemui.plugins.PluginManager
+import com.android.systemui.util.Assert
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
-private val TAG = ClockRegistry::class.simpleName
+private val TAG = ClockRegistry::class.simpleName!!
 private const val DEBUG = true
 
 /** ClockRegistry aggregates providers and plugins */
 open class ClockRegistry(
     val context: Context,
     val pluginManager: PluginManager,
-    val handler: Handler,
+    val scope: CoroutineScope,
+    val mainDispatcher: CoroutineDispatcher,
+    val bgDispatcher: CoroutineDispatcher,
     val isEnabled: Boolean,
-    userHandle: Int,
+    val handleAllUsers: Boolean,
     defaultClockProvider: ClockProvider,
     val fallbackClockId: ClockId = DEFAULT_CLOCK_ID,
 ) {
@@ -50,66 +58,132 @@
 
     private val availableClocks = mutableMapOf<ClockId, ClockInfo>()
     private val clockChangeListeners = mutableListOf<ClockChangeListener>()
-    private val settingObserver = object : ContentObserver(handler) {
-        override fun onChange(selfChange: Boolean, uris: Collection<Uri>, flags: Int, userId: Int) =
-            clockChangeListeners.forEach { it.onClockChanged() }
-    }
+    private val settingObserver =
+        object : ContentObserver(null) {
+            override fun onChange(
+                selfChange: Boolean,
+                uris: Collection<Uri>,
+                flags: Int,
+                userId: Int
+            ) {
+                scope.launch(bgDispatcher) { querySettings() }
+            }
+        }
 
-    private val pluginListener = object : PluginListener<ClockProviderPlugin> {
-        override fun onPluginConnected(plugin: ClockProviderPlugin, context: Context) =
-            connectClocks(plugin)
+    private val pluginListener =
+        object : PluginListener<ClockProviderPlugin> {
+            override fun onPluginConnected(plugin: ClockProviderPlugin, context: Context) =
+                connectClocks(plugin)
 
-        override fun onPluginDisconnected(plugin: ClockProviderPlugin) =
-            disconnectClocks(plugin)
-    }
+            override fun onPluginDisconnected(plugin: ClockProviderPlugin) =
+                disconnectClocks(plugin)
+        }
 
-    open var settings: ClockSettings?
-        get() {
+    private val userSwitchObserver =
+        object : UserSwitchObserver() {
+            override fun onUserSwitchComplete(newUserId: Int) {
+                scope.launch(bgDispatcher) { querySettings() }
+            }
+        }
+
+    // TODO(b/267372164): Migrate to flows
+    var settings: ClockSettings? = null
+        get() = field
+        protected set(value) {
+            if (field != value) {
+                field = value
+                scope.launch(mainDispatcher) { onClockChanged() }
+            }
+        }
+
+    var isRegistered: Boolean = false
+        private set
+
+    @OpenForTesting
+    open fun querySettings() {
+        assertNotMainThread()
+        val result =
             try {
-                val json = Settings.Secure.getString(
-                    context.contentResolver,
-                    Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE
-                )
-                if (json == null || json.isEmpty()) {
-                    return null
-                }
-                return ClockSettings.deserialize(json)
+                val json =
+                    if (handleAllUsers) {
+                        Settings.Secure.getStringForUser(
+                            context.contentResolver,
+                            Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+                            ActivityManager.getCurrentUser()
+                        )
+                    } else {
+                        Settings.Secure.getString(
+                            context.contentResolver,
+                            Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE
+                        )
+                    }
+
+                ClockSettings.deserialize(json)
             } catch (ex: Exception) {
                 Log.e(TAG, "Failed to parse clock settings", ex)
-                return null
+                null
             }
-        }
-        protected set(value) {
-            try {
-                val json = if (value != null) {
-                    value._applied_timestamp = System.currentTimeMillis()
-                    ClockSettings.serialize(value)
-                } else {
-                    ""
-                }
+        settings = result
+    }
 
+    @OpenForTesting
+    open fun applySettings(value: ClockSettings?) {
+        assertNotMainThread()
+
+        try {
+            value?._applied_timestamp = System.currentTimeMillis()
+            val json = ClockSettings.serialize(value)
+
+            if (handleAllUsers) {
+                Settings.Secure.putStringForUser(
+                    context.contentResolver,
+                    Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+                    json,
+                    ActivityManager.getCurrentUser()
+                )
+            } else {
                 Settings.Secure.putString(
                     context.contentResolver,
-                    Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, json
+                    Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+                    json
                 )
-            } catch (ex: Exception) {
-                Log.e(TAG, "Failed to set clock settings", ex)
             }
+        } catch (ex: Exception) {
+            Log.e(TAG, "Failed to set clock settings", ex)
         }
+        settings = value
+    }
 
-    private fun mutateSetting(mutator: (ClockSettings) -> Unit) {
-        val settings = this.settings ?: ClockSettings()
-        mutator(settings)
-        this.settings = settings
+    @OpenForTesting
+    protected open fun assertMainThread() {
+        Assert.isMainThread()
+    }
+
+    @OpenForTesting
+    protected open fun assertNotMainThread() {
+        Assert.isNotMainThread()
+    }
+
+    private fun onClockChanged() {
+        assertMainThread()
+        clockChangeListeners.forEach { it.onClockChanged() }
+    }
+
+    private fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
+        scope.launch(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
     }
 
     var currentClockId: ClockId
         get() = settings?.clockId ?: fallbackClockId
-        set(value) { mutateSetting { it.clockId = value } }
+        set(value) {
+            mutateSetting { it.copy(clockId = value) }
+        }
 
     var seedColor: Int?
         get() = settings?.seedColor
-        set(value) { mutateSetting { it.seedColor = value } }
+        set(value) {
+            mutateSetting { it.copy(seedColor = value) }
+        }
 
     init {
         connectClocks(defaultClockProvider)
@@ -118,19 +192,51 @@
                 "$defaultClockProvider did not register clock at $DEFAULT_CLOCK_ID"
             )
         }
+    }
 
-        if (isEnabled) {
-            pluginManager.addPluginListener(
-                pluginListener,
-                ClockProviderPlugin::class.java,
-                /*allowMultiple=*/ true
-            )
+    fun registerListeners() {
+        if (!isEnabled || isRegistered) {
+            return
+        }
+
+        isRegistered = true
+
+        pluginManager.addPluginListener(
+            pluginListener,
+            ClockProviderPlugin::class.java,
+            /*allowMultiple=*/ true
+        )
+
+        scope.launch(bgDispatcher) { querySettings() }
+        if (handleAllUsers) {
             context.contentResolver.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),
                 /*notifyForDescendants=*/ false,
                 settingObserver,
-                userHandle
+                UserHandle.USER_ALL
             )
+
+            ActivityManager.getService().registerUserSwitchObserver(userSwitchObserver, TAG)
+        } else {
+            context.contentResolver.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),
+                /*notifyForDescendants=*/ false,
+                settingObserver
+            )
+        }
+    }
+
+    fun unregisterListeners() {
+        if (!isRegistered) {
+            return
+        }
+
+        isRegistered = false
+
+        pluginManager.removePluginListener(pluginListener)
+        context.contentResolver.unregisterContentObserver(settingObserver)
+        if (handleAllUsers) {
+            ActivityManager.getService().unregisterUserSwitchObserver(userSwitchObserver)
         }
     }
 
@@ -157,7 +263,7 @@
                 if (DEBUG) {
                     Log.i(TAG, "Current clock ($currentId) was connected")
                 }
-                clockChangeListeners.forEach { it.onClockChanged() }
+                onClockChanged()
             }
         }
     }
@@ -172,13 +278,12 @@
 
             if (currentId == clock.clockId) {
                 Log.w(TAG, "Current clock ($currentId) was disconnected")
-                clockChangeListeners.forEach { it.onClockChanged() }
+                onClockChanged()
             }
         }
     }
 
-    @OpenForTesting
-    open fun getClocks(): List<ClockMetadata> {
+    fun getClocks(): List<ClockMetadata> {
         if (!isEnabled) {
             return listOf(availableClocks[DEFAULT_CLOCK_ID]!!.metadata)
         }
@@ -213,16 +318,16 @@
         return createClock(DEFAULT_CLOCK_ID)!!
     }
 
-    private fun createClock(clockId: ClockId): ClockController? {
-        val settings = this.settings ?: ClockSettings()
-        if (clockId != settings.clockId) {
-            settings.clockId = clockId
+    private fun createClock(targetClockId: ClockId): ClockController? {
+        var settings = this.settings ?: ClockSettings()
+        if (targetClockId != settings.clockId) {
+            settings = settings.copy(clockId = targetClockId)
         }
-        return availableClocks[clockId]?.provider?.createClock(settings)
+        return availableClocks[targetClockId]?.provider?.createClock(settings)
     }
 
     private data class ClockInfo(
         val metadata: ClockMetadata,
-        val provider: ClockProvider
+        val provider: ClockProvider,
     )
 }
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/shared/model/ClockPreviewConstants.kt
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to packages/SystemUI/customization/src/com/android/systemui/shared/clocks/shared/model/ClockPreviewConstants.kt
index 497c272..6a77936 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/shared/model/ClockPreviewConstants.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.
@@ -12,14 +12,11 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- */
-
-package com.android.credentialmanager.jetpack.developer
-
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
  *
- * @hide
  */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+
+package com.android.systemui.shared.clocks.shared.model
+
+object ClockPreviewConstants {
+    const val KEY_HIDE_CLOCK = "hide_clock"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/Assert.java b/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/util/Assert.java
rename to packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
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 bbfb6fb..1c2f38b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -45,7 +45,7 @@
     /** Initializes and returns the target clock design */
     @Deprecated("Use overload with ClockSettings")
     fun createClock(id: ClockId): ClockController {
-        return createClock(ClockSettings(id, null, null))
+        return createClock(ClockSettings(id, null))
     }
 
     /** Initializes and returns the target clock design */
@@ -111,6 +111,9 @@
 
     /** Call whenever the color palette should update */
     fun onColorPaletteChanged(resources: Resources) {}
+
+    /** Call whenever the weather data should update */
+    fun onWeatherDataChanged(data: Weather) {}
 }
 
 /** Methods which trigger various clock animations */
@@ -183,16 +186,21 @@
 /** Structure for keeping clock-specific settings */
 @Keep
 data class ClockSettings(
-    var clockId: ClockId? = null,
-    var seedColor: Int? = null,
-    var _applied_timestamp: Long? = null,
+    val clockId: ClockId? = null,
+    val seedColor: Int? = null,
 ) {
+    var _applied_timestamp: Long? = null
+
     companion object {
         private val KEY_CLOCK_ID = "clockId"
         private val KEY_SEED_COLOR = "seedColor"
         private val KEY_TIMESTAMP = "_applied_timestamp"
 
-        fun serialize(setting: ClockSettings): String {
+        fun serialize(setting: ClockSettings?): String {
+            if (setting == null) {
+                return ""
+            }
+
             return JSONObject()
                 .put(KEY_CLOCK_ID, setting.clockId)
                 .put(KEY_SEED_COLOR, setting.seedColor)
@@ -200,13 +208,21 @@
                 .toString()
         }
 
-        fun deserialize(jsonStr: String): ClockSettings {
+        fun deserialize(jsonStr: String?): ClockSettings? {
+            if (jsonStr.isNullOrEmpty()) {
+                return null
+            }
+
             val json = JSONObject(jsonStr)
-            return ClockSettings(
-                json.getString(KEY_CLOCK_ID),
-                if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null,
-                if (!json.isNull(KEY_TIMESTAMP)) json.getLong(KEY_TIMESTAMP) else null
-            )
+            val result =
+                ClockSettings(
+                    json.getString(KEY_CLOCK_ID),
+                    if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
+                )
+            if (!json.isNull(KEY_TIMESTAMP)) {
+                result._applied_timestamp = json.getLong(KEY_TIMESTAMP)
+            }
+            return result
         }
     }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/MotionEventsHandlerBase.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/MotionEventsHandlerBase.java
deleted file mode 100644
index 2a64185..0000000
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/MotionEventsHandlerBase.java
+++ /dev/null
@@ -1,31 +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.plugins;
-
-import android.view.MotionEvent;
-
-/** Handles both trackpad and touch events and report displacements in both axis's. */
-public interface MotionEventsHandlerBase {
-
-    void onMotionEvent(MotionEvent ev);
-
-    float getDisplacementX(MotionEvent ev);
-
-    float getDisplacementY(MotionEvent ev);
-
-    String dump();
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
index 054e300..5f6f11c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
@@ -48,9 +48,6 @@
     /** Sets the base LayoutParams for the UI. */
     void setLayoutParams(WindowManager.LayoutParams layoutParams);
 
-    /** Sets the motion events handler for the plugin. */
-    default void setMotionEventsHandler(MotionEventsHandlerBase motionEventsHandler) {}
-
     /** Updates the UI based on the motion events passed in device coordinates. */
     void onMotionEvent(MotionEvent motionEvent);
 
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt
index 85ec42d..302f175 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Weather.kt
@@ -1,4 +1,4 @@
-package com.android.systemui.statusbar
+package com.android.systemui.plugins
 
 import android.os.Bundle
 
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml
index c388f15..81f4c8c 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer_user_switcher_item.xml
@@ -15,6 +15,7 @@
   -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/user_switcher_item"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
   <TextView
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index 64ece47..ca4028a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -105,6 +105,7 @@
             android:id="@+id/key1"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key2"
             androidprv:digit="1"
             androidprv:textView="@+id/pinEntry" />
 
@@ -112,6 +113,7 @@
             android:id="@+id/key2"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key3"
             androidprv:digit="2"
             androidprv:textView="@+id/pinEntry" />
 
@@ -119,6 +121,7 @@
             android:id="@+id/key3"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key4"
             androidprv:digit="3"
             androidprv:textView="@+id/pinEntry" />
 
@@ -126,6 +129,7 @@
             android:id="@+id/key4"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key5"
             androidprv:digit="4"
             androidprv:textView="@+id/pinEntry" />
 
@@ -133,6 +137,7 @@
             android:id="@+id/key5"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key6"
             androidprv:digit="5"
             androidprv:textView="@+id/pinEntry" />
 
@@ -140,6 +145,7 @@
             android:id="@+id/key6"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key7"
             androidprv:digit="6"
             androidprv:textView="@+id/pinEntry" />
 
@@ -147,13 +153,16 @@
             android:id="@+id/key7"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key8"
             androidprv:digit="7"
             androidprv:textView="@+id/pinEntry" />
 
+
         <com.android.keyguard.NumPadKey
             android:id="@+id/key8"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key9"
             androidprv:digit="8"
             androidprv:textView="@+id/pinEntry" />
 
@@ -161,34 +170,33 @@
             android:id="@+id/key9"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/delete_button"
             androidprv:digit="9"
             androidprv:textView="@+id/pinEntry" />
 
-
         <com.android.keyguard.NumPadButton
             android:id="@+id/delete_button"
+            style="@style/NumPadKey.Delete"
             android:layout_width="0dp"
             android:layout_height="0dp"
-            style="@style/NumPadKey.Delete"
-            android:contentDescription="@string/keyboardview_keycode_delete"
-            />
+            android:accessibilityTraversalBefore="@id/key0"
+            android:contentDescription="@string/keyboardview_keycode_delete" />
 
         <com.android.keyguard.NumPadKey
             android:id="@+id/key0"
             android:layout_width="0dp"
             android:layout_height="0dp"
+            android:accessibilityTraversalBefore="@id/key_enter"
             androidprv:digit="0"
             androidprv:textView="@+id/pinEntry" />
 
         <com.android.keyguard.NumPadButton
             android:id="@+id/key_enter"
+            style="@style/NumPadKey.Enter"
             android:layout_width="0dp"
             android:layout_height="0dp"
-            style="@style/NumPadKey.Enter"
-            android:contentDescription="@string/keyboardview_keycode_enter"
-            />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
+            android:contentDescription="@string/keyboardview_keycode_enter" />
+</androidx.constraintlayout.widget.ConstraintLayout>
 
     <include layout="@layout/keyguard_eca"
              android:id="@+id/keyguard_selector_fade_container"
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index ca0be3f..e45df7ab 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -53,7 +53,7 @@
     <string name="kg_wrong_pattern" msgid="5907301342430102842">"Patró incorrecte"</string>
     <string name="kg_wrong_password" msgid="4143127991071670512">"Contrasenya incorrecta"</string>
     <string name="kg_wrong_pin" msgid="4160978845968732624">"El PIN no és correcte"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Torna-ho a provar d\'aquí a # segon.}many{Try again in # seconds.}other{Torna-ho a provar d\'aquí a # segons.}}"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="2038195171919795529">"{count,plural, =1{Torna-ho a provar d\'aquí a # segon.}many{Torna-ho a provar d\'aquí a # segons.}other{Torna-ho a provar d\'aquí a # segons.}}"</string>
     <string name="kg_sim_pin_instructions" msgid="1942424305184242951">"Introdueix el PIN de la SIM."</string>
     <string name="kg_sim_pin_instructions_multi" msgid="3639863309953109649">"Introdueix el PIN de la SIM de: <xliff:g id="CARRIER">%1$s</xliff:g>."</string>
     <string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Desactiva l\'eSIM per utilitzar el dispositiu sense servei mòbil."</string>
@@ -68,9 +68,9 @@
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Has escrit la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
     <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="8047350661459040581">"El codi PIN de la SIM no és correcte. Contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu."</string>
-    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{El codi PIN de la SIM no és correcte. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}many{Incorrect SIM PIN code, you have # remaining attempts. }other{El codi PIN de la SIM no és correcte. Et queden # intents. }}"</string>
+    <string name="kg_password_wrong_pin_code" msgid="5629415765976820357">"{count,plural, =1{El codi PIN de la SIM no és correcte. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}many{El codi PIN de la SIM no és correcte. Et queden # intents. }other{El codi PIN de la SIM no és correcte. Et queden # intents. }}"</string>
     <string name="kg_password_wrong_puk_code_dead" msgid="3698285357028468617">"La SIM no es pot fer servir. Contacta amb l\'operador de telefonia mòbil."</string>
-    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{El codi PUK de la SIM no és correcte. Et queda # intent; si no l\'encertes, la SIM no es podrà tornar a fer servir.}many{Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}other{El codi PUK de la SIM no és correcte. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir.}}"</string>
+    <string name="kg_password_wrong_puk_code" msgid="6820515467645087827">"{count,plural, =1{El codi PUK de la SIM no és correcte. Et queda # intent; si no l\'encertes, la SIM no es podrà tornar a fer servir.}many{El codi PUK de la SIM no és correcte. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir.}other{El codi PUK de la SIM no és correcte. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir.}}"</string>
     <string name="kg_password_pin_failed" msgid="5136259126330604009">"Ha fallat l\'operació del PIN de la SIM"</string>
     <string name="kg_password_puk_failed" msgid="6778867411556937118">"No s\'ha pogut desbloquejar la SIM amb el codi PUK."</string>
     <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Canvia el mètode d\'introducció"</string>
@@ -85,8 +85,8 @@
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"El dispositiu s\'ha bloquejat manualment"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"No s\'ha reconegut"</string>
     <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Desbloqueig facial necessita accés a la càmera"</string>
-    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Introdueix el PIN de la SIM. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}many{Enter SIM PIN. You have # remaining attempts.}other{Introdueix el PIN de la SIM. Et queden # intents.}}"</string>
-    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queda # intent; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}many{SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.}other{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}}"</string>
+    <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Introdueix el PIN de la SIM. Et queda # intent; si no l\'encertes, contacta amb l\'operador per desbloquejar el dispositiu.}many{Introdueix el PIN de la SIM. Et queden # intents.}other{Introdueix el PIN de la SIM. Et queden # intents.}}"</string>
+    <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queda # intent; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}many{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}other{La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden # intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador per obtenir informació.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Predeterminada"</string>
     <string name="clock_title_bubble" msgid="2204559396790593213">"Bombolla"</string>
     <string name="clock_title_analog" msgid="8409262532900918273">"Analògica"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index ea58cc8..b79ad39 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -84,7 +84,7 @@
     <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Administratzaileak blokeatu egin du gailua"</string>
     <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Eskuz blokeatu da gailua"</string>
     <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ez da ezagutu"</string>
-    <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aurpegi bidezko desblokeoak kamera atzitzeko baimena behar du"</string>
+    <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aurpegi bidezko desblokeoak kamera erabiltzeko baimena behar du"</string>
     <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Idatzi SIMaren PINa. # saiakera geratzen zaizu gailua desblokeatzeko operadorearekin harremanetan jarri behar izan aurretik.}other{Idatzi SIMaren PINa. # saiakera gelditzen zaizkizu.}}"</string>
     <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{Orain, SIMa desgaituta dago. Aurrera egiteko, idatzi PUK kodea. # saiakera geratzen zaizu SIMa betiko ez-erabilgarri geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.}other{Orain, SIMa desgaituta dago. Aurrera egiteko, idatzi PUK kodea. # saiakera geratzen zaizkizu SIMa betiko ez-erabilgarri geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.}}"</string>
     <string name="clock_title_default" msgid="6342735240617459864">"Lehenetsia"</string>
diff --git a/packages/SystemUI/res-keyguard/values/arrays.xml b/packages/SystemUI/res-keyguard/values/arrays.xml
index a8b3c1b..26bc865 100644
--- a/packages/SystemUI/res-keyguard/values/arrays.xml
+++ b/packages/SystemUI/res-keyguard/values/arrays.xml
@@ -32,4 +32,13 @@
         <item>TUV</item><!-- 8 -->
         <item>WXYZ</item><!-- 9 -->
     </string-array>
+
+    <integer-array name="bouncer_pin_shapes">
+        <item>@drawable/pin_dot_shape_1_avd</item>
+        <item>@drawable/pin_dot_shape_2_avd</item>
+        <item>@drawable/pin_dot_shape_3_avd</item>
+        <item>@drawable/pin_dot_shape_4_avd</item>
+        <item>@drawable/pin_dot_shape_5_avd</item>
+        <item>@drawable/pin_dot_shape_6_avd</item>
+    </integer-array>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 6cc5b9d..b9c7be2 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -69,6 +69,10 @@
 
     <!-- The size of the dots in the PIN unlock method. -->
     <dimen name="password_dot_size">9dp</dimen>
+
+    <!-- The size of the shape in the PIN unlock method. -->
+    <dimen name="password_shape_size">34dp</dimen>
+
     <!-- The size of PIN text in the PIN unlock method. -->
     <integer name="scaled_password_text_size">40</integer>
 
@@ -139,4 +143,9 @@
 
     <!-- Translation y for appear animation -->
     <dimen name="keyguard_host_view_translation_y">80dp</dimen>
+
+    <!-- Attributes for placeholder dots in 6 digit PIN view -->
+    <dimen name="default_dot_diameter">34dp</dimen>
+    <dimen name="default_dot_spacing">0dp</dimen>
+
 </resources>
diff --git a/packages/SystemUI/res/drawable/ic_sound_bars_anim.xml b/packages/SystemUI/res/drawable/ic_sound_bars_anim.xml
new file mode 100644
index 0000000..43fdec5
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sound_bars_anim.xml
@@ -0,0 +1,225 @@
+<?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.
+-->
+<animated-vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="30dp" android:width="36dp" android:viewportHeight="30"
+                android:viewportWidth="36">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_2_G" android:translateX="5.939"
+                       android:translateY="26.583" android:pivotY="0.379" android:scaleX="31.96611"
+                       android:scaleY="31.96611">
+                    <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#ffffff"
+                          android:fillAlpha="1" android:fillType="nonZero"
+                          android:pathData=" M0.09 0.27 C0.09,0.27 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.27 -0.09,0.27 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.27c "/>
+                </group>
+                <group android:name="_R_G_L_1_G_N_3_T_0" android:translateX="5.939"
+                       android:translateY="26.583" android:pivotY="0.379" android:scaleX="31.96611"
+                       android:scaleY="31.96611">
+                    <group android:name="_R_G_L_1_G" android:translateX="0.379"
+                           android:translateY="0.19">
+                        <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+                              android:fillAlpha="1" android:fillType="nonZero"
+                              android:pathData=" M0.09 0.09 C0.09,0.09 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,0.09 -0.1,0.09 C-0.1,0.04 -0.05,-0.01 0,-0.01 C0.05,-0.01 0.09,0.04 0.09,0.09c "/>
+                    </group>
+                </group>
+                <group android:name="_R_G_L_0_G_N_3_T_0" android:translateX="5.939"
+                       android:translateY="26.583" android:pivotY="0.379" android:scaleX="31.96611"
+                       android:scaleY="31.96611">
+                    <group android:name="_R_G_L_0_G" android:translateX="0.758">
+                        <path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff"
+                              android:fillAlpha="1" android:fillType="nonZero"
+                              android:pathData=" M0.09 0.28 C0.09,0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.28 -0.09,0.28 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.28c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_2_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="333"
+                        android:startOffset="0"
+                        android:valueFrom="M0.09 -0.28 C0.09,-0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.28 -0.09,-0.28 C-0.09,-0.34 -0.05,-0.38 0,-0.38 C0.05,-0.38 0.09,-0.34 0.09,-0.28c "
+                        android:valueTo="M0.09 0.27 C0.09,0.27 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.27 -0.09,0.27 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.27c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.595,0 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="333"
+                        android:startOffset="333"
+                        android:valueFrom="M0.09 0.27 C0.09,0.27 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.27 -0.09,0.27 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.27c "
+                        android:valueTo="M0.09 -0.28 C0.09,-0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.28 -0.09,-0.28 C-0.09,-0.34 -0.05,-0.38 0,-0.38 C0.05,-0.38 0.09,-0.34 0.09,-0.28c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.595,0 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="333"
+                        android:startOffset="667"
+                        android:valueFrom="M0.09 -0.28 C0.09,-0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.28 -0.09,-0.28 C-0.09,-0.34 -0.05,-0.38 0,-0.38 C0.05,-0.38 0.09,-0.34 0.09,-0.28c "
+                        android:valueTo="M0.09 0.27 C0.09,0.27 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.27 -0.09,0.27 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.27c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.595,0 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="83"
+                        android:startOffset="0"
+                        android:valueFrom="M0.09 -0.44 C0.09,-0.44 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,-0.44 -0.1,-0.44 C-0.1,-0.5 -0.05,-0.54 0,-0.54 C0.05,-0.54 0.09,-0.5 0.09,-0.44c "
+                        android:valueTo="M0.09 -0.49 C0.09,-0.49 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,-0.49 -0.1,-0.49 C-0.1,-0.54 -0.05,-0.58 0,-0.58 C0.05,-0.58 0.09,-0.54 0.09,-0.49c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.167,0.167 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="333"
+                        android:startOffset="83"
+                        android:valueFrom="M0.09 -0.49 C0.09,-0.49 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,-0.49 -0.1,-0.49 C-0.1,-0.54 -0.05,-0.58 0,-0.58 C0.05,-0.58 0.09,-0.54 0.09,-0.49c "
+                        android:valueTo="M0.09 0.09 C0.09,0.09 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,0.09 -0.1,0.09 C-0.1,0.04 -0.05,-0.01 0,-0.01 C0.05,-0.01 0.09,0.04 0.09,0.09c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.595,0 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="250"
+                        android:startOffset="417"
+                        android:valueFrom="M0.09 0.09 C0.09,0.09 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,0.09 -0.1,0.09 C-0.1,0.04 -0.05,-0.01 0,-0.01 C0.05,-0.01 0.09,0.04 0.09,0.09c "
+                        android:valueTo="M0.09 -0.44 C0.09,-0.44 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,-0.44 -0.1,-0.44 C-0.1,-0.5 -0.05,-0.54 0,-0.54 C0.05,-0.54 0.09,-0.5 0.09,-0.44c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.595,0 0.833,0.833 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="83"
+                        android:startOffset="667"
+                        android:valueFrom="M0.09 -0.44 C0.09,-0.44 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,-0.44 -0.1,-0.44 C-0.1,-0.5 -0.05,-0.54 0,-0.54 C0.05,-0.54 0.09,-0.5 0.09,-0.44c "
+                        android:valueTo="M0.09 -0.49 C0.09,-0.49 0.09,0.09 0.09,0.09 C0.09,0.15 0.05,0.19 0,0.19 C-0.05,0.19 -0.09,0.15 -0.09,0.09 C-0.09,0.09 -0.1,-0.49 -0.1,-0.49 C-0.1,-0.54 -0.05,-0.58 0,-0.58 C0.05,-0.58 0.09,-0.54 0.09,-0.49c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.167,0.167 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="167"
+                        android:startOffset="0"
+                        android:valueFrom="M0.09 -0.02 C0.09,-0.02 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.02 -0.09,-0.02 C-0.09,-0.07 -0.05,-0.12 0,-0.12 C0.05,-0.12 0.09,-0.07 0.09,-0.02c "
+                        android:valueTo="M0.09 -0.28 C0.09,-0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.28 -0.09,-0.28 C-0.09,-0.34 -0.05,-0.38 0,-0.38 C0.05,-0.38 0.09,-0.34 0.09,-0.28c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.167,0.167 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="333"
+                        android:startOffset="167"
+                        android:valueFrom="M0.09 -0.28 C0.09,-0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.28 -0.09,-0.28 C-0.09,-0.34 -0.05,-0.38 0,-0.38 C0.05,-0.38 0.09,-0.34 0.09,-0.28c "
+                        android:valueTo="M0.09 0.28 C0.09,0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.28 -0.09,0.28 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.28c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.595,0 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="167"
+                        android:startOffset="500"
+                        android:valueFrom="M0.09 0.28 C0.09,0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,0.28 -0.09,0.28 C-0.09,0.22 -0.05,0.18 0,0.18 C0.05,0.18 0.09,0.22 0.09,0.28c "
+                        android:valueTo="M0.09 -0.02 C0.09,-0.02 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.02 -0.09,-0.02 C-0.09,-0.07 -0.05,-0.12 0,-0.12 C0.05,-0.12 0.09,-0.07 0.09,-0.02c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.595,0 0.833,0.833 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+                <objectAnimator
+                        android:repeatCount="infinite"
+                        android:repeatMode="reverse"
+                        android:propertyName="pathData" android:duration="167"
+                        android:startOffset="667"
+                        android:valueFrom="M0.09 -0.02 C0.09,-0.02 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.02 -0.09,-0.02 C-0.09,-0.07 -0.05,-0.12 0,-0.12 C0.05,-0.12 0.09,-0.07 0.09,-0.02c "
+                        android:valueTo="M0.09 -0.28 C0.09,-0.28 0.09,0.28 0.09,0.28 C0.09,0.34 0.05,0.38 0,0.38 C-0.05,0.38 -0.09,0.34 -0.09,0.28 C-0.09,0.28 -0.09,-0.28 -0.09,-0.28 C-0.09,-0.34 -0.05,-0.38 0,-0.38 C0.05,-0.38 0.09,-0.34 0.09,-0.28c "
+                        android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator
+                            android:pathData="M 0.0,0.0 c0.167,0.167 0.372,1 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:repeatCount="infinite"
+                    android:repeatMode="reverse"
+                    android:propertyName="translateX"
+                    android:duration="683"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_edit_session.xml b/packages/SystemUI/res/drawable/media_output_status_edit_session.xml
new file mode 100644
index 0000000..0bd45ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable/media_output_status_edit_session.xml
@@ -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.
+  -->
+
+<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="M1,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.2V20ZM19,20V17Q19,15.9 18.388,14.887Q17.775,13.875 16.65,13.15Q17.925,13.3 19.05,13.662Q20.175,14.025 21.15,14.55Q22.05,15.05 22.525,15.662Q23,16.275 23,17V20ZM9,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,12ZM19,8Q19,9.65 17.825,10.825Q16.65,12 15,12Q14.725,12 14.3,11.938Q13.875,11.875 13.6,11.8Q14.275,11 14.637,10.025Q15,9.05 15,8Q15,6.95 14.637,5.975Q14.275,5 13.6,4.2Q13.95,4.075 14.3,4.037Q14.65,4 15,4Q16.65,4 17.825,5.175Q19,6.35 19,8Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_help.xml b/packages/SystemUI/res/drawable/media_output_status_help.xml
new file mode 100644
index 0000000..f93c07ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable/media_output_status_help.xml
@@ -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.
+  -->
+
+<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="@color/media_dialog_item_main_content"
+        android:pathData="M11.95,18Q12.475,18 12.838,17.637Q13.2,17.275 13.2,16.75Q13.2,16.225 12.838,15.863Q12.475,15.5 11.95,15.5Q11.425,15.5 11.062,15.863Q10.7,16.225 10.7,16.75Q10.7,17.275 11.062,17.637Q11.425,18 11.95,18ZM11.05,14.15H12.9Q12.9,13.325 13.088,12.85Q13.275,12.375 14.15,11.55Q14.8,10.9 15.175,10.312Q15.55,9.725 15.55,8.9Q15.55,7.5 14.525,6.75Q13.5,6 12.1,6Q10.675,6 9.788,6.75Q8.9,7.5 8.55,8.55L10.2,9.2Q10.325,8.75 10.763,8.225Q11.2,7.7 12.1,7.7Q12.9,7.7 13.3,8.137Q13.7,8.575 13.7,9.1Q13.7,9.6 13.4,10.037Q13.1,10.475 12.65,10.85Q11.55,11.825 11.3,12.325Q11.05,12.825 11.05,14.15ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_session.xml b/packages/SystemUI/res/drawable/media_output_status_session.xml
new file mode 100644
index 0000000..1deba1e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/media_output_status_session.xml
@@ -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.
+  -->
+
+<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="M4,20V12H8V20ZM10,20V4H14V20ZM16,20V9H20V20Z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/pin_dot_avd.xml b/packages/SystemUI/res/drawable/pin_dot_avd.xml
new file mode 100644
index 0000000..e0cd1fb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_avd.xml
@@ -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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt">
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator
+                    android:duration="500"
+                    android:propertyName="translateX"
+                    android:startOffset="0"
+                    android:valueFrom="0"
+                    android:valueTo="1"
+                    android:valueType="floatType" />
+            </set>
+        </aapt:attr>
+    </target>
+    <aapt:attr name="android:drawable">
+        <vector
+            android:width="60dp"
+            android:height="61dp"
+            android:viewportHeight="60"
+            android:viewportWidth="60">
+            <group android:name="_R_G">
+                <group
+                    android:name="_R_G_L_0_G"
+                    android:translateX="43.237"
+                    android:translateY="38.112">
+                    <path
+                        android:name="_R_G_L_0_G_D_0_P_0"
+                        android:pathData=" M-13.24 -12.11 C-11.03,-12.11 -9.24,-10.32 -9.24,-8.11 C-9.24,-5.9 -11.03,-4.11 -13.24,-4.11 C-15.44,-4.11 -17.24,-5.9 -17.24,-8.11 C-17.24,-10.32 -15.44,-12.11 -13.24,-12.11c "
+                        android:strokeAlpha="1"
+                        android:strokeColor="#ffffff"
+                        android:strokeLineCap="round"
+                        android:strokeLineJoin="round"
+                        android:strokeWidth="2" />
+                </group>
+            </group>
+            <group android:name="time_group" />
+        </vector>
+    </aapt:attr>
+</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_delete_avd.xml b/packages/SystemUI/res/drawable/pin_dot_delete_avd.xml
new file mode 100644
index 0000000..33f995c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_delete_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="43.54" android:translateY="38.54"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c "/><path android:name="_R_G_L_0_G_D_1_P_0" android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="0" android:strokeAlpha="1" android:pathData=" M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="150" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="fillAlpha" android:duration="200" android:startOffset="150" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="150" android:startOffset="0" android:valueFrom="M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c " android:valueTo="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="150" android:valueFrom="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueTo="M-13.54 -12.54 C-11.33,-12.54 -9.54,-10.75 -9.54,-8.54 C-9.54,-6.33 -11.33,-4.54 -13.54,-4.54 C-15.75,-4.54 -17.54,-6.33 -17.54,-8.54 C-17.54,-10.75 -15.75,-12.54 -13.54,-12.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeWidth" android:duration="150" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeWidth" android:duration="50" android:startOffset="150" android:valueFrom="0" android:valueTo="2" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="150" android:startOffset="0" android:valueFrom="M-13.54 -16.54 C-9.12,-16.54 -5.54,-12.96 -5.54,-8.54 C-5.54,-4.12 -9.12,-0.54 -13.54,-0.54 C-17.96,-0.54 -21.54,-4.12 -21.54,-8.54 C-21.54,-12.96 -17.96,-16.54 -13.54,-16.54c " android:valueTo="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="200" android:startOffset="150" android:valueFrom="M-13.54 -11.54 C-11.88,-11.54 -10.54,-10.2 -10.54,-8.54 C-10.54,-6.88 -11.88,-5.54 -13.54,-5.54 C-15.2,-5.54 -16.54,-6.88 -16.54,-8.54 C-16.54,-10.2 -15.2,-11.54 -13.54,-11.54c " android:valueTo="M-13.54 -12.54 C-11.33,-12.54 -9.54,-10.75 -9.54,-8.54 C-9.54,-6.33 -11.33,-4.54 -13.54,-4.54 C-15.75,-4.54 -17.54,-6.33 -17.54,-8.54 C-17.54,-10.75 -15.75,-12.54 -13.54,-12.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_shape_1_avd.xml b/packages/SystemUI/res/drawable/pin_dot_shape_1_avd.xml
new file mode 100644
index 0000000..da936a2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_shape_1_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="-187.543" android:translateY="-188.546"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="33" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c " android:valueTo="M217.52 203.54 C217.52,203.54 217.83,203.53 217.83,203.53 C217.83,203.53 218.14,203.52 218.14,203.52 C218.14,203.52 218.44,203.49 218.44,203.49 C218.44,203.49 218.75,203.45 218.75,203.45 C218.75,203.45 219.05,203.41 219.05,203.41 C219.05,203.41 219.36,203.35 219.36,203.35 C219.36,203.35 219.66,203.28 219.66,203.28 C219.66,203.28 219.96,203.21 219.96,203.21 C219.96,203.21 220.25,203.11 220.25,203.11 C220.25,203.11 220.54,203.02 220.54,203.02 C220.54,203.02 220.83,202.9 220.83,202.9 C220.83,202.9 221.11,202.79 221.11,202.79 C221.11,202.79 221.4,202.66 221.4,202.66 C221.4,202.66 221.68,202.54 221.68,202.54 C221.68,202.54 221.96,202.42 221.96,202.42 C221.96,202.42 222.25,202.3 222.25,202.3 C222.25,202.3 222.53,202.19 222.53,202.19 C222.53,202.19 222.82,202.08 222.82,202.08 C222.82,202.08 223.11,201.97 223.11,201.97 C223.11,201.97 223.41,201.89 223.41,201.89 C223.41,201.89 223.71,201.81 223.71,201.81 C223.71,201.81 224,201.73 224,201.73 C224,201.73 224.31,201.68 224.31,201.68 C224.31,201.68 224.61,201.63 224.61,201.63 C224.61,201.63 224.92,201.59 224.92,201.59 C224.92,201.59 225.23,201.57 225.23,201.57 C225.23,201.57 225.53,201.55 225.53,201.55 C225.53,201.55 225.84,201.55 225.84,201.55 C225.84,201.55 226.15,201.56 226.15,201.56 C226.15,201.56 226.46,201.57 226.46,201.57 C226.46,201.57 226.76,201.6 226.76,201.6 C226.76,201.6 227.07,201.65 227.07,201.65 C227.07,201.65 227.37,201.69 227.37,201.69 C227.37,201.69 227.67,201.76 227.67,201.76 C227.67,201.76 227.97,201.84 227.97,201.84 C227.97,201.84 228.27,201.92 228.27,201.92 C228.27,201.92 228.56,202.02 228.56,202.02 C228.56,202.02 228.85,202.12 228.85,202.12 C228.85,202.12 229.14,202.24 229.14,202.24 C229.14,202.24 229.42,202.37 229.42,202.37 C229.42,202.37 229.7,202.5 229.7,202.5 C229.7,202.5 229.97,202.65 229.97,202.65 C229.97,202.65 230.23,202.8 230.23,202.8 C230.23,202.8 230.5,202.96 230.5,202.96 C230.5,202.96 230.75,203.14 230.75,203.14 C230.75,203.14 231,203.32 231,203.32 C231,203.32 231.24,203.51 231.24,203.51 C231.24,203.51 231.48,203.71 231.48,203.71 C231.48,203.71 231.71,203.91 231.71,203.91 C231.71,203.91 231.93,204.13 231.93,204.13 C231.93,204.13 232.15,204.35 232.15,204.35 C232.15,204.35 232.35,204.58 232.35,204.58 C232.35,204.58 232.55,204.81 232.55,204.81 C232.55,204.81 232.75,205.05 232.75,205.05 C232.75,205.05 232.92,205.3 232.92,205.3 C232.92,205.3 233.1,205.56 233.1,205.56 C233.1,205.56 233.27,205.81 233.27,205.81 C233.27,205.81 233.42,206.08 233.42,206.08 C233.42,206.08 233.57,206.35 233.57,206.35 C233.57,206.35 233.7,206.63 233.7,206.63 C233.7,206.63 233.83,206.91 233.83,206.91 C233.83,206.91 233.95,207.19 233.95,207.19 C233.95,207.19 234.05,207.48 234.05,207.48 C234.05,207.48 234.16,207.77 234.16,207.77 C234.16,207.77 234.24,208.07 234.24,208.07 C234.24,208.07 234.31,208.37 234.31,208.37 C234.31,208.37 234.39,208.67 234.39,208.67 C234.39,208.67 234.43,208.97 234.43,208.97 C234.43,208.97 234.48,209.28 234.48,209.28 C234.48,209.28 234.52,209.58 234.52,209.58 C234.52,209.58 234.53,209.89 234.53,209.89 C234.53,209.89 234.54,210.2 234.54,210.2 C234.54,210.2 234.54,210.51 234.54,210.51 C234.54,210.51 234.52,210.82 234.52,210.82 C234.52,210.82 234.5,211.12 234.5,211.12 C234.5,211.12 234.46,211.43 234.46,211.43 C234.46,211.43 234.42,211.73 234.42,211.73 C234.42,211.73 234.37,212.04 234.37,212.04 C234.37,212.04 234.29,212.34 234.29,212.34 C234.29,212.34 234.21,212.64 234.21,212.64 C234.21,212.64 234.13,212.93 234.13,212.93 C234.13,212.93 234.03,213.22 234.03,213.22 C234.03,213.22 233.92,213.51 233.92,213.51 C233.92,213.51 233.81,213.8 233.81,213.8 C233.81,213.8 233.69,214.08 233.69,214.08 C233.69,214.08 233.57,214.37 233.57,214.37 C233.57,214.37 233.44,214.65 233.44,214.65 C233.44,214.65 233.32,214.93 233.32,214.93 C233.32,214.93 233.21,215.22 233.21,215.22 C233.21,215.22 233.1,215.51 233.1,215.51 C233.1,215.51 232.99,215.79 232.99,215.79 C232.99,215.79 232.9,216.09 232.9,216.09 C232.9,216.09 232.82,216.39 232.82,216.39 C232.82,216.39 232.74,216.69 232.74,216.69 C232.74,216.69 232.69,216.99 232.69,216.99 C232.69,216.99 232.64,217.29 232.64,217.29 C232.64,217.29 232.6,217.6 232.6,217.6 C232.6,217.6 232.58,217.91 232.58,217.91 C232.58,217.91 232.56,218.21 232.56,218.21 C232.56,218.21 232.55,218.52 232.55,218.52 C232.55,218.52 232.56,218.83 232.56,218.83 C232.56,218.83 232.57,219.14 232.57,219.14 C232.57,219.14 232.6,219.45 232.6,219.45 C232.6,219.45 232.64,219.75 232.64,219.75 C232.64,219.75 232.68,220.06 232.68,220.06 C232.68,220.06 232.74,220.36 232.74,220.36 C232.74,220.36 232.81,220.66 232.81,220.66 C232.81,220.66 232.88,220.96 232.88,220.96 C232.88,220.96 232.98,221.25 232.98,221.25 C232.98,221.25 233.07,221.54 233.07,221.54 C233.07,221.54 233.19,221.83 233.19,221.83 C233.19,221.83 233.3,222.12 233.3,222.12 C233.3,222.12 233.42,222.4 233.42,222.4 C233.42,222.4 233.55,222.68 233.55,222.68 C233.55,222.68 233.67,222.96 233.67,222.96 C233.67,222.96 233.79,223.25 233.79,223.25 C233.79,223.25 233.9,223.54 233.9,223.54 C233.9,223.54 234.01,223.82 234.01,223.82 C234.01,223.82 234.12,224.11 234.12,224.11 C234.12,224.11 234.2,224.41 234.2,224.41 C234.2,224.41 234.28,224.71 234.28,224.71 C234.28,224.71 234.36,225.01 234.36,225.01 C234.36,225.01 234.41,225.31 234.41,225.31 C234.41,225.31 234.46,225.62 234.46,225.62 C234.46,225.62 234.5,225.92 234.5,225.92 C234.5,225.92 234.52,226.23 234.52,226.23 C234.52,226.23 234.54,226.54 234.54,226.54 C234.54,226.54 234.54,226.84 234.54,226.84 C234.54,226.84 234.53,227.15 234.53,227.15 C234.53,227.15 234.52,227.46 234.52,227.46 C234.52,227.46 234.48,227.77 234.48,227.77 C234.48,227.77 234.44,228.07 234.44,228.07 C234.44,228.07 234.4,228.38 234.4,228.38 C234.4,228.38 234.33,228.68 234.33,228.68 C234.33,228.68 234.25,228.98 234.25,228.98 C234.25,228.98 234.17,229.27 234.17,229.27 C234.17,229.27 234.07,229.56 234.07,229.56 C234.07,229.56 233.97,229.86 233.97,229.86 C233.97,229.86 233.85,230.14 233.85,230.14 C233.85,230.14 233.72,230.42 233.72,230.42 C233.72,230.42 233.59,230.7 233.59,230.7 C233.59,230.7 233.44,230.97 233.44,230.97 C233.44,230.97 233.29,231.24 233.29,231.24 C233.29,231.24 233.13,231.5 233.13,231.5 C233.13,231.5 232.95,231.75 232.95,231.75 C232.95,231.75 232.77,232 232.77,232 C232.77,232 232.58,232.24 232.58,232.24 C232.58,232.24 232.38,232.48 232.38,232.48 C232.38,232.48 232.18,232.71 232.18,232.71 C232.18,232.71 231.96,232.93 231.96,232.93 C231.96,232.93 231.74,233.15 231.74,233.15 C231.74,233.15 231.51,233.35 231.51,233.35 C231.51,233.35 231.28,233.55 231.28,233.55 C231.28,233.55 231.04,233.75 231.04,233.75 C231.04,233.75 230.79,233.92 230.79,233.92 C230.79,233.92 230.53,234.1 230.53,234.1 C230.53,234.1 230.28,234.27 230.28,234.27 C230.28,234.27 230.01,234.42 230.01,234.42 C230.01,234.42 229.74,234.57 229.74,234.57 C229.74,234.57 229.46,234.71 229.46,234.71 C229.46,234.71 229.18,234.83 229.18,234.83 C229.18,234.83 228.9,234.96 228.9,234.96 C228.9,234.96 228.61,235.06 228.61,235.06 C228.61,235.06 228.32,235.16 228.32,235.16 C228.32,235.16 228.02,235.24 228.02,235.24 C228.02,235.24 227.72,235.32 227.72,235.32 C227.72,235.32 227.42,235.39 227.42,235.39 C227.42,235.39 227.12,235.44 227.12,235.44 C227.12,235.44 226.81,235.48 226.81,235.48 C226.81,235.48 226.51,235.52 226.51,235.52 C226.51,235.52 226.2,235.53 226.2,235.53 C226.2,235.53 225.89,235.54 225.89,235.54 C225.89,235.54 225.58,235.54 225.58,235.54 C225.58,235.54 225.27,235.52 225.27,235.52 C225.27,235.52 224.97,235.51 224.97,235.51 C224.97,235.51 224.66,235.47 224.66,235.47 C224.66,235.47 224.36,235.42 224.36,235.42 C224.36,235.42 224.05,235.37 224.05,235.37 C224.05,235.37 223.75,235.3 223.75,235.3 C223.75,235.3 223.45,235.22 223.45,235.22 C223.45,235.22 223.16,235.14 223.16,235.14 C223.16,235.14 222.87,235.03 222.87,235.03 C222.87,235.03 222.58,234.92 222.58,234.92 C222.58,234.92 222.29,234.81 222.29,234.81 C222.29,234.81 222.01,234.69 222.01,234.69 C222.01,234.69 221.72,234.57 221.72,234.57 C221.72,234.57 221.44,234.45 221.44,234.45 C221.44,234.45 221.16,234.32 221.16,234.32 C221.16,234.32 220.87,234.21 220.87,234.21 C220.87,234.21 220.58,234.1 220.58,234.1 C220.58,234.1 220.29,233.99 220.29,233.99 C220.29,233.99 220,233.91 220,233.91 C220,233.91 219.7,233.83 219.7,233.83 C219.7,233.83 219.4,233.75 219.4,233.75 C219.4,233.75 219.1,233.7 219.1,233.7 C219.1,233.7 218.8,233.65 218.8,233.65 C218.8,233.65 218.49,233.6 218.49,233.6 C218.49,233.6 218.18,233.58 218.18,233.58 C218.18,233.58 217.88,233.56 217.88,233.56 C217.88,233.56 217.57,233.55 217.57,233.55 C217.57,233.55 217.26,233.56 217.26,233.56 C217.26,233.56 216.95,233.57 216.95,233.57 C216.95,233.57 216.64,233.6 216.64,233.6 C216.64,233.6 216.34,233.64 216.34,233.64 C216.34,233.64 216.03,233.68 216.03,233.68 C216.03,233.68 215.73,233.74 215.73,233.74 C215.73,233.74 215.43,233.81 215.43,233.81 C215.43,233.81 215.13,233.88 215.13,233.88 C215.13,233.88 214.84,233.98 214.84,233.98 C214.84,233.98 214.55,234.08 214.55,234.08 C214.55,234.08 214.26,234.19 214.26,234.19 C214.26,234.19 213.97,234.3 213.97,234.3 C213.97,234.3 213.69,234.43 213.69,234.43 C213.69,234.43 213.41,234.55 213.41,234.55 C213.41,234.55 213.12,234.67 213.12,234.67 C213.12,234.67 212.84,234.8 212.84,234.8 C212.84,234.8 212.55,234.9 212.55,234.9 C212.55,234.9 212.26,235.01 212.26,235.01 C212.26,235.01 211.98,235.12 211.98,235.12 C211.98,235.12 211.68,235.2 211.68,235.2 C211.68,235.2 211.38,235.28 211.38,235.28 C211.38,235.28 211.08,235.36 211.08,235.36 C211.08,235.36 210.78,235.41 210.78,235.41 C210.78,235.41 210.47,235.46 210.47,235.46 C210.47,235.46 210.17,235.5 210.17,235.5 C210.17,235.5 209.86,235.52 209.86,235.52 C209.86,235.52 209.55,235.54 209.55,235.54 C209.55,235.54 209.25,235.55 209.25,235.55 C209.25,235.55 208.94,235.53 208.94,235.53 C208.94,235.53 208.63,235.52 208.63,235.52 C208.63,235.52 208.32,235.49 208.32,235.49 C208.32,235.49 208.02,235.44 208.02,235.44 C208.02,235.44 207.71,235.4 207.71,235.4 C207.71,235.4 207.41,235.33 207.41,235.33 C207.41,235.33 207.11,235.26 207.11,235.26 C207.11,235.26 206.82,235.17 206.82,235.17 C206.82,235.17 206.53,235.07 206.53,235.07 C206.53,235.07 206.23,234.97 206.23,234.97 C206.23,234.97 205.95,234.85 205.95,234.85 C205.95,234.85 205.67,234.73 205.67,234.73 C205.67,234.73 205.39,234.6 205.39,234.6 C205.39,234.6 205.12,234.44 205.12,234.44 C205.12,234.44 204.85,234.29 204.85,234.29 C204.85,234.29 204.59,234.13 204.59,234.13 C204.59,234.13 204.34,233.95 204.34,233.95 C204.34,233.95 204.09,233.78 204.09,233.78 C204.09,233.78 203.85,233.58 203.85,233.58 C203.85,233.58 203.61,233.39 203.61,233.39 C203.61,233.39 203.38,233.18 203.38,233.18 C203.38,233.18 203.16,232.96 203.16,232.96 C203.16,232.96 202.94,232.75 202.94,232.75 C202.94,232.75 202.74,232.52 202.74,232.52 C202.74,232.52 202.54,232.28 202.54,232.28 C202.54,232.28 202.34,232.04 202.34,232.04 C202.34,232.04 202.16,231.79 202.16,231.79 C202.16,231.79 201.99,231.54 201.99,231.54 C201.99,231.54 201.82,231.28 201.82,231.28 C201.82,231.28 201.67,231.01 201.67,231.01 C201.67,231.01 201.52,230.74 201.52,230.74 C201.52,230.74 201.38,230.46 201.38,230.46 C201.38,230.46 201.26,230.19 201.26,230.19 C201.26,230.19 201.13,229.9 201.13,229.9 C201.13,229.9 201.03,229.61 201.03,229.61 C201.03,229.61 200.93,229.32 200.93,229.32 C200.93,229.32 200.84,229.02 200.84,229.02 C200.84,229.02 200.77,228.72 200.77,228.72 C200.77,228.72 200.7,228.43 200.7,228.43 C200.7,228.43 200.65,228.12 200.65,228.12 C200.65,228.12 200.61,227.82 200.61,227.82 C200.61,227.82 200.57,227.51 200.57,227.51 C200.57,227.51 200.56,227.2 200.56,227.2 C200.56,227.2 200.54,226.89 200.54,226.89 C200.54,226.89 200.55,226.58 200.55,226.58 C200.55,226.58 200.56,226.28 200.56,226.28 C200.56,226.28 200.58,225.97 200.58,225.97 C200.58,225.97 200.62,225.66 200.62,225.66 C200.62,225.66 200.67,225.36 200.67,225.36 C200.67,225.36 200.72,225.06 200.72,225.06 C200.72,225.06 200.79,224.76 200.79,224.76 C200.79,224.76 200.87,224.46 200.87,224.46 C200.87,224.46 200.95,224.16 200.95,224.16 C200.95,224.16 201.06,223.87 201.06,223.87 C201.06,223.87 201.17,223.58 201.17,223.58 C201.17,223.58 201.27,223.29 201.27,223.29 C201.27,223.29 201.4,223.01 201.4,223.01 C201.4,223.01 201.52,222.73 201.52,222.73 C201.52,222.73 201.64,222.45 201.64,222.45 C201.64,222.45 201.76,222.16 201.76,222.16 C201.76,222.16 201.88,221.88 201.88,221.88 C201.88,221.88 201.99,221.59 201.99,221.59 C201.99,221.59 202.1,221.3 202.1,221.3 C202.1,221.3 202.18,221 202.18,221 C202.18,221 202.26,220.71 202.26,220.71 C202.26,220.71 202.34,220.41 202.34,220.41 C202.34,220.41 202.39,220.1 202.39,220.1 C202.39,220.1 202.44,219.8 202.44,219.8 C202.44,219.8 202.49,219.5 202.49,219.5 C202.49,219.5 202.51,219.19 202.51,219.19 C202.51,219.19 202.53,218.88 202.53,218.88 C202.53,218.88 202.54,218.57 202.54,218.57 C202.54,218.57 202.53,218.26 202.53,218.26 C202.53,218.26 202.52,217.96 202.52,217.96 C202.52,217.96 202.49,217.65 202.49,217.65 C202.49,217.65 202.45,217.34 202.45,217.34 C202.45,217.34 202.41,217.04 202.41,217.04 C202.41,217.04 202.34,216.74 202.34,216.74 C202.34,216.74 202.27,216.44 202.27,216.44 C202.27,216.44 202.2,216.14 202.2,216.14 C202.2,216.14 202.11,215.84 202.11,215.84 C202.11,215.84 202.01,215.55 202.01,215.55 C202.01,215.55 201.9,215.26 201.9,215.26 C201.9,215.26 201.78,214.98 201.78,214.98 C201.78,214.98 201.66,214.69 201.66,214.69 C201.66,214.69 201.54,214.41 201.54,214.41 C201.54,214.41 201.42,214.13 201.42,214.13 C201.42,214.13 201.29,213.84 201.29,213.84 C201.29,213.84 201.18,213.55 201.18,213.55 C201.18,213.55 201.07,213.26 201.07,213.26 C201.07,213.26 200.96,212.98 200.96,212.98 C200.96,212.98 200.88,212.68 200.88,212.68 C200.88,212.68 200.8,212.38 200.8,212.38 C200.8,212.38 200.73,212.08 200.73,212.08 C200.73,212.08 200.68,211.78 200.68,211.78 C200.68,211.78 200.63,211.47 200.63,211.47 C200.63,211.47 200.58,211.17 200.58,211.17 C200.58,211.17 200.57,210.86 200.57,210.86 C200.57,210.86 200.55,210.55 200.55,210.55 C200.55,210.55 200.54,210.25 200.54,210.25 C200.54,210.25 200.56,209.94 200.56,209.94 C200.56,209.94 200.57,209.63 200.57,209.63 C200.57,209.63 200.6,209.32 200.6,209.32 C200.6,209.32 200.65,209.02 200.65,209.02 C200.65,209.02 200.69,208.71 200.69,208.71 C200.69,208.71 200.76,208.41 200.76,208.41 C200.76,208.41 200.83,208.11 200.83,208.11 C200.83,208.11 200.92,207.82 200.92,207.82 C200.92,207.82 201.02,207.52 201.02,207.52 C201.02,207.52 201.12,207.23 201.12,207.23 C201.12,207.23 201.24,206.95 201.24,206.95 C201.24,206.95 201.36,206.67 201.36,206.67 C201.36,206.67 201.49,206.39 201.49,206.39 C201.49,206.39 201.65,206.12 201.65,206.12 C201.65,206.12 201.8,205.85 201.8,205.85 C201.8,205.85 201.96,205.59 201.96,205.59 C201.96,205.59 202.14,205.34 202.14,205.34 C202.14,205.34 202.31,205.09 202.31,205.09 C202.31,205.09 202.51,204.85 202.51,204.85 C202.51,204.85 202.71,204.61 202.71,204.61 C202.71,204.61 202.91,204.38 202.91,204.38 C202.91,204.38 203.13,204.16 203.13,204.16 C203.13,204.16 203.34,203.94 203.34,203.94 C203.34,203.94 203.57,203.74 203.57,203.74 C203.57,203.74 203.81,203.54 203.81,203.54 C203.81,203.54 204.05,203.34 204.05,203.34 C204.05,203.34 204.3,203.17 204.3,203.17 C204.3,203.17 204.55,202.99 204.55,202.99 C204.55,202.99 204.81,202.82 204.81,202.82 C204.81,202.82 205.08,202.67 205.08,202.67 C205.08,202.67 205.35,202.52 205.35,202.52 C205.35,202.52 205.63,202.38 205.63,202.38 C205.63,202.38 205.91,202.26 205.91,202.26 C205.91,202.26 206.19,202.13 206.19,202.13 C206.19,202.13 206.48,202.03 206.48,202.03 C206.48,202.03 206.77,201.93 206.77,201.93 C206.77,201.93 207.07,201.85 207.07,201.85 C207.07,201.85 207.37,201.77 207.37,201.77 C207.37,201.77 207.67,201.7 207.67,201.7 C207.67,201.7 207.97,201.65 207.97,201.65 C207.97,201.65 208.28,201.61 208.28,201.61 C208.28,201.61 208.58,201.57 208.58,201.57 C208.58,201.57 208.89,201.56 208.89,201.56 C208.89,201.56 209.2,201.55 209.2,201.55 C209.2,201.55 209.51,201.55 209.51,201.55 C209.51,201.55 209.81,201.57 209.81,201.57 C209.81,201.57 210.12,201.58 210.12,201.58 C210.12,201.58 210.43,201.62 210.43,201.62 C210.43,201.62 210.73,201.67 210.73,201.67 C210.73,201.67 211.04,201.72 211.04,201.72 C211.04,201.72 211.34,201.8 211.34,201.8 C211.34,201.8 211.63,201.88 211.63,201.88 C211.63,201.88 211.93,201.96 211.93,201.96 C211.93,201.96 212.22,202.06 212.22,202.06 C212.22,202.06 212.51,202.17 212.51,202.17 C212.51,202.17 212.8,202.28 212.8,202.28 C212.8,202.28 213.08,202.4 213.08,202.4 C213.08,202.4 213.36,202.52 213.36,202.52 C213.36,202.52 213.65,202.65 213.65,202.65 C213.65,202.65 213.93,202.77 213.93,202.77 C213.93,202.77 214.22,202.88 214.22,202.88 C214.22,202.88 214.5,202.99 214.5,202.99 C214.5,202.99 214.79,203.1 214.79,203.1 C214.79,203.1 215.09,203.19 215.09,203.19 C215.09,203.19 215.39,203.27 215.39,203.27 C215.39,203.27 215.68,203.35 215.68,203.35 C215.68,203.35 215.99,203.4 215.99,203.4 C215.99,203.4 216.29,203.45 216.29,203.45 C216.29,203.45 216.6,203.49 216.6,203.49 C216.6,203.49 216.9,203.51 216.9,203.51 C216.9,203.51 217.21,203.53 217.21,203.53 C217.21,203.53 217.52,203.54 217.52,203.54c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="67" android:valueFrom="M217.52 203.54 C217.52,203.54 217.83,203.53 217.83,203.53 C217.83,203.53 218.14,203.52 218.14,203.52 C218.14,203.52 218.44,203.49 218.44,203.49 C218.44,203.49 218.75,203.45 218.75,203.45 C218.75,203.45 219.05,203.41 219.05,203.41 C219.05,203.41 219.36,203.35 219.36,203.35 C219.36,203.35 219.66,203.28 219.66,203.28 C219.66,203.28 219.96,203.21 219.96,203.21 C219.96,203.21 220.25,203.11 220.25,203.11 C220.25,203.11 220.54,203.02 220.54,203.02 C220.54,203.02 220.83,202.9 220.83,202.9 C220.83,202.9 221.11,202.79 221.11,202.79 C221.11,202.79 221.4,202.66 221.4,202.66 C221.4,202.66 221.68,202.54 221.68,202.54 C221.68,202.54 221.96,202.42 221.96,202.42 C221.96,202.42 222.25,202.3 222.25,202.3 C222.25,202.3 222.53,202.19 222.53,202.19 C222.53,202.19 222.82,202.08 222.82,202.08 C222.82,202.08 223.11,201.97 223.11,201.97 C223.11,201.97 223.41,201.89 223.41,201.89 C223.41,201.89 223.71,201.81 223.71,201.81 C223.71,201.81 224,201.73 224,201.73 C224,201.73 224.31,201.68 224.31,201.68 C224.31,201.68 224.61,201.63 224.61,201.63 C224.61,201.63 224.92,201.59 224.92,201.59 C224.92,201.59 225.23,201.57 225.23,201.57 C225.23,201.57 225.53,201.55 225.53,201.55 C225.53,201.55 225.84,201.55 225.84,201.55 C225.84,201.55 226.15,201.56 226.15,201.56 C226.15,201.56 226.46,201.57 226.46,201.57 C226.46,201.57 226.76,201.6 226.76,201.6 C226.76,201.6 227.07,201.65 227.07,201.65 C227.07,201.65 227.37,201.69 227.37,201.69 C227.37,201.69 227.67,201.76 227.67,201.76 C227.67,201.76 227.97,201.84 227.97,201.84 C227.97,201.84 228.27,201.92 228.27,201.92 C228.27,201.92 228.56,202.02 228.56,202.02 C228.56,202.02 228.85,202.12 228.85,202.12 C228.85,202.12 229.14,202.24 229.14,202.24 C229.14,202.24 229.42,202.37 229.42,202.37 C229.42,202.37 229.7,202.5 229.7,202.5 C229.7,202.5 229.97,202.65 229.97,202.65 C229.97,202.65 230.23,202.8 230.23,202.8 C230.23,202.8 230.5,202.96 230.5,202.96 C230.5,202.96 230.75,203.14 230.75,203.14 C230.75,203.14 231,203.32 231,203.32 C231,203.32 231.24,203.51 231.24,203.51 C231.24,203.51 231.48,203.71 231.48,203.71 C231.48,203.71 231.71,203.91 231.71,203.91 C231.71,203.91 231.93,204.13 231.93,204.13 C231.93,204.13 232.15,204.35 232.15,204.35 C232.15,204.35 232.35,204.58 232.35,204.58 C232.35,204.58 232.55,204.81 232.55,204.81 C232.55,204.81 232.75,205.05 232.75,205.05 C232.75,205.05 232.92,205.3 232.92,205.3 C232.92,205.3 233.1,205.56 233.1,205.56 C233.1,205.56 233.27,205.81 233.27,205.81 C233.27,205.81 233.42,206.08 233.42,206.08 C233.42,206.08 233.57,206.35 233.57,206.35 C233.57,206.35 233.7,206.63 233.7,206.63 C233.7,206.63 233.83,206.91 233.83,206.91 C233.83,206.91 233.95,207.19 233.95,207.19 C233.95,207.19 234.05,207.48 234.05,207.48 C234.05,207.48 234.16,207.77 234.16,207.77 C234.16,207.77 234.24,208.07 234.24,208.07 C234.24,208.07 234.31,208.37 234.31,208.37 C234.31,208.37 234.39,208.67 234.39,208.67 C234.39,208.67 234.43,208.97 234.43,208.97 C234.43,208.97 234.48,209.28 234.48,209.28 C234.48,209.28 234.52,209.58 234.52,209.58 C234.52,209.58 234.53,209.89 234.53,209.89 C234.53,209.89 234.54,210.2 234.54,210.2 C234.54,210.2 234.54,210.51 234.54,210.51 C234.54,210.51 234.52,210.82 234.52,210.82 C234.52,210.82 234.5,211.12 234.5,211.12 C234.5,211.12 234.46,211.43 234.46,211.43 C234.46,211.43 234.42,211.73 234.42,211.73 C234.42,211.73 234.37,212.04 234.37,212.04 C234.37,212.04 234.29,212.34 234.29,212.34 C234.29,212.34 234.21,212.64 234.21,212.64 C234.21,212.64 234.13,212.93 234.13,212.93 C234.13,212.93 234.03,213.22 234.03,213.22 C234.03,213.22 233.92,213.51 233.92,213.51 C233.92,213.51 233.81,213.8 233.81,213.8 C233.81,213.8 233.69,214.08 233.69,214.08 C233.69,214.08 233.57,214.37 233.57,214.37 C233.57,214.37 233.44,214.65 233.44,214.65 C233.44,214.65 233.32,214.93 233.32,214.93 C233.32,214.93 233.21,215.22 233.21,215.22 C233.21,215.22 233.1,215.51 233.1,215.51 C233.1,215.51 232.99,215.79 232.99,215.79 C232.99,215.79 232.9,216.09 232.9,216.09 C232.9,216.09 232.82,216.39 232.82,216.39 C232.82,216.39 232.74,216.69 232.74,216.69 C232.74,216.69 232.69,216.99 232.69,216.99 C232.69,216.99 232.64,217.29 232.64,217.29 C232.64,217.29 232.6,217.6 232.6,217.6 C232.6,217.6 232.58,217.91 232.58,217.91 C232.58,217.91 232.56,218.21 232.56,218.21 C232.56,218.21 232.55,218.52 232.55,218.52 C232.55,218.52 232.56,218.83 232.56,218.83 C232.56,218.83 232.57,219.14 232.57,219.14 C232.57,219.14 232.6,219.45 232.6,219.45 C232.6,219.45 232.64,219.75 232.64,219.75 C232.64,219.75 232.68,220.06 232.68,220.06 C232.68,220.06 232.74,220.36 232.74,220.36 C232.74,220.36 232.81,220.66 232.81,220.66 C232.81,220.66 232.88,220.96 232.88,220.96 C232.88,220.96 232.98,221.25 232.98,221.25 C232.98,221.25 233.07,221.54 233.07,221.54 C233.07,221.54 233.19,221.83 233.19,221.83 C233.19,221.83 233.3,222.12 233.3,222.12 C233.3,222.12 233.42,222.4 233.42,222.4 C233.42,222.4 233.55,222.68 233.55,222.68 C233.55,222.68 233.67,222.96 233.67,222.96 C233.67,222.96 233.79,223.25 233.79,223.25 C233.79,223.25 233.9,223.54 233.9,223.54 C233.9,223.54 234.01,223.82 234.01,223.82 C234.01,223.82 234.12,224.11 234.12,224.11 C234.12,224.11 234.2,224.41 234.2,224.41 C234.2,224.41 234.28,224.71 234.28,224.71 C234.28,224.71 234.36,225.01 234.36,225.01 C234.36,225.01 234.41,225.31 234.41,225.31 C234.41,225.31 234.46,225.62 234.46,225.62 C234.46,225.62 234.5,225.92 234.5,225.92 C234.5,225.92 234.52,226.23 234.52,226.23 C234.52,226.23 234.54,226.54 234.54,226.54 C234.54,226.54 234.54,226.84 234.54,226.84 C234.54,226.84 234.53,227.15 234.53,227.15 C234.53,227.15 234.52,227.46 234.52,227.46 C234.52,227.46 234.48,227.77 234.48,227.77 C234.48,227.77 234.44,228.07 234.44,228.07 C234.44,228.07 234.4,228.38 234.4,228.38 C234.4,228.38 234.33,228.68 234.33,228.68 C234.33,228.68 234.25,228.98 234.25,228.98 C234.25,228.98 234.17,229.27 234.17,229.27 C234.17,229.27 234.07,229.56 234.07,229.56 C234.07,229.56 233.97,229.86 233.97,229.86 C233.97,229.86 233.85,230.14 233.85,230.14 C233.85,230.14 233.72,230.42 233.72,230.42 C233.72,230.42 233.59,230.7 233.59,230.7 C233.59,230.7 233.44,230.97 233.44,230.97 C233.44,230.97 233.29,231.24 233.29,231.24 C233.29,231.24 233.13,231.5 233.13,231.5 C233.13,231.5 232.95,231.75 232.95,231.75 C232.95,231.75 232.77,232 232.77,232 C232.77,232 232.58,232.24 232.58,232.24 C232.58,232.24 232.38,232.48 232.38,232.48 C232.38,232.48 232.18,232.71 232.18,232.71 C232.18,232.71 231.96,232.93 231.96,232.93 C231.96,232.93 231.74,233.15 231.74,233.15 C231.74,233.15 231.51,233.35 231.51,233.35 C231.51,233.35 231.28,233.55 231.28,233.55 C231.28,233.55 231.04,233.75 231.04,233.75 C231.04,233.75 230.79,233.92 230.79,233.92 C230.79,233.92 230.53,234.1 230.53,234.1 C230.53,234.1 230.28,234.27 230.28,234.27 C230.28,234.27 230.01,234.42 230.01,234.42 C230.01,234.42 229.74,234.57 229.74,234.57 C229.74,234.57 229.46,234.71 229.46,234.71 C229.46,234.71 229.18,234.83 229.18,234.83 C229.18,234.83 228.9,234.96 228.9,234.96 C228.9,234.96 228.61,235.06 228.61,235.06 C228.61,235.06 228.32,235.16 228.32,235.16 C228.32,235.16 228.02,235.24 228.02,235.24 C228.02,235.24 227.72,235.32 227.72,235.32 C227.72,235.32 227.42,235.39 227.42,235.39 C227.42,235.39 227.12,235.44 227.12,235.44 C227.12,235.44 226.81,235.48 226.81,235.48 C226.81,235.48 226.51,235.52 226.51,235.52 C226.51,235.52 226.2,235.53 226.2,235.53 C226.2,235.53 225.89,235.54 225.89,235.54 C225.89,235.54 225.58,235.54 225.58,235.54 C225.58,235.54 225.27,235.52 225.27,235.52 C225.27,235.52 224.97,235.51 224.97,235.51 C224.97,235.51 224.66,235.47 224.66,235.47 C224.66,235.47 224.36,235.42 224.36,235.42 C224.36,235.42 224.05,235.37 224.05,235.37 C224.05,235.37 223.75,235.3 223.75,235.3 C223.75,235.3 223.45,235.22 223.45,235.22 C223.45,235.22 223.16,235.14 223.16,235.14 C223.16,235.14 222.87,235.03 222.87,235.03 C222.87,235.03 222.58,234.92 222.58,234.92 C222.58,234.92 222.29,234.81 222.29,234.81 C222.29,234.81 222.01,234.69 222.01,234.69 C222.01,234.69 221.72,234.57 221.72,234.57 C221.72,234.57 221.44,234.45 221.44,234.45 C221.44,234.45 221.16,234.32 221.16,234.32 C221.16,234.32 220.87,234.21 220.87,234.21 C220.87,234.21 220.58,234.1 220.58,234.1 C220.58,234.1 220.29,233.99 220.29,233.99 C220.29,233.99 220,233.91 220,233.91 C220,233.91 219.7,233.83 219.7,233.83 C219.7,233.83 219.4,233.75 219.4,233.75 C219.4,233.75 219.1,233.7 219.1,233.7 C219.1,233.7 218.8,233.65 218.8,233.65 C218.8,233.65 218.49,233.6 218.49,233.6 C218.49,233.6 218.18,233.58 218.18,233.58 C218.18,233.58 217.88,233.56 217.88,233.56 C217.88,233.56 217.57,233.55 217.57,233.55 C217.57,233.55 217.26,233.56 217.26,233.56 C217.26,233.56 216.95,233.57 216.95,233.57 C216.95,233.57 216.64,233.6 216.64,233.6 C216.64,233.6 216.34,233.64 216.34,233.64 C216.34,233.64 216.03,233.68 216.03,233.68 C216.03,233.68 215.73,233.74 215.73,233.74 C215.73,233.74 215.43,233.81 215.43,233.81 C215.43,233.81 215.13,233.88 215.13,233.88 C215.13,233.88 214.84,233.98 214.84,233.98 C214.84,233.98 214.55,234.08 214.55,234.08 C214.55,234.08 214.26,234.19 214.26,234.19 C214.26,234.19 213.97,234.3 213.97,234.3 C213.97,234.3 213.69,234.43 213.69,234.43 C213.69,234.43 213.41,234.55 213.41,234.55 C213.41,234.55 213.12,234.67 213.12,234.67 C213.12,234.67 212.84,234.8 212.84,234.8 C212.84,234.8 212.55,234.9 212.55,234.9 C212.55,234.9 212.26,235.01 212.26,235.01 C212.26,235.01 211.98,235.12 211.98,235.12 C211.98,235.12 211.68,235.2 211.68,235.2 C211.68,235.2 211.38,235.28 211.38,235.28 C211.38,235.28 211.08,235.36 211.08,235.36 C211.08,235.36 210.78,235.41 210.78,235.41 C210.78,235.41 210.47,235.46 210.47,235.46 C210.47,235.46 210.17,235.5 210.17,235.5 C210.17,235.5 209.86,235.52 209.86,235.52 C209.86,235.52 209.55,235.54 209.55,235.54 C209.55,235.54 209.25,235.55 209.25,235.55 C209.25,235.55 208.94,235.53 208.94,235.53 C208.94,235.53 208.63,235.52 208.63,235.52 C208.63,235.52 208.32,235.49 208.32,235.49 C208.32,235.49 208.02,235.44 208.02,235.44 C208.02,235.44 207.71,235.4 207.71,235.4 C207.71,235.4 207.41,235.33 207.41,235.33 C207.41,235.33 207.11,235.26 207.11,235.26 C207.11,235.26 206.82,235.17 206.82,235.17 C206.82,235.17 206.53,235.07 206.53,235.07 C206.53,235.07 206.23,234.97 206.23,234.97 C206.23,234.97 205.95,234.85 205.95,234.85 C205.95,234.85 205.67,234.73 205.67,234.73 C205.67,234.73 205.39,234.6 205.39,234.6 C205.39,234.6 205.12,234.44 205.12,234.44 C205.12,234.44 204.85,234.29 204.85,234.29 C204.85,234.29 204.59,234.13 204.59,234.13 C204.59,234.13 204.34,233.95 204.34,233.95 C204.34,233.95 204.09,233.78 204.09,233.78 C204.09,233.78 203.85,233.58 203.85,233.58 C203.85,233.58 203.61,233.39 203.61,233.39 C203.61,233.39 203.38,233.18 203.38,233.18 C203.38,233.18 203.16,232.96 203.16,232.96 C203.16,232.96 202.94,232.75 202.94,232.75 C202.94,232.75 202.74,232.52 202.74,232.52 C202.74,232.52 202.54,232.28 202.54,232.28 C202.54,232.28 202.34,232.04 202.34,232.04 C202.34,232.04 202.16,231.79 202.16,231.79 C202.16,231.79 201.99,231.54 201.99,231.54 C201.99,231.54 201.82,231.28 201.82,231.28 C201.82,231.28 201.67,231.01 201.67,231.01 C201.67,231.01 201.52,230.74 201.52,230.74 C201.52,230.74 201.38,230.46 201.38,230.46 C201.38,230.46 201.26,230.19 201.26,230.19 C201.26,230.19 201.13,229.9 201.13,229.9 C201.13,229.9 201.03,229.61 201.03,229.61 C201.03,229.61 200.93,229.32 200.93,229.32 C200.93,229.32 200.84,229.02 200.84,229.02 C200.84,229.02 200.77,228.72 200.77,228.72 C200.77,228.72 200.7,228.43 200.7,228.43 C200.7,228.43 200.65,228.12 200.65,228.12 C200.65,228.12 200.61,227.82 200.61,227.82 C200.61,227.82 200.57,227.51 200.57,227.51 C200.57,227.51 200.56,227.2 200.56,227.2 C200.56,227.2 200.54,226.89 200.54,226.89 C200.54,226.89 200.55,226.58 200.55,226.58 C200.55,226.58 200.56,226.28 200.56,226.28 C200.56,226.28 200.58,225.97 200.58,225.97 C200.58,225.97 200.62,225.66 200.62,225.66 C200.62,225.66 200.67,225.36 200.67,225.36 C200.67,225.36 200.72,225.06 200.72,225.06 C200.72,225.06 200.79,224.76 200.79,224.76 C200.79,224.76 200.87,224.46 200.87,224.46 C200.87,224.46 200.95,224.16 200.95,224.16 C200.95,224.16 201.06,223.87 201.06,223.87 C201.06,223.87 201.17,223.58 201.17,223.58 C201.17,223.58 201.27,223.29 201.27,223.29 C201.27,223.29 201.4,223.01 201.4,223.01 C201.4,223.01 201.52,222.73 201.52,222.73 C201.52,222.73 201.64,222.45 201.64,222.45 C201.64,222.45 201.76,222.16 201.76,222.16 C201.76,222.16 201.88,221.88 201.88,221.88 C201.88,221.88 201.99,221.59 201.99,221.59 C201.99,221.59 202.1,221.3 202.1,221.3 C202.1,221.3 202.18,221 202.18,221 C202.18,221 202.26,220.71 202.26,220.71 C202.26,220.71 202.34,220.41 202.34,220.41 C202.34,220.41 202.39,220.1 202.39,220.1 C202.39,220.1 202.44,219.8 202.44,219.8 C202.44,219.8 202.49,219.5 202.49,219.5 C202.49,219.5 202.51,219.19 202.51,219.19 C202.51,219.19 202.53,218.88 202.53,218.88 C202.53,218.88 202.54,218.57 202.54,218.57 C202.54,218.57 202.53,218.26 202.53,218.26 C202.53,218.26 202.52,217.96 202.52,217.96 C202.52,217.96 202.49,217.65 202.49,217.65 C202.49,217.65 202.45,217.34 202.45,217.34 C202.45,217.34 202.41,217.04 202.41,217.04 C202.41,217.04 202.34,216.74 202.34,216.74 C202.34,216.74 202.27,216.44 202.27,216.44 C202.27,216.44 202.2,216.14 202.2,216.14 C202.2,216.14 202.11,215.84 202.11,215.84 C202.11,215.84 202.01,215.55 202.01,215.55 C202.01,215.55 201.9,215.26 201.9,215.26 C201.9,215.26 201.78,214.98 201.78,214.98 C201.78,214.98 201.66,214.69 201.66,214.69 C201.66,214.69 201.54,214.41 201.54,214.41 C201.54,214.41 201.42,214.13 201.42,214.13 C201.42,214.13 201.29,213.84 201.29,213.84 C201.29,213.84 201.18,213.55 201.18,213.55 C201.18,213.55 201.07,213.26 201.07,213.26 C201.07,213.26 200.96,212.98 200.96,212.98 C200.96,212.98 200.88,212.68 200.88,212.68 C200.88,212.68 200.8,212.38 200.8,212.38 C200.8,212.38 200.73,212.08 200.73,212.08 C200.73,212.08 200.68,211.78 200.68,211.78 C200.68,211.78 200.63,211.47 200.63,211.47 C200.63,211.47 200.58,211.17 200.58,211.17 C200.58,211.17 200.57,210.86 200.57,210.86 C200.57,210.86 200.55,210.55 200.55,210.55 C200.55,210.55 200.54,210.25 200.54,210.25 C200.54,210.25 200.56,209.94 200.56,209.94 C200.56,209.94 200.57,209.63 200.57,209.63 C200.57,209.63 200.6,209.32 200.6,209.32 C200.6,209.32 200.65,209.02 200.65,209.02 C200.65,209.02 200.69,208.71 200.69,208.71 C200.69,208.71 200.76,208.41 200.76,208.41 C200.76,208.41 200.83,208.11 200.83,208.11 C200.83,208.11 200.92,207.82 200.92,207.82 C200.92,207.82 201.02,207.52 201.02,207.52 C201.02,207.52 201.12,207.23 201.12,207.23 C201.12,207.23 201.24,206.95 201.24,206.95 C201.24,206.95 201.36,206.67 201.36,206.67 C201.36,206.67 201.49,206.39 201.49,206.39 C201.49,206.39 201.65,206.12 201.65,206.12 C201.65,206.12 201.8,205.85 201.8,205.85 C201.8,205.85 201.96,205.59 201.96,205.59 C201.96,205.59 202.14,205.34 202.14,205.34 C202.14,205.34 202.31,205.09 202.31,205.09 C202.31,205.09 202.51,204.85 202.51,204.85 C202.51,204.85 202.71,204.61 202.71,204.61 C202.71,204.61 202.91,204.38 202.91,204.38 C202.91,204.38 203.13,204.16 203.13,204.16 C203.13,204.16 203.34,203.94 203.34,203.94 C203.34,203.94 203.57,203.74 203.57,203.74 C203.57,203.74 203.81,203.54 203.81,203.54 C203.81,203.54 204.05,203.34 204.05,203.34 C204.05,203.34 204.3,203.17 204.3,203.17 C204.3,203.17 204.55,202.99 204.55,202.99 C204.55,202.99 204.81,202.82 204.81,202.82 C204.81,202.82 205.08,202.67 205.08,202.67 C205.08,202.67 205.35,202.52 205.35,202.52 C205.35,202.52 205.63,202.38 205.63,202.38 C205.63,202.38 205.91,202.26 205.91,202.26 C205.91,202.26 206.19,202.13 206.19,202.13 C206.19,202.13 206.48,202.03 206.48,202.03 C206.48,202.03 206.77,201.93 206.77,201.93 C206.77,201.93 207.07,201.85 207.07,201.85 C207.07,201.85 207.37,201.77 207.37,201.77 C207.37,201.77 207.67,201.7 207.67,201.7 C207.67,201.7 207.97,201.65 207.97,201.65 C207.97,201.65 208.28,201.61 208.28,201.61 C208.28,201.61 208.58,201.57 208.58,201.57 C208.58,201.57 208.89,201.56 208.89,201.56 C208.89,201.56 209.2,201.55 209.2,201.55 C209.2,201.55 209.51,201.55 209.51,201.55 C209.51,201.55 209.81,201.57 209.81,201.57 C209.81,201.57 210.12,201.58 210.12,201.58 C210.12,201.58 210.43,201.62 210.43,201.62 C210.43,201.62 210.73,201.67 210.73,201.67 C210.73,201.67 211.04,201.72 211.04,201.72 C211.04,201.72 211.34,201.8 211.34,201.8 C211.34,201.8 211.63,201.88 211.63,201.88 C211.63,201.88 211.93,201.96 211.93,201.96 C211.93,201.96 212.22,202.06 212.22,202.06 C212.22,202.06 212.51,202.17 212.51,202.17 C212.51,202.17 212.8,202.28 212.8,202.28 C212.8,202.28 213.08,202.4 213.08,202.4 C213.08,202.4 213.36,202.52 213.36,202.52 C213.36,202.52 213.65,202.65 213.65,202.65 C213.65,202.65 213.93,202.77 213.93,202.77 C213.93,202.77 214.22,202.88 214.22,202.88 C214.22,202.88 214.5,202.99 214.5,202.99 C214.5,202.99 214.79,203.1 214.79,203.1 C214.79,203.1 215.09,203.19 215.09,203.19 C215.09,203.19 215.39,203.27 215.39,203.27 C215.39,203.27 215.68,203.35 215.68,203.35 C215.68,203.35 215.99,203.4 215.99,203.4 C215.99,203.4 216.29,203.45 216.29,203.45 C216.29,203.45 216.6,203.49 216.6,203.49 C216.6,203.49 216.9,203.51 216.9,203.51 C216.9,203.51 217.21,203.53 217.21,203.53 C217.21,203.53 217.52,203.54 217.52,203.54c " android:valueTo="M217.68 210.56 C217.68,210.56 217.81,210.57 217.81,210.57 C217.81,210.57 217.93,210.57 217.93,210.57 C217.93,210.57 218.06,210.58 218.06,210.58 C218.06,210.58 218.18,210.59 218.18,210.59 C218.18,210.59 218.31,210.59 218.31,210.59 C218.31,210.59 218.43,210.61 218.43,210.61 C218.43,210.61 218.56,210.63 218.56,210.63 C218.56,210.63 218.68,210.64 218.68,210.64 C218.68,210.64 218.81,210.66 218.81,210.66 C218.81,210.66 218.93,210.68 218.93,210.68 C218.93,210.68 219.05,210.7 219.05,210.7 C219.05,210.7 219.18,210.72 219.18,210.72 C219.18,210.72 219.3,210.75 219.3,210.75 C219.3,210.75 219.42,210.78 219.42,210.78 C219.42,210.78 219.54,210.81 219.54,210.81 C219.54,210.81 219.66,210.84 219.66,210.84 C219.66,210.84 219.79,210.87 219.79,210.87 C219.79,210.87 219.91,210.91 219.91,210.91 C219.91,210.91 220.03,210.95 220.03,210.95 C220.03,210.95 220.14,210.99 220.14,210.99 C220.14,210.99 220.26,211.04 220.26,211.04 C220.26,211.04 220.38,211.08 220.38,211.08 C220.38,211.08 220.5,211.12 220.5,211.12 C220.5,211.12 220.62,211.17 220.62,211.17 C220.62,211.17 220.73,211.22 220.73,211.22 C220.73,211.22 220.84,211.27 220.84,211.27 C220.84,211.27 220.96,211.32 220.96,211.32 C220.96,211.32 221.07,211.38 221.07,211.38 C221.07,211.38 221.19,211.43 221.19,211.43 C221.19,211.43 221.3,211.49 221.3,211.49 C221.3,211.49 221.41,211.55 221.41,211.55 C221.41,211.55 221.51,211.61 221.51,211.61 C221.51,211.61 221.62,211.68 221.62,211.68 C221.62,211.68 221.73,211.74 221.73,211.74 C221.73,211.74 221.84,211.8 221.84,211.8 C221.84,211.8 221.94,211.87 221.94,211.87 C221.94,211.87 222.05,211.94 222.05,211.94 C222.05,211.94 222.15,212.02 222.15,212.02 C222.15,212.02 222.25,212.09 222.25,212.09 C222.25,212.09 222.35,212.16 222.35,212.16 C222.35,212.16 222.46,212.23 222.46,212.23 C222.46,212.23 222.55,212.31 222.55,212.31 C222.55,212.31 222.65,212.4 222.65,212.4 C222.65,212.4 222.74,212.48 222.74,212.48 C222.74,212.48 222.84,212.56 222.84,212.56 C222.84,212.56 222.93,212.64 222.93,212.64 C222.93,212.64 223.03,212.72 223.03,212.72 C223.03,212.72 223.12,212.81 223.12,212.81 C223.12,212.81 223.21,212.9 223.21,212.9 C223.21,212.9 223.29,212.99 223.29,212.99 C223.29,212.99 223.38,213.08 223.38,213.08 C223.38,213.08 223.47,213.17 223.47,213.17 C223.47,213.17 223.55,213.26 223.55,213.26 C223.55,213.26 223.63,213.36 223.63,213.36 C223.63,213.36 223.71,213.46 223.71,213.46 C223.71,213.46 223.79,213.56 223.79,213.56 C223.79,213.56 223.87,213.66 223.87,213.66 C223.87,213.66 223.95,213.75 223.95,213.75 C223.95,213.75 224.03,213.85 224.03,213.85 C224.03,213.85 224.09,213.96 224.09,213.96 C224.09,213.96 224.16,214.06 224.16,214.06 C224.16,214.06 224.23,214.17 224.23,214.17 C224.23,214.17 224.3,214.27 224.3,214.27 C224.3,214.27 224.37,214.38 224.37,214.38 C224.37,214.38 224.44,214.48 224.44,214.48 C224.44,214.48 224.5,214.59 224.5,214.59 C224.5,214.59 224.56,214.7 224.56,214.7 C224.56,214.7 224.62,214.81 224.62,214.81 C224.62,214.81 224.68,214.93 224.68,214.93 C224.68,214.93 224.74,215.04 224.74,215.04 C224.74,215.04 224.79,215.15 224.79,215.15 C224.79,215.15 224.84,215.26 224.84,215.26 C224.84,215.26 224.89,215.38 224.89,215.38 C224.89,215.38 224.94,215.5 224.94,215.5 C224.94,215.5 224.99,215.61 224.99,215.61 C224.99,215.61 225.04,215.73 225.04,215.73 C225.04,215.73 225.08,215.84 225.08,215.84 C225.08,215.84 225.12,215.96 225.12,215.96 C225.12,215.96 225.16,216.08 225.16,216.08 C225.16,216.08 225.19,216.2 225.19,216.2 C225.19,216.2 225.23,216.32 225.23,216.32 C225.23,216.32 225.27,216.44 225.27,216.44 C225.27,216.44 225.3,216.56 225.3,216.56 C225.3,216.56 225.33,216.69 225.33,216.69 C225.33,216.69 225.35,216.81 225.35,216.81 C225.35,216.81 225.38,216.93 225.38,216.93 C225.38,216.93 225.41,217.06 225.41,217.06 C225.41,217.06 225.43,217.18 225.43,217.18 C225.43,217.18 225.46,217.3 225.46,217.3 C225.46,217.3 225.47,217.43 225.47,217.43 C225.47,217.43 225.49,217.55 225.49,217.55 C225.49,217.55 225.5,217.68 225.5,217.68 C225.5,217.68 225.52,217.8 225.52,217.8 C225.52,217.8 225.52,217.93 225.52,217.93 C225.52,217.93 225.53,218.05 225.53,218.05 C225.53,218.05 225.54,218.18 225.54,218.18 C225.54,218.18 225.54,218.3 225.54,218.3 C225.54,218.3 225.55,218.43 225.55,218.43 C225.55,218.43 225.55,218.55 225.55,218.55 C225.55,218.55 225.55,218.68 225.55,218.68 C225.55,218.68 225.54,218.8 225.54,218.8 C225.54,218.8 225.54,218.93 225.54,218.93 C225.54,218.93 225.53,219.05 225.53,219.05 C225.53,219.05 225.52,219.18 225.52,219.18 C225.52,219.18 225.52,219.31 225.52,219.31 C225.52,219.31 225.5,219.43 225.5,219.43 C225.5,219.43 225.48,219.55 225.48,219.55 C225.48,219.55 225.47,219.68 225.47,219.68 C225.47,219.68 225.45,219.8 225.45,219.8 C225.45,219.8 225.43,219.93 225.43,219.93 C225.43,219.93 225.41,220.05 225.41,220.05 C225.41,220.05 225.39,220.17 225.39,220.17 C225.39,220.17 225.36,220.3 225.36,220.3 C225.36,220.3 225.33,220.42 225.33,220.42 C225.33,220.42 225.3,220.54 225.3,220.54 C225.3,220.54 225.27,220.66 225.27,220.66 C225.27,220.66 225.24,220.78 225.24,220.78 C225.24,220.78 225.2,220.9 225.2,220.9 C225.2,220.9 225.16,221.02 225.16,221.02 C225.16,221.02 225.12,221.14 225.12,221.14 C225.12,221.14 225.08,221.26 225.08,221.26 C225.08,221.26 225.03,221.38 225.03,221.38 C225.03,221.38 224.99,221.5 224.99,221.5 C224.99,221.5 224.95,221.61 224.95,221.61 C224.95,221.61 224.89,221.73 224.89,221.73 C224.89,221.73 224.84,221.84 224.84,221.84 C224.84,221.84 224.79,221.96 224.79,221.96 C224.79,221.96 224.73,222.07 224.73,222.07 C224.73,222.07 224.68,222.18 224.68,222.18 C224.68,222.18 224.62,222.29 224.62,222.29 C224.62,222.29 224.56,222.4 224.56,222.4 C224.56,222.4 224.5,222.51 224.5,222.51 C224.5,222.51 224.44,222.62 224.44,222.62 C224.44,222.62 224.37,222.73 224.37,222.73 C224.37,222.73 224.31,222.84 224.31,222.84 C224.31,222.84 224.24,222.94 224.24,222.94 C224.24,222.94 224.17,223.05 224.17,223.05 C224.17,223.05 224.09,223.15 224.09,223.15 C224.09,223.15 224.02,223.25 224.02,223.25 C224.02,223.25 223.95,223.35 223.95,223.35 C223.95,223.35 223.88,223.45 223.88,223.45 C223.88,223.45 223.8,223.55 223.8,223.55 C223.8,223.55 223.71,223.65 223.71,223.65 C223.71,223.65 223.63,223.74 223.63,223.74 C223.63,223.74 223.55,223.84 223.55,223.84 C223.55,223.84 223.47,223.93 223.47,223.93 C223.47,223.93 223.39,224.03 223.39,224.03 C223.39,224.03 223.3,224.12 223.3,224.12 C223.3,224.12 223.21,224.2 223.21,224.2 C223.21,224.2 223.12,224.29 223.12,224.29 C223.12,224.29 223.03,224.38 223.03,224.38 C223.03,224.38 222.94,224.46 222.94,224.46 C222.94,224.46 222.85,224.55 222.85,224.55 C222.85,224.55 222.75,224.63 222.75,224.63 C222.75,224.63 222.65,224.71 222.65,224.71 C222.65,224.71 222.55,224.79 222.55,224.79 C222.55,224.79 222.46,224.87 222.46,224.87 C222.46,224.87 222.36,224.95 222.36,224.95 C222.36,224.95 222.26,225.02 222.26,225.02 C222.26,225.02 222.15,225.09 222.15,225.09 C222.15,225.09 222.05,225.16 222.05,225.16 C222.05,225.16 221.94,225.23 221.94,225.23 C221.94,225.23 221.84,225.3 221.84,225.3 C221.84,225.3 221.74,225.37 221.74,225.37 C221.74,225.37 221.63,225.44 221.63,225.44 C221.63,225.44 221.52,225.5 221.52,225.5 C221.52,225.5 221.41,225.56 221.41,225.56 C221.41,225.56 221.3,225.62 221.3,225.62 C221.3,225.62 221.19,225.68 221.19,225.68 C221.19,225.68 221.08,225.73 221.08,225.73 C221.08,225.73 220.96,225.79 220.96,225.79 C220.96,225.79 220.85,225.84 220.85,225.84 C220.85,225.84 220.73,225.89 220.73,225.89 C220.73,225.89 220.62,225.94 220.62,225.94 C220.62,225.94 220.5,225.99 220.5,225.99 C220.5,225.99 220.38,226.03 220.38,226.03 C220.38,226.03 220.27,226.08 220.27,226.08 C220.27,226.08 220.15,226.12 220.15,226.12 C220.15,226.12 220.03,226.15 220.03,226.15 C220.03,226.15 219.91,226.19 219.91,226.19 C219.91,226.19 219.79,226.23 219.79,226.23 C219.79,226.23 219.67,226.27 219.67,226.27 C219.67,226.27 219.55,226.3 219.55,226.3 C219.55,226.3 219.42,226.33 219.42,226.33 C219.42,226.33 219.3,226.35 219.3,226.35 C219.3,226.35 219.18,226.38 219.18,226.38 C219.18,226.38 219.06,226.4 219.06,226.4 C219.06,226.4 218.93,226.43 218.93,226.43 C218.93,226.43 218.81,226.45 218.81,226.45 C218.81,226.45 218.68,226.47 218.68,226.47 C218.68,226.47 218.56,226.49 218.56,226.49 C218.56,226.49 218.44,226.5 218.44,226.5 C218.44,226.5 218.31,226.52 218.31,226.52 C218.31,226.52 218.19,226.52 218.19,226.52 C218.19,226.52 218.06,226.53 218.06,226.53 C218.06,226.53 217.93,226.53 217.93,226.53 C217.93,226.53 217.81,226.54 217.81,226.54 C217.81,226.54 217.68,226.55 217.68,226.55 C217.68,226.55 217.56,226.55 217.56,226.55 C217.56,226.55 217.43,226.55 217.43,226.55 C217.43,226.55 217.31,226.54 217.31,226.54 C217.31,226.54 217.18,226.53 217.18,226.53 C217.18,226.53 217.05,226.53 217.05,226.53 C217.05,226.53 216.93,226.52 216.93,226.52 C216.93,226.52 216.8,226.52 216.8,226.52 C216.8,226.52 216.68,226.5 216.68,226.5 C216.68,226.5 216.55,226.48 216.55,226.48 C216.55,226.48 216.43,226.46 216.43,226.46 C216.43,226.46 216.31,226.45 216.31,226.45 C216.31,226.45 216.18,226.43 216.18,226.43 C216.18,226.43 216.06,226.41 216.06,226.41 C216.06,226.41 215.93,226.38 215.93,226.38 C215.93,226.38 215.81,226.35 215.81,226.35 C215.81,226.35 215.69,226.32 215.69,226.32 C215.69,226.32 215.57,226.29 215.57,226.29 C215.57,226.29 215.45,226.26 215.45,226.26 C215.45,226.26 215.32,226.23 215.32,226.23 C215.32,226.23 215.2,226.2 215.2,226.2 C215.2,226.2 215.09,226.16 215.09,226.16 C215.09,226.16 214.97,226.12 214.97,226.12 C214.97,226.12 214.85,226.07 214.85,226.07 C214.85,226.07 214.73,226.03 214.73,226.03 C214.73,226.03 214.61,225.99 214.61,225.99 C214.61,225.99 214.5,225.94 214.5,225.94 C214.5,225.94 214.38,225.89 214.38,225.89 C214.38,225.89 214.27,225.84 214.27,225.84 C214.27,225.84 214.15,225.79 214.15,225.79 C214.15,225.79 214.04,225.73 214.04,225.73 C214.04,225.73 213.93,225.68 213.93,225.68 C213.93,225.68 213.81,225.62 213.81,225.62 C213.81,225.62 213.71,225.56 213.71,225.56 C213.71,225.56 213.6,225.5 213.6,225.5 C213.6,225.5 213.49,225.43 213.49,225.43 C213.49,225.43 213.38,225.37 213.38,225.37 C213.38,225.37 213.27,225.31 213.27,225.31 C213.27,225.31 213.17,225.24 213.17,225.24 C213.17,225.24 213.06,225.16 213.06,225.16 C213.06,225.16 212.96,225.09 212.96,225.09 C212.96,225.09 212.86,225.02 212.86,225.02 C212.86,225.02 212.76,224.95 212.76,224.95 C212.76,224.95 212.65,224.87 212.65,224.87 C212.65,224.87 212.56,224.79 212.56,224.79 C212.56,224.79 212.46,224.71 212.46,224.71 C212.46,224.71 212.37,224.63 212.37,224.63 C212.37,224.63 212.27,224.55 212.27,224.55 C212.27,224.55 212.18,224.47 212.18,224.47 C212.18,224.47 212.08,224.38 212.08,224.38 C212.08,224.38 211.99,224.3 211.99,224.3 C211.99,224.3 211.91,224.2 211.91,224.2 C211.91,224.2 211.82,224.11 211.82,224.11 C211.82,224.11 211.73,224.02 211.73,224.02 C211.73,224.02 211.64,223.93 211.64,223.93 C211.64,223.93 211.56,223.84 211.56,223.84 C211.56,223.84 211.48,223.75 211.48,223.75 C211.48,223.75 211.4,223.65 211.4,223.65 C211.4,223.65 211.32,223.55 211.32,223.55 C211.32,223.55 211.24,223.45 211.24,223.45 C211.24,223.45 211.16,223.35 211.16,223.35 C211.16,223.35 211.09,223.26 211.09,223.26 C211.09,223.26 211.02,223.15 211.02,223.15 C211.02,223.15 210.95,223.05 210.95,223.05 C210.95,223.05 210.88,222.94 210.88,222.94 C210.88,222.94 210.81,222.84 210.81,222.84 C210.81,222.84 210.74,222.73 210.74,222.73 C210.74,222.73 210.67,222.63 210.67,222.63 C210.67,222.63 210.61,222.52 210.61,222.52 C210.61,222.52 210.55,222.4 210.55,222.4 C210.55,222.4 210.49,222.29 210.49,222.29 C210.49,222.29 210.43,222.18 210.43,222.18 C210.43,222.18 210.38,222.07 210.38,222.07 C210.38,222.07 210.32,221.96 210.32,221.96 C210.32,221.96 210.27,221.84 210.27,221.84 C210.27,221.84 210.22,221.73 210.22,221.73 C210.22,221.73 210.17,221.61 210.17,221.61 C210.17,221.61 210.12,221.5 210.12,221.5 C210.12,221.5 210.08,221.38 210.08,221.38 C210.08,221.38 210.03,221.26 210.03,221.26 C210.03,221.26 209.99,221.14 209.99,221.14 C209.99,221.14 209.96,221.02 209.96,221.02 C209.96,221.02 209.92,220.9 209.92,220.9 C209.92,220.9 209.88,220.78 209.88,220.78 C209.88,220.78 209.84,220.67 209.84,220.67 C209.84,220.67 209.81,220.54 209.81,220.54 C209.81,220.54 209.78,220.42 209.78,220.42 C209.78,220.42 209.76,220.3 209.76,220.3 C209.76,220.3 209.73,220.18 209.73,220.18 C209.73,220.18 209.71,220.05 209.71,220.05 C209.71,220.05 209.68,219.93 209.68,219.93 C209.68,219.93 209.66,219.81 209.66,219.81 C209.66,219.81 209.64,219.68 209.64,219.68 C209.64,219.68 209.62,219.56 209.62,219.56 C209.62,219.56 209.61,219.43 209.61,219.43 C209.61,219.43 209.59,219.31 209.59,219.31 C209.59,219.31 209.59,219.18 209.59,219.18 C209.59,219.18 209.58,219.06 209.58,219.06 C209.58,219.06 209.58,218.93 209.58,218.93 C209.58,218.93 209.57,218.81 209.57,218.81 C209.57,218.81 209.56,218.68 209.56,218.68 C209.56,218.68 209.56,218.56 209.56,218.56 C209.56,218.56 209.56,218.43 209.56,218.43 C209.56,218.43 209.57,218.3 209.57,218.3 C209.57,218.3 209.58,218.18 209.58,218.18 C209.58,218.18 209.58,218.05 209.58,218.05 C209.58,218.05 209.59,217.93 209.59,217.93 C209.59,217.93 209.59,217.8 209.59,217.8 C209.59,217.8 209.61,217.68 209.61,217.68 C209.61,217.68 209.63,217.55 209.63,217.55 C209.63,217.55 209.65,217.43 209.65,217.43 C209.65,217.43 209.66,217.31 209.66,217.31 C209.66,217.31 209.68,217.18 209.68,217.18 C209.68,217.18 209.7,217.06 209.7,217.06 C209.7,217.06 209.73,216.93 209.73,216.93 C209.73,216.93 209.76,216.81 209.76,216.81 C209.76,216.81 209.79,216.69 209.79,216.69 C209.79,216.69 209.82,216.57 209.82,216.57 C209.82,216.57 209.85,216.45 209.85,216.45 C209.85,216.45 209.88,216.32 209.88,216.32 C209.88,216.32 209.91,216.2 209.91,216.2 C209.91,216.2 209.95,216.08 209.95,216.08 C209.95,216.08 210,215.97 210,215.97 C210,215.97 210.04,215.85 210.04,215.85 C210.04,215.85 210.08,215.73 210.08,215.73 C210.08,215.73 210.12,215.61 210.12,215.61 C210.12,215.61 210.17,215.49 210.17,215.49 C210.17,215.49 210.22,215.38 210.22,215.38 C210.22,215.38 210.27,215.27 210.27,215.27 C210.27,215.27 210.33,215.15 210.33,215.15 C210.33,215.15 210.38,215.04 210.38,215.04 C210.38,215.04 210.43,214.92 210.43,214.92 C210.43,214.92 210.49,214.81 210.49,214.81 C210.49,214.81 210.55,214.7 210.55,214.7 C210.55,214.7 210.61,214.6 210.61,214.6 C210.61,214.6 210.68,214.49 210.68,214.49 C210.68,214.49 210.74,214.38 210.74,214.38 C210.74,214.38 210.8,214.27 210.8,214.27 C210.8,214.27 210.87,214.17 210.87,214.17 C210.87,214.17 210.95,214.06 210.95,214.06 C210.95,214.06 211.02,213.96 211.02,213.96 C211.02,213.96 211.09,213.86 211.09,213.86 C211.09,213.86 211.16,213.76 211.16,213.76 C211.16,213.76 211.24,213.65 211.24,213.65 C211.24,213.65 211.32,213.56 211.32,213.56 C211.32,213.56 211.4,213.46 211.4,213.46 C211.4,213.46 211.48,213.37 211.48,213.37 C211.48,213.37 211.56,213.27 211.56,213.27 C211.56,213.27 211.64,213.18 211.64,213.18 C211.64,213.18 211.73,213.08 211.73,213.08 C211.73,213.08 211.82,212.99 211.82,212.99 C211.82,212.99 211.91,212.9 211.91,212.9 C211.91,212.9 212,212.82 212,212.82 C212,212.82 212.09,212.73 212.09,212.73 C212.09,212.73 212.18,212.64 212.18,212.64 C212.18,212.64 212.27,212.56 212.27,212.56 C212.27,212.56 212.36,212.48 212.36,212.48 C212.36,212.48 212.46,212.4 212.46,212.4 C212.46,212.4 212.56,212.32 212.56,212.32 C212.56,212.32 212.66,212.24 212.66,212.24 C212.66,212.24 212.76,212.16 212.76,212.16 C212.76,212.16 212.85,212.08 212.85,212.08 C212.85,212.08 212.96,212.02 212.96,212.02 C212.96,212.02 213.06,211.95 213.06,211.95 C213.06,211.95 213.17,211.88 213.17,211.88 C213.17,211.88 213.27,211.81 213.27,211.81 C213.27,211.81 213.38,211.74 213.38,211.74 C213.38,211.74 213.48,211.67 213.48,211.67 C213.48,211.67 213.6,211.61 213.6,211.61 C213.6,211.61 213.71,211.55 213.71,211.55 C213.71,211.55 213.82,211.49 213.82,211.49 C213.82,211.49 213.93,211.43 213.93,211.43 C213.93,211.43 214.04,211.37 214.04,211.37 C214.04,211.37 214.15,211.32 214.15,211.32 C214.15,211.32 214.27,211.27 214.27,211.27 C214.27,211.27 214.38,211.22 214.38,211.22 C214.38,211.22 214.5,211.17 214.5,211.17 C214.5,211.17 214.61,211.12 214.61,211.12 C214.61,211.12 214.73,211.07 214.73,211.07 C214.73,211.07 214.85,211.03 214.85,211.03 C214.85,211.03 214.97,210.99 214.97,210.99 C214.97,210.99 215.09,210.95 215.09,210.95 C215.09,210.95 215.21,210.92 215.21,210.92 C215.21,210.92 215.33,210.88 215.33,210.88 C215.33,210.88 215.45,210.84 215.45,210.84 C215.45,210.84 215.57,210.81 215.57,210.81 C215.57,210.81 215.69,210.78 215.69,210.78 C215.69,210.78 215.81,210.76 215.81,210.76 C215.81,210.76 215.93,210.73 215.93,210.73 C215.93,210.73 216.06,210.7 216.06,210.7 C216.06,210.7 216.18,210.68 216.18,210.68 C216.18,210.68 216.3,210.65 216.3,210.65 C216.3,210.65 216.43,210.64 216.43,210.64 C216.43,210.64 216.55,210.62 216.55,210.62 C216.55,210.62 216.68,210.61 216.68,210.61 C216.68,210.61 216.8,210.59 216.8,210.59 C216.8,210.59 216.93,210.59 216.93,210.59 C216.93,210.59 217.05,210.58 217.05,210.58 C217.05,210.58 217.18,210.58 217.18,210.58 C217.18,210.58 217.3,210.57 217.3,210.57 C217.3,210.57 217.43,210.56 217.43,210.56 C217.43,210.56 217.56,210.56 217.56,210.56 C217.56,210.56 217.68,210.56 217.68,210.56c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_shape_2_avd.xml b/packages/SystemUI/res/drawable/pin_dot_shape_2_avd.xml
new file mode 100644
index 0000000..d910990
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_shape_2_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="-187.543" android:translateY="-188.546"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="33" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c " android:valueTo="M217.78 201.61 C217.78,201.61 218.06,201.63 218.06,201.63 C218.06,201.63 218.33,201.65 218.33,201.65 C218.33,201.65 218.6,201.68 218.6,201.68 C218.6,201.68 218.87,201.73 218.87,201.73 C218.87,201.73 219.14,201.78 219.14,201.78 C219.14,201.78 219.41,201.84 219.41,201.84 C219.41,201.84 219.67,201.93 219.67,201.93 C219.67,201.93 219.93,202.01 219.93,202.01 C219.93,202.01 220.19,202.09 220.19,202.09 C220.19,202.09 220.44,202.21 220.44,202.21 C220.44,202.21 220.69,202.32 220.69,202.32 C220.69,202.32 220.93,202.45 220.93,202.45 C220.93,202.45 221.17,202.58 221.17,202.58 C221.17,202.58 221.4,202.73 221.4,202.73 C221.4,202.73 221.62,202.88 221.62,202.88 C221.62,202.88 221.85,203.04 221.85,203.04 C221.85,203.04 222.06,203.22 222.06,203.22 C222.06,203.22 222.27,203.39 222.27,203.39 C222.27,203.39 222.46,203.59 222.46,203.59 C222.46,203.59 222.65,203.78 222.65,203.78 C222.65,203.78 222.83,203.99 222.83,203.99 C222.83,203.99 223.01,204.2 223.01,204.2 C223.01,204.2 223.18,204.41 223.18,204.41 C223.18,204.41 223.33,204.64 223.33,204.64 C223.33,204.64 223.48,204.87 223.48,204.87 C223.48,204.87 223.62,205.11 223.62,205.11 C223.62,205.11 223.75,205.34 223.75,205.34 C223.75,205.34 223.88,205.59 223.88,205.59 C223.88,205.59 224,205.83 224,205.83 C224,205.83 224.12,206.08 224.12,206.08 C224.12,206.08 224.24,206.32 224.24,206.32 C224.24,206.32 224.37,206.57 224.37,206.57 C224.37,206.57 224.49,206.81 224.49,206.81 C224.49,206.81 224.61,207.06 224.61,207.06 C224.61,207.06 224.73,207.3 224.73,207.3 C224.73,207.3 224.86,207.55 224.86,207.55 C224.86,207.55 224.98,207.79 224.98,207.79 C224.98,207.79 225.1,208.04 225.1,208.04 C225.1,208.04 225.22,208.28 225.22,208.28 C225.22,208.28 225.35,208.53 225.35,208.53 C225.35,208.53 225.47,208.77 225.47,208.77 C225.47,208.77 225.59,209.02 225.59,209.02 C225.59,209.02 225.71,209.26 225.71,209.26 C225.71,209.26 225.84,209.51 225.84,209.51 C225.84,209.51 225.96,209.75 225.96,209.75 C225.96,209.75 226.08,210 226.08,210 C226.08,210 226.2,210.24 226.2,210.24 C226.2,210.24 226.33,210.49 226.33,210.49 C226.33,210.49 226.45,210.73 226.45,210.73 C226.45,210.73 226.57,210.98 226.57,210.98 C226.57,210.98 226.69,211.22 226.69,211.22 C226.69,211.22 226.82,211.47 226.82,211.47 C226.82,211.47 226.94,211.71 226.94,211.71 C226.94,211.71 227.06,211.96 227.06,211.96 C227.06,211.96 227.18,212.2 227.18,212.2 C227.18,212.2 227.3,212.45 227.3,212.45 C227.3,212.45 227.43,212.69 227.43,212.69 C227.43,212.69 227.55,212.94 227.55,212.94 C227.55,212.94 227.67,213.18 227.67,213.18 C227.67,213.18 227.79,213.43 227.79,213.43 C227.79,213.43 227.92,213.67 227.92,213.67 C227.92,213.67 228.04,213.92 228.04,213.92 C228.04,213.92 228.16,214.16 228.16,214.16 C228.16,214.16 228.28,214.41 228.28,214.41 C228.28,214.41 228.41,214.65 228.41,214.65 C228.41,214.65 228.53,214.9 228.53,214.9 C228.53,214.9 228.65,215.14 228.65,215.14 C228.65,215.14 228.77,215.39 228.77,215.39 C228.77,215.39 228.9,215.63 228.9,215.63 C228.9,215.63 229.02,215.88 229.02,215.88 C229.02,215.88 229.14,216.12 229.14,216.12 C229.14,216.12 229.26,216.37 229.26,216.37 C229.26,216.37 229.39,216.61 229.39,216.61 C229.39,216.61 229.51,216.86 229.51,216.86 C229.51,216.86 229.63,217.1 229.63,217.1 C229.63,217.1 229.75,217.35 229.75,217.35 C229.75,217.35 229.87,217.59 229.87,217.59 C229.87,217.59 230,217.84 230,217.84 C230,217.84 230.12,218.08 230.12,218.08 C230.12,218.08 230.24,218.33 230.24,218.33 C230.24,218.33 230.36,218.57 230.36,218.57 C230.36,218.57 230.49,218.82 230.49,218.82 C230.49,218.82 230.61,219.06 230.61,219.06 C230.61,219.06 230.73,219.31 230.73,219.31 C230.73,219.31 230.85,219.55 230.85,219.55 C230.85,219.55 230.98,219.8 230.98,219.8 C230.98,219.8 231.1,220.04 231.1,220.04 C231.1,220.04 231.22,220.29 231.22,220.29 C231.22,220.29 231.34,220.53 231.34,220.53 C231.34,220.53 231.47,220.78 231.47,220.78 C231.47,220.78 231.59,221.02 231.59,221.02 C231.59,221.02 231.71,221.27 231.71,221.27 C231.71,221.27 231.83,221.51 231.83,221.51 C231.83,221.51 231.96,221.76 231.96,221.76 C231.96,221.76 232.08,222 232.08,222 C232.08,222 232.2,222.25 232.2,222.25 C232.2,222.25 232.32,222.49 232.32,222.49 C232.32,222.49 232.44,222.74 232.44,222.74 C232.44,222.74 232.57,222.98 232.57,222.98 C232.57,222.98 232.69,223.23 232.69,223.23 C232.69,223.23 232.81,223.47 232.81,223.47 C232.81,223.47 232.93,223.71 232.93,223.71 C232.93,223.71 233.06,223.96 233.06,223.96 C233.06,223.96 233.18,224.21 233.18,224.21 C233.18,224.21 233.3,224.45 233.3,224.45 C233.3,224.45 233.42,224.7 233.42,224.7 C233.42,224.7 233.55,224.94 233.55,224.94 C233.55,224.94 233.67,225.19 233.67,225.19 C233.67,225.19 233.79,225.43 233.79,225.43 C233.79,225.43 233.9,225.69 233.9,225.69 C233.9,225.69 234.01,225.94 234.01,225.94 C234.01,225.94 234.12,226.19 234.12,226.19 C234.12,226.19 234.2,226.45 234.2,226.45 C234.2,226.45 234.28,226.71 234.28,226.71 C234.28,226.71 234.35,226.98 234.35,226.98 C234.35,226.98 234.41,227.24 234.41,227.24 C234.41,227.24 234.47,227.51 234.47,227.51 C234.47,227.51 234.5,227.78 234.5,227.78 C234.5,227.78 234.52,228.06 234.52,228.06 C234.52,228.06 234.54,228.33 234.54,228.33 C234.54,228.33 234.54,228.6 234.54,228.6 C234.54,228.6 234.54,228.88 234.54,228.88 C234.54,228.88 234.52,229.15 234.52,229.15 C234.52,229.15 234.49,229.42 234.49,229.42 C234.49,229.42 234.45,229.69 234.45,229.69 C234.45,229.69 234.4,229.96 234.4,229.96 C234.4,229.96 234.34,230.23 234.34,230.23 C234.34,230.23 234.26,230.49 234.26,230.49 C234.26,230.49 234.18,230.75 234.18,230.75 C234.18,230.75 234.08,231.01 234.08,231.01 C234.08,231.01 233.98,231.26 233.98,231.26 C233.98,231.26 233.87,231.51 233.87,231.51 C233.87,231.51 233.74,231.75 233.74,231.75 C233.74,231.75 233.61,232 233.61,232 C233.61,232 233.46,232.23 233.46,232.23 C233.46,232.23 233.31,232.46 233.31,232.46 C233.31,232.46 233.16,232.68 233.16,232.68 C233.16,232.68 232.98,232.89 232.98,232.89 C232.98,232.89 232.81,233.11 232.81,233.11 C232.81,233.11 232.62,233.3 232.62,233.3 C232.62,233.3 232.44,233.5 232.44,233.5 C232.44,233.5 232.24,233.69 232.24,233.69 C232.24,233.69 232.03,233.87 232.03,233.87 C232.03,233.87 231.82,234.04 231.82,234.04 C231.82,234.04 231.6,234.2 231.6,234.2 C231.6,234.2 231.37,234.37 231.37,234.37 C231.37,234.37 231.14,234.51 231.14,234.51 C231.14,234.51 230.91,234.65 230.91,234.65 C230.91,234.65 230.66,234.78 230.66,234.78 C230.66,234.78 230.42,234.89 230.42,234.89 C230.42,234.89 230.17,235.01 230.17,235.01 C230.17,235.01 229.91,235.1 229.91,235.1 C229.91,235.1 229.65,235.19 229.65,235.19 C229.65,235.19 229.39,235.27 229.39,235.27 C229.39,235.27 229.12,235.33 229.12,235.33 C229.12,235.33 228.86,235.4 228.86,235.4 C228.86,235.4 228.59,235.44 228.59,235.44 C228.59,235.44 228.32,235.48 228.32,235.48 C228.32,235.48 228.04,235.49 228.04,235.49 C228.04,235.49 227.77,235.51 227.77,235.51 C227.77,235.51 227.5,235.51 227.5,235.51 C227.5,235.51 227.22,235.49 227.22,235.49 C227.22,235.49 226.95,235.48 226.95,235.48 C226.95,235.48 226.68,235.44 226.68,235.44 C226.68,235.44 226.41,235.4 226.41,235.4 C226.41,235.4 226.14,235.35 226.14,235.35 C226.14,235.35 225.87,235.27 225.87,235.27 C225.87,235.27 225.61,235.2 225.61,235.2 C225.61,235.2 225.35,235.12 225.35,235.12 C225.35,235.12 225.09,235.02 225.09,235.02 C225.09,235.02 224.84,234.92 224.84,234.92 C224.84,234.92 224.59,234.81 224.59,234.81 C224.59,234.81 224.34,234.7 224.34,234.7 C224.34,234.7 224.09,234.59 224.09,234.59 C224.09,234.59 223.84,234.48 223.84,234.48 C223.84,234.48 223.59,234.36 223.59,234.36 C223.59,234.36 223.34,234.25 223.34,234.25 C223.34,234.25 223.09,234.14 223.09,234.14 C223.09,234.14 222.84,234.02 222.84,234.02 C222.84,234.02 222.59,233.91 222.59,233.91 C222.59,233.91 222.34,233.8 222.34,233.8 C222.34,233.8 222.09,233.69 222.09,233.69 C222.09,233.69 221.84,233.58 221.84,233.58 C221.84,233.58 221.59,233.46 221.59,233.46 C221.59,233.46 221.34,233.35 221.34,233.35 C221.34,233.35 221.09,233.24 221.09,233.24 C221.09,233.24 220.84,233.13 220.84,233.13 C220.84,233.13 220.59,233.01 220.59,233.01 C220.59,233.01 220.34,232.9 220.34,232.9 C220.34,232.9 220.09,232.8 220.09,232.8 C220.09,232.8 219.83,232.71 219.83,232.71 C219.83,232.71 219.57,232.62 219.57,232.62 C219.57,232.62 219.3,232.56 219.3,232.56 C219.3,232.56 219.04,232.49 219.04,232.49 C219.04,232.49 218.77,232.44 218.77,232.44 C218.77,232.44 218.5,232.4 218.5,232.4 C218.5,232.4 218.23,232.37 218.23,232.37 C218.23,232.37 217.95,232.35 217.95,232.35 C217.95,232.35 217.68,232.34 217.68,232.34 C217.68,232.34 217.41,232.34 217.41,232.34 C217.41,232.34 217.13,232.36 217.13,232.36 C217.13,232.36 216.86,232.38 216.86,232.38 C216.86,232.38 216.59,232.42 216.59,232.42 C216.59,232.42 216.32,232.46 216.32,232.46 C216.32,232.46 216.05,232.51 216.05,232.51 C216.05,232.51 215.79,232.58 215.79,232.58 C215.79,232.58 215.52,232.66 215.52,232.66 C215.52,232.66 215.26,232.75 215.26,232.75 C215.26,232.75 215.01,232.84 215.01,232.84 C215.01,232.84 214.75,232.94 214.75,232.94 C214.75,232.94 214.5,233.06 214.5,233.06 C214.5,233.06 214.25,233.17 214.25,233.17 C214.25,233.17 214,233.28 214,233.28 C214,233.28 213.75,233.39 213.75,233.39 C213.75,233.39 213.5,233.51 213.5,233.51 C213.5,233.51 213.25,233.62 213.25,233.62 C213.25,233.62 213,233.73 213,233.73 C213,233.73 212.75,233.84 212.75,233.84 C212.75,233.84 212.5,233.96 212.5,233.96 C212.5,233.96 212.26,234.07 212.26,234.07 C212.26,234.07 212.01,234.18 212.01,234.18 C212.01,234.18 211.76,234.29 211.76,234.29 C211.76,234.29 211.51,234.4 211.51,234.4 C211.51,234.4 211.26,234.52 211.26,234.52 C211.26,234.52 211.01,234.63 211.01,234.63 C211.01,234.63 210.76,234.74 210.76,234.74 C210.76,234.74 210.51,234.86 210.51,234.86 C210.51,234.86 210.25,234.96 210.25,234.96 C210.25,234.96 210,235.06 210,235.06 C210,235.06 209.74,235.16 209.74,235.16 C209.74,235.16 209.48,235.23 209.48,235.23 C209.48,235.23 209.22,235.3 209.22,235.3 C209.22,235.3 208.95,235.37 208.95,235.37 C208.95,235.37 208.68,235.41 208.68,235.41 C208.68,235.41 208.41,235.46 208.41,235.46 C208.41,235.46 208.14,235.48 208.14,235.48 C208.14,235.48 207.86,235.5 207.86,235.5 C207.86,235.5 207.59,235.51 207.59,235.51 C207.59,235.51 207.32,235.5 207.32,235.5 C207.32,235.5 207.04,235.49 207.04,235.49 C207.04,235.49 206.77,235.46 206.77,235.46 C206.77,235.46 206.5,235.42 206.5,235.42 C206.5,235.42 206.23,235.38 206.23,235.38 C206.23,235.38 205.96,235.31 205.96,235.31 C205.96,235.31 205.7,235.24 205.7,235.24 C205.7,235.24 205.44,235.16 205.44,235.16 C205.44,235.16 205.18,235.06 205.18,235.06 C205.18,235.06 204.93,234.96 204.93,234.96 C204.93,234.96 204.68,234.85 204.68,234.85 C204.68,234.85 204.43,234.73 204.43,234.73 C204.43,234.73 204.19,234.59 204.19,234.59 C204.19,234.59 203.96,234.45 203.96,234.45 C203.96,234.45 203.73,234.3 203.73,234.3 C203.73,234.3 203.51,234.14 203.51,234.14 C203.51,234.14 203.29,233.98 203.29,233.98 C203.29,233.98 203.08,233.8 203.08,233.8 C203.08,233.8 202.88,233.62 202.88,233.62 C202.88,233.62 202.68,233.43 202.68,233.43 C202.68,233.43 202.49,233.23 202.49,233.23 C202.49,233.23 202.31,233.02 202.31,233.02 C202.31,233.02 202.14,232.81 202.14,232.81 C202.14,232.81 201.97,232.6 201.97,232.6 C201.97,232.6 201.82,232.37 201.82,232.37 C201.82,232.37 201.67,232.14 201.67,232.14 C201.67,232.14 201.53,231.9 201.53,231.9 C201.53,231.9 201.4,231.66 201.4,231.66 C201.4,231.66 201.28,231.42 201.28,231.42 C201.28,231.42 201.17,231.16 201.17,231.16 C201.17,231.16 201.07,230.91 201.07,230.91 C201.07,230.91 200.98,230.65 200.98,230.65 C200.98,230.65 200.9,230.39 200.9,230.39 C200.9,230.39 200.83,230.13 200.83,230.13 C200.83,230.13 200.77,229.86 200.77,229.86 C200.77,229.86 200.72,229.59 200.72,229.59 C200.72,229.59 200.69,229.32 200.69,229.32 C200.69,229.32 200.66,229.04 200.66,229.04 C200.66,229.04 200.65,228.77 200.65,228.77 C200.65,228.77 200.65,228.5 200.65,228.5 C200.65,228.5 200.65,228.22 200.65,228.22 C200.65,228.22 200.68,227.95 200.68,227.95 C200.68,227.95 200.7,227.68 200.7,227.68 C200.7,227.68 200.75,227.41 200.75,227.41 C200.75,227.41 200.8,227.14 200.8,227.14 C200.8,227.14 200.86,226.87 200.86,226.87 C200.86,226.87 200.94,226.61 200.94,226.61 C200.94,226.61 201.02,226.35 201.02,226.35 C201.02,226.35 201.11,226.09 201.11,226.09 C201.11,226.09 201.22,225.84 201.22,225.84 C201.22,225.84 201.33,225.59 201.33,225.59 C201.33,225.59 201.44,225.34 201.44,225.34 C201.44,225.34 201.57,225.1 201.57,225.1 C201.57,225.1 201.69,224.85 201.69,224.85 C201.69,224.85 201.81,224.61 201.81,224.61 C201.81,224.61 201.93,224.36 201.93,224.36 C201.93,224.36 202.06,224.12 202.06,224.12 C202.06,224.12 202.18,223.87 202.18,223.87 C202.18,223.87 202.3,223.63 202.3,223.63 C202.3,223.63 202.42,223.38 202.42,223.38 C202.42,223.38 202.55,223.14 202.55,223.14 C202.55,223.14 202.67,222.89 202.67,222.89 C202.67,222.89 202.79,222.65 202.79,222.65 C202.79,222.65 202.91,222.4 202.91,222.4 C202.91,222.4 203.04,222.16 203.04,222.16 C203.04,222.16 203.16,221.91 203.16,221.91 C203.16,221.91 203.28,221.67 203.28,221.67 C203.28,221.67 203.4,221.42 203.4,221.42 C203.4,221.42 203.52,221.18 203.52,221.18 C203.52,221.18 203.65,220.93 203.65,220.93 C203.65,220.93 203.77,220.69 203.77,220.69 C203.77,220.69 203.89,220.44 203.89,220.44 C203.89,220.44 204.01,220.2 204.01,220.2 C204.01,220.2 204.14,219.95 204.14,219.95 C204.14,219.95 204.26,219.71 204.26,219.71 C204.26,219.71 204.38,219.46 204.38,219.46 C204.38,219.46 204.5,219.22 204.5,219.22 C204.5,219.22 204.63,218.97 204.63,218.97 C204.63,218.97 204.75,218.73 204.75,218.73 C204.75,218.73 204.87,218.48 204.87,218.48 C204.87,218.48 204.99,218.24 204.99,218.24 C204.99,218.24 205.12,217.99 205.12,217.99 C205.12,217.99 205.24,217.75 205.24,217.75 C205.24,217.75 205.36,217.5 205.36,217.5 C205.36,217.5 205.48,217.26 205.48,217.26 C205.48,217.26 205.61,217.01 205.61,217.01 C205.61,217.01 205.73,216.77 205.73,216.77 C205.73,216.77 205.85,216.52 205.85,216.52 C205.85,216.52 205.97,216.28 205.97,216.28 C205.97,216.28 206.09,216.03 206.09,216.03 C206.09,216.03 206.22,215.79 206.22,215.79 C206.22,215.79 206.34,215.54 206.34,215.54 C206.34,215.54 206.46,215.3 206.46,215.3 C206.46,215.3 206.58,215.05 206.58,215.05 C206.58,215.05 206.71,214.81 206.71,214.81 C206.71,214.81 206.83,214.56 206.83,214.56 C206.83,214.56 206.95,214.32 206.95,214.32 C206.95,214.32 207.07,214.07 207.07,214.07 C207.07,214.07 207.2,213.83 207.2,213.83 C207.2,213.83 207.32,213.58 207.32,213.58 C207.32,213.58 207.44,213.34 207.44,213.34 C207.44,213.34 207.56,213.09 207.56,213.09 C207.56,213.09 207.69,212.85 207.69,212.85 C207.69,212.85 207.81,212.6 207.81,212.6 C207.81,212.6 207.93,212.36 207.93,212.36 C207.93,212.36 208.05,212.11 208.05,212.11 C208.05,212.11 208.18,211.87 208.18,211.87 C208.18,211.87 208.3,211.62 208.3,211.62 C208.3,211.62 208.42,211.38 208.42,211.38 C208.42,211.38 208.54,211.13 208.54,211.13 C208.54,211.13 208.66,210.89 208.66,210.89 C208.66,210.89 208.79,210.64 208.79,210.64 C208.79,210.64 208.91,210.4 208.91,210.4 C208.91,210.4 209.03,210.15 209.03,210.15 C209.03,210.15 209.15,209.91 209.15,209.91 C209.15,209.91 209.28,209.66 209.28,209.66 C209.28,209.66 209.4,209.42 209.4,209.42 C209.4,209.42 209.52,209.17 209.52,209.17 C209.52,209.17 209.64,208.93 209.64,208.93 C209.64,208.93 209.77,208.68 209.77,208.68 C209.77,208.68 209.89,208.44 209.89,208.44 C209.89,208.44 210.01,208.19 210.01,208.19 C210.01,208.19 210.13,207.95 210.13,207.95 C210.13,207.95 210.26,207.7 210.26,207.7 C210.26,207.7 210.38,207.46 210.38,207.46 C210.38,207.46 210.5,207.21 210.5,207.21 C210.5,207.21 210.62,206.97 210.62,206.97 C210.62,206.97 210.75,206.72 210.75,206.72 C210.75,206.72 210.87,206.48 210.87,206.48 C210.87,206.48 210.99,206.23 210.99,206.23 C210.99,206.23 211.11,205.99 211.11,205.99 C211.11,205.99 211.24,205.74 211.24,205.74 C211.24,205.74 211.36,205.5 211.36,205.5 C211.36,205.5 211.49,205.26 211.49,205.26 C211.49,205.26 211.62,205.02 211.62,205.02 C211.62,205.02 211.76,204.78 211.76,204.78 C211.76,204.78 211.92,204.56 211.92,204.56 C211.92,204.56 212.07,204.33 212.07,204.33 C212.07,204.33 212.25,204.12 212.25,204.12 C212.25,204.12 212.42,203.91 212.42,203.91 C212.42,203.91 212.61,203.71 212.61,203.71 C212.61,203.71 212.8,203.52 212.8,203.52 C212.8,203.52 213,203.33 213,203.33 C213,203.33 213.21,203.15 213.21,203.15 C213.21,203.15 213.42,202.98 213.42,202.98 C213.42,202.98 213.65,202.82 213.65,202.82 C213.65,202.82 213.87,202.67 213.87,202.67 C213.87,202.67 214.11,202.53 214.11,202.53 C214.11,202.53 214.35,202.4 214.35,202.4 C214.35,202.4 214.6,202.28 214.6,202.28 C214.6,202.28 214.85,202.16 214.85,202.16 C214.85,202.16 215.1,202.06 215.1,202.06 C215.1,202.06 215.36,201.98 215.36,201.98 C215.36,201.98 215.62,201.89 215.62,201.89 C215.62,201.89 215.88,201.81 215.88,201.81 C215.88,201.81 216.15,201.76 216.15,201.76 C216.15,201.76 216.42,201.71 216.42,201.71 C216.42,201.71 216.69,201.66 216.69,201.66 C216.69,201.66 216.96,201.64 216.96,201.64 C216.96,201.64 217.24,201.62 217.24,201.62 C217.24,201.62 217.51,201.61 217.51,201.61 C217.51,201.61 217.78,201.61 217.78,201.61c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="67" android:valueFrom="M217.78 201.61 C217.78,201.61 218.06,201.63 218.06,201.63 C218.06,201.63 218.33,201.65 218.33,201.65 C218.33,201.65 218.6,201.68 218.6,201.68 C218.6,201.68 218.87,201.73 218.87,201.73 C218.87,201.73 219.14,201.78 219.14,201.78 C219.14,201.78 219.41,201.84 219.41,201.84 C219.41,201.84 219.67,201.93 219.67,201.93 C219.67,201.93 219.93,202.01 219.93,202.01 C219.93,202.01 220.19,202.09 220.19,202.09 C220.19,202.09 220.44,202.21 220.44,202.21 C220.44,202.21 220.69,202.32 220.69,202.32 C220.69,202.32 220.93,202.45 220.93,202.45 C220.93,202.45 221.17,202.58 221.17,202.58 C221.17,202.58 221.4,202.73 221.4,202.73 C221.4,202.73 221.62,202.88 221.62,202.88 C221.62,202.88 221.85,203.04 221.85,203.04 C221.85,203.04 222.06,203.22 222.06,203.22 C222.06,203.22 222.27,203.39 222.27,203.39 C222.27,203.39 222.46,203.59 222.46,203.59 C222.46,203.59 222.65,203.78 222.65,203.78 C222.65,203.78 222.83,203.99 222.83,203.99 C222.83,203.99 223.01,204.2 223.01,204.2 C223.01,204.2 223.18,204.41 223.18,204.41 C223.18,204.41 223.33,204.64 223.33,204.64 C223.33,204.64 223.48,204.87 223.48,204.87 C223.48,204.87 223.62,205.11 223.62,205.11 C223.62,205.11 223.75,205.34 223.75,205.34 C223.75,205.34 223.88,205.59 223.88,205.59 C223.88,205.59 224,205.83 224,205.83 C224,205.83 224.12,206.08 224.12,206.08 C224.12,206.08 224.24,206.32 224.24,206.32 C224.24,206.32 224.37,206.57 224.37,206.57 C224.37,206.57 224.49,206.81 224.49,206.81 C224.49,206.81 224.61,207.06 224.61,207.06 C224.61,207.06 224.73,207.3 224.73,207.3 C224.73,207.3 224.86,207.55 224.86,207.55 C224.86,207.55 224.98,207.79 224.98,207.79 C224.98,207.79 225.1,208.04 225.1,208.04 C225.1,208.04 225.22,208.28 225.22,208.28 C225.22,208.28 225.35,208.53 225.35,208.53 C225.35,208.53 225.47,208.77 225.47,208.77 C225.47,208.77 225.59,209.02 225.59,209.02 C225.59,209.02 225.71,209.26 225.71,209.26 C225.71,209.26 225.84,209.51 225.84,209.51 C225.84,209.51 225.96,209.75 225.96,209.75 C225.96,209.75 226.08,210 226.08,210 C226.08,210 226.2,210.24 226.2,210.24 C226.2,210.24 226.33,210.49 226.33,210.49 C226.33,210.49 226.45,210.73 226.45,210.73 C226.45,210.73 226.57,210.98 226.57,210.98 C226.57,210.98 226.69,211.22 226.69,211.22 C226.69,211.22 226.82,211.47 226.82,211.47 C226.82,211.47 226.94,211.71 226.94,211.71 C226.94,211.71 227.06,211.96 227.06,211.96 C227.06,211.96 227.18,212.2 227.18,212.2 C227.18,212.2 227.3,212.45 227.3,212.45 C227.3,212.45 227.43,212.69 227.43,212.69 C227.43,212.69 227.55,212.94 227.55,212.94 C227.55,212.94 227.67,213.18 227.67,213.18 C227.67,213.18 227.79,213.43 227.79,213.43 C227.79,213.43 227.92,213.67 227.92,213.67 C227.92,213.67 228.04,213.92 228.04,213.92 C228.04,213.92 228.16,214.16 228.16,214.16 C228.16,214.16 228.28,214.41 228.28,214.41 C228.28,214.41 228.41,214.65 228.41,214.65 C228.41,214.65 228.53,214.9 228.53,214.9 C228.53,214.9 228.65,215.14 228.65,215.14 C228.65,215.14 228.77,215.39 228.77,215.39 C228.77,215.39 228.9,215.63 228.9,215.63 C228.9,215.63 229.02,215.88 229.02,215.88 C229.02,215.88 229.14,216.12 229.14,216.12 C229.14,216.12 229.26,216.37 229.26,216.37 C229.26,216.37 229.39,216.61 229.39,216.61 C229.39,216.61 229.51,216.86 229.51,216.86 C229.51,216.86 229.63,217.1 229.63,217.1 C229.63,217.1 229.75,217.35 229.75,217.35 C229.75,217.35 229.87,217.59 229.87,217.59 C229.87,217.59 230,217.84 230,217.84 C230,217.84 230.12,218.08 230.12,218.08 C230.12,218.08 230.24,218.33 230.24,218.33 C230.24,218.33 230.36,218.57 230.36,218.57 C230.36,218.57 230.49,218.82 230.49,218.82 C230.49,218.82 230.61,219.06 230.61,219.06 C230.61,219.06 230.73,219.31 230.73,219.31 C230.73,219.31 230.85,219.55 230.85,219.55 C230.85,219.55 230.98,219.8 230.98,219.8 C230.98,219.8 231.1,220.04 231.1,220.04 C231.1,220.04 231.22,220.29 231.22,220.29 C231.22,220.29 231.34,220.53 231.34,220.53 C231.34,220.53 231.47,220.78 231.47,220.78 C231.47,220.78 231.59,221.02 231.59,221.02 C231.59,221.02 231.71,221.27 231.71,221.27 C231.71,221.27 231.83,221.51 231.83,221.51 C231.83,221.51 231.96,221.76 231.96,221.76 C231.96,221.76 232.08,222 232.08,222 C232.08,222 232.2,222.25 232.2,222.25 C232.2,222.25 232.32,222.49 232.32,222.49 C232.32,222.49 232.44,222.74 232.44,222.74 C232.44,222.74 232.57,222.98 232.57,222.98 C232.57,222.98 232.69,223.23 232.69,223.23 C232.69,223.23 232.81,223.47 232.81,223.47 C232.81,223.47 232.93,223.71 232.93,223.71 C232.93,223.71 233.06,223.96 233.06,223.96 C233.06,223.96 233.18,224.21 233.18,224.21 C233.18,224.21 233.3,224.45 233.3,224.45 C233.3,224.45 233.42,224.7 233.42,224.7 C233.42,224.7 233.55,224.94 233.55,224.94 C233.55,224.94 233.67,225.19 233.67,225.19 C233.67,225.19 233.79,225.43 233.79,225.43 C233.79,225.43 233.9,225.69 233.9,225.69 C233.9,225.69 234.01,225.94 234.01,225.94 C234.01,225.94 234.12,226.19 234.12,226.19 C234.12,226.19 234.2,226.45 234.2,226.45 C234.2,226.45 234.28,226.71 234.28,226.71 C234.28,226.71 234.35,226.98 234.35,226.98 C234.35,226.98 234.41,227.24 234.41,227.24 C234.41,227.24 234.47,227.51 234.47,227.51 C234.47,227.51 234.5,227.78 234.5,227.78 C234.5,227.78 234.52,228.06 234.52,228.06 C234.52,228.06 234.54,228.33 234.54,228.33 C234.54,228.33 234.54,228.6 234.54,228.6 C234.54,228.6 234.54,228.88 234.54,228.88 C234.54,228.88 234.52,229.15 234.52,229.15 C234.52,229.15 234.49,229.42 234.49,229.42 C234.49,229.42 234.45,229.69 234.45,229.69 C234.45,229.69 234.4,229.96 234.4,229.96 C234.4,229.96 234.34,230.23 234.34,230.23 C234.34,230.23 234.26,230.49 234.26,230.49 C234.26,230.49 234.18,230.75 234.18,230.75 C234.18,230.75 234.08,231.01 234.08,231.01 C234.08,231.01 233.98,231.26 233.98,231.26 C233.98,231.26 233.87,231.51 233.87,231.51 C233.87,231.51 233.74,231.75 233.74,231.75 C233.74,231.75 233.61,232 233.61,232 C233.61,232 233.46,232.23 233.46,232.23 C233.46,232.23 233.31,232.46 233.31,232.46 C233.31,232.46 233.16,232.68 233.16,232.68 C233.16,232.68 232.98,232.89 232.98,232.89 C232.98,232.89 232.81,233.11 232.81,233.11 C232.81,233.11 232.62,233.3 232.62,233.3 C232.62,233.3 232.44,233.5 232.44,233.5 C232.44,233.5 232.24,233.69 232.24,233.69 C232.24,233.69 232.03,233.87 232.03,233.87 C232.03,233.87 231.82,234.04 231.82,234.04 C231.82,234.04 231.6,234.2 231.6,234.2 C231.6,234.2 231.37,234.37 231.37,234.37 C231.37,234.37 231.14,234.51 231.14,234.51 C231.14,234.51 230.91,234.65 230.91,234.65 C230.91,234.65 230.66,234.78 230.66,234.78 C230.66,234.78 230.42,234.89 230.42,234.89 C230.42,234.89 230.17,235.01 230.17,235.01 C230.17,235.01 229.91,235.1 229.91,235.1 C229.91,235.1 229.65,235.19 229.65,235.19 C229.65,235.19 229.39,235.27 229.39,235.27 C229.39,235.27 229.12,235.33 229.12,235.33 C229.12,235.33 228.86,235.4 228.86,235.4 C228.86,235.4 228.59,235.44 228.59,235.44 C228.59,235.44 228.32,235.48 228.32,235.48 C228.32,235.48 228.04,235.49 228.04,235.49 C228.04,235.49 227.77,235.51 227.77,235.51 C227.77,235.51 227.5,235.51 227.5,235.51 C227.5,235.51 227.22,235.49 227.22,235.49 C227.22,235.49 226.95,235.48 226.95,235.48 C226.95,235.48 226.68,235.44 226.68,235.44 C226.68,235.44 226.41,235.4 226.41,235.4 C226.41,235.4 226.14,235.35 226.14,235.35 C226.14,235.35 225.87,235.27 225.87,235.27 C225.87,235.27 225.61,235.2 225.61,235.2 C225.61,235.2 225.35,235.12 225.35,235.12 C225.35,235.12 225.09,235.02 225.09,235.02 C225.09,235.02 224.84,234.92 224.84,234.92 C224.84,234.92 224.59,234.81 224.59,234.81 C224.59,234.81 224.34,234.7 224.34,234.7 C224.34,234.7 224.09,234.59 224.09,234.59 C224.09,234.59 223.84,234.48 223.84,234.48 C223.84,234.48 223.59,234.36 223.59,234.36 C223.59,234.36 223.34,234.25 223.34,234.25 C223.34,234.25 223.09,234.14 223.09,234.14 C223.09,234.14 222.84,234.02 222.84,234.02 C222.84,234.02 222.59,233.91 222.59,233.91 C222.59,233.91 222.34,233.8 222.34,233.8 C222.34,233.8 222.09,233.69 222.09,233.69 C222.09,233.69 221.84,233.58 221.84,233.58 C221.84,233.58 221.59,233.46 221.59,233.46 C221.59,233.46 221.34,233.35 221.34,233.35 C221.34,233.35 221.09,233.24 221.09,233.24 C221.09,233.24 220.84,233.13 220.84,233.13 C220.84,233.13 220.59,233.01 220.59,233.01 C220.59,233.01 220.34,232.9 220.34,232.9 C220.34,232.9 220.09,232.8 220.09,232.8 C220.09,232.8 219.83,232.71 219.83,232.71 C219.83,232.71 219.57,232.62 219.57,232.62 C219.57,232.62 219.3,232.56 219.3,232.56 C219.3,232.56 219.04,232.49 219.04,232.49 C219.04,232.49 218.77,232.44 218.77,232.44 C218.77,232.44 218.5,232.4 218.5,232.4 C218.5,232.4 218.23,232.37 218.23,232.37 C218.23,232.37 217.95,232.35 217.95,232.35 C217.95,232.35 217.68,232.34 217.68,232.34 C217.68,232.34 217.41,232.34 217.41,232.34 C217.41,232.34 217.13,232.36 217.13,232.36 C217.13,232.36 216.86,232.38 216.86,232.38 C216.86,232.38 216.59,232.42 216.59,232.42 C216.59,232.42 216.32,232.46 216.32,232.46 C216.32,232.46 216.05,232.51 216.05,232.51 C216.05,232.51 215.79,232.58 215.79,232.58 C215.79,232.58 215.52,232.66 215.52,232.66 C215.52,232.66 215.26,232.75 215.26,232.75 C215.26,232.75 215.01,232.84 215.01,232.84 C215.01,232.84 214.75,232.94 214.75,232.94 C214.75,232.94 214.5,233.06 214.5,233.06 C214.5,233.06 214.25,233.17 214.25,233.17 C214.25,233.17 214,233.28 214,233.28 C214,233.28 213.75,233.39 213.75,233.39 C213.75,233.39 213.5,233.51 213.5,233.51 C213.5,233.51 213.25,233.62 213.25,233.62 C213.25,233.62 213,233.73 213,233.73 C213,233.73 212.75,233.84 212.75,233.84 C212.75,233.84 212.5,233.96 212.5,233.96 C212.5,233.96 212.26,234.07 212.26,234.07 C212.26,234.07 212.01,234.18 212.01,234.18 C212.01,234.18 211.76,234.29 211.76,234.29 C211.76,234.29 211.51,234.4 211.51,234.4 C211.51,234.4 211.26,234.52 211.26,234.52 C211.26,234.52 211.01,234.63 211.01,234.63 C211.01,234.63 210.76,234.74 210.76,234.74 C210.76,234.74 210.51,234.86 210.51,234.86 C210.51,234.86 210.25,234.96 210.25,234.96 C210.25,234.96 210,235.06 210,235.06 C210,235.06 209.74,235.16 209.74,235.16 C209.74,235.16 209.48,235.23 209.48,235.23 C209.48,235.23 209.22,235.3 209.22,235.3 C209.22,235.3 208.95,235.37 208.95,235.37 C208.95,235.37 208.68,235.41 208.68,235.41 C208.68,235.41 208.41,235.46 208.41,235.46 C208.41,235.46 208.14,235.48 208.14,235.48 C208.14,235.48 207.86,235.5 207.86,235.5 C207.86,235.5 207.59,235.51 207.59,235.51 C207.59,235.51 207.32,235.5 207.32,235.5 C207.32,235.5 207.04,235.49 207.04,235.49 C207.04,235.49 206.77,235.46 206.77,235.46 C206.77,235.46 206.5,235.42 206.5,235.42 C206.5,235.42 206.23,235.38 206.23,235.38 C206.23,235.38 205.96,235.31 205.96,235.31 C205.96,235.31 205.7,235.24 205.7,235.24 C205.7,235.24 205.44,235.16 205.44,235.16 C205.44,235.16 205.18,235.06 205.18,235.06 C205.18,235.06 204.93,234.96 204.93,234.96 C204.93,234.96 204.68,234.85 204.68,234.85 C204.68,234.85 204.43,234.73 204.43,234.73 C204.43,234.73 204.19,234.59 204.19,234.59 C204.19,234.59 203.96,234.45 203.96,234.45 C203.96,234.45 203.73,234.3 203.73,234.3 C203.73,234.3 203.51,234.14 203.51,234.14 C203.51,234.14 203.29,233.98 203.29,233.98 C203.29,233.98 203.08,233.8 203.08,233.8 C203.08,233.8 202.88,233.62 202.88,233.62 C202.88,233.62 202.68,233.43 202.68,233.43 C202.68,233.43 202.49,233.23 202.49,233.23 C202.49,233.23 202.31,233.02 202.31,233.02 C202.31,233.02 202.14,232.81 202.14,232.81 C202.14,232.81 201.97,232.6 201.97,232.6 C201.97,232.6 201.82,232.37 201.82,232.37 C201.82,232.37 201.67,232.14 201.67,232.14 C201.67,232.14 201.53,231.9 201.53,231.9 C201.53,231.9 201.4,231.66 201.4,231.66 C201.4,231.66 201.28,231.42 201.28,231.42 C201.28,231.42 201.17,231.16 201.17,231.16 C201.17,231.16 201.07,230.91 201.07,230.91 C201.07,230.91 200.98,230.65 200.98,230.65 C200.98,230.65 200.9,230.39 200.9,230.39 C200.9,230.39 200.83,230.13 200.83,230.13 C200.83,230.13 200.77,229.86 200.77,229.86 C200.77,229.86 200.72,229.59 200.72,229.59 C200.72,229.59 200.69,229.32 200.69,229.32 C200.69,229.32 200.66,229.04 200.66,229.04 C200.66,229.04 200.65,228.77 200.65,228.77 C200.65,228.77 200.65,228.5 200.65,228.5 C200.65,228.5 200.65,228.22 200.65,228.22 C200.65,228.22 200.68,227.95 200.68,227.95 C200.68,227.95 200.7,227.68 200.7,227.68 C200.7,227.68 200.75,227.41 200.75,227.41 C200.75,227.41 200.8,227.14 200.8,227.14 C200.8,227.14 200.86,226.87 200.86,226.87 C200.86,226.87 200.94,226.61 200.94,226.61 C200.94,226.61 201.02,226.35 201.02,226.35 C201.02,226.35 201.11,226.09 201.11,226.09 C201.11,226.09 201.22,225.84 201.22,225.84 C201.22,225.84 201.33,225.59 201.33,225.59 C201.33,225.59 201.44,225.34 201.44,225.34 C201.44,225.34 201.57,225.1 201.57,225.1 C201.57,225.1 201.69,224.85 201.69,224.85 C201.69,224.85 201.81,224.61 201.81,224.61 C201.81,224.61 201.93,224.36 201.93,224.36 C201.93,224.36 202.06,224.12 202.06,224.12 C202.06,224.12 202.18,223.87 202.18,223.87 C202.18,223.87 202.3,223.63 202.3,223.63 C202.3,223.63 202.42,223.38 202.42,223.38 C202.42,223.38 202.55,223.14 202.55,223.14 C202.55,223.14 202.67,222.89 202.67,222.89 C202.67,222.89 202.79,222.65 202.79,222.65 C202.79,222.65 202.91,222.4 202.91,222.4 C202.91,222.4 203.04,222.16 203.04,222.16 C203.04,222.16 203.16,221.91 203.16,221.91 C203.16,221.91 203.28,221.67 203.28,221.67 C203.28,221.67 203.4,221.42 203.4,221.42 C203.4,221.42 203.52,221.18 203.52,221.18 C203.52,221.18 203.65,220.93 203.65,220.93 C203.65,220.93 203.77,220.69 203.77,220.69 C203.77,220.69 203.89,220.44 203.89,220.44 C203.89,220.44 204.01,220.2 204.01,220.2 C204.01,220.2 204.14,219.95 204.14,219.95 C204.14,219.95 204.26,219.71 204.26,219.71 C204.26,219.71 204.38,219.46 204.38,219.46 C204.38,219.46 204.5,219.22 204.5,219.22 C204.5,219.22 204.63,218.97 204.63,218.97 C204.63,218.97 204.75,218.73 204.75,218.73 C204.75,218.73 204.87,218.48 204.87,218.48 C204.87,218.48 204.99,218.24 204.99,218.24 C204.99,218.24 205.12,217.99 205.12,217.99 C205.12,217.99 205.24,217.75 205.24,217.75 C205.24,217.75 205.36,217.5 205.36,217.5 C205.36,217.5 205.48,217.26 205.48,217.26 C205.48,217.26 205.61,217.01 205.61,217.01 C205.61,217.01 205.73,216.77 205.73,216.77 C205.73,216.77 205.85,216.52 205.85,216.52 C205.85,216.52 205.97,216.28 205.97,216.28 C205.97,216.28 206.09,216.03 206.09,216.03 C206.09,216.03 206.22,215.79 206.22,215.79 C206.22,215.79 206.34,215.54 206.34,215.54 C206.34,215.54 206.46,215.3 206.46,215.3 C206.46,215.3 206.58,215.05 206.58,215.05 C206.58,215.05 206.71,214.81 206.71,214.81 C206.71,214.81 206.83,214.56 206.83,214.56 C206.83,214.56 206.95,214.32 206.95,214.32 C206.95,214.32 207.07,214.07 207.07,214.07 C207.07,214.07 207.2,213.83 207.2,213.83 C207.2,213.83 207.32,213.58 207.32,213.58 C207.32,213.58 207.44,213.34 207.44,213.34 C207.44,213.34 207.56,213.09 207.56,213.09 C207.56,213.09 207.69,212.85 207.69,212.85 C207.69,212.85 207.81,212.6 207.81,212.6 C207.81,212.6 207.93,212.36 207.93,212.36 C207.93,212.36 208.05,212.11 208.05,212.11 C208.05,212.11 208.18,211.87 208.18,211.87 C208.18,211.87 208.3,211.62 208.3,211.62 C208.3,211.62 208.42,211.38 208.42,211.38 C208.42,211.38 208.54,211.13 208.54,211.13 C208.54,211.13 208.66,210.89 208.66,210.89 C208.66,210.89 208.79,210.64 208.79,210.64 C208.79,210.64 208.91,210.4 208.91,210.4 C208.91,210.4 209.03,210.15 209.03,210.15 C209.03,210.15 209.15,209.91 209.15,209.91 C209.15,209.91 209.28,209.66 209.28,209.66 C209.28,209.66 209.4,209.42 209.4,209.42 C209.4,209.42 209.52,209.17 209.52,209.17 C209.52,209.17 209.64,208.93 209.64,208.93 C209.64,208.93 209.77,208.68 209.77,208.68 C209.77,208.68 209.89,208.44 209.89,208.44 C209.89,208.44 210.01,208.19 210.01,208.19 C210.01,208.19 210.13,207.95 210.13,207.95 C210.13,207.95 210.26,207.7 210.26,207.7 C210.26,207.7 210.38,207.46 210.38,207.46 C210.38,207.46 210.5,207.21 210.5,207.21 C210.5,207.21 210.62,206.97 210.62,206.97 C210.62,206.97 210.75,206.72 210.75,206.72 C210.75,206.72 210.87,206.48 210.87,206.48 C210.87,206.48 210.99,206.23 210.99,206.23 C210.99,206.23 211.11,205.99 211.11,205.99 C211.11,205.99 211.24,205.74 211.24,205.74 C211.24,205.74 211.36,205.5 211.36,205.5 C211.36,205.5 211.49,205.26 211.49,205.26 C211.49,205.26 211.62,205.02 211.62,205.02 C211.62,205.02 211.76,204.78 211.76,204.78 C211.76,204.78 211.92,204.56 211.92,204.56 C211.92,204.56 212.07,204.33 212.07,204.33 C212.07,204.33 212.25,204.12 212.25,204.12 C212.25,204.12 212.42,203.91 212.42,203.91 C212.42,203.91 212.61,203.71 212.61,203.71 C212.61,203.71 212.8,203.52 212.8,203.52 C212.8,203.52 213,203.33 213,203.33 C213,203.33 213.21,203.15 213.21,203.15 C213.21,203.15 213.42,202.98 213.42,202.98 C213.42,202.98 213.65,202.82 213.65,202.82 C213.65,202.82 213.87,202.67 213.87,202.67 C213.87,202.67 214.11,202.53 214.11,202.53 C214.11,202.53 214.35,202.4 214.35,202.4 C214.35,202.4 214.6,202.28 214.6,202.28 C214.6,202.28 214.85,202.16 214.85,202.16 C214.85,202.16 215.1,202.06 215.1,202.06 C215.1,202.06 215.36,201.98 215.36,201.98 C215.36,201.98 215.62,201.89 215.62,201.89 C215.62,201.89 215.88,201.81 215.88,201.81 C215.88,201.81 216.15,201.76 216.15,201.76 C216.15,201.76 216.42,201.71 216.42,201.71 C216.42,201.71 216.69,201.66 216.69,201.66 C216.69,201.66 216.96,201.64 216.96,201.64 C216.96,201.64 217.24,201.62 217.24,201.62 C217.24,201.62 217.51,201.61 217.51,201.61 C217.51,201.61 217.78,201.61 217.78,201.61c " android:valueTo="M217.68 210.56 C217.68,210.56 217.81,210.57 217.81,210.57 C217.81,210.57 217.93,210.57 217.93,210.57 C217.93,210.57 218.06,210.58 218.06,210.58 C218.06,210.58 218.18,210.59 218.18,210.59 C218.18,210.59 218.31,210.59 218.31,210.59 C218.31,210.59 218.43,210.61 218.43,210.61 C218.43,210.61 218.56,210.63 218.56,210.63 C218.56,210.63 218.68,210.64 218.68,210.64 C218.68,210.64 218.81,210.66 218.81,210.66 C218.81,210.66 218.93,210.68 218.93,210.68 C218.93,210.68 219.05,210.7 219.05,210.7 C219.05,210.7 219.18,210.72 219.18,210.72 C219.18,210.72 219.3,210.75 219.3,210.75 C219.3,210.75 219.42,210.78 219.42,210.78 C219.42,210.78 219.54,210.81 219.54,210.81 C219.54,210.81 219.66,210.84 219.66,210.84 C219.66,210.84 219.79,210.87 219.79,210.87 C219.79,210.87 219.91,210.91 219.91,210.91 C219.91,210.91 220.03,210.95 220.03,210.95 C220.03,210.95 220.14,210.99 220.14,210.99 C220.14,210.99 220.26,211.04 220.26,211.04 C220.26,211.04 220.38,211.08 220.38,211.08 C220.38,211.08 220.5,211.12 220.5,211.12 C220.5,211.12 220.62,211.17 220.62,211.17 C220.62,211.17 220.73,211.22 220.73,211.22 C220.73,211.22 220.84,211.27 220.84,211.27 C220.84,211.27 220.96,211.32 220.96,211.32 C220.96,211.32 221.07,211.38 221.07,211.38 C221.07,211.38 221.19,211.43 221.19,211.43 C221.19,211.43 221.3,211.49 221.3,211.49 C221.3,211.49 221.41,211.55 221.41,211.55 C221.41,211.55 221.51,211.61 221.51,211.61 C221.51,211.61 221.62,211.68 221.62,211.68 C221.62,211.68 221.73,211.74 221.73,211.74 C221.73,211.74 221.84,211.8 221.84,211.8 C221.84,211.8 221.94,211.87 221.94,211.87 C221.94,211.87 222.05,211.94 222.05,211.94 C222.05,211.94 222.15,212.02 222.15,212.02 C222.15,212.02 222.25,212.09 222.25,212.09 C222.25,212.09 222.35,212.16 222.35,212.16 C222.35,212.16 222.46,212.23 222.46,212.23 C222.46,212.23 222.55,212.31 222.55,212.31 C222.55,212.31 222.65,212.4 222.65,212.4 C222.65,212.4 222.74,212.48 222.74,212.48 C222.74,212.48 222.84,212.56 222.84,212.56 C222.84,212.56 222.93,212.64 222.93,212.64 C222.93,212.64 223.03,212.72 223.03,212.72 C223.03,212.72 223.12,212.81 223.12,212.81 C223.12,212.81 223.21,212.9 223.21,212.9 C223.21,212.9 223.29,212.99 223.29,212.99 C223.29,212.99 223.38,213.08 223.38,213.08 C223.38,213.08 223.47,213.17 223.47,213.17 C223.47,213.17 223.55,213.26 223.55,213.26 C223.55,213.26 223.63,213.36 223.63,213.36 C223.63,213.36 223.71,213.46 223.71,213.46 C223.71,213.46 223.79,213.56 223.79,213.56 C223.79,213.56 223.87,213.66 223.87,213.66 C223.87,213.66 223.95,213.75 223.95,213.75 C223.95,213.75 224.03,213.85 224.03,213.85 C224.03,213.85 224.09,213.96 224.09,213.96 C224.09,213.96 224.16,214.06 224.16,214.06 C224.16,214.06 224.23,214.17 224.23,214.17 C224.23,214.17 224.3,214.27 224.3,214.27 C224.3,214.27 224.37,214.38 224.37,214.38 C224.37,214.38 224.44,214.48 224.44,214.48 C224.44,214.48 224.5,214.59 224.5,214.59 C224.5,214.59 224.56,214.7 224.56,214.7 C224.56,214.7 224.62,214.81 224.62,214.81 C224.62,214.81 224.68,214.93 224.68,214.93 C224.68,214.93 224.74,215.04 224.74,215.04 C224.74,215.04 224.79,215.15 224.79,215.15 C224.79,215.15 224.84,215.26 224.84,215.26 C224.84,215.26 224.89,215.38 224.89,215.38 C224.89,215.38 224.94,215.5 224.94,215.5 C224.94,215.5 224.99,215.61 224.99,215.61 C224.99,215.61 225.04,215.73 225.04,215.73 C225.04,215.73 225.08,215.84 225.08,215.84 C225.08,215.84 225.12,215.96 225.12,215.96 C225.12,215.96 225.16,216.08 225.16,216.08 C225.16,216.08 225.19,216.2 225.19,216.2 C225.19,216.2 225.23,216.32 225.23,216.32 C225.23,216.32 225.27,216.44 225.27,216.44 C225.27,216.44 225.3,216.56 225.3,216.56 C225.3,216.56 225.33,216.69 225.33,216.69 C225.33,216.69 225.35,216.81 225.35,216.81 C225.35,216.81 225.38,216.93 225.38,216.93 C225.38,216.93 225.41,217.06 225.41,217.06 C225.41,217.06 225.43,217.18 225.43,217.18 C225.43,217.18 225.46,217.3 225.46,217.3 C225.46,217.3 225.47,217.43 225.47,217.43 C225.47,217.43 225.49,217.55 225.49,217.55 C225.49,217.55 225.5,217.68 225.5,217.68 C225.5,217.68 225.52,217.8 225.52,217.8 C225.52,217.8 225.52,217.93 225.52,217.93 C225.52,217.93 225.53,218.05 225.53,218.05 C225.53,218.05 225.54,218.18 225.54,218.18 C225.54,218.18 225.54,218.3 225.54,218.3 C225.54,218.3 225.55,218.43 225.55,218.43 C225.55,218.43 225.55,218.55 225.55,218.55 C225.55,218.55 225.55,218.68 225.55,218.68 C225.55,218.68 225.54,218.8 225.54,218.8 C225.54,218.8 225.54,218.93 225.54,218.93 C225.54,218.93 225.53,219.05 225.53,219.05 C225.53,219.05 225.52,219.18 225.52,219.18 C225.52,219.18 225.52,219.31 225.52,219.31 C225.52,219.31 225.5,219.43 225.5,219.43 C225.5,219.43 225.48,219.55 225.48,219.55 C225.48,219.55 225.47,219.68 225.47,219.68 C225.47,219.68 225.45,219.8 225.45,219.8 C225.45,219.8 225.43,219.93 225.43,219.93 C225.43,219.93 225.41,220.05 225.41,220.05 C225.41,220.05 225.39,220.17 225.39,220.17 C225.39,220.17 225.36,220.3 225.36,220.3 C225.36,220.3 225.33,220.42 225.33,220.42 C225.33,220.42 225.3,220.54 225.3,220.54 C225.3,220.54 225.27,220.66 225.27,220.66 C225.27,220.66 225.24,220.78 225.24,220.78 C225.24,220.78 225.2,220.9 225.2,220.9 C225.2,220.9 225.16,221.02 225.16,221.02 C225.16,221.02 225.12,221.14 225.12,221.14 C225.12,221.14 225.08,221.26 225.08,221.26 C225.08,221.26 225.03,221.38 225.03,221.38 C225.03,221.38 224.99,221.5 224.99,221.5 C224.99,221.5 224.95,221.61 224.95,221.61 C224.95,221.61 224.89,221.73 224.89,221.73 C224.89,221.73 224.84,221.84 224.84,221.84 C224.84,221.84 224.79,221.96 224.79,221.96 C224.79,221.96 224.73,222.07 224.73,222.07 C224.73,222.07 224.68,222.18 224.68,222.18 C224.68,222.18 224.62,222.29 224.62,222.29 C224.62,222.29 224.56,222.4 224.56,222.4 C224.56,222.4 224.5,222.51 224.5,222.51 C224.5,222.51 224.44,222.62 224.44,222.62 C224.44,222.62 224.37,222.73 224.37,222.73 C224.37,222.73 224.31,222.84 224.31,222.84 C224.31,222.84 224.24,222.94 224.24,222.94 C224.24,222.94 224.17,223.05 224.17,223.05 C224.17,223.05 224.09,223.15 224.09,223.15 C224.09,223.15 224.02,223.25 224.02,223.25 C224.02,223.25 223.95,223.35 223.95,223.35 C223.95,223.35 223.88,223.45 223.88,223.45 C223.88,223.45 223.8,223.55 223.8,223.55 C223.8,223.55 223.71,223.65 223.71,223.65 C223.71,223.65 223.63,223.74 223.63,223.74 C223.63,223.74 223.55,223.84 223.55,223.84 C223.55,223.84 223.47,223.93 223.47,223.93 C223.47,223.93 223.39,224.03 223.39,224.03 C223.39,224.03 223.3,224.12 223.3,224.12 C223.3,224.12 223.21,224.2 223.21,224.2 C223.21,224.2 223.12,224.29 223.12,224.29 C223.12,224.29 223.03,224.38 223.03,224.38 C223.03,224.38 222.94,224.46 222.94,224.46 C222.94,224.46 222.85,224.55 222.85,224.55 C222.85,224.55 222.75,224.63 222.75,224.63 C222.75,224.63 222.65,224.71 222.65,224.71 C222.65,224.71 222.55,224.79 222.55,224.79 C222.55,224.79 222.46,224.87 222.46,224.87 C222.46,224.87 222.36,224.95 222.36,224.95 C222.36,224.95 222.26,225.02 222.26,225.02 C222.26,225.02 222.15,225.09 222.15,225.09 C222.15,225.09 222.05,225.16 222.05,225.16 C222.05,225.16 221.94,225.23 221.94,225.23 C221.94,225.23 221.84,225.3 221.84,225.3 C221.84,225.3 221.74,225.37 221.74,225.37 C221.74,225.37 221.63,225.44 221.63,225.44 C221.63,225.44 221.52,225.5 221.52,225.5 C221.52,225.5 221.41,225.56 221.41,225.56 C221.41,225.56 221.3,225.62 221.3,225.62 C221.3,225.62 221.19,225.68 221.19,225.68 C221.19,225.68 221.08,225.73 221.08,225.73 C221.08,225.73 220.96,225.79 220.96,225.79 C220.96,225.79 220.85,225.84 220.85,225.84 C220.85,225.84 220.73,225.89 220.73,225.89 C220.73,225.89 220.62,225.94 220.62,225.94 C220.62,225.94 220.5,225.99 220.5,225.99 C220.5,225.99 220.38,226.03 220.38,226.03 C220.38,226.03 220.27,226.08 220.27,226.08 C220.27,226.08 220.15,226.12 220.15,226.12 C220.15,226.12 220.03,226.15 220.03,226.15 C220.03,226.15 219.91,226.19 219.91,226.19 C219.91,226.19 219.79,226.23 219.79,226.23 C219.79,226.23 219.67,226.27 219.67,226.27 C219.67,226.27 219.55,226.3 219.55,226.3 C219.55,226.3 219.42,226.33 219.42,226.33 C219.42,226.33 219.3,226.35 219.3,226.35 C219.3,226.35 219.18,226.38 219.18,226.38 C219.18,226.38 219.06,226.4 219.06,226.4 C219.06,226.4 218.93,226.43 218.93,226.43 C218.93,226.43 218.81,226.45 218.81,226.45 C218.81,226.45 218.68,226.47 218.68,226.47 C218.68,226.47 218.56,226.49 218.56,226.49 C218.56,226.49 218.44,226.5 218.44,226.5 C218.44,226.5 218.31,226.52 218.31,226.52 C218.31,226.52 218.19,226.52 218.19,226.52 C218.19,226.52 218.06,226.53 218.06,226.53 C218.06,226.53 217.93,226.53 217.93,226.53 C217.93,226.53 217.81,226.54 217.81,226.54 C217.81,226.54 217.68,226.55 217.68,226.55 C217.68,226.55 217.56,226.55 217.56,226.55 C217.56,226.55 217.43,226.55 217.43,226.55 C217.43,226.55 217.31,226.54 217.31,226.54 C217.31,226.54 217.18,226.53 217.18,226.53 C217.18,226.53 217.05,226.53 217.05,226.53 C217.05,226.53 216.93,226.52 216.93,226.52 C216.93,226.52 216.8,226.52 216.8,226.52 C216.8,226.52 216.68,226.5 216.68,226.5 C216.68,226.5 216.55,226.48 216.55,226.48 C216.55,226.48 216.43,226.46 216.43,226.46 C216.43,226.46 216.31,226.45 216.31,226.45 C216.31,226.45 216.18,226.43 216.18,226.43 C216.18,226.43 216.06,226.41 216.06,226.41 C216.06,226.41 215.93,226.38 215.93,226.38 C215.93,226.38 215.81,226.35 215.81,226.35 C215.81,226.35 215.69,226.32 215.69,226.32 C215.69,226.32 215.57,226.29 215.57,226.29 C215.57,226.29 215.45,226.26 215.45,226.26 C215.45,226.26 215.32,226.23 215.32,226.23 C215.32,226.23 215.2,226.2 215.2,226.2 C215.2,226.2 215.09,226.16 215.09,226.16 C215.09,226.16 214.97,226.12 214.97,226.12 C214.97,226.12 214.85,226.07 214.85,226.07 C214.85,226.07 214.73,226.03 214.73,226.03 C214.73,226.03 214.61,225.99 214.61,225.99 C214.61,225.99 214.5,225.94 214.5,225.94 C214.5,225.94 214.38,225.89 214.38,225.89 C214.38,225.89 214.27,225.84 214.27,225.84 C214.27,225.84 214.15,225.79 214.15,225.79 C214.15,225.79 214.04,225.73 214.04,225.73 C214.04,225.73 213.93,225.68 213.93,225.68 C213.93,225.68 213.81,225.62 213.81,225.62 C213.81,225.62 213.71,225.56 213.71,225.56 C213.71,225.56 213.6,225.5 213.6,225.5 C213.6,225.5 213.49,225.43 213.49,225.43 C213.49,225.43 213.38,225.37 213.38,225.37 C213.38,225.37 213.27,225.31 213.27,225.31 C213.27,225.31 213.17,225.24 213.17,225.24 C213.17,225.24 213.06,225.16 213.06,225.16 C213.06,225.16 212.96,225.09 212.96,225.09 C212.96,225.09 212.86,225.02 212.86,225.02 C212.86,225.02 212.76,224.95 212.76,224.95 C212.76,224.95 212.65,224.87 212.65,224.87 C212.65,224.87 212.56,224.79 212.56,224.79 C212.56,224.79 212.46,224.71 212.46,224.71 C212.46,224.71 212.37,224.63 212.37,224.63 C212.37,224.63 212.27,224.55 212.27,224.55 C212.27,224.55 212.18,224.47 212.18,224.47 C212.18,224.47 212.08,224.38 212.08,224.38 C212.08,224.38 211.99,224.3 211.99,224.3 C211.99,224.3 211.91,224.2 211.91,224.2 C211.91,224.2 211.82,224.11 211.82,224.11 C211.82,224.11 211.73,224.02 211.73,224.02 C211.73,224.02 211.64,223.93 211.64,223.93 C211.64,223.93 211.56,223.84 211.56,223.84 C211.56,223.84 211.48,223.75 211.48,223.75 C211.48,223.75 211.4,223.65 211.4,223.65 C211.4,223.65 211.32,223.55 211.32,223.55 C211.32,223.55 211.24,223.45 211.24,223.45 C211.24,223.45 211.16,223.35 211.16,223.35 C211.16,223.35 211.09,223.26 211.09,223.26 C211.09,223.26 211.02,223.15 211.02,223.15 C211.02,223.15 210.95,223.05 210.95,223.05 C210.95,223.05 210.88,222.94 210.88,222.94 C210.88,222.94 210.81,222.84 210.81,222.84 C210.81,222.84 210.74,222.73 210.74,222.73 C210.74,222.73 210.67,222.63 210.67,222.63 C210.67,222.63 210.61,222.52 210.61,222.52 C210.61,222.52 210.55,222.4 210.55,222.4 C210.55,222.4 210.49,222.29 210.49,222.29 C210.49,222.29 210.43,222.18 210.43,222.18 C210.43,222.18 210.38,222.07 210.38,222.07 C210.38,222.07 210.32,221.96 210.32,221.96 C210.32,221.96 210.27,221.84 210.27,221.84 C210.27,221.84 210.22,221.73 210.22,221.73 C210.22,221.73 210.17,221.61 210.17,221.61 C210.17,221.61 210.12,221.5 210.12,221.5 C210.12,221.5 210.08,221.38 210.08,221.38 C210.08,221.38 210.03,221.26 210.03,221.26 C210.03,221.26 209.99,221.14 209.99,221.14 C209.99,221.14 209.96,221.02 209.96,221.02 C209.96,221.02 209.92,220.9 209.92,220.9 C209.92,220.9 209.88,220.78 209.88,220.78 C209.88,220.78 209.84,220.67 209.84,220.67 C209.84,220.67 209.81,220.54 209.81,220.54 C209.81,220.54 209.78,220.42 209.78,220.42 C209.78,220.42 209.76,220.3 209.76,220.3 C209.76,220.3 209.73,220.18 209.73,220.18 C209.73,220.18 209.71,220.05 209.71,220.05 C209.71,220.05 209.68,219.93 209.68,219.93 C209.68,219.93 209.66,219.81 209.66,219.81 C209.66,219.81 209.64,219.68 209.64,219.68 C209.64,219.68 209.62,219.56 209.62,219.56 C209.62,219.56 209.61,219.43 209.61,219.43 C209.61,219.43 209.59,219.31 209.59,219.31 C209.59,219.31 209.59,219.18 209.59,219.18 C209.59,219.18 209.58,219.06 209.58,219.06 C209.58,219.06 209.58,218.93 209.58,218.93 C209.58,218.93 209.57,218.81 209.57,218.81 C209.57,218.81 209.56,218.68 209.56,218.68 C209.56,218.68 209.56,218.56 209.56,218.56 C209.56,218.56 209.56,218.43 209.56,218.43 C209.56,218.43 209.57,218.3 209.57,218.3 C209.57,218.3 209.58,218.18 209.58,218.18 C209.58,218.18 209.58,218.05 209.58,218.05 C209.58,218.05 209.59,217.93 209.59,217.93 C209.59,217.93 209.59,217.8 209.59,217.8 C209.59,217.8 209.61,217.68 209.61,217.68 C209.61,217.68 209.63,217.55 209.63,217.55 C209.63,217.55 209.65,217.43 209.65,217.43 C209.65,217.43 209.66,217.31 209.66,217.31 C209.66,217.31 209.68,217.18 209.68,217.18 C209.68,217.18 209.7,217.06 209.7,217.06 C209.7,217.06 209.73,216.93 209.73,216.93 C209.73,216.93 209.76,216.81 209.76,216.81 C209.76,216.81 209.79,216.69 209.79,216.69 C209.79,216.69 209.82,216.57 209.82,216.57 C209.82,216.57 209.85,216.45 209.85,216.45 C209.85,216.45 209.88,216.32 209.88,216.32 C209.88,216.32 209.91,216.2 209.91,216.2 C209.91,216.2 209.95,216.08 209.95,216.08 C209.95,216.08 210,215.97 210,215.97 C210,215.97 210.04,215.85 210.04,215.85 C210.04,215.85 210.08,215.73 210.08,215.73 C210.08,215.73 210.12,215.61 210.12,215.61 C210.12,215.61 210.17,215.49 210.17,215.49 C210.17,215.49 210.22,215.38 210.22,215.38 C210.22,215.38 210.27,215.27 210.27,215.27 C210.27,215.27 210.33,215.15 210.33,215.15 C210.33,215.15 210.38,215.04 210.38,215.04 C210.38,215.04 210.43,214.92 210.43,214.92 C210.43,214.92 210.49,214.81 210.49,214.81 C210.49,214.81 210.55,214.7 210.55,214.7 C210.55,214.7 210.61,214.6 210.61,214.6 C210.61,214.6 210.68,214.49 210.68,214.49 C210.68,214.49 210.74,214.38 210.74,214.38 C210.74,214.38 210.8,214.27 210.8,214.27 C210.8,214.27 210.87,214.17 210.87,214.17 C210.87,214.17 210.95,214.06 210.95,214.06 C210.95,214.06 211.02,213.96 211.02,213.96 C211.02,213.96 211.09,213.86 211.09,213.86 C211.09,213.86 211.16,213.76 211.16,213.76 C211.16,213.76 211.24,213.65 211.24,213.65 C211.24,213.65 211.32,213.56 211.32,213.56 C211.32,213.56 211.4,213.46 211.4,213.46 C211.4,213.46 211.48,213.37 211.48,213.37 C211.48,213.37 211.56,213.27 211.56,213.27 C211.56,213.27 211.64,213.18 211.64,213.18 C211.64,213.18 211.73,213.08 211.73,213.08 C211.73,213.08 211.82,212.99 211.82,212.99 C211.82,212.99 211.91,212.9 211.91,212.9 C211.91,212.9 212,212.82 212,212.82 C212,212.82 212.09,212.73 212.09,212.73 C212.09,212.73 212.18,212.64 212.18,212.64 C212.18,212.64 212.27,212.56 212.27,212.56 C212.27,212.56 212.36,212.48 212.36,212.48 C212.36,212.48 212.46,212.4 212.46,212.4 C212.46,212.4 212.56,212.32 212.56,212.32 C212.56,212.32 212.66,212.24 212.66,212.24 C212.66,212.24 212.76,212.16 212.76,212.16 C212.76,212.16 212.85,212.08 212.85,212.08 C212.85,212.08 212.96,212.02 212.96,212.02 C212.96,212.02 213.06,211.95 213.06,211.95 C213.06,211.95 213.17,211.88 213.17,211.88 C213.17,211.88 213.27,211.81 213.27,211.81 C213.27,211.81 213.38,211.74 213.38,211.74 C213.38,211.74 213.48,211.67 213.48,211.67 C213.48,211.67 213.6,211.61 213.6,211.61 C213.6,211.61 213.71,211.55 213.71,211.55 C213.71,211.55 213.82,211.49 213.82,211.49 C213.82,211.49 213.93,211.43 213.93,211.43 C213.93,211.43 214.04,211.37 214.04,211.37 C214.04,211.37 214.15,211.32 214.15,211.32 C214.15,211.32 214.27,211.27 214.27,211.27 C214.27,211.27 214.38,211.22 214.38,211.22 C214.38,211.22 214.5,211.17 214.5,211.17 C214.5,211.17 214.61,211.12 214.61,211.12 C214.61,211.12 214.73,211.07 214.73,211.07 C214.73,211.07 214.85,211.03 214.85,211.03 C214.85,211.03 214.97,210.99 214.97,210.99 C214.97,210.99 215.09,210.95 215.09,210.95 C215.09,210.95 215.21,210.92 215.21,210.92 C215.21,210.92 215.33,210.88 215.33,210.88 C215.33,210.88 215.45,210.84 215.45,210.84 C215.45,210.84 215.57,210.81 215.57,210.81 C215.57,210.81 215.69,210.78 215.69,210.78 C215.69,210.78 215.81,210.76 215.81,210.76 C215.81,210.76 215.93,210.73 215.93,210.73 C215.93,210.73 216.06,210.7 216.06,210.7 C216.06,210.7 216.18,210.68 216.18,210.68 C216.18,210.68 216.3,210.65 216.3,210.65 C216.3,210.65 216.43,210.64 216.43,210.64 C216.43,210.64 216.55,210.62 216.55,210.62 C216.55,210.62 216.68,210.61 216.68,210.61 C216.68,210.61 216.8,210.59 216.8,210.59 C216.8,210.59 216.93,210.59 216.93,210.59 C216.93,210.59 217.05,210.58 217.05,210.58 C217.05,210.58 217.18,210.58 217.18,210.58 C217.18,210.58 217.3,210.57 217.3,210.57 C217.3,210.57 217.43,210.56 217.43,210.56 C217.43,210.56 217.56,210.56 217.56,210.56 C217.56,210.56 217.68,210.56 217.68,210.56c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_shape_3_avd.xml b/packages/SystemUI/res/drawable/pin_dot_shape_3_avd.xml
new file mode 100644
index 0000000..cf08899
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_shape_3_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="-187.543" android:translateY="-188.546"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="33" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c " android:valueTo="M217.57 201.76 C217.57,201.76 217.82,201.81 217.82,201.81 C217.82,201.81 218.08,201.86 218.08,201.86 C218.08,201.86 218.34,201.92 218.34,201.92 C218.34,201.92 218.6,201.97 218.6,201.97 C218.6,201.97 218.85,202.04 218.85,202.04 C218.85,202.04 219.11,202.12 219.11,202.12 C219.11,202.12 219.36,202.19 219.36,202.19 C219.36,202.19 219.61,202.27 219.61,202.27 C219.61,202.27 219.86,202.34 219.86,202.34 C219.86,202.34 220.11,202.44 220.11,202.44 C220.11,202.44 220.35,202.54 220.35,202.54 C220.35,202.54 220.6,202.64 220.6,202.64 C220.6,202.64 220.84,202.73 220.84,202.73 C220.84,202.73 221.09,202.83 221.09,202.83 C221.09,202.83 221.32,202.94 221.32,202.94 C221.32,202.94 221.56,203.07 221.56,203.07 C221.56,203.07 221.79,203.19 221.79,203.19 C221.79,203.19 222.03,203.31 222.03,203.31 C222.03,203.31 222.26,203.43 222.26,203.43 C222.26,203.43 222.49,203.56 222.49,203.56 C222.49,203.56 222.71,203.7 222.71,203.7 C222.71,203.7 222.93,203.85 222.93,203.85 C222.93,203.85 223.15,203.99 223.15,203.99 C223.15,203.99 223.37,204.13 223.37,204.13 C223.37,204.13 223.59,204.28 223.59,204.28 C223.59,204.28 223.8,204.44 223.8,204.44 C223.8,204.44 224.01,204.6 224.01,204.6 C224.01,204.6 224.22,204.76 224.22,204.76 C224.22,204.76 224.42,204.93 224.42,204.93 C224.42,204.93 224.62,205.1 224.62,205.1 C224.62,205.1 224.81,205.28 224.81,205.28 C224.81,205.28 225.01,205.46 225.01,205.46 C225.01,205.46 225.2,205.64 225.2,205.64 C225.2,205.64 225.4,205.81 225.4,205.81 C225.4,205.81 225.59,206 225.59,206 C225.59,206 225.77,206.19 225.77,206.19 C225.77,206.19 225.96,206.37 225.96,206.37 C225.96,206.37 226.15,206.56 226.15,206.56 C226.15,206.56 226.33,206.74 226.33,206.74 C226.33,206.74 226.52,206.93 226.52,206.93 C226.52,206.93 226.7,207.12 226.7,207.12 C226.7,207.12 226.89,207.3 226.89,207.3 C226.89,207.3 227.08,207.49 227.08,207.49 C227.08,207.49 227.26,207.68 227.26,207.68 C227.26,207.68 227.45,207.86 227.45,207.86 C227.45,207.86 227.64,208.05 227.64,208.05 C227.64,208.05 227.82,208.24 227.82,208.24 C227.82,208.24 228.01,208.42 228.01,208.42 C228.01,208.42 228.2,208.61 228.2,208.61 C228.2,208.61 228.38,208.79 228.38,208.79 C228.38,208.79 228.57,208.98 228.57,208.98 C228.57,208.98 228.75,209.17 228.75,209.17 C228.75,209.17 228.94,209.35 228.94,209.35 C228.94,209.35 229.13,209.54 229.13,209.54 C229.13,209.54 229.31,209.73 229.31,209.73 C229.31,209.73 229.5,209.91 229.5,209.91 C229.5,209.91 229.69,210.1 229.69,210.1 C229.69,210.1 229.87,210.29 229.87,210.29 C229.87,210.29 230.06,210.47 230.06,210.47 C230.06,210.47 230.25,210.66 230.25,210.66 C230.25,210.66 230.42,210.85 230.42,210.85 C230.42,210.85 230.6,211.05 230.6,211.05 C230.6,211.05 230.78,211.24 230.78,211.24 C230.78,211.24 230.95,211.44 230.95,211.44 C230.95,211.44 231.13,211.63 231.13,211.63 C231.13,211.63 231.3,211.84 231.3,211.84 C231.3,211.84 231.45,212.05 231.45,212.05 C231.45,212.05 231.61,212.26 231.61,212.26 C231.61,212.26 231.77,212.47 231.77,212.47 C231.77,212.47 231.93,212.68 231.93,212.68 C231.93,212.68 232.08,212.9 232.08,212.9 C232.08,212.9 232.22,213.12 232.22,213.12 C232.22,213.12 232.35,213.35 232.35,213.35 C232.35,213.35 232.49,213.57 232.49,213.57 C232.49,213.57 232.63,213.8 232.63,213.8 C232.63,213.8 232.76,214.02 232.76,214.02 C232.76,214.02 232.88,214.26 232.88,214.26 C232.88,214.26 232.99,214.5 232.99,214.5 C232.99,214.5 233.11,214.74 233.11,214.74 C233.11,214.74 233.22,214.97 233.22,214.97 C233.22,214.97 233.33,215.21 233.33,215.21 C233.33,215.21 233.43,215.46 233.43,215.46 C233.43,215.46 233.52,215.7 233.52,215.7 C233.52,215.7 233.62,215.95 233.62,215.95 C233.62,215.95 233.71,216.2 233.71,216.2 C233.71,216.2 233.8,216.45 233.8,216.45 C233.8,216.45 233.88,216.7 233.88,216.7 C233.88,216.7 233.94,216.95 233.94,216.95 C233.94,216.95 234.01,217.21 234.01,217.21 C234.01,217.21 234.08,217.46 234.08,217.46 C234.08,217.46 234.15,217.71 234.15,217.71 C234.15,217.71 234.21,217.97 234.21,217.97 C234.21,217.97 234.25,218.23 234.25,218.23 C234.25,218.23 234.3,218.49 234.3,218.49 C234.3,218.49 234.34,218.75 234.34,218.75 C234.34,218.75 234.38,219.01 234.38,219.01 C234.38,219.01 234.42,219.27 234.42,219.27 C234.42,219.27 234.44,219.53 234.44,219.53 C234.44,219.53 234.46,219.8 234.46,219.8 C234.46,219.8 234.48,220.06 234.48,220.06 C234.48,220.06 234.5,220.32 234.5,220.32 C234.5,220.32 234.52,220.58 234.52,220.58 C234.52,220.58 234.51,220.85 234.51,220.85 C234.51,220.85 234.51,221.11 234.51,221.11 C234.51,221.11 234.5,221.38 234.5,221.38 C234.5,221.38 234.5,221.64 234.5,221.64 C234.5,221.64 234.49,221.9 234.49,221.9 C234.49,221.9 234.47,222.17 234.47,222.17 C234.47,222.17 234.44,222.43 234.44,222.43 C234.44,222.43 234.41,222.69 234.41,222.69 C234.41,222.69 234.38,222.95 234.38,222.95 C234.38,222.95 234.35,223.21 234.35,223.21 C234.35,223.21 234.3,223.47 234.3,223.47 C234.3,223.47 234.25,223.73 234.25,223.73 C234.25,223.73 234.2,223.99 234.2,223.99 C234.2,223.99 234.15,224.25 234.15,224.25 C234.15,224.25 234.09,224.51 234.09,224.51 C234.09,224.51 234.02,224.76 234.02,224.76 C234.02,224.76 233.95,225.01 233.95,225.01 C233.95,225.01 233.87,225.26 233.87,225.26 C233.87,225.26 233.79,225.52 233.79,225.52 C233.79,225.52 233.72,225.77 233.72,225.77 C233.72,225.77 233.63,226.01 233.63,226.01 C233.63,226.01 233.53,226.26 233.53,226.26 C233.53,226.26 233.43,226.5 233.43,226.5 C233.43,226.5 233.33,226.75 233.33,226.75 C233.33,226.75 233.23,226.99 233.23,226.99 C233.23,226.99 233.12,227.23 233.12,227.23 C233.12,227.23 233,227.46 233,227.46 C233,227.46 232.88,227.7 232.88,227.7 C232.88,227.7 232.75,227.93 232.75,227.93 C232.75,227.93 232.63,228.17 232.63,228.17 C232.63,228.17 232.5,228.4 232.5,228.4 C232.5,228.4 232.36,228.62 232.36,228.62 C232.36,228.62 232.22,228.84 232.22,228.84 C232.22,228.84 232.07,229.06 232.07,229.06 C232.07,229.06 231.93,229.28 231.93,229.28 C231.93,229.28 231.79,229.5 231.79,229.5 C231.79,229.5 231.63,229.71 231.63,229.71 C231.63,229.71 231.46,229.92 231.46,229.92 C231.46,229.92 231.3,230.13 231.3,230.13 C231.3,230.13 231.14,230.33 231.14,230.33 C231.14,230.33 230.96,230.52 230.96,230.52 C230.96,230.52 230.78,230.72 230.78,230.72 C230.78,230.72 230.6,230.92 230.6,230.92 C230.6,230.92 230.43,231.11 230.43,231.11 C230.43,231.11 230.25,231.31 230.25,231.31 C230.25,231.31 230.05,231.49 230.05,231.49 C230.05,231.49 229.86,231.66 229.86,231.66 C229.86,231.66 229.66,231.84 229.66,231.84 C229.66,231.84 229.47,232.02 229.47,232.02 C229.47,232.02 229.27,232.19 229.27,232.19 C229.27,232.19 229.07,232.36 229.07,232.36 C229.07,232.36 228.86,232.52 228.86,232.52 C228.86,232.52 228.64,232.68 228.64,232.68 C228.64,232.68 228.43,232.83 228.43,232.83 C228.43,232.83 228.22,232.99 228.22,232.99 C228.22,232.99 228.01,233.14 228.01,233.14 C228.01,233.14 227.78,233.28 227.78,233.28 C227.78,233.28 227.56,233.42 227.56,233.42 C227.56,233.42 227.33,233.55 227.33,233.55 C227.33,233.55 227.11,233.69 227.11,233.69 C227.11,233.69 226.88,233.83 226.88,233.83 C226.88,233.83 226.64,233.94 226.64,233.94 C226.64,233.94 226.41,234.06 226.41,234.06 C226.41,234.06 226.17,234.17 226.17,234.17 C226.17,234.17 225.93,234.28 225.93,234.28 C225.93,234.28 225.69,234.4 225.69,234.4 C225.69,234.4 225.45,234.5 225.45,234.5 C225.45,234.5 225.2,234.59 225.2,234.59 C225.2,234.59 224.95,234.68 224.95,234.68 C224.95,234.68 224.71,234.77 224.71,234.77 C224.71,234.77 224.46,234.86 224.46,234.86 C224.46,234.86 224.21,234.94 224.21,234.94 C224.21,234.94 223.95,235.01 223.95,235.01 C223.95,235.01 223.7,235.08 223.7,235.08 C223.7,235.08 223.44,235.14 223.44,235.14 C223.44,235.14 223.19,235.21 223.19,235.21 C223.19,235.21 222.93,235.27 222.93,235.27 C222.93,235.27 222.67,235.31 222.67,235.31 C222.67,235.31 222.41,235.36 222.41,235.36 C222.41,235.36 222.15,235.4 222.15,235.4 C222.15,235.4 221.89,235.45 221.89,235.45 C221.89,235.45 221.63,235.48 221.63,235.48 C221.63,235.48 221.37,235.5 221.37,235.5 C221.37,235.5 221.11,235.52 221.11,235.52 C221.11,235.52 220.84,235.54 220.84,235.54 C220.84,235.54 220.58,235.56 220.58,235.56 C220.58,235.56 220.32,235.58 220.32,235.58 C220.32,235.58 220.06,235.57 220.06,235.57 C220.06,235.57 219.79,235.57 219.79,235.57 C219.79,235.57 219.53,235.57 219.53,235.57 C219.53,235.57 219.26,235.56 219.26,235.56 C219.26,235.56 219,235.56 219,235.56 C219,235.56 218.74,235.53 218.74,235.53 C218.74,235.53 218.48,235.5 218.48,235.5 C218.48,235.5 218.22,235.47 218.22,235.47 C218.22,235.47 217.95,235.44 217.95,235.44 C217.95,235.44 217.69,235.41 217.69,235.41 C217.69,235.41 217.43,235.36 217.43,235.36 C217.43,235.36 217.17,235.31 217.17,235.31 C217.17,235.31 216.92,235.26 216.92,235.26 C216.92,235.26 216.66,235.21 216.66,235.21 C216.66,235.21 216.4,235.15 216.4,235.15 C216.4,235.15 216.15,235.08 216.15,235.08 C216.15,235.08 215.89,235.01 215.89,235.01 C215.89,235.01 215.64,234.93 215.64,234.93 C215.64,234.93 215.39,234.85 215.39,234.85 C215.39,234.85 215.14,234.78 215.14,234.78 C215.14,234.78 214.89,234.69 214.89,234.69 C214.89,234.69 214.65,234.59 214.65,234.59 C214.65,234.59 214.4,234.49 214.4,234.49 C214.4,234.49 214.16,234.39 214.16,234.39 C214.16,234.39 213.91,234.29 213.91,234.29 C213.91,234.29 213.67,234.18 213.67,234.18 C213.67,234.18 213.44,234.06 213.44,234.06 C213.44,234.06 213.21,233.94 213.21,233.94 C213.21,233.94 212.97,233.81 212.97,233.81 C212.97,233.81 212.74,233.69 212.74,233.69 C212.74,233.69 212.51,233.56 212.51,233.56 C212.51,233.56 212.29,233.42 212.29,233.42 C212.29,233.42 212.07,233.28 212.07,233.28 C212.07,233.28 211.85,233.13 211.85,233.13 C211.85,233.13 211.63,232.99 211.63,232.99 C211.63,232.99 211.4,232.85 211.4,232.85 C211.4,232.85 211.2,232.69 211.2,232.69 C211.2,232.69 210.99,232.52 210.99,232.52 C210.99,232.52 210.78,232.36 210.78,232.36 C210.78,232.36 210.58,232.2 210.58,232.2 C210.58,232.2 210.38,232.02 210.38,232.02 C210.38,232.02 210.18,231.84 210.18,231.84 C210.18,231.84 209.99,231.66 209.99,231.66 C209.99,231.66 209.79,231.49 209.79,231.49 C209.79,231.49 209.6,231.31 209.6,231.31 C209.6,231.31 209.41,231.12 209.41,231.12 C209.41,231.12 209.23,230.94 209.23,230.94 C209.23,230.94 209.04,230.75 209.04,230.75 C209.04,230.75 208.85,230.56 208.85,230.56 C208.85,230.56 208.67,230.38 208.67,230.38 C208.67,230.38 208.48,230.19 208.48,230.19 C208.48,230.19 208.29,230.01 208.29,230.01 C208.29,230.01 208.11,229.82 208.11,229.82 C208.11,229.82 207.92,229.63 207.92,229.63 C207.92,229.63 207.74,229.45 207.74,229.45 C207.74,229.45 207.55,229.26 207.55,229.26 C207.55,229.26 207.36,229.07 207.36,229.07 C207.36,229.07 207.18,228.89 207.18,228.89 C207.18,228.89 206.99,228.7 206.99,228.7 C206.99,228.7 206.8,228.51 206.8,228.51 C206.8,228.51 206.62,228.33 206.62,228.33 C206.62,228.33 206.43,228.14 206.43,228.14 C206.43,228.14 206.24,227.96 206.24,227.96 C206.24,227.96 206.06,227.77 206.06,227.77 C206.06,227.77 205.87,227.58 205.87,227.58 C205.87,227.58 205.69,227.4 205.69,227.4 C205.69,227.4 205.5,227.21 205.5,227.21 C205.5,227.21 205.31,227.02 205.31,227.02 C205.31,227.02 205.13,226.84 205.13,226.84 C205.13,226.84 204.94,226.65 204.94,226.65 C204.94,226.65 204.75,226.46 204.75,226.46 C204.75,226.46 204.58,226.27 204.58,226.27 C204.58,226.27 204.4,226.07 204.4,226.07 C204.4,226.07 204.22,225.88 204.22,225.88 C204.22,225.88 204.05,225.68 204.05,225.68 C204.05,225.68 203.87,225.49 203.87,225.49 C203.87,225.49 203.7,225.28 203.7,225.28 C203.7,225.28 203.54,225.07 203.54,225.07 C203.54,225.07 203.39,224.86 203.39,224.86 C203.39,224.86 203.23,224.65 203.23,224.65 C203.23,224.65 203.07,224.44 203.07,224.44 C203.07,224.44 202.92,224.22 202.92,224.22 C202.92,224.22 202.78,224 202.78,224 C202.78,224 202.65,223.77 202.65,223.77 C202.65,223.77 202.51,223.55 202.51,223.55 C202.51,223.55 202.37,223.32 202.37,223.32 C202.37,223.32 202.24,223.1 202.24,223.1 C202.24,223.1 202.12,222.86 202.12,222.86 C202.12,222.86 202.01,222.62 202.01,222.62 C202.01,222.62 201.89,222.39 201.89,222.39 C201.89,222.39 201.78,222.15 201.78,222.15 C201.78,222.15 201.67,221.91 201.67,221.91 C201.67,221.91 201.57,221.67 201.57,221.67 C201.57,221.67 201.48,221.42 201.48,221.42 C201.48,221.42 201.38,221.17 201.38,221.17 C201.38,221.17 201.29,220.92 201.29,220.92 C201.29,220.92 201.2,220.68 201.2,220.68 C201.2,220.68 201.12,220.43 201.12,220.43 C201.12,220.43 201.06,220.17 201.06,220.17 C201.06,220.17 200.99,219.92 200.99,219.92 C200.99,219.92 200.92,219.66 200.92,219.66 C200.92,219.66 200.85,219.41 200.85,219.41 C200.85,219.41 200.79,219.15 200.79,219.15 C200.79,219.15 200.75,218.89 200.75,218.89 C200.75,218.89 200.71,218.63 200.71,218.63 C200.71,218.63 200.66,218.37 200.66,218.37 C200.66,218.37 200.62,218.11 200.62,218.11 C200.62,218.11 200.58,217.85 200.58,217.85 C200.58,217.85 200.56,217.59 200.56,217.59 C200.56,217.59 200.54,217.32 200.54,217.32 C200.54,217.32 200.52,217.06 200.52,217.06 C200.52,217.06 200.5,216.8 200.5,216.8 C200.5,216.8 200.48,216.54 200.48,216.54 C200.48,216.54 200.49,216.27 200.49,216.27 C200.49,216.27 200.49,216.01 200.49,216.01 C200.49,216.01 200.5,215.75 200.5,215.75 C200.5,215.75 200.5,215.48 200.5,215.48 C200.5,215.48 200.51,215.22 200.51,215.22 C200.51,215.22 200.53,214.96 200.53,214.96 C200.53,214.96 200.56,214.69 200.56,214.69 C200.56,214.69 200.59,214.43 200.59,214.43 C200.59,214.43 200.62,214.17 200.62,214.17 C200.62,214.17 200.65,213.91 200.65,213.91 C200.65,213.91 200.7,213.65 200.7,213.65 C200.7,213.65 200.75,213.39 200.75,213.39 C200.75,213.39 200.8,213.13 200.8,213.13 C200.8,213.13 200.86,212.88 200.86,212.88 C200.86,212.88 200.91,212.62 200.91,212.62 C200.91,212.62 200.98,212.36 200.98,212.36 C200.98,212.36 201.06,212.11 201.06,212.11 C201.06,212.11 201.13,211.86 201.13,211.86 C201.13,211.86 201.21,211.61 201.21,211.61 C201.21,211.61 201.28,211.35 201.28,211.35 C201.28,211.35 201.38,211.11 201.38,211.11 C201.38,211.11 201.47,210.86 201.47,210.86 C201.47,210.86 201.57,210.62 201.57,210.62 C201.57,210.62 201.67,210.37 201.67,210.37 C201.67,210.37 201.77,210.13 201.77,210.13 C201.77,210.13 201.88,209.89 201.88,209.89 C201.88,209.89 202,209.66 202,209.66 C202,209.66 202.13,209.42 202.13,209.42 C202.13,209.42 202.25,209.19 202.25,209.19 C202.25,209.19 202.37,208.96 202.37,208.96 C202.37,208.96 202.5,208.73 202.5,208.73 C202.5,208.73 202.64,208.51 202.64,208.51 C202.64,208.51 202.79,208.28 202.79,208.28 C202.79,208.28 202.93,208.06 202.93,208.06 C202.93,208.06 203.07,207.84 203.07,207.84 C203.07,207.84 203.22,207.62 203.22,207.62 C203.22,207.62 203.38,207.41 203.38,207.41 C203.38,207.41 203.54,207.2 203.54,207.2 C203.54,207.2 203.7,207 203.7,207 C203.7,207 203.87,206.79 203.87,206.79 C203.87,206.79 204.04,206.6 204.04,206.6 C204.04,206.6 204.22,206.4 204.22,206.4 C204.22,206.4 204.4,206.21 204.4,206.21 C204.4,206.21 204.57,206.01 204.57,206.01 C204.57,206.01 204.75,205.82 204.75,205.82 C204.75,205.82 204.95,205.64 204.95,205.64 C204.95,205.64 205.14,205.46 205.14,205.46 C205.14,205.46 205.34,205.29 205.34,205.29 C205.34,205.29 205.53,205.11 205.53,205.11 C205.53,205.11 205.73,204.93 205.73,204.93 C205.73,204.93 205.93,204.76 205.93,204.76 C205.93,204.76 206.14,204.61 206.14,204.61 C206.14,204.61 206.35,204.45 206.35,204.45 C206.35,204.45 206.57,204.29 206.57,204.29 C206.57,204.29 206.78,204.13 206.78,204.13 C206.78,204.13 206.99,203.98 206.99,203.98 C206.99,203.98 207.22,203.85 207.22,203.85 C207.22,203.85 207.44,203.71 207.44,203.71 C207.44,203.71 207.67,203.57 207.67,203.57 C207.67,203.57 207.89,203.44 207.89,203.44 C207.89,203.44 208.12,203.3 208.12,203.3 C208.12,203.3 208.36,203.18 208.36,203.18 C208.36,203.18 208.59,203.07 208.59,203.07 C208.59,203.07 208.83,202.96 208.83,202.96 C208.83,202.96 209.07,202.84 209.07,202.84 C209.07,202.84 209.31,202.73 209.31,202.73 C209.31,202.73 209.55,202.63 209.55,202.63 C209.55,202.63 209.8,202.54 209.8,202.54 C209.8,202.54 210.04,202.45 210.04,202.45 C210.04,202.45 210.29,202.36 210.29,202.36 C210.29,202.36 210.54,202.26 210.54,202.26 C210.54,202.26 210.79,202.19 210.79,202.19 C210.79,202.19 211.05,202.12 211.05,202.12 C211.05,202.12 211.3,202.05 211.3,202.05 C211.3,202.05 211.55,201.98 211.55,201.98 C211.55,201.98 211.81,201.91 211.81,201.91 C211.81,201.91 212.07,201.86 212.07,201.86 C212.07,201.86 212.33,201.81 212.33,201.81 C212.33,201.81 212.59,201.77 212.59,201.77 C212.59,201.77 212.85,201.72 212.85,201.72 C212.85,201.72 213.11,201.68 213.11,201.68 C213.11,201.68 213.37,201.64 213.37,201.64 C213.37,201.64 213.63,201.62 213.63,201.62 C213.63,201.62 213.89,201.6 213.89,201.6 C213.89,201.6 214.15,201.58 214.15,201.58 C214.15,201.58 214.42,201.56 214.42,201.56 C214.42,201.56 214.68,201.55 214.68,201.55 C214.68,201.55 214.94,201.55 214.94,201.55 C214.94,201.55 215.21,201.55 215.21,201.55 C215.21,201.55 215.47,201.56 215.47,201.56 C215.47,201.56 215.73,201.56 215.73,201.56 C215.73,201.56 216,201.57 216,201.57 C216,201.57 216.26,201.6 216.26,201.6 C216.26,201.6 216.52,201.62 216.52,201.62 C216.52,201.62 216.78,201.65 216.78,201.65 C216.78,201.65 217.05,201.68 217.05,201.68 C217.05,201.68 217.31,201.71 217.31,201.71 C217.31,201.71 217.57,201.76 217.57,201.76c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="67" android:valueFrom="M217.57 201.76 C217.57,201.76 217.82,201.81 217.82,201.81 C217.82,201.81 218.08,201.86 218.08,201.86 C218.08,201.86 218.34,201.92 218.34,201.92 C218.34,201.92 218.6,201.97 218.6,201.97 C218.6,201.97 218.85,202.04 218.85,202.04 C218.85,202.04 219.11,202.12 219.11,202.12 C219.11,202.12 219.36,202.19 219.36,202.19 C219.36,202.19 219.61,202.27 219.61,202.27 C219.61,202.27 219.86,202.34 219.86,202.34 C219.86,202.34 220.11,202.44 220.11,202.44 C220.11,202.44 220.35,202.54 220.35,202.54 C220.35,202.54 220.6,202.64 220.6,202.64 C220.6,202.64 220.84,202.73 220.84,202.73 C220.84,202.73 221.09,202.83 221.09,202.83 C221.09,202.83 221.32,202.94 221.32,202.94 C221.32,202.94 221.56,203.07 221.56,203.07 C221.56,203.07 221.79,203.19 221.79,203.19 C221.79,203.19 222.03,203.31 222.03,203.31 C222.03,203.31 222.26,203.43 222.26,203.43 C222.26,203.43 222.49,203.56 222.49,203.56 C222.49,203.56 222.71,203.7 222.71,203.7 C222.71,203.7 222.93,203.85 222.93,203.85 C222.93,203.85 223.15,203.99 223.15,203.99 C223.15,203.99 223.37,204.13 223.37,204.13 C223.37,204.13 223.59,204.28 223.59,204.28 C223.59,204.28 223.8,204.44 223.8,204.44 C223.8,204.44 224.01,204.6 224.01,204.6 C224.01,204.6 224.22,204.76 224.22,204.76 C224.22,204.76 224.42,204.93 224.42,204.93 C224.42,204.93 224.62,205.1 224.62,205.1 C224.62,205.1 224.81,205.28 224.81,205.28 C224.81,205.28 225.01,205.46 225.01,205.46 C225.01,205.46 225.2,205.64 225.2,205.64 C225.2,205.64 225.4,205.81 225.4,205.81 C225.4,205.81 225.59,206 225.59,206 C225.59,206 225.77,206.19 225.77,206.19 C225.77,206.19 225.96,206.37 225.96,206.37 C225.96,206.37 226.15,206.56 226.15,206.56 C226.15,206.56 226.33,206.74 226.33,206.74 C226.33,206.74 226.52,206.93 226.52,206.93 C226.52,206.93 226.7,207.12 226.7,207.12 C226.7,207.12 226.89,207.3 226.89,207.3 C226.89,207.3 227.08,207.49 227.08,207.49 C227.08,207.49 227.26,207.68 227.26,207.68 C227.26,207.68 227.45,207.86 227.45,207.86 C227.45,207.86 227.64,208.05 227.64,208.05 C227.64,208.05 227.82,208.24 227.82,208.24 C227.82,208.24 228.01,208.42 228.01,208.42 C228.01,208.42 228.2,208.61 228.2,208.61 C228.2,208.61 228.38,208.79 228.38,208.79 C228.38,208.79 228.57,208.98 228.57,208.98 C228.57,208.98 228.75,209.17 228.75,209.17 C228.75,209.17 228.94,209.35 228.94,209.35 C228.94,209.35 229.13,209.54 229.13,209.54 C229.13,209.54 229.31,209.73 229.31,209.73 C229.31,209.73 229.5,209.91 229.5,209.91 C229.5,209.91 229.69,210.1 229.69,210.1 C229.69,210.1 229.87,210.29 229.87,210.29 C229.87,210.29 230.06,210.47 230.06,210.47 C230.06,210.47 230.25,210.66 230.25,210.66 C230.25,210.66 230.42,210.85 230.42,210.85 C230.42,210.85 230.6,211.05 230.6,211.05 C230.6,211.05 230.78,211.24 230.78,211.24 C230.78,211.24 230.95,211.44 230.95,211.44 C230.95,211.44 231.13,211.63 231.13,211.63 C231.13,211.63 231.3,211.84 231.3,211.84 C231.3,211.84 231.45,212.05 231.45,212.05 C231.45,212.05 231.61,212.26 231.61,212.26 C231.61,212.26 231.77,212.47 231.77,212.47 C231.77,212.47 231.93,212.68 231.93,212.68 C231.93,212.68 232.08,212.9 232.08,212.9 C232.08,212.9 232.22,213.12 232.22,213.12 C232.22,213.12 232.35,213.35 232.35,213.35 C232.35,213.35 232.49,213.57 232.49,213.57 C232.49,213.57 232.63,213.8 232.63,213.8 C232.63,213.8 232.76,214.02 232.76,214.02 C232.76,214.02 232.88,214.26 232.88,214.26 C232.88,214.26 232.99,214.5 232.99,214.5 C232.99,214.5 233.11,214.74 233.11,214.74 C233.11,214.74 233.22,214.97 233.22,214.97 C233.22,214.97 233.33,215.21 233.33,215.21 C233.33,215.21 233.43,215.46 233.43,215.46 C233.43,215.46 233.52,215.7 233.52,215.7 C233.52,215.7 233.62,215.95 233.62,215.95 C233.62,215.95 233.71,216.2 233.71,216.2 C233.71,216.2 233.8,216.45 233.8,216.45 C233.8,216.45 233.88,216.7 233.88,216.7 C233.88,216.7 233.94,216.95 233.94,216.95 C233.94,216.95 234.01,217.21 234.01,217.21 C234.01,217.21 234.08,217.46 234.08,217.46 C234.08,217.46 234.15,217.71 234.15,217.71 C234.15,217.71 234.21,217.97 234.21,217.97 C234.21,217.97 234.25,218.23 234.25,218.23 C234.25,218.23 234.3,218.49 234.3,218.49 C234.3,218.49 234.34,218.75 234.34,218.75 C234.34,218.75 234.38,219.01 234.38,219.01 C234.38,219.01 234.42,219.27 234.42,219.27 C234.42,219.27 234.44,219.53 234.44,219.53 C234.44,219.53 234.46,219.8 234.46,219.8 C234.46,219.8 234.48,220.06 234.48,220.06 C234.48,220.06 234.5,220.32 234.5,220.32 C234.5,220.32 234.52,220.58 234.52,220.58 C234.52,220.58 234.51,220.85 234.51,220.85 C234.51,220.85 234.51,221.11 234.51,221.11 C234.51,221.11 234.5,221.38 234.5,221.38 C234.5,221.38 234.5,221.64 234.5,221.64 C234.5,221.64 234.49,221.9 234.49,221.9 C234.49,221.9 234.47,222.17 234.47,222.17 C234.47,222.17 234.44,222.43 234.44,222.43 C234.44,222.43 234.41,222.69 234.41,222.69 C234.41,222.69 234.38,222.95 234.38,222.95 C234.38,222.95 234.35,223.21 234.35,223.21 C234.35,223.21 234.3,223.47 234.3,223.47 C234.3,223.47 234.25,223.73 234.25,223.73 C234.25,223.73 234.2,223.99 234.2,223.99 C234.2,223.99 234.15,224.25 234.15,224.25 C234.15,224.25 234.09,224.51 234.09,224.51 C234.09,224.51 234.02,224.76 234.02,224.76 C234.02,224.76 233.95,225.01 233.95,225.01 C233.95,225.01 233.87,225.26 233.87,225.26 C233.87,225.26 233.79,225.52 233.79,225.52 C233.79,225.52 233.72,225.77 233.72,225.77 C233.72,225.77 233.63,226.01 233.63,226.01 C233.63,226.01 233.53,226.26 233.53,226.26 C233.53,226.26 233.43,226.5 233.43,226.5 C233.43,226.5 233.33,226.75 233.33,226.75 C233.33,226.75 233.23,226.99 233.23,226.99 C233.23,226.99 233.12,227.23 233.12,227.23 C233.12,227.23 233,227.46 233,227.46 C233,227.46 232.88,227.7 232.88,227.7 C232.88,227.7 232.75,227.93 232.75,227.93 C232.75,227.93 232.63,228.17 232.63,228.17 C232.63,228.17 232.5,228.4 232.5,228.4 C232.5,228.4 232.36,228.62 232.36,228.62 C232.36,228.62 232.22,228.84 232.22,228.84 C232.22,228.84 232.07,229.06 232.07,229.06 C232.07,229.06 231.93,229.28 231.93,229.28 C231.93,229.28 231.79,229.5 231.79,229.5 C231.79,229.5 231.63,229.71 231.63,229.71 C231.63,229.71 231.46,229.92 231.46,229.92 C231.46,229.92 231.3,230.13 231.3,230.13 C231.3,230.13 231.14,230.33 231.14,230.33 C231.14,230.33 230.96,230.52 230.96,230.52 C230.96,230.52 230.78,230.72 230.78,230.72 C230.78,230.72 230.6,230.92 230.6,230.92 C230.6,230.92 230.43,231.11 230.43,231.11 C230.43,231.11 230.25,231.31 230.25,231.31 C230.25,231.31 230.05,231.49 230.05,231.49 C230.05,231.49 229.86,231.66 229.86,231.66 C229.86,231.66 229.66,231.84 229.66,231.84 C229.66,231.84 229.47,232.02 229.47,232.02 C229.47,232.02 229.27,232.19 229.27,232.19 C229.27,232.19 229.07,232.36 229.07,232.36 C229.07,232.36 228.86,232.52 228.86,232.52 C228.86,232.52 228.64,232.68 228.64,232.68 C228.64,232.68 228.43,232.83 228.43,232.83 C228.43,232.83 228.22,232.99 228.22,232.99 C228.22,232.99 228.01,233.14 228.01,233.14 C228.01,233.14 227.78,233.28 227.78,233.28 C227.78,233.28 227.56,233.42 227.56,233.42 C227.56,233.42 227.33,233.55 227.33,233.55 C227.33,233.55 227.11,233.69 227.11,233.69 C227.11,233.69 226.88,233.83 226.88,233.83 C226.88,233.83 226.64,233.94 226.64,233.94 C226.64,233.94 226.41,234.06 226.41,234.06 C226.41,234.06 226.17,234.17 226.17,234.17 C226.17,234.17 225.93,234.28 225.93,234.28 C225.93,234.28 225.69,234.4 225.69,234.4 C225.69,234.4 225.45,234.5 225.45,234.5 C225.45,234.5 225.2,234.59 225.2,234.59 C225.2,234.59 224.95,234.68 224.95,234.68 C224.95,234.68 224.71,234.77 224.71,234.77 C224.71,234.77 224.46,234.86 224.46,234.86 C224.46,234.86 224.21,234.94 224.21,234.94 C224.21,234.94 223.95,235.01 223.95,235.01 C223.95,235.01 223.7,235.08 223.7,235.08 C223.7,235.08 223.44,235.14 223.44,235.14 C223.44,235.14 223.19,235.21 223.19,235.21 C223.19,235.21 222.93,235.27 222.93,235.27 C222.93,235.27 222.67,235.31 222.67,235.31 C222.67,235.31 222.41,235.36 222.41,235.36 C222.41,235.36 222.15,235.4 222.15,235.4 C222.15,235.4 221.89,235.45 221.89,235.45 C221.89,235.45 221.63,235.48 221.63,235.48 C221.63,235.48 221.37,235.5 221.37,235.5 C221.37,235.5 221.11,235.52 221.11,235.52 C221.11,235.52 220.84,235.54 220.84,235.54 C220.84,235.54 220.58,235.56 220.58,235.56 C220.58,235.56 220.32,235.58 220.32,235.58 C220.32,235.58 220.06,235.57 220.06,235.57 C220.06,235.57 219.79,235.57 219.79,235.57 C219.79,235.57 219.53,235.57 219.53,235.57 C219.53,235.57 219.26,235.56 219.26,235.56 C219.26,235.56 219,235.56 219,235.56 C219,235.56 218.74,235.53 218.74,235.53 C218.74,235.53 218.48,235.5 218.48,235.5 C218.48,235.5 218.22,235.47 218.22,235.47 C218.22,235.47 217.95,235.44 217.95,235.44 C217.95,235.44 217.69,235.41 217.69,235.41 C217.69,235.41 217.43,235.36 217.43,235.36 C217.43,235.36 217.17,235.31 217.17,235.31 C217.17,235.31 216.92,235.26 216.92,235.26 C216.92,235.26 216.66,235.21 216.66,235.21 C216.66,235.21 216.4,235.15 216.4,235.15 C216.4,235.15 216.15,235.08 216.15,235.08 C216.15,235.08 215.89,235.01 215.89,235.01 C215.89,235.01 215.64,234.93 215.64,234.93 C215.64,234.93 215.39,234.85 215.39,234.85 C215.39,234.85 215.14,234.78 215.14,234.78 C215.14,234.78 214.89,234.69 214.89,234.69 C214.89,234.69 214.65,234.59 214.65,234.59 C214.65,234.59 214.4,234.49 214.4,234.49 C214.4,234.49 214.16,234.39 214.16,234.39 C214.16,234.39 213.91,234.29 213.91,234.29 C213.91,234.29 213.67,234.18 213.67,234.18 C213.67,234.18 213.44,234.06 213.44,234.06 C213.44,234.06 213.21,233.94 213.21,233.94 C213.21,233.94 212.97,233.81 212.97,233.81 C212.97,233.81 212.74,233.69 212.74,233.69 C212.74,233.69 212.51,233.56 212.51,233.56 C212.51,233.56 212.29,233.42 212.29,233.42 C212.29,233.42 212.07,233.28 212.07,233.28 C212.07,233.28 211.85,233.13 211.85,233.13 C211.85,233.13 211.63,232.99 211.63,232.99 C211.63,232.99 211.4,232.85 211.4,232.85 C211.4,232.85 211.2,232.69 211.2,232.69 C211.2,232.69 210.99,232.52 210.99,232.52 C210.99,232.52 210.78,232.36 210.78,232.36 C210.78,232.36 210.58,232.2 210.58,232.2 C210.58,232.2 210.38,232.02 210.38,232.02 C210.38,232.02 210.18,231.84 210.18,231.84 C210.18,231.84 209.99,231.66 209.99,231.66 C209.99,231.66 209.79,231.49 209.79,231.49 C209.79,231.49 209.6,231.31 209.6,231.31 C209.6,231.31 209.41,231.12 209.41,231.12 C209.41,231.12 209.23,230.94 209.23,230.94 C209.23,230.94 209.04,230.75 209.04,230.75 C209.04,230.75 208.85,230.56 208.85,230.56 C208.85,230.56 208.67,230.38 208.67,230.38 C208.67,230.38 208.48,230.19 208.48,230.19 C208.48,230.19 208.29,230.01 208.29,230.01 C208.29,230.01 208.11,229.82 208.11,229.82 C208.11,229.82 207.92,229.63 207.92,229.63 C207.92,229.63 207.74,229.45 207.74,229.45 C207.74,229.45 207.55,229.26 207.55,229.26 C207.55,229.26 207.36,229.07 207.36,229.07 C207.36,229.07 207.18,228.89 207.18,228.89 C207.18,228.89 206.99,228.7 206.99,228.7 C206.99,228.7 206.8,228.51 206.8,228.51 C206.8,228.51 206.62,228.33 206.62,228.33 C206.62,228.33 206.43,228.14 206.43,228.14 C206.43,228.14 206.24,227.96 206.24,227.96 C206.24,227.96 206.06,227.77 206.06,227.77 C206.06,227.77 205.87,227.58 205.87,227.58 C205.87,227.58 205.69,227.4 205.69,227.4 C205.69,227.4 205.5,227.21 205.5,227.21 C205.5,227.21 205.31,227.02 205.31,227.02 C205.31,227.02 205.13,226.84 205.13,226.84 C205.13,226.84 204.94,226.65 204.94,226.65 C204.94,226.65 204.75,226.46 204.75,226.46 C204.75,226.46 204.58,226.27 204.58,226.27 C204.58,226.27 204.4,226.07 204.4,226.07 C204.4,226.07 204.22,225.88 204.22,225.88 C204.22,225.88 204.05,225.68 204.05,225.68 C204.05,225.68 203.87,225.49 203.87,225.49 C203.87,225.49 203.7,225.28 203.7,225.28 C203.7,225.28 203.54,225.07 203.54,225.07 C203.54,225.07 203.39,224.86 203.39,224.86 C203.39,224.86 203.23,224.65 203.23,224.65 C203.23,224.65 203.07,224.44 203.07,224.44 C203.07,224.44 202.92,224.22 202.92,224.22 C202.92,224.22 202.78,224 202.78,224 C202.78,224 202.65,223.77 202.65,223.77 C202.65,223.77 202.51,223.55 202.51,223.55 C202.51,223.55 202.37,223.32 202.37,223.32 C202.37,223.32 202.24,223.1 202.24,223.1 C202.24,223.1 202.12,222.86 202.12,222.86 C202.12,222.86 202.01,222.62 202.01,222.62 C202.01,222.62 201.89,222.39 201.89,222.39 C201.89,222.39 201.78,222.15 201.78,222.15 C201.78,222.15 201.67,221.91 201.67,221.91 C201.67,221.91 201.57,221.67 201.57,221.67 C201.57,221.67 201.48,221.42 201.48,221.42 C201.48,221.42 201.38,221.17 201.38,221.17 C201.38,221.17 201.29,220.92 201.29,220.92 C201.29,220.92 201.2,220.68 201.2,220.68 C201.2,220.68 201.12,220.43 201.12,220.43 C201.12,220.43 201.06,220.17 201.06,220.17 C201.06,220.17 200.99,219.92 200.99,219.92 C200.99,219.92 200.92,219.66 200.92,219.66 C200.92,219.66 200.85,219.41 200.85,219.41 C200.85,219.41 200.79,219.15 200.79,219.15 C200.79,219.15 200.75,218.89 200.75,218.89 C200.75,218.89 200.71,218.63 200.71,218.63 C200.71,218.63 200.66,218.37 200.66,218.37 C200.66,218.37 200.62,218.11 200.62,218.11 C200.62,218.11 200.58,217.85 200.58,217.85 C200.58,217.85 200.56,217.59 200.56,217.59 C200.56,217.59 200.54,217.32 200.54,217.32 C200.54,217.32 200.52,217.06 200.52,217.06 C200.52,217.06 200.5,216.8 200.5,216.8 C200.5,216.8 200.48,216.54 200.48,216.54 C200.48,216.54 200.49,216.27 200.49,216.27 C200.49,216.27 200.49,216.01 200.49,216.01 C200.49,216.01 200.5,215.75 200.5,215.75 C200.5,215.75 200.5,215.48 200.5,215.48 C200.5,215.48 200.51,215.22 200.51,215.22 C200.51,215.22 200.53,214.96 200.53,214.96 C200.53,214.96 200.56,214.69 200.56,214.69 C200.56,214.69 200.59,214.43 200.59,214.43 C200.59,214.43 200.62,214.17 200.62,214.17 C200.62,214.17 200.65,213.91 200.65,213.91 C200.65,213.91 200.7,213.65 200.7,213.65 C200.7,213.65 200.75,213.39 200.75,213.39 C200.75,213.39 200.8,213.13 200.8,213.13 C200.8,213.13 200.86,212.88 200.86,212.88 C200.86,212.88 200.91,212.62 200.91,212.62 C200.91,212.62 200.98,212.36 200.98,212.36 C200.98,212.36 201.06,212.11 201.06,212.11 C201.06,212.11 201.13,211.86 201.13,211.86 C201.13,211.86 201.21,211.61 201.21,211.61 C201.21,211.61 201.28,211.35 201.28,211.35 C201.28,211.35 201.38,211.11 201.38,211.11 C201.38,211.11 201.47,210.86 201.47,210.86 C201.47,210.86 201.57,210.62 201.57,210.62 C201.57,210.62 201.67,210.37 201.67,210.37 C201.67,210.37 201.77,210.13 201.77,210.13 C201.77,210.13 201.88,209.89 201.88,209.89 C201.88,209.89 202,209.66 202,209.66 C202,209.66 202.13,209.42 202.13,209.42 C202.13,209.42 202.25,209.19 202.25,209.19 C202.25,209.19 202.37,208.96 202.37,208.96 C202.37,208.96 202.5,208.73 202.5,208.73 C202.5,208.73 202.64,208.51 202.64,208.51 C202.64,208.51 202.79,208.28 202.79,208.28 C202.79,208.28 202.93,208.06 202.93,208.06 C202.93,208.06 203.07,207.84 203.07,207.84 C203.07,207.84 203.22,207.62 203.22,207.62 C203.22,207.62 203.38,207.41 203.38,207.41 C203.38,207.41 203.54,207.2 203.54,207.2 C203.54,207.2 203.7,207 203.7,207 C203.7,207 203.87,206.79 203.87,206.79 C203.87,206.79 204.04,206.6 204.04,206.6 C204.04,206.6 204.22,206.4 204.22,206.4 C204.22,206.4 204.4,206.21 204.4,206.21 C204.4,206.21 204.57,206.01 204.57,206.01 C204.57,206.01 204.75,205.82 204.75,205.82 C204.75,205.82 204.95,205.64 204.95,205.64 C204.95,205.64 205.14,205.46 205.14,205.46 C205.14,205.46 205.34,205.29 205.34,205.29 C205.34,205.29 205.53,205.11 205.53,205.11 C205.53,205.11 205.73,204.93 205.73,204.93 C205.73,204.93 205.93,204.76 205.93,204.76 C205.93,204.76 206.14,204.61 206.14,204.61 C206.14,204.61 206.35,204.45 206.35,204.45 C206.35,204.45 206.57,204.29 206.57,204.29 C206.57,204.29 206.78,204.13 206.78,204.13 C206.78,204.13 206.99,203.98 206.99,203.98 C206.99,203.98 207.22,203.85 207.22,203.85 C207.22,203.85 207.44,203.71 207.44,203.71 C207.44,203.71 207.67,203.57 207.67,203.57 C207.67,203.57 207.89,203.44 207.89,203.44 C207.89,203.44 208.12,203.3 208.12,203.3 C208.12,203.3 208.36,203.18 208.36,203.18 C208.36,203.18 208.59,203.07 208.59,203.07 C208.59,203.07 208.83,202.96 208.83,202.96 C208.83,202.96 209.07,202.84 209.07,202.84 C209.07,202.84 209.31,202.73 209.31,202.73 C209.31,202.73 209.55,202.63 209.55,202.63 C209.55,202.63 209.8,202.54 209.8,202.54 C209.8,202.54 210.04,202.45 210.04,202.45 C210.04,202.45 210.29,202.36 210.29,202.36 C210.29,202.36 210.54,202.26 210.54,202.26 C210.54,202.26 210.79,202.19 210.79,202.19 C210.79,202.19 211.05,202.12 211.05,202.12 C211.05,202.12 211.3,202.05 211.3,202.05 C211.3,202.05 211.55,201.98 211.55,201.98 C211.55,201.98 211.81,201.91 211.81,201.91 C211.81,201.91 212.07,201.86 212.07,201.86 C212.07,201.86 212.33,201.81 212.33,201.81 C212.33,201.81 212.59,201.77 212.59,201.77 C212.59,201.77 212.85,201.72 212.85,201.72 C212.85,201.72 213.11,201.68 213.11,201.68 C213.11,201.68 213.37,201.64 213.37,201.64 C213.37,201.64 213.63,201.62 213.63,201.62 C213.63,201.62 213.89,201.6 213.89,201.6 C213.89,201.6 214.15,201.58 214.15,201.58 C214.15,201.58 214.42,201.56 214.42,201.56 C214.42,201.56 214.68,201.55 214.68,201.55 C214.68,201.55 214.94,201.55 214.94,201.55 C214.94,201.55 215.21,201.55 215.21,201.55 C215.21,201.55 215.47,201.56 215.47,201.56 C215.47,201.56 215.73,201.56 215.73,201.56 C215.73,201.56 216,201.57 216,201.57 C216,201.57 216.26,201.6 216.26,201.6 C216.26,201.6 216.52,201.62 216.52,201.62 C216.52,201.62 216.78,201.65 216.78,201.65 C216.78,201.65 217.05,201.68 217.05,201.68 C217.05,201.68 217.31,201.71 217.31,201.71 C217.31,201.71 217.57,201.76 217.57,201.76c " android:valueTo="M217.68 210.56 C217.68,210.56 217.81,210.57 217.81,210.57 C217.81,210.57 217.93,210.57 217.93,210.57 C217.93,210.57 218.06,210.58 218.06,210.58 C218.06,210.58 218.18,210.59 218.18,210.59 C218.18,210.59 218.31,210.59 218.31,210.59 C218.31,210.59 218.43,210.61 218.43,210.61 C218.43,210.61 218.56,210.63 218.56,210.63 C218.56,210.63 218.68,210.64 218.68,210.64 C218.68,210.64 218.81,210.66 218.81,210.66 C218.81,210.66 218.93,210.68 218.93,210.68 C218.93,210.68 219.05,210.7 219.05,210.7 C219.05,210.7 219.18,210.72 219.18,210.72 C219.18,210.72 219.3,210.75 219.3,210.75 C219.3,210.75 219.42,210.78 219.42,210.78 C219.42,210.78 219.54,210.81 219.54,210.81 C219.54,210.81 219.66,210.84 219.66,210.84 C219.66,210.84 219.79,210.87 219.79,210.87 C219.79,210.87 219.91,210.91 219.91,210.91 C219.91,210.91 220.03,210.95 220.03,210.95 C220.03,210.95 220.14,210.99 220.14,210.99 C220.14,210.99 220.26,211.04 220.26,211.04 C220.26,211.04 220.38,211.08 220.38,211.08 C220.38,211.08 220.5,211.12 220.5,211.12 C220.5,211.12 220.62,211.17 220.62,211.17 C220.62,211.17 220.73,211.22 220.73,211.22 C220.73,211.22 220.84,211.27 220.84,211.27 C220.84,211.27 220.96,211.32 220.96,211.32 C220.96,211.32 221.07,211.38 221.07,211.38 C221.07,211.38 221.19,211.43 221.19,211.43 C221.19,211.43 221.3,211.49 221.3,211.49 C221.3,211.49 221.41,211.55 221.41,211.55 C221.41,211.55 221.51,211.61 221.51,211.61 C221.51,211.61 221.62,211.68 221.62,211.68 C221.62,211.68 221.73,211.74 221.73,211.74 C221.73,211.74 221.84,211.8 221.84,211.8 C221.84,211.8 221.94,211.87 221.94,211.87 C221.94,211.87 222.05,211.94 222.05,211.94 C222.05,211.94 222.15,212.02 222.15,212.02 C222.15,212.02 222.25,212.09 222.25,212.09 C222.25,212.09 222.35,212.16 222.35,212.16 C222.35,212.16 222.46,212.23 222.46,212.23 C222.46,212.23 222.55,212.31 222.55,212.31 C222.55,212.31 222.65,212.4 222.65,212.4 C222.65,212.4 222.74,212.48 222.74,212.48 C222.74,212.48 222.84,212.56 222.84,212.56 C222.84,212.56 222.93,212.64 222.93,212.64 C222.93,212.64 223.03,212.72 223.03,212.72 C223.03,212.72 223.12,212.81 223.12,212.81 C223.12,212.81 223.21,212.9 223.21,212.9 C223.21,212.9 223.29,212.99 223.29,212.99 C223.29,212.99 223.38,213.08 223.38,213.08 C223.38,213.08 223.47,213.17 223.47,213.17 C223.47,213.17 223.55,213.26 223.55,213.26 C223.55,213.26 223.63,213.36 223.63,213.36 C223.63,213.36 223.71,213.46 223.71,213.46 C223.71,213.46 223.79,213.56 223.79,213.56 C223.79,213.56 223.87,213.66 223.87,213.66 C223.87,213.66 223.95,213.75 223.95,213.75 C223.95,213.75 224.03,213.85 224.03,213.85 C224.03,213.85 224.09,213.96 224.09,213.96 C224.09,213.96 224.16,214.06 224.16,214.06 C224.16,214.06 224.23,214.17 224.23,214.17 C224.23,214.17 224.3,214.27 224.3,214.27 C224.3,214.27 224.37,214.38 224.37,214.38 C224.37,214.38 224.44,214.48 224.44,214.48 C224.44,214.48 224.5,214.59 224.5,214.59 C224.5,214.59 224.56,214.7 224.56,214.7 C224.56,214.7 224.62,214.81 224.62,214.81 C224.62,214.81 224.68,214.93 224.68,214.93 C224.68,214.93 224.74,215.04 224.74,215.04 C224.74,215.04 224.79,215.15 224.79,215.15 C224.79,215.15 224.84,215.26 224.84,215.26 C224.84,215.26 224.89,215.38 224.89,215.38 C224.89,215.38 224.94,215.5 224.94,215.5 C224.94,215.5 224.99,215.61 224.99,215.61 C224.99,215.61 225.04,215.73 225.04,215.73 C225.04,215.73 225.08,215.84 225.08,215.84 C225.08,215.84 225.12,215.96 225.12,215.96 C225.12,215.96 225.16,216.08 225.16,216.08 C225.16,216.08 225.19,216.2 225.19,216.2 C225.19,216.2 225.23,216.32 225.23,216.32 C225.23,216.32 225.27,216.44 225.27,216.44 C225.27,216.44 225.3,216.56 225.3,216.56 C225.3,216.56 225.33,216.69 225.33,216.69 C225.33,216.69 225.35,216.81 225.35,216.81 C225.35,216.81 225.38,216.93 225.38,216.93 C225.38,216.93 225.41,217.06 225.41,217.06 C225.41,217.06 225.43,217.18 225.43,217.18 C225.43,217.18 225.46,217.3 225.46,217.3 C225.46,217.3 225.47,217.43 225.47,217.43 C225.47,217.43 225.49,217.55 225.49,217.55 C225.49,217.55 225.5,217.68 225.5,217.68 C225.5,217.68 225.52,217.8 225.52,217.8 C225.52,217.8 225.52,217.93 225.52,217.93 C225.52,217.93 225.53,218.05 225.53,218.05 C225.53,218.05 225.54,218.18 225.54,218.18 C225.54,218.18 225.54,218.3 225.54,218.3 C225.54,218.3 225.55,218.43 225.55,218.43 C225.55,218.43 225.55,218.55 225.55,218.55 C225.55,218.55 225.55,218.68 225.55,218.68 C225.55,218.68 225.54,218.8 225.54,218.8 C225.54,218.8 225.54,218.93 225.54,218.93 C225.54,218.93 225.53,219.05 225.53,219.05 C225.53,219.05 225.52,219.18 225.52,219.18 C225.52,219.18 225.52,219.31 225.52,219.31 C225.52,219.31 225.5,219.43 225.5,219.43 C225.5,219.43 225.48,219.55 225.48,219.55 C225.48,219.55 225.47,219.68 225.47,219.68 C225.47,219.68 225.45,219.8 225.45,219.8 C225.45,219.8 225.43,219.93 225.43,219.93 C225.43,219.93 225.41,220.05 225.41,220.05 C225.41,220.05 225.39,220.17 225.39,220.17 C225.39,220.17 225.36,220.3 225.36,220.3 C225.36,220.3 225.33,220.42 225.33,220.42 C225.33,220.42 225.3,220.54 225.3,220.54 C225.3,220.54 225.27,220.66 225.27,220.66 C225.27,220.66 225.24,220.78 225.24,220.78 C225.24,220.78 225.2,220.9 225.2,220.9 C225.2,220.9 225.16,221.02 225.16,221.02 C225.16,221.02 225.12,221.14 225.12,221.14 C225.12,221.14 225.08,221.26 225.08,221.26 C225.08,221.26 225.03,221.38 225.03,221.38 C225.03,221.38 224.99,221.5 224.99,221.5 C224.99,221.5 224.95,221.61 224.95,221.61 C224.95,221.61 224.89,221.73 224.89,221.73 C224.89,221.73 224.84,221.84 224.84,221.84 C224.84,221.84 224.79,221.96 224.79,221.96 C224.79,221.96 224.73,222.07 224.73,222.07 C224.73,222.07 224.68,222.18 224.68,222.18 C224.68,222.18 224.62,222.29 224.62,222.29 C224.62,222.29 224.56,222.4 224.56,222.4 C224.56,222.4 224.5,222.51 224.5,222.51 C224.5,222.51 224.44,222.62 224.44,222.62 C224.44,222.62 224.37,222.73 224.37,222.73 C224.37,222.73 224.31,222.84 224.31,222.84 C224.31,222.84 224.24,222.94 224.24,222.94 C224.24,222.94 224.17,223.05 224.17,223.05 C224.17,223.05 224.09,223.15 224.09,223.15 C224.09,223.15 224.02,223.25 224.02,223.25 C224.02,223.25 223.95,223.35 223.95,223.35 C223.95,223.35 223.88,223.45 223.88,223.45 C223.88,223.45 223.8,223.55 223.8,223.55 C223.8,223.55 223.71,223.65 223.71,223.65 C223.71,223.65 223.63,223.74 223.63,223.74 C223.63,223.74 223.55,223.84 223.55,223.84 C223.55,223.84 223.47,223.93 223.47,223.93 C223.47,223.93 223.39,224.03 223.39,224.03 C223.39,224.03 223.3,224.12 223.3,224.12 C223.3,224.12 223.21,224.2 223.21,224.2 C223.21,224.2 223.12,224.29 223.12,224.29 C223.12,224.29 223.03,224.38 223.03,224.38 C223.03,224.38 222.94,224.46 222.94,224.46 C222.94,224.46 222.85,224.55 222.85,224.55 C222.85,224.55 222.75,224.63 222.75,224.63 C222.75,224.63 222.65,224.71 222.65,224.71 C222.65,224.71 222.55,224.79 222.55,224.79 C222.55,224.79 222.46,224.87 222.46,224.87 C222.46,224.87 222.36,224.95 222.36,224.95 C222.36,224.95 222.26,225.02 222.26,225.02 C222.26,225.02 222.15,225.09 222.15,225.09 C222.15,225.09 222.05,225.16 222.05,225.16 C222.05,225.16 221.94,225.23 221.94,225.23 C221.94,225.23 221.84,225.3 221.84,225.3 C221.84,225.3 221.74,225.37 221.74,225.37 C221.74,225.37 221.63,225.44 221.63,225.44 C221.63,225.44 221.52,225.5 221.52,225.5 C221.52,225.5 221.41,225.56 221.41,225.56 C221.41,225.56 221.3,225.62 221.3,225.62 C221.3,225.62 221.19,225.68 221.19,225.68 C221.19,225.68 221.08,225.73 221.08,225.73 C221.08,225.73 220.96,225.79 220.96,225.79 C220.96,225.79 220.85,225.84 220.85,225.84 C220.85,225.84 220.73,225.89 220.73,225.89 C220.73,225.89 220.62,225.94 220.62,225.94 C220.62,225.94 220.5,225.99 220.5,225.99 C220.5,225.99 220.38,226.03 220.38,226.03 C220.38,226.03 220.27,226.08 220.27,226.08 C220.27,226.08 220.15,226.12 220.15,226.12 C220.15,226.12 220.03,226.15 220.03,226.15 C220.03,226.15 219.91,226.19 219.91,226.19 C219.91,226.19 219.79,226.23 219.79,226.23 C219.79,226.23 219.67,226.27 219.67,226.27 C219.67,226.27 219.55,226.3 219.55,226.3 C219.55,226.3 219.42,226.33 219.42,226.33 C219.42,226.33 219.3,226.35 219.3,226.35 C219.3,226.35 219.18,226.38 219.18,226.38 C219.18,226.38 219.06,226.4 219.06,226.4 C219.06,226.4 218.93,226.43 218.93,226.43 C218.93,226.43 218.81,226.45 218.81,226.45 C218.81,226.45 218.68,226.47 218.68,226.47 C218.68,226.47 218.56,226.49 218.56,226.49 C218.56,226.49 218.44,226.5 218.44,226.5 C218.44,226.5 218.31,226.52 218.31,226.52 C218.31,226.52 218.19,226.52 218.19,226.52 C218.19,226.52 218.06,226.53 218.06,226.53 C218.06,226.53 217.93,226.53 217.93,226.53 C217.93,226.53 217.81,226.54 217.81,226.54 C217.81,226.54 217.68,226.55 217.68,226.55 C217.68,226.55 217.56,226.55 217.56,226.55 C217.56,226.55 217.43,226.55 217.43,226.55 C217.43,226.55 217.31,226.54 217.31,226.54 C217.31,226.54 217.18,226.53 217.18,226.53 C217.18,226.53 217.05,226.53 217.05,226.53 C217.05,226.53 216.93,226.52 216.93,226.52 C216.93,226.52 216.8,226.52 216.8,226.52 C216.8,226.52 216.68,226.5 216.68,226.5 C216.68,226.5 216.55,226.48 216.55,226.48 C216.55,226.48 216.43,226.46 216.43,226.46 C216.43,226.46 216.31,226.45 216.31,226.45 C216.31,226.45 216.18,226.43 216.18,226.43 C216.18,226.43 216.06,226.41 216.06,226.41 C216.06,226.41 215.93,226.38 215.93,226.38 C215.93,226.38 215.81,226.35 215.81,226.35 C215.81,226.35 215.69,226.32 215.69,226.32 C215.69,226.32 215.57,226.29 215.57,226.29 C215.57,226.29 215.45,226.26 215.45,226.26 C215.45,226.26 215.32,226.23 215.32,226.23 C215.32,226.23 215.2,226.2 215.2,226.2 C215.2,226.2 215.09,226.16 215.09,226.16 C215.09,226.16 214.97,226.12 214.97,226.12 C214.97,226.12 214.85,226.07 214.85,226.07 C214.85,226.07 214.73,226.03 214.73,226.03 C214.73,226.03 214.61,225.99 214.61,225.99 C214.61,225.99 214.5,225.94 214.5,225.94 C214.5,225.94 214.38,225.89 214.38,225.89 C214.38,225.89 214.27,225.84 214.27,225.84 C214.27,225.84 214.15,225.79 214.15,225.79 C214.15,225.79 214.04,225.73 214.04,225.73 C214.04,225.73 213.93,225.68 213.93,225.68 C213.93,225.68 213.81,225.62 213.81,225.62 C213.81,225.62 213.71,225.56 213.71,225.56 C213.71,225.56 213.6,225.5 213.6,225.5 C213.6,225.5 213.49,225.43 213.49,225.43 C213.49,225.43 213.38,225.37 213.38,225.37 C213.38,225.37 213.27,225.31 213.27,225.31 C213.27,225.31 213.17,225.24 213.17,225.24 C213.17,225.24 213.06,225.16 213.06,225.16 C213.06,225.16 212.96,225.09 212.96,225.09 C212.96,225.09 212.86,225.02 212.86,225.02 C212.86,225.02 212.76,224.95 212.76,224.95 C212.76,224.95 212.65,224.87 212.65,224.87 C212.65,224.87 212.56,224.79 212.56,224.79 C212.56,224.79 212.46,224.71 212.46,224.71 C212.46,224.71 212.37,224.63 212.37,224.63 C212.37,224.63 212.27,224.55 212.27,224.55 C212.27,224.55 212.18,224.47 212.18,224.47 C212.18,224.47 212.08,224.38 212.08,224.38 C212.08,224.38 211.99,224.3 211.99,224.3 C211.99,224.3 211.91,224.2 211.91,224.2 C211.91,224.2 211.82,224.11 211.82,224.11 C211.82,224.11 211.73,224.02 211.73,224.02 C211.73,224.02 211.64,223.93 211.64,223.93 C211.64,223.93 211.56,223.84 211.56,223.84 C211.56,223.84 211.48,223.75 211.48,223.75 C211.48,223.75 211.4,223.65 211.4,223.65 C211.4,223.65 211.32,223.55 211.32,223.55 C211.32,223.55 211.24,223.45 211.24,223.45 C211.24,223.45 211.16,223.35 211.16,223.35 C211.16,223.35 211.09,223.26 211.09,223.26 C211.09,223.26 211.02,223.15 211.02,223.15 C211.02,223.15 210.95,223.05 210.95,223.05 C210.95,223.05 210.88,222.94 210.88,222.94 C210.88,222.94 210.81,222.84 210.81,222.84 C210.81,222.84 210.74,222.73 210.74,222.73 C210.74,222.73 210.67,222.63 210.67,222.63 C210.67,222.63 210.61,222.52 210.61,222.52 C210.61,222.52 210.55,222.4 210.55,222.4 C210.55,222.4 210.49,222.29 210.49,222.29 C210.49,222.29 210.43,222.18 210.43,222.18 C210.43,222.18 210.38,222.07 210.38,222.07 C210.38,222.07 210.32,221.96 210.32,221.96 C210.32,221.96 210.27,221.84 210.27,221.84 C210.27,221.84 210.22,221.73 210.22,221.73 C210.22,221.73 210.17,221.61 210.17,221.61 C210.17,221.61 210.12,221.5 210.12,221.5 C210.12,221.5 210.08,221.38 210.08,221.38 C210.08,221.38 210.03,221.26 210.03,221.26 C210.03,221.26 209.99,221.14 209.99,221.14 C209.99,221.14 209.96,221.02 209.96,221.02 C209.96,221.02 209.92,220.9 209.92,220.9 C209.92,220.9 209.88,220.78 209.88,220.78 C209.88,220.78 209.84,220.67 209.84,220.67 C209.84,220.67 209.81,220.54 209.81,220.54 C209.81,220.54 209.78,220.42 209.78,220.42 C209.78,220.42 209.76,220.3 209.76,220.3 C209.76,220.3 209.73,220.18 209.73,220.18 C209.73,220.18 209.71,220.05 209.71,220.05 C209.71,220.05 209.68,219.93 209.68,219.93 C209.68,219.93 209.66,219.81 209.66,219.81 C209.66,219.81 209.64,219.68 209.64,219.68 C209.64,219.68 209.62,219.56 209.62,219.56 C209.62,219.56 209.61,219.43 209.61,219.43 C209.61,219.43 209.59,219.31 209.59,219.31 C209.59,219.31 209.59,219.18 209.59,219.18 C209.59,219.18 209.58,219.06 209.58,219.06 C209.58,219.06 209.58,218.93 209.58,218.93 C209.58,218.93 209.57,218.81 209.57,218.81 C209.57,218.81 209.56,218.68 209.56,218.68 C209.56,218.68 209.56,218.56 209.56,218.56 C209.56,218.56 209.56,218.43 209.56,218.43 C209.56,218.43 209.57,218.3 209.57,218.3 C209.57,218.3 209.58,218.18 209.58,218.18 C209.58,218.18 209.58,218.05 209.58,218.05 C209.58,218.05 209.59,217.93 209.59,217.93 C209.59,217.93 209.59,217.8 209.59,217.8 C209.59,217.8 209.61,217.68 209.61,217.68 C209.61,217.68 209.63,217.55 209.63,217.55 C209.63,217.55 209.65,217.43 209.65,217.43 C209.65,217.43 209.66,217.31 209.66,217.31 C209.66,217.31 209.68,217.18 209.68,217.18 C209.68,217.18 209.7,217.06 209.7,217.06 C209.7,217.06 209.73,216.93 209.73,216.93 C209.73,216.93 209.76,216.81 209.76,216.81 C209.76,216.81 209.79,216.69 209.79,216.69 C209.79,216.69 209.82,216.57 209.82,216.57 C209.82,216.57 209.85,216.45 209.85,216.45 C209.85,216.45 209.88,216.32 209.88,216.32 C209.88,216.32 209.91,216.2 209.91,216.2 C209.91,216.2 209.95,216.08 209.95,216.08 C209.95,216.08 210,215.97 210,215.97 C210,215.97 210.04,215.85 210.04,215.85 C210.04,215.85 210.08,215.73 210.08,215.73 C210.08,215.73 210.12,215.61 210.12,215.61 C210.12,215.61 210.17,215.49 210.17,215.49 C210.17,215.49 210.22,215.38 210.22,215.38 C210.22,215.38 210.27,215.27 210.27,215.27 C210.27,215.27 210.33,215.15 210.33,215.15 C210.33,215.15 210.38,215.04 210.38,215.04 C210.38,215.04 210.43,214.92 210.43,214.92 C210.43,214.92 210.49,214.81 210.49,214.81 C210.49,214.81 210.55,214.7 210.55,214.7 C210.55,214.7 210.61,214.6 210.61,214.6 C210.61,214.6 210.68,214.49 210.68,214.49 C210.68,214.49 210.74,214.38 210.74,214.38 C210.74,214.38 210.8,214.27 210.8,214.27 C210.8,214.27 210.87,214.17 210.87,214.17 C210.87,214.17 210.95,214.06 210.95,214.06 C210.95,214.06 211.02,213.96 211.02,213.96 C211.02,213.96 211.09,213.86 211.09,213.86 C211.09,213.86 211.16,213.76 211.16,213.76 C211.16,213.76 211.24,213.65 211.24,213.65 C211.24,213.65 211.32,213.56 211.32,213.56 C211.32,213.56 211.4,213.46 211.4,213.46 C211.4,213.46 211.48,213.37 211.48,213.37 C211.48,213.37 211.56,213.27 211.56,213.27 C211.56,213.27 211.64,213.18 211.64,213.18 C211.64,213.18 211.73,213.08 211.73,213.08 C211.73,213.08 211.82,212.99 211.82,212.99 C211.82,212.99 211.91,212.9 211.91,212.9 C211.91,212.9 212,212.82 212,212.82 C212,212.82 212.09,212.73 212.09,212.73 C212.09,212.73 212.18,212.64 212.18,212.64 C212.18,212.64 212.27,212.56 212.27,212.56 C212.27,212.56 212.36,212.48 212.36,212.48 C212.36,212.48 212.46,212.4 212.46,212.4 C212.46,212.4 212.56,212.32 212.56,212.32 C212.56,212.32 212.66,212.24 212.66,212.24 C212.66,212.24 212.76,212.16 212.76,212.16 C212.76,212.16 212.85,212.08 212.85,212.08 C212.85,212.08 212.96,212.02 212.96,212.02 C212.96,212.02 213.06,211.95 213.06,211.95 C213.06,211.95 213.17,211.88 213.17,211.88 C213.17,211.88 213.27,211.81 213.27,211.81 C213.27,211.81 213.38,211.74 213.38,211.74 C213.38,211.74 213.48,211.67 213.48,211.67 C213.48,211.67 213.6,211.61 213.6,211.61 C213.6,211.61 213.71,211.55 213.71,211.55 C213.71,211.55 213.82,211.49 213.82,211.49 C213.82,211.49 213.93,211.43 213.93,211.43 C213.93,211.43 214.04,211.37 214.04,211.37 C214.04,211.37 214.15,211.32 214.15,211.32 C214.15,211.32 214.27,211.27 214.27,211.27 C214.27,211.27 214.38,211.22 214.38,211.22 C214.38,211.22 214.5,211.17 214.5,211.17 C214.5,211.17 214.61,211.12 214.61,211.12 C214.61,211.12 214.73,211.07 214.73,211.07 C214.73,211.07 214.85,211.03 214.85,211.03 C214.85,211.03 214.97,210.99 214.97,210.99 C214.97,210.99 215.09,210.95 215.09,210.95 C215.09,210.95 215.21,210.92 215.21,210.92 C215.21,210.92 215.33,210.88 215.33,210.88 C215.33,210.88 215.45,210.84 215.45,210.84 C215.45,210.84 215.57,210.81 215.57,210.81 C215.57,210.81 215.69,210.78 215.69,210.78 C215.69,210.78 215.81,210.76 215.81,210.76 C215.81,210.76 215.93,210.73 215.93,210.73 C215.93,210.73 216.06,210.7 216.06,210.7 C216.06,210.7 216.18,210.68 216.18,210.68 C216.18,210.68 216.3,210.65 216.3,210.65 C216.3,210.65 216.43,210.64 216.43,210.64 C216.43,210.64 216.55,210.62 216.55,210.62 C216.55,210.62 216.68,210.61 216.68,210.61 C216.68,210.61 216.8,210.59 216.8,210.59 C216.8,210.59 216.93,210.59 216.93,210.59 C216.93,210.59 217.05,210.58 217.05,210.58 C217.05,210.58 217.18,210.58 217.18,210.58 C217.18,210.58 217.3,210.57 217.3,210.57 C217.3,210.57 217.43,210.56 217.43,210.56 C217.43,210.56 217.56,210.56 217.56,210.56 C217.56,210.56 217.68,210.56 217.68,210.56c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_shape_4_avd.xml b/packages/SystemUI/res/drawable/pin_dot_shape_4_avd.xml
new file mode 100644
index 0000000..76ee65b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_shape_4_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="-187.543" android:translateY="-188.546"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="33" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c " android:valueTo="M217.78 201.58 C217.78,201.58 218.07,201.62 218.07,201.62 C218.07,201.62 218.35,201.69 218.35,201.69 C218.35,201.69 218.63,201.78 218.63,201.78 C218.63,201.78 218.89,201.9 218.89,201.9 C218.89,201.9 219.14,202.04 219.14,202.04 C219.14,202.04 219.38,202.21 219.38,202.21 C219.38,202.21 219.59,202.41 219.59,202.41 C219.59,202.41 219.78,202.62 219.78,202.62 C219.78,202.62 219.95,202.86 219.95,202.86 C219.95,202.86 220.11,203.1 220.11,203.1 C220.11,203.1 220.26,203.35 220.26,203.35 C220.26,203.35 220.41,203.6 220.41,203.6 C220.41,203.6 220.55,203.85 220.55,203.85 C220.55,203.85 220.7,204.1 220.7,204.1 C220.7,204.1 220.85,204.35 220.85,204.35 C220.85,204.35 221,204.59 221,204.59 C221,204.59 221.15,204.84 221.15,204.84 C221.15,204.84 221.3,205.09 221.3,205.09 C221.3,205.09 221.46,205.33 221.46,205.33 C221.46,205.33 221.65,205.55 221.65,205.55 C221.65,205.55 221.86,205.75 221.86,205.75 C221.86,205.75 222.09,205.93 222.09,205.93 C222.09,205.93 222.33,206.09 222.33,206.09 C222.33,206.09 222.59,206.22 222.59,206.22 C222.59,206.22 222.86,206.32 222.86,206.32 C222.86,206.32 223.14,206.4 223.14,206.4 C223.14,206.4 223.42,206.45 223.42,206.45 C223.42,206.45 223.71,206.46 223.71,206.46 C223.71,206.46 224,206.45 224,206.45 C224,206.45 224.29,206.41 224.29,206.41 C224.29,206.41 224.57,206.35 224.57,206.35 C224.57,206.35 224.85,206.28 224.85,206.28 C224.85,206.28 225.13,206.21 225.13,206.21 C225.13,206.21 225.41,206.14 225.41,206.14 C225.41,206.14 225.7,206.07 225.7,206.07 C225.7,206.07 225.98,206 225.98,206 C225.98,206 226.26,205.93 226.26,205.93 C226.26,205.93 226.54,205.86 226.54,205.86 C226.54,205.86 226.82,205.78 226.82,205.78 C226.82,205.78 227.1,205.73 227.1,205.73 C227.1,205.73 227.39,205.71 227.39,205.71 C227.39,205.71 227.68,205.7 227.68,205.7 C227.68,205.7 227.97,205.73 227.97,205.73 C227.97,205.73 228.25,205.79 228.25,205.79 C228.25,205.79 228.53,205.88 228.53,205.88 C228.53,205.88 228.79,206 228.79,206 C228.79,206 229.04,206.14 229.04,206.14 C229.04,206.14 229.28,206.31 229.28,206.31 C229.28,206.31 229.5,206.49 229.5,206.49 C229.5,206.49 229.7,206.7 229.7,206.7 C229.7,206.7 229.88,206.93 229.88,206.93 C229.88,206.93 230.03,207.18 230.03,207.18 C230.03,207.18 230.16,207.44 230.16,207.44 C230.16,207.44 230.26,207.71 230.26,207.71 C230.26,207.71 230.34,207.99 230.34,207.99 C230.34,207.99 230.38,208.27 230.38,208.27 C230.38,208.27 230.39,208.56 230.39,208.56 C230.39,208.56 230.38,208.85 230.38,208.85 C230.38,208.85 230.33,209.14 230.33,209.14 C230.33,209.14 230.27,209.42 230.27,209.42 C230.27,209.42 230.2,209.7 230.2,209.7 C230.2,209.7 230.13,209.98 230.13,209.98 C230.13,209.98 230.06,210.26 230.06,210.26 C230.06,210.26 229.99,210.55 229.99,210.55 C229.99,210.55 229.92,210.83 229.92,210.83 C229.92,210.83 229.85,211.11 229.85,211.11 C229.85,211.11 229.78,211.39 229.78,211.39 C229.78,211.39 229.71,211.67 229.71,211.67 C229.71,211.67 229.66,211.95 229.66,211.95 C229.66,211.95 229.63,212.24 229.63,212.24 C229.63,212.24 229.64,212.53 229.64,212.53 C229.64,212.53 229.67,212.82 229.67,212.82 C229.67,212.82 229.73,213.1 229.73,213.1 C229.73,213.1 229.82,213.38 229.82,213.38 C229.82,213.38 229.94,213.64 229.94,213.64 C229.94,213.64 230.08,213.89 230.08,213.89 C230.08,213.89 230.25,214.13 230.25,214.13 C230.25,214.13 230.44,214.35 230.44,214.35 C230.44,214.35 230.66,214.54 230.66,214.54 C230.66,214.54 230.89,214.72 230.89,214.72 C230.89,214.72 231.13,214.87 231.13,214.87 C231.13,214.87 231.38,215.02 231.38,215.02 C231.38,215.02 231.63,215.17 231.63,215.17 C231.63,215.17 231.88,215.32 231.88,215.32 C231.88,215.32 232.13,215.47 232.13,215.47 C232.13,215.47 232.38,215.62 232.38,215.62 C232.38,215.62 232.62,215.77 232.62,215.77 C232.62,215.77 232.87,215.91 232.87,215.91 C232.87,215.91 233.12,216.06 233.12,216.06 C233.12,216.06 233.36,216.23 233.36,216.23 C233.36,216.23 233.58,216.41 233.58,216.41 C233.58,216.41 233.79,216.62 233.79,216.62 C233.79,216.62 233.97,216.84 233.97,216.84 C233.97,216.84 234.13,217.08 234.13,217.08 C234.13,217.08 234.26,217.34 234.26,217.34 C234.26,217.34 234.36,217.61 234.36,217.61 C234.36,217.61 234.44,217.89 234.44,217.89 C234.44,217.89 234.49,218.17 234.49,218.17 C234.49,218.17 234.52,218.46 234.52,218.46 C234.52,218.46 234.51,218.75 234.51,218.75 C234.51,218.75 234.47,219.04 234.47,219.04 C234.47,219.04 234.41,219.32 234.41,219.32 C234.41,219.32 234.31,219.59 234.31,219.59 C234.31,219.59 234.19,219.86 234.19,219.86 C234.19,219.86 234.05,220.11 234.05,220.11 C234.05,220.11 233.88,220.34 233.88,220.34 C233.88,220.34 233.68,220.56 233.68,220.56 C233.68,220.56 233.47,220.75 233.47,220.75 C233.47,220.75 233.23,220.92 233.23,220.92 C233.23,220.92 232.99,221.08 232.99,221.08 C232.99,221.08 232.74,221.22 232.74,221.22 C232.74,221.22 232.49,221.37 232.49,221.37 C232.49,221.37 232.25,221.52 232.25,221.52 C232.25,221.52 232,221.67 232,221.67 C232,221.67 231.75,221.82 231.75,221.82 C231.75,221.82 231.5,221.97 231.5,221.97 C231.5,221.97 231.25,222.12 231.25,222.12 C231.25,222.12 231,222.27 231,222.27 C231,222.27 230.76,222.43 230.76,222.43 C230.76,222.43 230.54,222.62 230.54,222.62 C230.54,222.62 230.34,222.83 230.34,222.83 C230.34,222.83 230.16,223.05 230.16,223.05 C230.16,223.05 230.01,223.3 230.01,223.3 C230.01,223.3 229.87,223.56 229.87,223.56 C229.87,223.56 229.77,223.83 229.77,223.83 C229.77,223.83 229.7,224.11 229.7,224.11 C229.7,224.11 229.65,224.39 229.65,224.39 C229.65,224.39 229.63,224.68 229.63,224.68 C229.63,224.68 229.64,224.97 229.64,224.97 C229.64,224.97 229.68,225.26 229.68,225.26 C229.68,225.26 229.75,225.54 229.75,225.54 C229.75,225.54 229.82,225.82 229.82,225.82 C229.82,225.82 229.89,226.1 229.89,226.1 C229.89,226.1 229.96,226.38 229.96,226.38 C229.96,226.38 230.03,226.66 230.03,226.66 C230.03,226.66 230.1,226.94 230.1,226.94 C230.1,226.94 230.17,227.22 230.17,227.22 C230.17,227.22 230.24,227.51 230.24,227.51 C230.24,227.51 230.31,227.79 230.31,227.79 C230.31,227.79 230.36,228.07 230.36,228.07 C230.36,228.07 230.39,228.36 230.39,228.36 C230.39,228.36 230.39,228.65 230.39,228.65 C230.39,228.65 230.36,228.94 230.36,228.94 C230.36,228.94 230.3,229.22 230.3,229.22 C230.3,229.22 230.21,229.5 230.21,229.5 C230.21,229.5 230.1,229.76 230.1,229.76 C230.1,229.76 229.95,230.01 229.95,230.01 C229.95,230.01 229.79,230.25 229.79,230.25 C229.79,230.25 229.6,230.47 229.6,230.47 C229.6,230.47 229.39,230.67 229.39,230.67 C229.39,230.67 229.16,230.85 229.16,230.85 C229.16,230.85 228.91,231 228.91,231 C228.91,231 228.66,231.13 228.66,231.13 C228.66,231.13 228.38,231.23 228.38,231.23 C228.38,231.23 228.11,231.3 228.11,231.3 C228.11,231.3 227.82,231.35 227.82,231.35 C227.82,231.35 227.53,231.36 227.53,231.36 C227.53,231.36 227.24,231.35 227.24,231.35 C227.24,231.35 226.96,231.3 226.96,231.3 C226.96,231.3 226.67,231.24 226.67,231.24 C226.67,231.24 226.39,231.17 226.39,231.17 C226.39,231.17 226.11,231.1 226.11,231.1 C226.11,231.1 225.83,231.03 225.83,231.03 C225.83,231.03 225.55,230.96 225.55,230.96 C225.55,230.96 225.27,230.89 225.27,230.89 C225.27,230.89 224.99,230.82 224.99,230.82 C224.99,230.82 224.71,230.75 224.71,230.75 C224.71,230.75 224.42,230.68 224.42,230.68 C224.42,230.68 224.14,230.62 224.14,230.62 C224.14,230.62 223.85,230.6 223.85,230.6 C223.85,230.6 223.56,230.6 223.56,230.6 C223.56,230.6 223.27,230.64 223.27,230.64 C223.27,230.64 222.99,230.7 222.99,230.7 C222.99,230.7 222.72,230.79 222.72,230.79 C222.72,230.79 222.45,230.91 222.45,230.91 C222.45,230.91 222.2,231.05 222.2,231.05 C222.2,231.05 221.96,231.22 221.96,231.22 C221.96,231.22 221.75,231.41 221.75,231.41 C221.75,231.41 221.55,231.62 221.55,231.62 C221.55,231.62 221.38,231.85 221.38,231.85 C221.38,231.85 221.22,232.1 221.22,232.1 C221.22,232.1 221.07,232.35 221.07,232.35 C221.07,232.35 220.92,232.6 220.92,232.6 C220.92,232.6 220.77,232.85 220.77,232.85 C220.77,232.85 220.63,233.09 220.63,233.09 C220.63,233.09 220.48,233.34 220.48,233.34 C220.48,233.34 220.33,233.59 220.33,233.59 C220.33,233.59 220.18,233.84 220.18,233.84 C220.18,233.84 220.03,234.09 220.03,234.09 C220.03,234.09 219.87,234.33 219.87,234.33 C219.87,234.33 219.68,234.55 219.68,234.55 C219.68,234.55 219.48,234.75 219.48,234.75 C219.48,234.75 219.25,234.94 219.25,234.94 C219.25,234.94 219.01,235.1 219.01,235.1 C219.01,235.1 218.75,235.23 218.75,235.23 C218.75,235.23 218.48,235.33 218.48,235.33 C218.48,235.33 218.21,235.41 218.21,235.41 C218.21,235.41 217.92,235.46 217.92,235.46 C217.92,235.46 217.63,235.48 217.63,235.48 C217.63,235.48 217.34,235.48 217.34,235.48 C217.34,235.48 217.06,235.44 217.06,235.44 C217.06,235.44 216.77,235.37 216.77,235.37 C216.77,235.37 216.5,235.28 216.5,235.28 C216.5,235.28 216.24,235.16 216.24,235.16 C216.24,235.16 215.99,235.02 215.99,235.02 C215.99,235.02 215.75,234.85 215.75,234.85 C215.75,234.85 215.54,234.65 215.54,234.65 C215.54,234.65 215.34,234.44 215.34,234.44 C215.34,234.44 215.17,234.2 215.17,234.2 C215.17,234.2 215.02,233.96 215.02,233.96 C215.02,233.96 214.87,233.71 214.87,233.71 C214.87,233.71 214.72,233.46 214.72,233.46 C214.72,233.46 214.57,233.21 214.57,233.21 C214.57,233.21 214.42,232.96 214.42,232.96 C214.42,232.96 214.27,232.72 214.27,232.72 C214.27,232.72 214.12,232.47 214.12,232.47 C214.12,232.47 213.98,232.22 213.98,232.22 C213.98,232.22 213.83,231.97 213.83,231.97 C213.83,231.97 213.66,231.73 213.66,231.73 C213.66,231.73 213.48,231.51 213.48,231.51 C213.48,231.51 213.27,231.31 213.27,231.31 C213.27,231.31 213.04,231.13 213.04,231.13 C213.04,231.13 212.8,230.97 212.8,230.97 C212.8,230.97 212.54,230.84 212.54,230.84 C212.54,230.84 212.27,230.74 212.27,230.74 C212.27,230.74 211.99,230.66 211.99,230.66 C211.99,230.66 211.7,230.62 211.7,230.62 C211.7,230.62 211.41,230.6 211.41,230.6 C211.41,230.6 211.12,230.61 211.12,230.61 C211.12,230.61 210.84,230.65 210.84,230.65 C210.84,230.65 210.56,230.71 210.56,230.71 C210.56,230.71 210.27,230.78 210.27,230.78 C210.27,230.78 209.99,230.85 209.99,230.85 C209.99,230.85 209.71,230.92 209.71,230.92 C209.71,230.92 209.43,230.99 209.43,230.99 C209.43,230.99 209.15,231.06 209.15,231.06 C209.15,231.06 208.87,231.14 208.87,231.14 C208.87,231.14 208.59,231.21 208.59,231.21 C208.59,231.21 208.31,231.28 208.31,231.28 C208.31,231.28 208.02,231.33 208.02,231.33 C208.02,231.33 207.73,231.36 207.73,231.36 C207.73,231.36 207.45,231.36 207.45,231.36 C207.45,231.36 207.16,231.33 207.16,231.33 C207.16,231.33 206.87,231.27 206.87,231.27 C206.87,231.27 206.6,231.18 206.6,231.18 C206.6,231.18 206.33,231.06 206.33,231.06 C206.33,231.06 206.08,230.92 206.08,230.92 C206.08,230.92 205.85,230.76 205.85,230.76 C205.85,230.76 205.62,230.57 205.62,230.57 C205.62,230.57 205.42,230.36 205.42,230.36 C205.42,230.36 205.25,230.13 205.25,230.13 C205.25,230.13 205.1,229.88 205.1,229.88 C205.1,229.88 204.97,229.62 204.97,229.62 C204.97,229.62 204.87,229.35 204.87,229.35 C204.87,229.35 204.79,229.07 204.79,229.07 C204.79,229.07 204.74,228.79 204.74,228.79 C204.74,228.79 204.73,228.5 204.73,228.5 C204.73,228.5 204.74,228.21 204.74,228.21 C204.74,228.21 204.79,227.92 204.79,227.92 C204.79,227.92 204.85,227.64 204.85,227.64 C204.85,227.64 204.92,227.36 204.92,227.36 C204.92,227.36 204.99,227.08 204.99,227.08 C204.99,227.08 205.06,226.8 205.06,226.8 C205.06,226.8 205.13,226.52 205.13,226.52 C205.13,226.52 205.21,226.24 205.21,226.24 C205.21,226.24 205.28,225.96 205.28,225.96 C205.28,225.96 205.35,225.68 205.35,225.68 C205.35,225.68 205.42,225.39 205.42,225.39 C205.42,225.39 205.47,225.11 205.47,225.11 C205.47,225.11 205.49,224.82 205.49,224.82 C205.49,224.82 205.49,224.53 205.49,224.53 C205.49,224.53 205.46,224.24 205.46,224.24 C205.46,224.24 205.39,223.96 205.39,223.96 C205.39,223.96 205.3,223.69 205.3,223.69 C205.3,223.69 205.19,223.42 205.19,223.42 C205.19,223.42 205.04,223.17 205.04,223.17 C205.04,223.17 204.87,222.93 204.87,222.93 C204.87,222.93 204.68,222.71 204.68,222.71 C204.68,222.71 204.47,222.52 204.47,222.52 C204.47,222.52 204.24,222.34 204.24,222.34 C204.24,222.34 203.99,222.19 203.99,222.19 C203.99,222.19 203.75,222.04 203.75,222.04 C203.75,222.04 203.5,221.89 203.5,221.89 C203.5,221.89 203.25,221.74 203.25,221.74 C203.25,221.74 203,221.59 203,221.59 C203,221.59 202.75,221.45 202.75,221.45 C202.75,221.45 202.5,221.3 202.5,221.3 C202.5,221.3 202.25,221.15 202.25,221.15 C202.25,221.15 202.01,221 202.01,221 C202.01,221 201.77,220.83 201.77,220.83 C201.77,220.83 201.54,220.65 201.54,220.65 C201.54,220.65 201.34,220.45 201.34,220.45 C201.34,220.45 201.16,220.22 201.16,220.22 C201.16,220.22 201,219.98 201,219.98 C201,219.98 200.87,219.72 200.87,219.72 C200.87,219.72 200.76,219.45 200.76,219.45 C200.76,219.45 200.68,219.18 200.68,219.18 C200.68,219.18 200.63,218.89 200.63,218.89 C200.63,218.89 200.61,218.6 200.61,218.6 C200.61,218.6 200.61,218.31 200.61,218.31 C200.61,218.31 200.65,218.02 200.65,218.02 C200.65,218.02 200.72,217.74 200.72,217.74 C200.72,217.74 200.81,217.47 200.81,217.47 C200.81,217.47 200.93,217.21 200.93,217.21 C200.93,217.21 201.07,216.96 201.07,216.96 C201.07,216.96 201.24,216.72 201.24,216.72 C201.24,216.72 201.44,216.51 201.44,216.51 C201.44,216.51 201.65,216.31 201.65,216.31 C201.65,216.31 201.89,216.14 201.89,216.14 C201.89,216.14 202.13,215.99 202.13,215.99 C202.13,215.99 202.38,215.84 202.38,215.84 C202.38,215.84 202.63,215.69 202.63,215.69 C202.63,215.69 202.88,215.54 202.88,215.54 C202.88,215.54 203.13,215.39 203.13,215.39 C203.13,215.39 203.37,215.24 203.37,215.24 C203.37,215.24 203.62,215.09 203.62,215.09 C203.62,215.09 203.87,214.94 203.87,214.94 C203.87,214.94 204.12,214.79 204.12,214.79 C204.12,214.79 204.36,214.63 204.36,214.63 C204.36,214.63 204.58,214.45 204.58,214.45 C204.58,214.45 204.78,214.24 204.78,214.24 C204.78,214.24 204.96,214.01 204.96,214.01 C204.96,214.01 205.12,213.77 205.12,213.77 C205.12,213.77 205.25,213.51 205.25,213.51 C205.25,213.51 205.35,213.24 205.35,213.24 C205.35,213.24 205.43,212.96 205.43,212.96 C205.43,212.96 205.48,212.67 205.48,212.67 C205.48,212.67 205.5,212.38 205.5,212.38 C205.5,212.38 205.49,212.09 205.49,212.09 C205.49,212.09 205.44,211.81 205.44,211.81 C205.44,211.81 205.38,211.52 205.38,211.52 C205.38,211.52 205.31,211.24 205.31,211.24 C205.31,211.24 205.24,210.96 205.24,210.96 C205.24,210.96 205.17,210.68 205.17,210.68 C205.17,210.68 205.1,210.4 205.1,210.4 C205.1,210.4 205.03,210.12 205.03,210.12 C205.03,210.12 204.96,209.84 204.96,209.84 C204.96,209.84 204.89,209.56 204.89,209.56 C204.89,209.56 204.82,209.28 204.82,209.28 C204.82,209.28 204.76,208.99 204.76,208.99 C204.76,208.99 204.74,208.7 204.74,208.7 C204.74,208.7 204.74,208.42 204.74,208.42 C204.74,208.42 204.76,208.13 204.76,208.13 C204.76,208.13 204.82,207.84 204.82,207.84 C204.82,207.84 204.91,207.57 204.91,207.57 C204.91,207.57 205.03,207.3 205.03,207.3 C205.03,207.3 205.17,207.05 205.17,207.05 C205.17,207.05 205.34,206.81 205.34,206.81 C205.34,206.81 205.52,206.59 205.52,206.59 C205.52,206.59 205.73,206.39 205.73,206.39 C205.73,206.39 205.96,206.22 205.96,206.22 C205.96,206.22 206.21,206.06 206.21,206.06 C206.21,206.06 206.47,205.94 206.47,205.94 C206.47,205.94 206.74,205.83 206.74,205.83 C206.74,205.83 207.02,205.76 207.02,205.76 C207.02,205.76 207.3,205.71 207.3,205.71 C207.3,205.71 207.59,205.7 207.59,205.7 C207.59,205.7 207.88,205.71 207.88,205.71 C207.88,205.71 208.17,205.76 208.17,205.76 C208.17,205.76 208.45,205.82 208.45,205.82 C208.45,205.82 208.73,205.89 208.73,205.89 C208.73,205.89 209.01,205.96 209.01,205.96 C209.01,205.96 209.29,206.03 209.29,206.03 C209.29,206.03 209.57,206.1 209.57,206.1 C209.57,206.1 209.85,206.17 209.85,206.17 C209.85,206.17 210.14,206.24 210.14,206.24 C210.14,206.24 210.42,206.31 210.42,206.31 C210.42,206.31 210.7,206.38 210.7,206.38 C210.7,206.38 210.98,206.44 210.98,206.44 C210.98,206.44 211.27,206.46 211.27,206.46 C211.27,206.46 211.56,206.46 211.56,206.46 C211.56,206.46 211.85,206.43 211.85,206.43 C211.85,206.43 212.13,206.36 212.13,206.36 C212.13,206.36 212.41,206.27 212.41,206.27 C212.41,206.27 212.67,206.15 212.67,206.15 C212.67,206.15 212.92,206.01 212.92,206.01 C212.92,206.01 213.16,205.84 213.16,205.84 C213.16,205.84 213.38,205.65 213.38,205.65 C213.38,205.65 213.57,205.44 213.57,205.44 C213.57,205.44 213.75,205.21 213.75,205.21 C213.75,205.21 213.9,204.96 213.9,204.96 C213.9,204.96 214.05,204.71 214.05,204.71 C214.05,204.71 214.2,204.47 214.2,204.47 C214.2,204.47 214.35,204.22 214.35,204.22 C214.35,204.22 214.5,203.97 214.5,203.97 C214.5,203.97 214.65,203.72 214.65,203.72 C214.65,203.72 214.8,203.47 214.8,203.47 C214.8,203.47 214.94,203.22 214.94,203.22 C214.94,203.22 215.1,202.97 215.1,202.97 C215.1,202.97 215.26,202.73 215.26,202.73 C215.26,202.73 215.44,202.51 215.44,202.51 C215.44,202.51 215.65,202.31 215.65,202.31 C215.65,202.31 215.87,202.12 215.87,202.12 C215.87,202.12 216.11,201.96 216.11,201.96 C216.11,201.96 216.37,201.83 216.37,201.83 C216.37,201.83 216.64,201.73 216.64,201.73 C216.64,201.73 216.92,201.65 216.92,201.65 C216.92,201.65 217.21,201.6 217.21,201.6 C217.21,201.6 217.49,201.58 217.49,201.58 C217.49,201.58 217.78,201.58 217.78,201.58c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="67" android:valueFrom="M217.78 201.58 C217.78,201.58 218.07,201.62 218.07,201.62 C218.07,201.62 218.35,201.69 218.35,201.69 C218.35,201.69 218.63,201.78 218.63,201.78 C218.63,201.78 218.89,201.9 218.89,201.9 C218.89,201.9 219.14,202.04 219.14,202.04 C219.14,202.04 219.38,202.21 219.38,202.21 C219.38,202.21 219.59,202.41 219.59,202.41 C219.59,202.41 219.78,202.62 219.78,202.62 C219.78,202.62 219.95,202.86 219.95,202.86 C219.95,202.86 220.11,203.1 220.11,203.1 C220.11,203.1 220.26,203.35 220.26,203.35 C220.26,203.35 220.41,203.6 220.41,203.6 C220.41,203.6 220.55,203.85 220.55,203.85 C220.55,203.85 220.7,204.1 220.7,204.1 C220.7,204.1 220.85,204.35 220.85,204.35 C220.85,204.35 221,204.59 221,204.59 C221,204.59 221.15,204.84 221.15,204.84 C221.15,204.84 221.3,205.09 221.3,205.09 C221.3,205.09 221.46,205.33 221.46,205.33 C221.46,205.33 221.65,205.55 221.65,205.55 C221.65,205.55 221.86,205.75 221.86,205.75 C221.86,205.75 222.09,205.93 222.09,205.93 C222.09,205.93 222.33,206.09 222.33,206.09 C222.33,206.09 222.59,206.22 222.59,206.22 C222.59,206.22 222.86,206.32 222.86,206.32 C222.86,206.32 223.14,206.4 223.14,206.4 C223.14,206.4 223.42,206.45 223.42,206.45 C223.42,206.45 223.71,206.46 223.71,206.46 C223.71,206.46 224,206.45 224,206.45 C224,206.45 224.29,206.41 224.29,206.41 C224.29,206.41 224.57,206.35 224.57,206.35 C224.57,206.35 224.85,206.28 224.85,206.28 C224.85,206.28 225.13,206.21 225.13,206.21 C225.13,206.21 225.41,206.14 225.41,206.14 C225.41,206.14 225.7,206.07 225.7,206.07 C225.7,206.07 225.98,206 225.98,206 C225.98,206 226.26,205.93 226.26,205.93 C226.26,205.93 226.54,205.86 226.54,205.86 C226.54,205.86 226.82,205.78 226.82,205.78 C226.82,205.78 227.1,205.73 227.1,205.73 C227.1,205.73 227.39,205.71 227.39,205.71 C227.39,205.71 227.68,205.7 227.68,205.7 C227.68,205.7 227.97,205.73 227.97,205.73 C227.97,205.73 228.25,205.79 228.25,205.79 C228.25,205.79 228.53,205.88 228.53,205.88 C228.53,205.88 228.79,206 228.79,206 C228.79,206 229.04,206.14 229.04,206.14 C229.04,206.14 229.28,206.31 229.28,206.31 C229.28,206.31 229.5,206.49 229.5,206.49 C229.5,206.49 229.7,206.7 229.7,206.7 C229.7,206.7 229.88,206.93 229.88,206.93 C229.88,206.93 230.03,207.18 230.03,207.18 C230.03,207.18 230.16,207.44 230.16,207.44 C230.16,207.44 230.26,207.71 230.26,207.71 C230.26,207.71 230.34,207.99 230.34,207.99 C230.34,207.99 230.38,208.27 230.38,208.27 C230.38,208.27 230.39,208.56 230.39,208.56 C230.39,208.56 230.38,208.85 230.38,208.85 C230.38,208.85 230.33,209.14 230.33,209.14 C230.33,209.14 230.27,209.42 230.27,209.42 C230.27,209.42 230.2,209.7 230.2,209.7 C230.2,209.7 230.13,209.98 230.13,209.98 C230.13,209.98 230.06,210.26 230.06,210.26 C230.06,210.26 229.99,210.55 229.99,210.55 C229.99,210.55 229.92,210.83 229.92,210.83 C229.92,210.83 229.85,211.11 229.85,211.11 C229.85,211.11 229.78,211.39 229.78,211.39 C229.78,211.39 229.71,211.67 229.71,211.67 C229.71,211.67 229.66,211.95 229.66,211.95 C229.66,211.95 229.63,212.24 229.63,212.24 C229.63,212.24 229.64,212.53 229.64,212.53 C229.64,212.53 229.67,212.82 229.67,212.82 C229.67,212.82 229.73,213.1 229.73,213.1 C229.73,213.1 229.82,213.38 229.82,213.38 C229.82,213.38 229.94,213.64 229.94,213.64 C229.94,213.64 230.08,213.89 230.08,213.89 C230.08,213.89 230.25,214.13 230.25,214.13 C230.25,214.13 230.44,214.35 230.44,214.35 C230.44,214.35 230.66,214.54 230.66,214.54 C230.66,214.54 230.89,214.72 230.89,214.72 C230.89,214.72 231.13,214.87 231.13,214.87 C231.13,214.87 231.38,215.02 231.38,215.02 C231.38,215.02 231.63,215.17 231.63,215.17 C231.63,215.17 231.88,215.32 231.88,215.32 C231.88,215.32 232.13,215.47 232.13,215.47 C232.13,215.47 232.38,215.62 232.38,215.62 C232.38,215.62 232.62,215.77 232.62,215.77 C232.62,215.77 232.87,215.91 232.87,215.91 C232.87,215.91 233.12,216.06 233.12,216.06 C233.12,216.06 233.36,216.23 233.36,216.23 C233.36,216.23 233.58,216.41 233.58,216.41 C233.58,216.41 233.79,216.62 233.79,216.62 C233.79,216.62 233.97,216.84 233.97,216.84 C233.97,216.84 234.13,217.08 234.13,217.08 C234.13,217.08 234.26,217.34 234.26,217.34 C234.26,217.34 234.36,217.61 234.36,217.61 C234.36,217.61 234.44,217.89 234.44,217.89 C234.44,217.89 234.49,218.17 234.49,218.17 C234.49,218.17 234.52,218.46 234.52,218.46 C234.52,218.46 234.51,218.75 234.51,218.75 C234.51,218.75 234.47,219.04 234.47,219.04 C234.47,219.04 234.41,219.32 234.41,219.32 C234.41,219.32 234.31,219.59 234.31,219.59 C234.31,219.59 234.19,219.86 234.19,219.86 C234.19,219.86 234.05,220.11 234.05,220.11 C234.05,220.11 233.88,220.34 233.88,220.34 C233.88,220.34 233.68,220.56 233.68,220.56 C233.68,220.56 233.47,220.75 233.47,220.75 C233.47,220.75 233.23,220.92 233.23,220.92 C233.23,220.92 232.99,221.08 232.99,221.08 C232.99,221.08 232.74,221.22 232.74,221.22 C232.74,221.22 232.49,221.37 232.49,221.37 C232.49,221.37 232.25,221.52 232.25,221.52 C232.25,221.52 232,221.67 232,221.67 C232,221.67 231.75,221.82 231.75,221.82 C231.75,221.82 231.5,221.97 231.5,221.97 C231.5,221.97 231.25,222.12 231.25,222.12 C231.25,222.12 231,222.27 231,222.27 C231,222.27 230.76,222.43 230.76,222.43 C230.76,222.43 230.54,222.62 230.54,222.62 C230.54,222.62 230.34,222.83 230.34,222.83 C230.34,222.83 230.16,223.05 230.16,223.05 C230.16,223.05 230.01,223.3 230.01,223.3 C230.01,223.3 229.87,223.56 229.87,223.56 C229.87,223.56 229.77,223.83 229.77,223.83 C229.77,223.83 229.7,224.11 229.7,224.11 C229.7,224.11 229.65,224.39 229.65,224.39 C229.65,224.39 229.63,224.68 229.63,224.68 C229.63,224.68 229.64,224.97 229.64,224.97 C229.64,224.97 229.68,225.26 229.68,225.26 C229.68,225.26 229.75,225.54 229.75,225.54 C229.75,225.54 229.82,225.82 229.82,225.82 C229.82,225.82 229.89,226.1 229.89,226.1 C229.89,226.1 229.96,226.38 229.96,226.38 C229.96,226.38 230.03,226.66 230.03,226.66 C230.03,226.66 230.1,226.94 230.1,226.94 C230.1,226.94 230.17,227.22 230.17,227.22 C230.17,227.22 230.24,227.51 230.24,227.51 C230.24,227.51 230.31,227.79 230.31,227.79 C230.31,227.79 230.36,228.07 230.36,228.07 C230.36,228.07 230.39,228.36 230.39,228.36 C230.39,228.36 230.39,228.65 230.39,228.65 C230.39,228.65 230.36,228.94 230.36,228.94 C230.36,228.94 230.3,229.22 230.3,229.22 C230.3,229.22 230.21,229.5 230.21,229.5 C230.21,229.5 230.1,229.76 230.1,229.76 C230.1,229.76 229.95,230.01 229.95,230.01 C229.95,230.01 229.79,230.25 229.79,230.25 C229.79,230.25 229.6,230.47 229.6,230.47 C229.6,230.47 229.39,230.67 229.39,230.67 C229.39,230.67 229.16,230.85 229.16,230.85 C229.16,230.85 228.91,231 228.91,231 C228.91,231 228.66,231.13 228.66,231.13 C228.66,231.13 228.38,231.23 228.38,231.23 C228.38,231.23 228.11,231.3 228.11,231.3 C228.11,231.3 227.82,231.35 227.82,231.35 C227.82,231.35 227.53,231.36 227.53,231.36 C227.53,231.36 227.24,231.35 227.24,231.35 C227.24,231.35 226.96,231.3 226.96,231.3 C226.96,231.3 226.67,231.24 226.67,231.24 C226.67,231.24 226.39,231.17 226.39,231.17 C226.39,231.17 226.11,231.1 226.11,231.1 C226.11,231.1 225.83,231.03 225.83,231.03 C225.83,231.03 225.55,230.96 225.55,230.96 C225.55,230.96 225.27,230.89 225.27,230.89 C225.27,230.89 224.99,230.82 224.99,230.82 C224.99,230.82 224.71,230.75 224.71,230.75 C224.71,230.75 224.42,230.68 224.42,230.68 C224.42,230.68 224.14,230.62 224.14,230.62 C224.14,230.62 223.85,230.6 223.85,230.6 C223.85,230.6 223.56,230.6 223.56,230.6 C223.56,230.6 223.27,230.64 223.27,230.64 C223.27,230.64 222.99,230.7 222.99,230.7 C222.99,230.7 222.72,230.79 222.72,230.79 C222.72,230.79 222.45,230.91 222.45,230.91 C222.45,230.91 222.2,231.05 222.2,231.05 C222.2,231.05 221.96,231.22 221.96,231.22 C221.96,231.22 221.75,231.41 221.75,231.41 C221.75,231.41 221.55,231.62 221.55,231.62 C221.55,231.62 221.38,231.85 221.38,231.85 C221.38,231.85 221.22,232.1 221.22,232.1 C221.22,232.1 221.07,232.35 221.07,232.35 C221.07,232.35 220.92,232.6 220.92,232.6 C220.92,232.6 220.77,232.85 220.77,232.85 C220.77,232.85 220.63,233.09 220.63,233.09 C220.63,233.09 220.48,233.34 220.48,233.34 C220.48,233.34 220.33,233.59 220.33,233.59 C220.33,233.59 220.18,233.84 220.18,233.84 C220.18,233.84 220.03,234.09 220.03,234.09 C220.03,234.09 219.87,234.33 219.87,234.33 C219.87,234.33 219.68,234.55 219.68,234.55 C219.68,234.55 219.48,234.75 219.48,234.75 C219.48,234.75 219.25,234.94 219.25,234.94 C219.25,234.94 219.01,235.1 219.01,235.1 C219.01,235.1 218.75,235.23 218.75,235.23 C218.75,235.23 218.48,235.33 218.48,235.33 C218.48,235.33 218.21,235.41 218.21,235.41 C218.21,235.41 217.92,235.46 217.92,235.46 C217.92,235.46 217.63,235.48 217.63,235.48 C217.63,235.48 217.34,235.48 217.34,235.48 C217.34,235.48 217.06,235.44 217.06,235.44 C217.06,235.44 216.77,235.37 216.77,235.37 C216.77,235.37 216.5,235.28 216.5,235.28 C216.5,235.28 216.24,235.16 216.24,235.16 C216.24,235.16 215.99,235.02 215.99,235.02 C215.99,235.02 215.75,234.85 215.75,234.85 C215.75,234.85 215.54,234.65 215.54,234.65 C215.54,234.65 215.34,234.44 215.34,234.44 C215.34,234.44 215.17,234.2 215.17,234.2 C215.17,234.2 215.02,233.96 215.02,233.96 C215.02,233.96 214.87,233.71 214.87,233.71 C214.87,233.71 214.72,233.46 214.72,233.46 C214.72,233.46 214.57,233.21 214.57,233.21 C214.57,233.21 214.42,232.96 214.42,232.96 C214.42,232.96 214.27,232.72 214.27,232.72 C214.27,232.72 214.12,232.47 214.12,232.47 C214.12,232.47 213.98,232.22 213.98,232.22 C213.98,232.22 213.83,231.97 213.83,231.97 C213.83,231.97 213.66,231.73 213.66,231.73 C213.66,231.73 213.48,231.51 213.48,231.51 C213.48,231.51 213.27,231.31 213.27,231.31 C213.27,231.31 213.04,231.13 213.04,231.13 C213.04,231.13 212.8,230.97 212.8,230.97 C212.8,230.97 212.54,230.84 212.54,230.84 C212.54,230.84 212.27,230.74 212.27,230.74 C212.27,230.74 211.99,230.66 211.99,230.66 C211.99,230.66 211.7,230.62 211.7,230.62 C211.7,230.62 211.41,230.6 211.41,230.6 C211.41,230.6 211.12,230.61 211.12,230.61 C211.12,230.61 210.84,230.65 210.84,230.65 C210.84,230.65 210.56,230.71 210.56,230.71 C210.56,230.71 210.27,230.78 210.27,230.78 C210.27,230.78 209.99,230.85 209.99,230.85 C209.99,230.85 209.71,230.92 209.71,230.92 C209.71,230.92 209.43,230.99 209.43,230.99 C209.43,230.99 209.15,231.06 209.15,231.06 C209.15,231.06 208.87,231.14 208.87,231.14 C208.87,231.14 208.59,231.21 208.59,231.21 C208.59,231.21 208.31,231.28 208.31,231.28 C208.31,231.28 208.02,231.33 208.02,231.33 C208.02,231.33 207.73,231.36 207.73,231.36 C207.73,231.36 207.45,231.36 207.45,231.36 C207.45,231.36 207.16,231.33 207.16,231.33 C207.16,231.33 206.87,231.27 206.87,231.27 C206.87,231.27 206.6,231.18 206.6,231.18 C206.6,231.18 206.33,231.06 206.33,231.06 C206.33,231.06 206.08,230.92 206.08,230.92 C206.08,230.92 205.85,230.76 205.85,230.76 C205.85,230.76 205.62,230.57 205.62,230.57 C205.62,230.57 205.42,230.36 205.42,230.36 C205.42,230.36 205.25,230.13 205.25,230.13 C205.25,230.13 205.1,229.88 205.1,229.88 C205.1,229.88 204.97,229.62 204.97,229.62 C204.97,229.62 204.87,229.35 204.87,229.35 C204.87,229.35 204.79,229.07 204.79,229.07 C204.79,229.07 204.74,228.79 204.74,228.79 C204.74,228.79 204.73,228.5 204.73,228.5 C204.73,228.5 204.74,228.21 204.74,228.21 C204.74,228.21 204.79,227.92 204.79,227.92 C204.79,227.92 204.85,227.64 204.85,227.64 C204.85,227.64 204.92,227.36 204.92,227.36 C204.92,227.36 204.99,227.08 204.99,227.08 C204.99,227.08 205.06,226.8 205.06,226.8 C205.06,226.8 205.13,226.52 205.13,226.52 C205.13,226.52 205.21,226.24 205.21,226.24 C205.21,226.24 205.28,225.96 205.28,225.96 C205.28,225.96 205.35,225.68 205.35,225.68 C205.35,225.68 205.42,225.39 205.42,225.39 C205.42,225.39 205.47,225.11 205.47,225.11 C205.47,225.11 205.49,224.82 205.49,224.82 C205.49,224.82 205.49,224.53 205.49,224.53 C205.49,224.53 205.46,224.24 205.46,224.24 C205.46,224.24 205.39,223.96 205.39,223.96 C205.39,223.96 205.3,223.69 205.3,223.69 C205.3,223.69 205.19,223.42 205.19,223.42 C205.19,223.42 205.04,223.17 205.04,223.17 C205.04,223.17 204.87,222.93 204.87,222.93 C204.87,222.93 204.68,222.71 204.68,222.71 C204.68,222.71 204.47,222.52 204.47,222.52 C204.47,222.52 204.24,222.34 204.24,222.34 C204.24,222.34 203.99,222.19 203.99,222.19 C203.99,222.19 203.75,222.04 203.75,222.04 C203.75,222.04 203.5,221.89 203.5,221.89 C203.5,221.89 203.25,221.74 203.25,221.74 C203.25,221.74 203,221.59 203,221.59 C203,221.59 202.75,221.45 202.75,221.45 C202.75,221.45 202.5,221.3 202.5,221.3 C202.5,221.3 202.25,221.15 202.25,221.15 C202.25,221.15 202.01,221 202.01,221 C202.01,221 201.77,220.83 201.77,220.83 C201.77,220.83 201.54,220.65 201.54,220.65 C201.54,220.65 201.34,220.45 201.34,220.45 C201.34,220.45 201.16,220.22 201.16,220.22 C201.16,220.22 201,219.98 201,219.98 C201,219.98 200.87,219.72 200.87,219.72 C200.87,219.72 200.76,219.45 200.76,219.45 C200.76,219.45 200.68,219.18 200.68,219.18 C200.68,219.18 200.63,218.89 200.63,218.89 C200.63,218.89 200.61,218.6 200.61,218.6 C200.61,218.6 200.61,218.31 200.61,218.31 C200.61,218.31 200.65,218.02 200.65,218.02 C200.65,218.02 200.72,217.74 200.72,217.74 C200.72,217.74 200.81,217.47 200.81,217.47 C200.81,217.47 200.93,217.21 200.93,217.21 C200.93,217.21 201.07,216.96 201.07,216.96 C201.07,216.96 201.24,216.72 201.24,216.72 C201.24,216.72 201.44,216.51 201.44,216.51 C201.44,216.51 201.65,216.31 201.65,216.31 C201.65,216.31 201.89,216.14 201.89,216.14 C201.89,216.14 202.13,215.99 202.13,215.99 C202.13,215.99 202.38,215.84 202.38,215.84 C202.38,215.84 202.63,215.69 202.63,215.69 C202.63,215.69 202.88,215.54 202.88,215.54 C202.88,215.54 203.13,215.39 203.13,215.39 C203.13,215.39 203.37,215.24 203.37,215.24 C203.37,215.24 203.62,215.09 203.62,215.09 C203.62,215.09 203.87,214.94 203.87,214.94 C203.87,214.94 204.12,214.79 204.12,214.79 C204.12,214.79 204.36,214.63 204.36,214.63 C204.36,214.63 204.58,214.45 204.58,214.45 C204.58,214.45 204.78,214.24 204.78,214.24 C204.78,214.24 204.96,214.01 204.96,214.01 C204.96,214.01 205.12,213.77 205.12,213.77 C205.12,213.77 205.25,213.51 205.25,213.51 C205.25,213.51 205.35,213.24 205.35,213.24 C205.35,213.24 205.43,212.96 205.43,212.96 C205.43,212.96 205.48,212.67 205.48,212.67 C205.48,212.67 205.5,212.38 205.5,212.38 C205.5,212.38 205.49,212.09 205.49,212.09 C205.49,212.09 205.44,211.81 205.44,211.81 C205.44,211.81 205.38,211.52 205.38,211.52 C205.38,211.52 205.31,211.24 205.31,211.24 C205.31,211.24 205.24,210.96 205.24,210.96 C205.24,210.96 205.17,210.68 205.17,210.68 C205.17,210.68 205.1,210.4 205.1,210.4 C205.1,210.4 205.03,210.12 205.03,210.12 C205.03,210.12 204.96,209.84 204.96,209.84 C204.96,209.84 204.89,209.56 204.89,209.56 C204.89,209.56 204.82,209.28 204.82,209.28 C204.82,209.28 204.76,208.99 204.76,208.99 C204.76,208.99 204.74,208.7 204.74,208.7 C204.74,208.7 204.74,208.42 204.74,208.42 C204.74,208.42 204.76,208.13 204.76,208.13 C204.76,208.13 204.82,207.84 204.82,207.84 C204.82,207.84 204.91,207.57 204.91,207.57 C204.91,207.57 205.03,207.3 205.03,207.3 C205.03,207.3 205.17,207.05 205.17,207.05 C205.17,207.05 205.34,206.81 205.34,206.81 C205.34,206.81 205.52,206.59 205.52,206.59 C205.52,206.59 205.73,206.39 205.73,206.39 C205.73,206.39 205.96,206.22 205.96,206.22 C205.96,206.22 206.21,206.06 206.21,206.06 C206.21,206.06 206.47,205.94 206.47,205.94 C206.47,205.94 206.74,205.83 206.74,205.83 C206.74,205.83 207.02,205.76 207.02,205.76 C207.02,205.76 207.3,205.71 207.3,205.71 C207.3,205.71 207.59,205.7 207.59,205.7 C207.59,205.7 207.88,205.71 207.88,205.71 C207.88,205.71 208.17,205.76 208.17,205.76 C208.17,205.76 208.45,205.82 208.45,205.82 C208.45,205.82 208.73,205.89 208.73,205.89 C208.73,205.89 209.01,205.96 209.01,205.96 C209.01,205.96 209.29,206.03 209.29,206.03 C209.29,206.03 209.57,206.1 209.57,206.1 C209.57,206.1 209.85,206.17 209.85,206.17 C209.85,206.17 210.14,206.24 210.14,206.24 C210.14,206.24 210.42,206.31 210.42,206.31 C210.42,206.31 210.7,206.38 210.7,206.38 C210.7,206.38 210.98,206.44 210.98,206.44 C210.98,206.44 211.27,206.46 211.27,206.46 C211.27,206.46 211.56,206.46 211.56,206.46 C211.56,206.46 211.85,206.43 211.85,206.43 C211.85,206.43 212.13,206.36 212.13,206.36 C212.13,206.36 212.41,206.27 212.41,206.27 C212.41,206.27 212.67,206.15 212.67,206.15 C212.67,206.15 212.92,206.01 212.92,206.01 C212.92,206.01 213.16,205.84 213.16,205.84 C213.16,205.84 213.38,205.65 213.38,205.65 C213.38,205.65 213.57,205.44 213.57,205.44 C213.57,205.44 213.75,205.21 213.75,205.21 C213.75,205.21 213.9,204.96 213.9,204.96 C213.9,204.96 214.05,204.71 214.05,204.71 C214.05,204.71 214.2,204.47 214.2,204.47 C214.2,204.47 214.35,204.22 214.35,204.22 C214.35,204.22 214.5,203.97 214.5,203.97 C214.5,203.97 214.65,203.72 214.65,203.72 C214.65,203.72 214.8,203.47 214.8,203.47 C214.8,203.47 214.94,203.22 214.94,203.22 C214.94,203.22 215.1,202.97 215.1,202.97 C215.1,202.97 215.26,202.73 215.26,202.73 C215.26,202.73 215.44,202.51 215.44,202.51 C215.44,202.51 215.65,202.31 215.65,202.31 C215.65,202.31 215.87,202.12 215.87,202.12 C215.87,202.12 216.11,201.96 216.11,201.96 C216.11,201.96 216.37,201.83 216.37,201.83 C216.37,201.83 216.64,201.73 216.64,201.73 C216.64,201.73 216.92,201.65 216.92,201.65 C216.92,201.65 217.21,201.6 217.21,201.6 C217.21,201.6 217.49,201.58 217.49,201.58 C217.49,201.58 217.78,201.58 217.78,201.58c " android:valueTo="M217.68 210.56 C217.68,210.56 217.81,210.57 217.81,210.57 C217.81,210.57 217.93,210.57 217.93,210.57 C217.93,210.57 218.06,210.58 218.06,210.58 C218.06,210.58 218.18,210.59 218.18,210.59 C218.18,210.59 218.31,210.59 218.31,210.59 C218.31,210.59 218.43,210.61 218.43,210.61 C218.43,210.61 218.56,210.63 218.56,210.63 C218.56,210.63 218.68,210.64 218.68,210.64 C218.68,210.64 218.81,210.66 218.81,210.66 C218.81,210.66 218.93,210.68 218.93,210.68 C218.93,210.68 219.05,210.7 219.05,210.7 C219.05,210.7 219.18,210.72 219.18,210.72 C219.18,210.72 219.3,210.75 219.3,210.75 C219.3,210.75 219.42,210.78 219.42,210.78 C219.42,210.78 219.54,210.81 219.54,210.81 C219.54,210.81 219.66,210.84 219.66,210.84 C219.66,210.84 219.79,210.87 219.79,210.87 C219.79,210.87 219.91,210.91 219.91,210.91 C219.91,210.91 220.03,210.95 220.03,210.95 C220.03,210.95 220.14,210.99 220.14,210.99 C220.14,210.99 220.26,211.04 220.26,211.04 C220.26,211.04 220.38,211.08 220.38,211.08 C220.38,211.08 220.5,211.12 220.5,211.12 C220.5,211.12 220.62,211.17 220.62,211.17 C220.62,211.17 220.73,211.22 220.73,211.22 C220.73,211.22 220.84,211.27 220.84,211.27 C220.84,211.27 220.96,211.32 220.96,211.32 C220.96,211.32 221.07,211.38 221.07,211.38 C221.07,211.38 221.19,211.43 221.19,211.43 C221.19,211.43 221.3,211.49 221.3,211.49 C221.3,211.49 221.41,211.55 221.41,211.55 C221.41,211.55 221.51,211.61 221.51,211.61 C221.51,211.61 221.62,211.68 221.62,211.68 C221.62,211.68 221.73,211.74 221.73,211.74 C221.73,211.74 221.84,211.8 221.84,211.8 C221.84,211.8 221.94,211.87 221.94,211.87 C221.94,211.87 222.05,211.94 222.05,211.94 C222.05,211.94 222.15,212.02 222.15,212.02 C222.15,212.02 222.25,212.09 222.25,212.09 C222.25,212.09 222.35,212.16 222.35,212.16 C222.35,212.16 222.46,212.23 222.46,212.23 C222.46,212.23 222.55,212.31 222.55,212.31 C222.55,212.31 222.65,212.4 222.65,212.4 C222.65,212.4 222.74,212.48 222.74,212.48 C222.74,212.48 222.84,212.56 222.84,212.56 C222.84,212.56 222.93,212.64 222.93,212.64 C222.93,212.64 223.03,212.72 223.03,212.72 C223.03,212.72 223.12,212.81 223.12,212.81 C223.12,212.81 223.21,212.9 223.21,212.9 C223.21,212.9 223.29,212.99 223.29,212.99 C223.29,212.99 223.38,213.08 223.38,213.08 C223.38,213.08 223.47,213.17 223.47,213.17 C223.47,213.17 223.55,213.26 223.55,213.26 C223.55,213.26 223.63,213.36 223.63,213.36 C223.63,213.36 223.71,213.46 223.71,213.46 C223.71,213.46 223.79,213.56 223.79,213.56 C223.79,213.56 223.87,213.66 223.87,213.66 C223.87,213.66 223.95,213.75 223.95,213.75 C223.95,213.75 224.03,213.85 224.03,213.85 C224.03,213.85 224.09,213.96 224.09,213.96 C224.09,213.96 224.16,214.06 224.16,214.06 C224.16,214.06 224.23,214.17 224.23,214.17 C224.23,214.17 224.3,214.27 224.3,214.27 C224.3,214.27 224.37,214.38 224.37,214.38 C224.37,214.38 224.44,214.48 224.44,214.48 C224.44,214.48 224.5,214.59 224.5,214.59 C224.5,214.59 224.56,214.7 224.56,214.7 C224.56,214.7 224.62,214.81 224.62,214.81 C224.62,214.81 224.68,214.93 224.68,214.93 C224.68,214.93 224.74,215.04 224.74,215.04 C224.74,215.04 224.79,215.15 224.79,215.15 C224.79,215.15 224.84,215.26 224.84,215.26 C224.84,215.26 224.89,215.38 224.89,215.38 C224.89,215.38 224.94,215.5 224.94,215.5 C224.94,215.5 224.99,215.61 224.99,215.61 C224.99,215.61 225.04,215.73 225.04,215.73 C225.04,215.73 225.08,215.84 225.08,215.84 C225.08,215.84 225.12,215.96 225.12,215.96 C225.12,215.96 225.16,216.08 225.16,216.08 C225.16,216.08 225.19,216.2 225.19,216.2 C225.19,216.2 225.23,216.32 225.23,216.32 C225.23,216.32 225.27,216.44 225.27,216.44 C225.27,216.44 225.3,216.56 225.3,216.56 C225.3,216.56 225.33,216.69 225.33,216.69 C225.33,216.69 225.35,216.81 225.35,216.81 C225.35,216.81 225.38,216.93 225.38,216.93 C225.38,216.93 225.41,217.06 225.41,217.06 C225.41,217.06 225.43,217.18 225.43,217.18 C225.43,217.18 225.46,217.3 225.46,217.3 C225.46,217.3 225.47,217.43 225.47,217.43 C225.47,217.43 225.49,217.55 225.49,217.55 C225.49,217.55 225.5,217.68 225.5,217.68 C225.5,217.68 225.52,217.8 225.52,217.8 C225.52,217.8 225.52,217.93 225.52,217.93 C225.52,217.93 225.53,218.05 225.53,218.05 C225.53,218.05 225.54,218.18 225.54,218.18 C225.54,218.18 225.54,218.3 225.54,218.3 C225.54,218.3 225.55,218.43 225.55,218.43 C225.55,218.43 225.55,218.55 225.55,218.55 C225.55,218.55 225.55,218.68 225.55,218.68 C225.55,218.68 225.54,218.8 225.54,218.8 C225.54,218.8 225.54,218.93 225.54,218.93 C225.54,218.93 225.53,219.05 225.53,219.05 C225.53,219.05 225.52,219.18 225.52,219.18 C225.52,219.18 225.52,219.31 225.52,219.31 C225.52,219.31 225.5,219.43 225.5,219.43 C225.5,219.43 225.48,219.55 225.48,219.55 C225.48,219.55 225.47,219.68 225.47,219.68 C225.47,219.68 225.45,219.8 225.45,219.8 C225.45,219.8 225.43,219.93 225.43,219.93 C225.43,219.93 225.41,220.05 225.41,220.05 C225.41,220.05 225.39,220.17 225.39,220.17 C225.39,220.17 225.36,220.3 225.36,220.3 C225.36,220.3 225.33,220.42 225.33,220.42 C225.33,220.42 225.3,220.54 225.3,220.54 C225.3,220.54 225.27,220.66 225.27,220.66 C225.27,220.66 225.24,220.78 225.24,220.78 C225.24,220.78 225.2,220.9 225.2,220.9 C225.2,220.9 225.16,221.02 225.16,221.02 C225.16,221.02 225.12,221.14 225.12,221.14 C225.12,221.14 225.08,221.26 225.08,221.26 C225.08,221.26 225.03,221.38 225.03,221.38 C225.03,221.38 224.99,221.5 224.99,221.5 C224.99,221.5 224.95,221.61 224.95,221.61 C224.95,221.61 224.89,221.73 224.89,221.73 C224.89,221.73 224.84,221.84 224.84,221.84 C224.84,221.84 224.79,221.96 224.79,221.96 C224.79,221.96 224.73,222.07 224.73,222.07 C224.73,222.07 224.68,222.18 224.68,222.18 C224.68,222.18 224.62,222.29 224.62,222.29 C224.62,222.29 224.56,222.4 224.56,222.4 C224.56,222.4 224.5,222.51 224.5,222.51 C224.5,222.51 224.44,222.62 224.44,222.62 C224.44,222.62 224.37,222.73 224.37,222.73 C224.37,222.73 224.31,222.84 224.31,222.84 C224.31,222.84 224.24,222.94 224.24,222.94 C224.24,222.94 224.17,223.05 224.17,223.05 C224.17,223.05 224.09,223.15 224.09,223.15 C224.09,223.15 224.02,223.25 224.02,223.25 C224.02,223.25 223.95,223.35 223.95,223.35 C223.95,223.35 223.88,223.45 223.88,223.45 C223.88,223.45 223.8,223.55 223.8,223.55 C223.8,223.55 223.71,223.65 223.71,223.65 C223.71,223.65 223.63,223.74 223.63,223.74 C223.63,223.74 223.55,223.84 223.55,223.84 C223.55,223.84 223.47,223.93 223.47,223.93 C223.47,223.93 223.39,224.03 223.39,224.03 C223.39,224.03 223.3,224.12 223.3,224.12 C223.3,224.12 223.21,224.2 223.21,224.2 C223.21,224.2 223.12,224.29 223.12,224.29 C223.12,224.29 223.03,224.38 223.03,224.38 C223.03,224.38 222.94,224.46 222.94,224.46 C222.94,224.46 222.85,224.55 222.85,224.55 C222.85,224.55 222.75,224.63 222.75,224.63 C222.75,224.63 222.65,224.71 222.65,224.71 C222.65,224.71 222.55,224.79 222.55,224.79 C222.55,224.79 222.46,224.87 222.46,224.87 C222.46,224.87 222.36,224.95 222.36,224.95 C222.36,224.95 222.26,225.02 222.26,225.02 C222.26,225.02 222.15,225.09 222.15,225.09 C222.15,225.09 222.05,225.16 222.05,225.16 C222.05,225.16 221.94,225.23 221.94,225.23 C221.94,225.23 221.84,225.3 221.84,225.3 C221.84,225.3 221.74,225.37 221.74,225.37 C221.74,225.37 221.63,225.44 221.63,225.44 C221.63,225.44 221.52,225.5 221.52,225.5 C221.52,225.5 221.41,225.56 221.41,225.56 C221.41,225.56 221.3,225.62 221.3,225.62 C221.3,225.62 221.19,225.68 221.19,225.68 C221.19,225.68 221.08,225.73 221.08,225.73 C221.08,225.73 220.96,225.79 220.96,225.79 C220.96,225.79 220.85,225.84 220.85,225.84 C220.85,225.84 220.73,225.89 220.73,225.89 C220.73,225.89 220.62,225.94 220.62,225.94 C220.62,225.94 220.5,225.99 220.5,225.99 C220.5,225.99 220.38,226.03 220.38,226.03 C220.38,226.03 220.27,226.08 220.27,226.08 C220.27,226.08 220.15,226.12 220.15,226.12 C220.15,226.12 220.03,226.15 220.03,226.15 C220.03,226.15 219.91,226.19 219.91,226.19 C219.91,226.19 219.79,226.23 219.79,226.23 C219.79,226.23 219.67,226.27 219.67,226.27 C219.67,226.27 219.55,226.3 219.55,226.3 C219.55,226.3 219.42,226.33 219.42,226.33 C219.42,226.33 219.3,226.35 219.3,226.35 C219.3,226.35 219.18,226.38 219.18,226.38 C219.18,226.38 219.06,226.4 219.06,226.4 C219.06,226.4 218.93,226.43 218.93,226.43 C218.93,226.43 218.81,226.45 218.81,226.45 C218.81,226.45 218.68,226.47 218.68,226.47 C218.68,226.47 218.56,226.49 218.56,226.49 C218.56,226.49 218.44,226.5 218.44,226.5 C218.44,226.5 218.31,226.52 218.31,226.52 C218.31,226.52 218.19,226.52 218.19,226.52 C218.19,226.52 218.06,226.53 218.06,226.53 C218.06,226.53 217.93,226.53 217.93,226.53 C217.93,226.53 217.81,226.54 217.81,226.54 C217.81,226.54 217.68,226.55 217.68,226.55 C217.68,226.55 217.56,226.55 217.56,226.55 C217.56,226.55 217.43,226.55 217.43,226.55 C217.43,226.55 217.31,226.54 217.31,226.54 C217.31,226.54 217.18,226.53 217.18,226.53 C217.18,226.53 217.05,226.53 217.05,226.53 C217.05,226.53 216.93,226.52 216.93,226.52 C216.93,226.52 216.8,226.52 216.8,226.52 C216.8,226.52 216.68,226.5 216.68,226.5 C216.68,226.5 216.55,226.48 216.55,226.48 C216.55,226.48 216.43,226.46 216.43,226.46 C216.43,226.46 216.31,226.45 216.31,226.45 C216.31,226.45 216.18,226.43 216.18,226.43 C216.18,226.43 216.06,226.41 216.06,226.41 C216.06,226.41 215.93,226.38 215.93,226.38 C215.93,226.38 215.81,226.35 215.81,226.35 C215.81,226.35 215.69,226.32 215.69,226.32 C215.69,226.32 215.57,226.29 215.57,226.29 C215.57,226.29 215.45,226.26 215.45,226.26 C215.45,226.26 215.32,226.23 215.32,226.23 C215.32,226.23 215.2,226.2 215.2,226.2 C215.2,226.2 215.09,226.16 215.09,226.16 C215.09,226.16 214.97,226.12 214.97,226.12 C214.97,226.12 214.85,226.07 214.85,226.07 C214.85,226.07 214.73,226.03 214.73,226.03 C214.73,226.03 214.61,225.99 214.61,225.99 C214.61,225.99 214.5,225.94 214.5,225.94 C214.5,225.94 214.38,225.89 214.38,225.89 C214.38,225.89 214.27,225.84 214.27,225.84 C214.27,225.84 214.15,225.79 214.15,225.79 C214.15,225.79 214.04,225.73 214.04,225.73 C214.04,225.73 213.93,225.68 213.93,225.68 C213.93,225.68 213.81,225.62 213.81,225.62 C213.81,225.62 213.71,225.56 213.71,225.56 C213.71,225.56 213.6,225.5 213.6,225.5 C213.6,225.5 213.49,225.43 213.49,225.43 C213.49,225.43 213.38,225.37 213.38,225.37 C213.38,225.37 213.27,225.31 213.27,225.31 C213.27,225.31 213.17,225.24 213.17,225.24 C213.17,225.24 213.06,225.16 213.06,225.16 C213.06,225.16 212.96,225.09 212.96,225.09 C212.96,225.09 212.86,225.02 212.86,225.02 C212.86,225.02 212.76,224.95 212.76,224.95 C212.76,224.95 212.65,224.87 212.65,224.87 C212.65,224.87 212.56,224.79 212.56,224.79 C212.56,224.79 212.46,224.71 212.46,224.71 C212.46,224.71 212.37,224.63 212.37,224.63 C212.37,224.63 212.27,224.55 212.27,224.55 C212.27,224.55 212.18,224.47 212.18,224.47 C212.18,224.47 212.08,224.38 212.08,224.38 C212.08,224.38 211.99,224.3 211.99,224.3 C211.99,224.3 211.91,224.2 211.91,224.2 C211.91,224.2 211.82,224.11 211.82,224.11 C211.82,224.11 211.73,224.02 211.73,224.02 C211.73,224.02 211.64,223.93 211.64,223.93 C211.64,223.93 211.56,223.84 211.56,223.84 C211.56,223.84 211.48,223.75 211.48,223.75 C211.48,223.75 211.4,223.65 211.4,223.65 C211.4,223.65 211.32,223.55 211.32,223.55 C211.32,223.55 211.24,223.45 211.24,223.45 C211.24,223.45 211.16,223.35 211.16,223.35 C211.16,223.35 211.09,223.26 211.09,223.26 C211.09,223.26 211.02,223.15 211.02,223.15 C211.02,223.15 210.95,223.05 210.95,223.05 C210.95,223.05 210.88,222.94 210.88,222.94 C210.88,222.94 210.81,222.84 210.81,222.84 C210.81,222.84 210.74,222.73 210.74,222.73 C210.74,222.73 210.67,222.63 210.67,222.63 C210.67,222.63 210.61,222.52 210.61,222.52 C210.61,222.52 210.55,222.4 210.55,222.4 C210.55,222.4 210.49,222.29 210.49,222.29 C210.49,222.29 210.43,222.18 210.43,222.18 C210.43,222.18 210.38,222.07 210.38,222.07 C210.38,222.07 210.32,221.96 210.32,221.96 C210.32,221.96 210.27,221.84 210.27,221.84 C210.27,221.84 210.22,221.73 210.22,221.73 C210.22,221.73 210.17,221.61 210.17,221.61 C210.17,221.61 210.12,221.5 210.12,221.5 C210.12,221.5 210.08,221.38 210.08,221.38 C210.08,221.38 210.03,221.26 210.03,221.26 C210.03,221.26 209.99,221.14 209.99,221.14 C209.99,221.14 209.96,221.02 209.96,221.02 C209.96,221.02 209.92,220.9 209.92,220.9 C209.92,220.9 209.88,220.78 209.88,220.78 C209.88,220.78 209.84,220.67 209.84,220.67 C209.84,220.67 209.81,220.54 209.81,220.54 C209.81,220.54 209.78,220.42 209.78,220.42 C209.78,220.42 209.76,220.3 209.76,220.3 C209.76,220.3 209.73,220.18 209.73,220.18 C209.73,220.18 209.71,220.05 209.71,220.05 C209.71,220.05 209.68,219.93 209.68,219.93 C209.68,219.93 209.66,219.81 209.66,219.81 C209.66,219.81 209.64,219.68 209.64,219.68 C209.64,219.68 209.62,219.56 209.62,219.56 C209.62,219.56 209.61,219.43 209.61,219.43 C209.61,219.43 209.59,219.31 209.59,219.31 C209.59,219.31 209.59,219.18 209.59,219.18 C209.59,219.18 209.58,219.06 209.58,219.06 C209.58,219.06 209.58,218.93 209.58,218.93 C209.58,218.93 209.57,218.81 209.57,218.81 C209.57,218.81 209.56,218.68 209.56,218.68 C209.56,218.68 209.56,218.56 209.56,218.56 C209.56,218.56 209.56,218.43 209.56,218.43 C209.56,218.43 209.57,218.3 209.57,218.3 C209.57,218.3 209.58,218.18 209.58,218.18 C209.58,218.18 209.58,218.05 209.58,218.05 C209.58,218.05 209.59,217.93 209.59,217.93 C209.59,217.93 209.59,217.8 209.59,217.8 C209.59,217.8 209.61,217.68 209.61,217.68 C209.61,217.68 209.63,217.55 209.63,217.55 C209.63,217.55 209.65,217.43 209.65,217.43 C209.65,217.43 209.66,217.31 209.66,217.31 C209.66,217.31 209.68,217.18 209.68,217.18 C209.68,217.18 209.7,217.06 209.7,217.06 C209.7,217.06 209.73,216.93 209.73,216.93 C209.73,216.93 209.76,216.81 209.76,216.81 C209.76,216.81 209.79,216.69 209.79,216.69 C209.79,216.69 209.82,216.57 209.82,216.57 C209.82,216.57 209.85,216.45 209.85,216.45 C209.85,216.45 209.88,216.32 209.88,216.32 C209.88,216.32 209.91,216.2 209.91,216.2 C209.91,216.2 209.95,216.08 209.95,216.08 C209.95,216.08 210,215.97 210,215.97 C210,215.97 210.04,215.85 210.04,215.85 C210.04,215.85 210.08,215.73 210.08,215.73 C210.08,215.73 210.12,215.61 210.12,215.61 C210.12,215.61 210.17,215.49 210.17,215.49 C210.17,215.49 210.22,215.38 210.22,215.38 C210.22,215.38 210.27,215.27 210.27,215.27 C210.27,215.27 210.33,215.15 210.33,215.15 C210.33,215.15 210.38,215.04 210.38,215.04 C210.38,215.04 210.43,214.92 210.43,214.92 C210.43,214.92 210.49,214.81 210.49,214.81 C210.49,214.81 210.55,214.7 210.55,214.7 C210.55,214.7 210.61,214.6 210.61,214.6 C210.61,214.6 210.68,214.49 210.68,214.49 C210.68,214.49 210.74,214.38 210.74,214.38 C210.74,214.38 210.8,214.27 210.8,214.27 C210.8,214.27 210.87,214.17 210.87,214.17 C210.87,214.17 210.95,214.06 210.95,214.06 C210.95,214.06 211.02,213.96 211.02,213.96 C211.02,213.96 211.09,213.86 211.09,213.86 C211.09,213.86 211.16,213.76 211.16,213.76 C211.16,213.76 211.24,213.65 211.24,213.65 C211.24,213.65 211.32,213.56 211.32,213.56 C211.32,213.56 211.4,213.46 211.4,213.46 C211.4,213.46 211.48,213.37 211.48,213.37 C211.48,213.37 211.56,213.27 211.56,213.27 C211.56,213.27 211.64,213.18 211.64,213.18 C211.64,213.18 211.73,213.08 211.73,213.08 C211.73,213.08 211.82,212.99 211.82,212.99 C211.82,212.99 211.91,212.9 211.91,212.9 C211.91,212.9 212,212.82 212,212.82 C212,212.82 212.09,212.73 212.09,212.73 C212.09,212.73 212.18,212.64 212.18,212.64 C212.18,212.64 212.27,212.56 212.27,212.56 C212.27,212.56 212.36,212.48 212.36,212.48 C212.36,212.48 212.46,212.4 212.46,212.4 C212.46,212.4 212.56,212.32 212.56,212.32 C212.56,212.32 212.66,212.24 212.66,212.24 C212.66,212.24 212.76,212.16 212.76,212.16 C212.76,212.16 212.85,212.08 212.85,212.08 C212.85,212.08 212.96,212.02 212.96,212.02 C212.96,212.02 213.06,211.95 213.06,211.95 C213.06,211.95 213.17,211.88 213.17,211.88 C213.17,211.88 213.27,211.81 213.27,211.81 C213.27,211.81 213.38,211.74 213.38,211.74 C213.38,211.74 213.48,211.67 213.48,211.67 C213.48,211.67 213.6,211.61 213.6,211.61 C213.6,211.61 213.71,211.55 213.71,211.55 C213.71,211.55 213.82,211.49 213.82,211.49 C213.82,211.49 213.93,211.43 213.93,211.43 C213.93,211.43 214.04,211.37 214.04,211.37 C214.04,211.37 214.15,211.32 214.15,211.32 C214.15,211.32 214.27,211.27 214.27,211.27 C214.27,211.27 214.38,211.22 214.38,211.22 C214.38,211.22 214.5,211.17 214.5,211.17 C214.5,211.17 214.61,211.12 214.61,211.12 C214.61,211.12 214.73,211.07 214.73,211.07 C214.73,211.07 214.85,211.03 214.85,211.03 C214.85,211.03 214.97,210.99 214.97,210.99 C214.97,210.99 215.09,210.95 215.09,210.95 C215.09,210.95 215.21,210.92 215.21,210.92 C215.21,210.92 215.33,210.88 215.33,210.88 C215.33,210.88 215.45,210.84 215.45,210.84 C215.45,210.84 215.57,210.81 215.57,210.81 C215.57,210.81 215.69,210.78 215.69,210.78 C215.69,210.78 215.81,210.76 215.81,210.76 C215.81,210.76 215.93,210.73 215.93,210.73 C215.93,210.73 216.06,210.7 216.06,210.7 C216.06,210.7 216.18,210.68 216.18,210.68 C216.18,210.68 216.3,210.65 216.3,210.65 C216.3,210.65 216.43,210.64 216.43,210.64 C216.43,210.64 216.55,210.62 216.55,210.62 C216.55,210.62 216.68,210.61 216.68,210.61 C216.68,210.61 216.8,210.59 216.8,210.59 C216.8,210.59 216.93,210.59 216.93,210.59 C216.93,210.59 217.05,210.58 217.05,210.58 C217.05,210.58 217.18,210.58 217.18,210.58 C217.18,210.58 217.3,210.57 217.3,210.57 C217.3,210.57 217.43,210.56 217.43,210.56 C217.43,210.56 217.56,210.56 217.56,210.56 C217.56,210.56 217.68,210.56 217.68,210.56c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_shape_5_avd.xml b/packages/SystemUI/res/drawable/pin_dot_shape_5_avd.xml
new file mode 100644
index 0000000..de2a7db
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_shape_5_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="-187.543" android:translateY="-188.546"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="33" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c " android:valueTo="M217.59 202.73 C217.59,202.73 217.85,202.75 217.85,202.75 C217.85,202.75 218.11,202.76 218.11,202.76 C218.11,202.76 218.37,202.79 218.37,202.79 C218.37,202.79 218.63,202.83 218.63,202.83 C218.63,202.83 218.88,202.88 218.88,202.88 C218.88,202.88 219.14,202.93 219.14,202.93 C219.14,202.93 219.39,203.01 219.39,203.01 C219.39,203.01 219.64,203.09 219.64,203.09 C219.64,203.09 219.88,203.18 219.88,203.18 C219.88,203.18 220.12,203.28 220.12,203.28 C220.12,203.28 220.36,203.39 220.36,203.39 C220.36,203.39 220.59,203.51 220.59,203.51 C220.59,203.51 220.82,203.64 220.82,203.64 C220.82,203.64 221.04,203.78 221.04,203.78 C221.04,203.78 221.26,203.92 221.26,203.92 C221.26,203.92 221.46,204.09 221.46,204.09 C221.46,204.09 221.66,204.25 221.66,204.25 C221.66,204.25 221.87,204.42 221.87,204.42 C221.87,204.42 222.05,204.61 222.05,204.61 C222.05,204.61 222.23,204.79 222.23,204.79 C222.23,204.79 222.4,204.99 222.4,204.99 C222.4,204.99 222.57,205.19 222.57,205.19 C222.57,205.19 222.72,205.41 222.72,205.41 C222.72,205.41 222.86,205.62 222.86,205.62 C222.86,205.62 223.01,205.84 223.01,205.84 C223.01,205.84 223.14,206.06 223.14,206.06 C223.14,206.06 223.27,206.29 223.27,206.29 C223.27,206.29 223.4,206.52 223.4,206.52 C223.4,206.52 223.53,206.75 223.53,206.75 C223.53,206.75 223.66,206.97 223.66,206.97 C223.66,206.97 223.79,207.2 223.79,207.2 C223.79,207.2 223.92,207.43 223.92,207.43 C223.92,207.43 224.05,207.65 224.05,207.65 C224.05,207.65 224.18,207.88 224.18,207.88 C224.18,207.88 224.31,208.11 224.31,208.11 C224.31,208.11 224.44,208.34 224.44,208.34 C224.44,208.34 224.56,208.56 224.56,208.56 C224.56,208.56 224.69,208.79 224.69,208.79 C224.69,208.79 224.82,209.02 224.82,209.02 C224.82,209.02 224.95,209.25 224.95,209.25 C224.95,209.25 225.08,209.47 225.08,209.47 C225.08,209.47 225.21,209.7 225.21,209.7 C225.21,209.7 225.34,209.93 225.34,209.93 C225.34,209.93 225.47,210.15 225.47,210.15 C225.47,210.15 225.6,210.38 225.6,210.38 C225.6,210.38 225.73,210.61 225.73,210.61 C225.73,210.61 225.86,210.84 225.86,210.84 C225.86,210.84 225.99,211.06 225.99,211.06 C225.99,211.06 226.11,211.29 226.11,211.29 C226.11,211.29 226.24,211.52 226.24,211.52 C226.24,211.52 226.37,211.75 226.37,211.75 C226.37,211.75 226.5,211.97 226.5,211.97 C226.5,211.97 226.63,212.2 226.63,212.2 C226.63,212.2 226.76,212.43 226.76,212.43 C226.76,212.43 226.89,212.65 226.89,212.65 C226.89,212.65 227.02,212.88 227.02,212.88 C227.02,212.88 227.15,213.11 227.15,213.11 C227.15,213.11 227.28,213.34 227.28,213.34 C227.28,213.34 227.41,213.56 227.41,213.56 C227.41,213.56 227.54,213.79 227.54,213.79 C227.54,213.79 227.66,214.02 227.66,214.02 C227.66,214.02 227.79,214.25 227.79,214.25 C227.79,214.25 227.92,214.47 227.92,214.47 C227.92,214.47 228.05,214.7 228.05,214.7 C228.05,214.7 228.18,214.93 228.18,214.93 C228.18,214.93 228.31,215.15 228.31,215.15 C228.31,215.15 228.44,215.38 228.44,215.38 C228.44,215.38 228.57,215.61 228.57,215.61 C228.57,215.61 228.7,215.83 228.7,215.83 C228.7,215.83 228.83,216.06 228.83,216.06 C228.83,216.06 228.96,216.29 228.96,216.29 C228.96,216.29 229.09,216.52 229.09,216.52 C229.09,216.52 229.21,216.74 229.21,216.74 C229.21,216.74 229.34,216.97 229.34,216.97 C229.34,216.97 229.47,217.2 229.47,217.2 C229.47,217.2 229.6,217.43 229.6,217.43 C229.6,217.43 229.73,217.65 229.73,217.65 C229.73,217.65 229.86,217.88 229.86,217.88 C229.86,217.88 229.99,218.11 229.99,218.11 C229.99,218.11 230.12,218.33 230.12,218.33 C230.12,218.33 230.25,218.56 230.25,218.56 C230.25,218.56 230.38,218.79 230.38,218.79 C230.38,218.79 230.51,219.02 230.51,219.02 C230.51,219.02 230.64,219.24 230.64,219.24 C230.64,219.24 230.76,219.47 230.76,219.47 C230.76,219.47 230.89,219.7 230.89,219.7 C230.89,219.7 231.02,219.93 231.02,219.93 C231.02,219.93 231.15,220.15 231.15,220.15 C231.15,220.15 231.28,220.38 231.28,220.38 C231.28,220.38 231.41,220.61 231.41,220.61 C231.41,220.61 231.54,220.83 231.54,220.83 C231.54,220.83 231.67,221.06 231.67,221.06 C231.67,221.06 231.8,221.29 231.8,221.29 C231.8,221.29 231.93,221.52 231.93,221.52 C231.93,221.52 232.06,221.74 232.06,221.74 C232.06,221.74 232.19,221.97 232.19,221.97 C232.19,221.97 232.31,222.2 232.31,222.2 C232.31,222.2 232.44,222.43 232.44,222.43 C232.44,222.43 232.57,222.65 232.57,222.65 C232.57,222.65 232.7,222.88 232.7,222.88 C232.7,222.88 232.83,223.11 232.83,223.11 C232.83,223.11 232.96,223.33 232.96,223.33 C232.96,223.33 233.09,223.56 233.09,223.56 C233.09,223.56 233.22,223.79 233.22,223.79 C233.22,223.79 233.35,224.02 233.35,224.02 C233.35,224.02 233.48,224.24 233.48,224.24 C233.48,224.24 233.61,224.47 233.61,224.47 C233.61,224.47 233.73,224.7 233.73,224.7 C233.73,224.7 233.84,224.94 233.84,224.94 C233.84,224.94 233.96,225.17 233.96,225.17 C233.96,225.17 234.07,225.41 234.07,225.41 C234.07,225.41 234.16,225.65 234.16,225.65 C234.16,225.65 234.24,225.9 234.24,225.9 C234.24,225.9 234.32,226.15 234.32,226.15 C234.32,226.15 234.38,226.4 234.38,226.4 C234.38,226.4 234.43,226.66 234.43,226.66 C234.43,226.66 234.48,226.92 234.48,226.92 C234.48,226.92 234.51,227.18 234.51,227.18 C234.51,227.18 234.53,227.44 234.53,227.44 C234.53,227.44 234.54,227.7 234.54,227.7 C234.54,227.7 234.54,227.96 234.54,227.96 C234.54,227.96 234.53,228.22 234.53,228.22 C234.53,228.22 234.51,228.48 234.51,228.48 C234.51,228.48 234.48,228.74 234.48,228.74 C234.48,228.74 234.43,229 234.43,229 C234.43,229 234.39,229.25 234.39,229.25 C234.39,229.25 234.32,229.51 234.32,229.51 C234.32,229.51 234.25,229.76 234.25,229.76 C234.25,229.76 234.17,230.01 234.17,230.01 C234.17,230.01 234.08,230.25 234.08,230.25 C234.08,230.25 233.97,230.49 233.97,230.49 C233.97,230.49 233.86,230.73 233.86,230.73 C233.86,230.73 233.75,230.96 233.75,230.96 C233.75,230.96 233.61,231.18 233.61,231.18 C233.61,231.18 233.48,231.41 233.48,231.41 C233.48,231.41 233.33,231.63 233.33,231.63 C233.33,231.63 233.17,231.83 233.17,231.83 C233.17,231.83 233.01,232.04 233.01,232.04 C233.01,232.04 232.84,232.24 232.84,232.24 C232.84,232.24 232.66,232.42 232.66,232.42 C232.66,232.42 232.47,232.61 232.47,232.61 C232.47,232.61 232.28,232.78 232.28,232.78 C232.28,232.78 232.08,232.95 232.08,232.95 C232.08,232.95 231.87,233.11 231.87,233.11 C231.87,233.11 231.66,233.26 231.66,233.26 C231.66,233.26 231.43,233.39 231.43,233.39 C231.43,233.39 231.21,233.53 231.21,233.53 C231.21,233.53 230.98,233.65 230.98,233.65 C230.98,233.65 230.74,233.76 230.74,233.76 C230.74,233.76 230.5,233.87 230.5,233.87 C230.5,233.87 230.26,233.96 230.26,233.96 C230.26,233.96 230.01,234.04 230.01,234.04 C230.01,234.04 229.76,234.12 229.76,234.12 C229.76,234.12 229.51,234.17 229.51,234.17 C229.51,234.17 229.25,234.23 229.25,234.23 C229.25,234.23 228.99,234.26 228.99,234.26 C228.99,234.26 228.73,234.3 228.73,234.3 C228.73,234.3 228.47,234.31 228.47,234.31 C228.47,234.31 228.21,234.32 228.21,234.32 C228.21,234.32 227.95,234.32 227.95,234.32 C227.95,234.32 227.69,234.32 227.69,234.32 C227.69,234.32 227.43,234.32 227.43,234.32 C227.43,234.32 227.16,234.32 227.16,234.32 C227.16,234.32 226.9,234.32 226.9,234.32 C226.9,234.32 226.64,234.32 226.64,234.32 C226.64,234.32 226.38,234.32 226.38,234.32 C226.38,234.32 226.12,234.32 226.12,234.32 C226.12,234.32 225.86,234.32 225.86,234.32 C225.86,234.32 225.6,234.32 225.6,234.32 C225.6,234.32 225.33,234.32 225.33,234.32 C225.33,234.32 225.07,234.32 225.07,234.32 C225.07,234.32 224.81,234.32 224.81,234.32 C224.81,234.32 224.55,234.32 224.55,234.32 C224.55,234.32 224.29,234.32 224.29,234.32 C224.29,234.32 224.03,234.32 224.03,234.32 C224.03,234.32 223.77,234.32 223.77,234.32 C223.77,234.32 223.5,234.32 223.5,234.32 C223.5,234.32 223.24,234.32 223.24,234.32 C223.24,234.32 222.98,234.32 222.98,234.32 C222.98,234.32 222.72,234.32 222.72,234.32 C222.72,234.32 222.46,234.32 222.46,234.32 C222.46,234.32 222.2,234.32 222.2,234.32 C222.2,234.32 221.94,234.32 221.94,234.32 C221.94,234.32 221.68,234.32 221.68,234.32 C221.68,234.32 221.41,234.32 221.41,234.32 C221.41,234.32 221.15,234.32 221.15,234.32 C221.15,234.32 220.89,234.32 220.89,234.32 C220.89,234.32 220.63,234.32 220.63,234.32 C220.63,234.32 220.37,234.32 220.37,234.32 C220.37,234.32 220.11,234.32 220.11,234.32 C220.11,234.32 219.85,234.32 219.85,234.32 C219.85,234.32 219.58,234.32 219.58,234.32 C219.58,234.32 219.32,234.32 219.32,234.32 C219.32,234.32 219.06,234.32 219.06,234.32 C219.06,234.32 218.8,234.32 218.8,234.32 C218.8,234.32 218.54,234.32 218.54,234.32 C218.54,234.32 218.28,234.32 218.28,234.32 C218.28,234.32 218.02,234.32 218.02,234.32 C218.02,234.32 217.75,234.32 217.75,234.32 C217.75,234.32 217.49,234.32 217.49,234.32 C217.49,234.32 217.23,234.32 217.23,234.32 C217.23,234.32 216.97,234.32 216.97,234.32 C216.97,234.32 216.71,234.32 216.71,234.32 C216.71,234.32 216.45,234.32 216.45,234.32 C216.45,234.32 216.19,234.32 216.19,234.32 C216.19,234.32 215.92,234.32 215.92,234.32 C215.92,234.32 215.66,234.32 215.66,234.32 C215.66,234.32 215.4,234.32 215.4,234.32 C215.4,234.32 215.14,234.32 215.14,234.32 C215.14,234.32 214.88,234.32 214.88,234.32 C214.88,234.32 214.62,234.32 214.62,234.32 C214.62,234.32 214.36,234.32 214.36,234.32 C214.36,234.32 214.1,234.32 214.1,234.32 C214.1,234.32 213.83,234.32 213.83,234.32 C213.83,234.32 213.57,234.32 213.57,234.32 C213.57,234.32 213.31,234.32 213.31,234.32 C213.31,234.32 213.05,234.32 213.05,234.32 C213.05,234.32 212.79,234.32 212.79,234.32 C212.79,234.32 212.53,234.32 212.53,234.32 C212.53,234.32 212.27,234.32 212.27,234.32 C212.27,234.32 212,234.32 212,234.32 C212,234.32 211.74,234.32 211.74,234.32 C211.74,234.32 211.48,234.32 211.48,234.32 C211.48,234.32 211.22,234.32 211.22,234.32 C211.22,234.32 210.96,234.32 210.96,234.32 C210.96,234.32 210.7,234.32 210.7,234.32 C210.7,234.32 210.44,234.32 210.44,234.32 C210.44,234.32 210.17,234.32 210.17,234.32 C210.17,234.32 209.91,234.32 209.91,234.32 C209.91,234.32 209.65,234.32 209.65,234.32 C209.65,234.32 209.39,234.32 209.39,234.32 C209.39,234.32 209.13,234.32 209.13,234.32 C209.13,234.32 208.87,234.32 208.87,234.32 C208.87,234.32 208.61,234.32 208.61,234.32 C208.61,234.32 208.34,234.32 208.34,234.32 C208.34,234.32 208.08,234.32 208.08,234.32 C208.08,234.32 207.82,234.32 207.82,234.32 C207.82,234.32 207.56,234.32 207.56,234.32 C207.56,234.32 207.3,234.32 207.3,234.32 C207.3,234.32 207.04,234.32 207.04,234.32 C207.04,234.32 206.78,234.32 206.78,234.32 C206.78,234.32 206.52,234.3 206.52,234.3 C206.52,234.3 206.26,234.28 206.26,234.28 C206.26,234.28 206,234.25 206,234.25 C206,234.25 205.74,234.21 205.74,234.21 C205.74,234.21 205.48,234.15 205.48,234.15 C205.48,234.15 205.23,234.09 205.23,234.09 C205.23,234.09 204.98,234.01 204.98,234.01 C204.98,234.01 204.73,233.93 204.73,233.93 C204.73,233.93 204.49,233.83 204.49,233.83 C204.49,233.83 204.25,233.72 204.25,233.72 C204.25,233.72 204.01,233.62 204.01,233.62 C204.01,233.62 203.79,233.48 203.79,233.48 C203.79,233.48 203.57,233.35 203.57,233.35 C203.57,233.35 203.34,233.21 203.34,233.21 C203.34,233.21 203.14,233.05 203.14,233.05 C203.14,233.05 202.93,232.89 202.93,232.89 C202.93,232.89 202.73,232.73 202.73,232.73 C202.73,232.73 202.54,232.54 202.54,232.54 C202.54,232.54 202.36,232.36 202.36,232.36 C202.36,232.36 202.17,232.17 202.17,232.17 C202.17,232.17 202.01,231.97 202.01,231.97 C202.01,231.97 201.85,231.76 201.85,231.76 C201.85,231.76 201.69,231.55 201.69,231.55 C201.69,231.55 201.55,231.33 201.55,231.33 C201.55,231.33 201.42,231.11 201.42,231.11 C201.42,231.11 201.29,230.88 201.29,230.88 C201.29,230.88 201.18,230.64 201.18,230.64 C201.18,230.64 201.07,230.4 201.07,230.4 C201.07,230.4 200.96,230.17 200.96,230.17 C200.96,230.17 200.88,229.92 200.88,229.92 C200.88,229.92 200.8,229.67 200.8,229.67 C200.8,229.67 200.73,229.42 200.73,229.42 C200.73,229.42 200.68,229.16 200.68,229.16 C200.68,229.16 200.63,228.91 200.63,228.91 C200.63,228.91 200.58,228.65 200.58,228.65 C200.58,228.65 200.56,228.39 200.56,228.39 C200.56,228.39 200.55,228.13 200.55,228.13 C200.55,228.13 200.53,227.87 200.53,227.87 C200.53,227.87 200.54,227.61 200.54,227.61 C200.54,227.61 200.56,227.35 200.56,227.35 C200.56,227.35 200.58,227.08 200.58,227.08 C200.58,227.08 200.62,226.83 200.62,226.83 C200.62,226.83 200.67,226.57 200.67,226.57 C200.67,226.57 200.72,226.31 200.72,226.31 C200.72,226.31 200.79,226.06 200.79,226.06 C200.79,226.06 200.87,225.81 200.87,225.81 C200.87,225.81 200.95,225.57 200.95,225.57 C200.95,225.57 201.05,225.32 201.05,225.32 C201.05,225.32 201.16,225.09 201.16,225.09 C201.16,225.09 201.27,224.85 201.27,224.85 C201.27,224.85 201.39,224.62 201.39,224.62 C201.39,224.62 201.52,224.39 201.52,224.39 C201.52,224.39 201.65,224.16 201.65,224.16 C201.65,224.16 201.78,223.94 201.78,223.94 C201.78,223.94 201.91,223.71 201.91,223.71 C201.91,223.71 202.03,223.48 202.03,223.48 C202.03,223.48 202.16,223.25 202.16,223.25 C202.16,223.25 202.29,223.03 202.29,223.03 C202.29,223.03 202.42,222.8 202.42,222.8 C202.42,222.8 202.55,222.57 202.55,222.57 C202.55,222.57 202.68,222.35 202.68,222.35 C202.68,222.35 202.81,222.12 202.81,222.12 C202.81,222.12 202.94,221.89 202.94,221.89 C202.94,221.89 203.07,221.66 203.07,221.66 C203.07,221.66 203.2,221.44 203.2,221.44 C203.2,221.44 203.33,221.21 203.33,221.21 C203.33,221.21 203.46,220.98 203.46,220.98 C203.46,220.98 203.58,220.76 203.58,220.76 C203.58,220.76 203.71,220.53 203.71,220.53 C203.71,220.53 203.84,220.3 203.84,220.3 C203.84,220.3 203.97,220.07 203.97,220.07 C203.97,220.07 204.1,219.85 204.1,219.85 C204.1,219.85 204.23,219.62 204.23,219.62 C204.23,219.62 204.36,219.39 204.36,219.39 C204.36,219.39 204.49,219.16 204.49,219.16 C204.49,219.16 204.62,218.94 204.62,218.94 C204.62,218.94 204.75,218.71 204.75,218.71 C204.75,218.71 204.88,218.48 204.88,218.48 C204.88,218.48 205.01,218.26 205.01,218.26 C205.01,218.26 205.13,218.03 205.13,218.03 C205.13,218.03 205.26,217.8 205.26,217.8 C205.26,217.8 205.39,217.57 205.39,217.57 C205.39,217.57 205.52,217.35 205.52,217.35 C205.52,217.35 205.65,217.12 205.65,217.12 C205.65,217.12 205.78,216.89 205.78,216.89 C205.78,216.89 205.91,216.66 205.91,216.66 C205.91,216.66 206.04,216.44 206.04,216.44 C206.04,216.44 206.17,216.21 206.17,216.21 C206.17,216.21 206.3,215.98 206.3,215.98 C206.3,215.98 206.43,215.76 206.43,215.76 C206.43,215.76 206.56,215.53 206.56,215.53 C206.56,215.53 206.68,215.3 206.68,215.3 C206.68,215.3 206.81,215.07 206.81,215.07 C206.81,215.07 206.94,214.85 206.94,214.85 C206.94,214.85 207.07,214.62 207.07,214.62 C207.07,214.62 207.2,214.39 207.2,214.39 C207.2,214.39 207.33,214.17 207.33,214.17 C207.33,214.17 207.46,213.94 207.46,213.94 C207.46,213.94 207.59,213.71 207.59,213.71 C207.59,213.71 207.72,213.48 207.72,213.48 C207.72,213.48 207.85,213.26 207.85,213.26 C207.85,213.26 207.98,213.03 207.98,213.03 C207.98,213.03 208.11,212.8 208.11,212.8 C208.11,212.8 208.23,212.57 208.23,212.57 C208.23,212.57 208.36,212.35 208.36,212.35 C208.36,212.35 208.49,212.12 208.49,212.12 C208.49,212.12 208.62,211.89 208.62,211.89 C208.62,211.89 208.75,211.67 208.75,211.67 C208.75,211.67 208.88,211.44 208.88,211.44 C208.88,211.44 209.01,211.21 209.01,211.21 C209.01,211.21 209.14,210.98 209.14,210.98 C209.14,210.98 209.27,210.76 209.27,210.76 C209.27,210.76 209.4,210.53 209.4,210.53 C209.4,210.53 209.53,210.3 209.53,210.3 C209.53,210.3 209.66,210.08 209.66,210.08 C209.66,210.08 209.78,209.85 209.78,209.85 C209.78,209.85 209.91,209.62 209.91,209.62 C209.91,209.62 210.04,209.39 210.04,209.39 C210.04,209.39 210.17,209.17 210.17,209.17 C210.17,209.17 210.3,208.94 210.3,208.94 C210.3,208.94 210.43,208.71 210.43,208.71 C210.43,208.71 210.56,208.48 210.56,208.48 C210.56,208.48 210.69,208.26 210.69,208.26 C210.69,208.26 210.82,208.03 210.82,208.03 C210.82,208.03 210.95,207.8 210.95,207.8 C210.95,207.8 211.08,207.58 211.08,207.58 C211.08,207.58 211.21,207.35 211.21,207.35 C211.21,207.35 211.33,207.12 211.33,207.12 C211.33,207.12 211.46,206.89 211.46,206.89 C211.46,206.89 211.59,206.67 211.59,206.67 C211.59,206.67 211.72,206.44 211.72,206.44 C211.72,206.44 211.85,206.21 211.85,206.21 C211.85,206.21 211.98,205.98 211.98,205.98 C211.98,205.98 212.13,205.76 212.13,205.76 C212.13,205.76 212.27,205.54 212.27,205.54 C212.27,205.54 212.41,205.33 212.41,205.33 C212.41,205.33 212.57,205.12 212.57,205.12 C212.57,205.12 212.74,204.92 212.74,204.92 C212.74,204.92 212.91,204.72 212.91,204.72 C212.91,204.72 213.1,204.54 213.1,204.54 C213.1,204.54 213.29,204.36 213.29,204.36 C213.29,204.36 213.49,204.19 213.49,204.19 C213.49,204.19 213.69,204.03 213.69,204.03 C213.69,204.03 213.9,203.87 213.9,203.87 C213.9,203.87 214.12,203.73 214.12,203.73 C214.12,203.73 214.34,203.59 214.34,203.59 C214.34,203.59 214.57,203.46 214.57,203.46 C214.57,203.46 214.81,203.35 214.81,203.35 C214.81,203.35 215.04,203.24 215.04,203.24 C215.04,203.24 215.28,203.14 215.28,203.14 C215.28,203.14 215.53,203.06 215.53,203.06 C215.53,203.06 215.78,202.98 215.78,202.98 C215.78,202.98 216.03,202.91 216.03,202.91 C216.03,202.91 216.29,202.86 216.29,202.86 C216.29,202.86 216.55,202.82 216.55,202.82 C216.55,202.82 216.8,202.77 216.8,202.77 C216.8,202.77 217.07,202.76 217.07,202.76 C217.07,202.76 217.33,202.74 217.33,202.74 C217.33,202.74 217.59,202.73 217.59,202.73c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="67" android:valueFrom="M217.59 202.73 C217.59,202.73 217.85,202.75 217.85,202.75 C217.85,202.75 218.11,202.76 218.11,202.76 C218.11,202.76 218.37,202.79 218.37,202.79 C218.37,202.79 218.63,202.83 218.63,202.83 C218.63,202.83 218.88,202.88 218.88,202.88 C218.88,202.88 219.14,202.93 219.14,202.93 C219.14,202.93 219.39,203.01 219.39,203.01 C219.39,203.01 219.64,203.09 219.64,203.09 C219.64,203.09 219.88,203.18 219.88,203.18 C219.88,203.18 220.12,203.28 220.12,203.28 C220.12,203.28 220.36,203.39 220.36,203.39 C220.36,203.39 220.59,203.51 220.59,203.51 C220.59,203.51 220.82,203.64 220.82,203.64 C220.82,203.64 221.04,203.78 221.04,203.78 C221.04,203.78 221.26,203.92 221.26,203.92 C221.26,203.92 221.46,204.09 221.46,204.09 C221.46,204.09 221.66,204.25 221.66,204.25 C221.66,204.25 221.87,204.42 221.87,204.42 C221.87,204.42 222.05,204.61 222.05,204.61 C222.05,204.61 222.23,204.79 222.23,204.79 C222.23,204.79 222.4,204.99 222.4,204.99 C222.4,204.99 222.57,205.19 222.57,205.19 C222.57,205.19 222.72,205.41 222.72,205.41 C222.72,205.41 222.86,205.62 222.86,205.62 C222.86,205.62 223.01,205.84 223.01,205.84 C223.01,205.84 223.14,206.06 223.14,206.06 C223.14,206.06 223.27,206.29 223.27,206.29 C223.27,206.29 223.4,206.52 223.4,206.52 C223.4,206.52 223.53,206.75 223.53,206.75 C223.53,206.75 223.66,206.97 223.66,206.97 C223.66,206.97 223.79,207.2 223.79,207.2 C223.79,207.2 223.92,207.43 223.92,207.43 C223.92,207.43 224.05,207.65 224.05,207.65 C224.05,207.65 224.18,207.88 224.18,207.88 C224.18,207.88 224.31,208.11 224.31,208.11 C224.31,208.11 224.44,208.34 224.44,208.34 C224.44,208.34 224.56,208.56 224.56,208.56 C224.56,208.56 224.69,208.79 224.69,208.79 C224.69,208.79 224.82,209.02 224.82,209.02 C224.82,209.02 224.95,209.25 224.95,209.25 C224.95,209.25 225.08,209.47 225.08,209.47 C225.08,209.47 225.21,209.7 225.21,209.7 C225.21,209.7 225.34,209.93 225.34,209.93 C225.34,209.93 225.47,210.15 225.47,210.15 C225.47,210.15 225.6,210.38 225.6,210.38 C225.6,210.38 225.73,210.61 225.73,210.61 C225.73,210.61 225.86,210.84 225.86,210.84 C225.86,210.84 225.99,211.06 225.99,211.06 C225.99,211.06 226.11,211.29 226.11,211.29 C226.11,211.29 226.24,211.52 226.24,211.52 C226.24,211.52 226.37,211.75 226.37,211.75 C226.37,211.75 226.5,211.97 226.5,211.97 C226.5,211.97 226.63,212.2 226.63,212.2 C226.63,212.2 226.76,212.43 226.76,212.43 C226.76,212.43 226.89,212.65 226.89,212.65 C226.89,212.65 227.02,212.88 227.02,212.88 C227.02,212.88 227.15,213.11 227.15,213.11 C227.15,213.11 227.28,213.34 227.28,213.34 C227.28,213.34 227.41,213.56 227.41,213.56 C227.41,213.56 227.54,213.79 227.54,213.79 C227.54,213.79 227.66,214.02 227.66,214.02 C227.66,214.02 227.79,214.25 227.79,214.25 C227.79,214.25 227.92,214.47 227.92,214.47 C227.92,214.47 228.05,214.7 228.05,214.7 C228.05,214.7 228.18,214.93 228.18,214.93 C228.18,214.93 228.31,215.15 228.31,215.15 C228.31,215.15 228.44,215.38 228.44,215.38 C228.44,215.38 228.57,215.61 228.57,215.61 C228.57,215.61 228.7,215.83 228.7,215.83 C228.7,215.83 228.83,216.06 228.83,216.06 C228.83,216.06 228.96,216.29 228.96,216.29 C228.96,216.29 229.09,216.52 229.09,216.52 C229.09,216.52 229.21,216.74 229.21,216.74 C229.21,216.74 229.34,216.97 229.34,216.97 C229.34,216.97 229.47,217.2 229.47,217.2 C229.47,217.2 229.6,217.43 229.6,217.43 C229.6,217.43 229.73,217.65 229.73,217.65 C229.73,217.65 229.86,217.88 229.86,217.88 C229.86,217.88 229.99,218.11 229.99,218.11 C229.99,218.11 230.12,218.33 230.12,218.33 C230.12,218.33 230.25,218.56 230.25,218.56 C230.25,218.56 230.38,218.79 230.38,218.79 C230.38,218.79 230.51,219.02 230.51,219.02 C230.51,219.02 230.64,219.24 230.64,219.24 C230.64,219.24 230.76,219.47 230.76,219.47 C230.76,219.47 230.89,219.7 230.89,219.7 C230.89,219.7 231.02,219.93 231.02,219.93 C231.02,219.93 231.15,220.15 231.15,220.15 C231.15,220.15 231.28,220.38 231.28,220.38 C231.28,220.38 231.41,220.61 231.41,220.61 C231.41,220.61 231.54,220.83 231.54,220.83 C231.54,220.83 231.67,221.06 231.67,221.06 C231.67,221.06 231.8,221.29 231.8,221.29 C231.8,221.29 231.93,221.52 231.93,221.52 C231.93,221.52 232.06,221.74 232.06,221.74 C232.06,221.74 232.19,221.97 232.19,221.97 C232.19,221.97 232.31,222.2 232.31,222.2 C232.31,222.2 232.44,222.43 232.44,222.43 C232.44,222.43 232.57,222.65 232.57,222.65 C232.57,222.65 232.7,222.88 232.7,222.88 C232.7,222.88 232.83,223.11 232.83,223.11 C232.83,223.11 232.96,223.33 232.96,223.33 C232.96,223.33 233.09,223.56 233.09,223.56 C233.09,223.56 233.22,223.79 233.22,223.79 C233.22,223.79 233.35,224.02 233.35,224.02 C233.35,224.02 233.48,224.24 233.48,224.24 C233.48,224.24 233.61,224.47 233.61,224.47 C233.61,224.47 233.73,224.7 233.73,224.7 C233.73,224.7 233.84,224.94 233.84,224.94 C233.84,224.94 233.96,225.17 233.96,225.17 C233.96,225.17 234.07,225.41 234.07,225.41 C234.07,225.41 234.16,225.65 234.16,225.65 C234.16,225.65 234.24,225.9 234.24,225.9 C234.24,225.9 234.32,226.15 234.32,226.15 C234.32,226.15 234.38,226.4 234.38,226.4 C234.38,226.4 234.43,226.66 234.43,226.66 C234.43,226.66 234.48,226.92 234.48,226.92 C234.48,226.92 234.51,227.18 234.51,227.18 C234.51,227.18 234.53,227.44 234.53,227.44 C234.53,227.44 234.54,227.7 234.54,227.7 C234.54,227.7 234.54,227.96 234.54,227.96 C234.54,227.96 234.53,228.22 234.53,228.22 C234.53,228.22 234.51,228.48 234.51,228.48 C234.51,228.48 234.48,228.74 234.48,228.74 C234.48,228.74 234.43,229 234.43,229 C234.43,229 234.39,229.25 234.39,229.25 C234.39,229.25 234.32,229.51 234.32,229.51 C234.32,229.51 234.25,229.76 234.25,229.76 C234.25,229.76 234.17,230.01 234.17,230.01 C234.17,230.01 234.08,230.25 234.08,230.25 C234.08,230.25 233.97,230.49 233.97,230.49 C233.97,230.49 233.86,230.73 233.86,230.73 C233.86,230.73 233.75,230.96 233.75,230.96 C233.75,230.96 233.61,231.18 233.61,231.18 C233.61,231.18 233.48,231.41 233.48,231.41 C233.48,231.41 233.33,231.63 233.33,231.63 C233.33,231.63 233.17,231.83 233.17,231.83 C233.17,231.83 233.01,232.04 233.01,232.04 C233.01,232.04 232.84,232.24 232.84,232.24 C232.84,232.24 232.66,232.42 232.66,232.42 C232.66,232.42 232.47,232.61 232.47,232.61 C232.47,232.61 232.28,232.78 232.28,232.78 C232.28,232.78 232.08,232.95 232.08,232.95 C232.08,232.95 231.87,233.11 231.87,233.11 C231.87,233.11 231.66,233.26 231.66,233.26 C231.66,233.26 231.43,233.39 231.43,233.39 C231.43,233.39 231.21,233.53 231.21,233.53 C231.21,233.53 230.98,233.65 230.98,233.65 C230.98,233.65 230.74,233.76 230.74,233.76 C230.74,233.76 230.5,233.87 230.5,233.87 C230.5,233.87 230.26,233.96 230.26,233.96 C230.26,233.96 230.01,234.04 230.01,234.04 C230.01,234.04 229.76,234.12 229.76,234.12 C229.76,234.12 229.51,234.17 229.51,234.17 C229.51,234.17 229.25,234.23 229.25,234.23 C229.25,234.23 228.99,234.26 228.99,234.26 C228.99,234.26 228.73,234.3 228.73,234.3 C228.73,234.3 228.47,234.31 228.47,234.31 C228.47,234.31 228.21,234.32 228.21,234.32 C228.21,234.32 227.95,234.32 227.95,234.32 C227.95,234.32 227.69,234.32 227.69,234.32 C227.69,234.32 227.43,234.32 227.43,234.32 C227.43,234.32 227.16,234.32 227.16,234.32 C227.16,234.32 226.9,234.32 226.9,234.32 C226.9,234.32 226.64,234.32 226.64,234.32 C226.64,234.32 226.38,234.32 226.38,234.32 C226.38,234.32 226.12,234.32 226.12,234.32 C226.12,234.32 225.86,234.32 225.86,234.32 C225.86,234.32 225.6,234.32 225.6,234.32 C225.6,234.32 225.33,234.32 225.33,234.32 C225.33,234.32 225.07,234.32 225.07,234.32 C225.07,234.32 224.81,234.32 224.81,234.32 C224.81,234.32 224.55,234.32 224.55,234.32 C224.55,234.32 224.29,234.32 224.29,234.32 C224.29,234.32 224.03,234.32 224.03,234.32 C224.03,234.32 223.77,234.32 223.77,234.32 C223.77,234.32 223.5,234.32 223.5,234.32 C223.5,234.32 223.24,234.32 223.24,234.32 C223.24,234.32 222.98,234.32 222.98,234.32 C222.98,234.32 222.72,234.32 222.72,234.32 C222.72,234.32 222.46,234.32 222.46,234.32 C222.46,234.32 222.2,234.32 222.2,234.32 C222.2,234.32 221.94,234.32 221.94,234.32 C221.94,234.32 221.68,234.32 221.68,234.32 C221.68,234.32 221.41,234.32 221.41,234.32 C221.41,234.32 221.15,234.32 221.15,234.32 C221.15,234.32 220.89,234.32 220.89,234.32 C220.89,234.32 220.63,234.32 220.63,234.32 C220.63,234.32 220.37,234.32 220.37,234.32 C220.37,234.32 220.11,234.32 220.11,234.32 C220.11,234.32 219.85,234.32 219.85,234.32 C219.85,234.32 219.58,234.32 219.58,234.32 C219.58,234.32 219.32,234.32 219.32,234.32 C219.32,234.32 219.06,234.32 219.06,234.32 C219.06,234.32 218.8,234.32 218.8,234.32 C218.8,234.32 218.54,234.32 218.54,234.32 C218.54,234.32 218.28,234.32 218.28,234.32 C218.28,234.32 218.02,234.32 218.02,234.32 C218.02,234.32 217.75,234.32 217.75,234.32 C217.75,234.32 217.49,234.32 217.49,234.32 C217.49,234.32 217.23,234.32 217.23,234.32 C217.23,234.32 216.97,234.32 216.97,234.32 C216.97,234.32 216.71,234.32 216.71,234.32 C216.71,234.32 216.45,234.32 216.45,234.32 C216.45,234.32 216.19,234.32 216.19,234.32 C216.19,234.32 215.92,234.32 215.92,234.32 C215.92,234.32 215.66,234.32 215.66,234.32 C215.66,234.32 215.4,234.32 215.4,234.32 C215.4,234.32 215.14,234.32 215.14,234.32 C215.14,234.32 214.88,234.32 214.88,234.32 C214.88,234.32 214.62,234.32 214.62,234.32 C214.62,234.32 214.36,234.32 214.36,234.32 C214.36,234.32 214.1,234.32 214.1,234.32 C214.1,234.32 213.83,234.32 213.83,234.32 C213.83,234.32 213.57,234.32 213.57,234.32 C213.57,234.32 213.31,234.32 213.31,234.32 C213.31,234.32 213.05,234.32 213.05,234.32 C213.05,234.32 212.79,234.32 212.79,234.32 C212.79,234.32 212.53,234.32 212.53,234.32 C212.53,234.32 212.27,234.32 212.27,234.32 C212.27,234.32 212,234.32 212,234.32 C212,234.32 211.74,234.32 211.74,234.32 C211.74,234.32 211.48,234.32 211.48,234.32 C211.48,234.32 211.22,234.32 211.22,234.32 C211.22,234.32 210.96,234.32 210.96,234.32 C210.96,234.32 210.7,234.32 210.7,234.32 C210.7,234.32 210.44,234.32 210.44,234.32 C210.44,234.32 210.17,234.32 210.17,234.32 C210.17,234.32 209.91,234.32 209.91,234.32 C209.91,234.32 209.65,234.32 209.65,234.32 C209.65,234.32 209.39,234.32 209.39,234.32 C209.39,234.32 209.13,234.32 209.13,234.32 C209.13,234.32 208.87,234.32 208.87,234.32 C208.87,234.32 208.61,234.32 208.61,234.32 C208.61,234.32 208.34,234.32 208.34,234.32 C208.34,234.32 208.08,234.32 208.08,234.32 C208.08,234.32 207.82,234.32 207.82,234.32 C207.82,234.32 207.56,234.32 207.56,234.32 C207.56,234.32 207.3,234.32 207.3,234.32 C207.3,234.32 207.04,234.32 207.04,234.32 C207.04,234.32 206.78,234.32 206.78,234.32 C206.78,234.32 206.52,234.3 206.52,234.3 C206.52,234.3 206.26,234.28 206.26,234.28 C206.26,234.28 206,234.25 206,234.25 C206,234.25 205.74,234.21 205.74,234.21 C205.74,234.21 205.48,234.15 205.48,234.15 C205.48,234.15 205.23,234.09 205.23,234.09 C205.23,234.09 204.98,234.01 204.98,234.01 C204.98,234.01 204.73,233.93 204.73,233.93 C204.73,233.93 204.49,233.83 204.49,233.83 C204.49,233.83 204.25,233.72 204.25,233.72 C204.25,233.72 204.01,233.62 204.01,233.62 C204.01,233.62 203.79,233.48 203.79,233.48 C203.79,233.48 203.57,233.35 203.57,233.35 C203.57,233.35 203.34,233.21 203.34,233.21 C203.34,233.21 203.14,233.05 203.14,233.05 C203.14,233.05 202.93,232.89 202.93,232.89 C202.93,232.89 202.73,232.73 202.73,232.73 C202.73,232.73 202.54,232.54 202.54,232.54 C202.54,232.54 202.36,232.36 202.36,232.36 C202.36,232.36 202.17,232.17 202.17,232.17 C202.17,232.17 202.01,231.97 202.01,231.97 C202.01,231.97 201.85,231.76 201.85,231.76 C201.85,231.76 201.69,231.55 201.69,231.55 C201.69,231.55 201.55,231.33 201.55,231.33 C201.55,231.33 201.42,231.11 201.42,231.11 C201.42,231.11 201.29,230.88 201.29,230.88 C201.29,230.88 201.18,230.64 201.18,230.64 C201.18,230.64 201.07,230.4 201.07,230.4 C201.07,230.4 200.96,230.17 200.96,230.17 C200.96,230.17 200.88,229.92 200.88,229.92 C200.88,229.92 200.8,229.67 200.8,229.67 C200.8,229.67 200.73,229.42 200.73,229.42 C200.73,229.42 200.68,229.16 200.68,229.16 C200.68,229.16 200.63,228.91 200.63,228.91 C200.63,228.91 200.58,228.65 200.58,228.65 C200.58,228.65 200.56,228.39 200.56,228.39 C200.56,228.39 200.55,228.13 200.55,228.13 C200.55,228.13 200.53,227.87 200.53,227.87 C200.53,227.87 200.54,227.61 200.54,227.61 C200.54,227.61 200.56,227.35 200.56,227.35 C200.56,227.35 200.58,227.08 200.58,227.08 C200.58,227.08 200.62,226.83 200.62,226.83 C200.62,226.83 200.67,226.57 200.67,226.57 C200.67,226.57 200.72,226.31 200.72,226.31 C200.72,226.31 200.79,226.06 200.79,226.06 C200.79,226.06 200.87,225.81 200.87,225.81 C200.87,225.81 200.95,225.57 200.95,225.57 C200.95,225.57 201.05,225.32 201.05,225.32 C201.05,225.32 201.16,225.09 201.16,225.09 C201.16,225.09 201.27,224.85 201.27,224.85 C201.27,224.85 201.39,224.62 201.39,224.62 C201.39,224.62 201.52,224.39 201.52,224.39 C201.52,224.39 201.65,224.16 201.65,224.16 C201.65,224.16 201.78,223.94 201.78,223.94 C201.78,223.94 201.91,223.71 201.91,223.71 C201.91,223.71 202.03,223.48 202.03,223.48 C202.03,223.48 202.16,223.25 202.16,223.25 C202.16,223.25 202.29,223.03 202.29,223.03 C202.29,223.03 202.42,222.8 202.42,222.8 C202.42,222.8 202.55,222.57 202.55,222.57 C202.55,222.57 202.68,222.35 202.68,222.35 C202.68,222.35 202.81,222.12 202.81,222.12 C202.81,222.12 202.94,221.89 202.94,221.89 C202.94,221.89 203.07,221.66 203.07,221.66 C203.07,221.66 203.2,221.44 203.2,221.44 C203.2,221.44 203.33,221.21 203.33,221.21 C203.33,221.21 203.46,220.98 203.46,220.98 C203.46,220.98 203.58,220.76 203.58,220.76 C203.58,220.76 203.71,220.53 203.71,220.53 C203.71,220.53 203.84,220.3 203.84,220.3 C203.84,220.3 203.97,220.07 203.97,220.07 C203.97,220.07 204.1,219.85 204.1,219.85 C204.1,219.85 204.23,219.62 204.23,219.62 C204.23,219.62 204.36,219.39 204.36,219.39 C204.36,219.39 204.49,219.16 204.49,219.16 C204.49,219.16 204.62,218.94 204.62,218.94 C204.62,218.94 204.75,218.71 204.75,218.71 C204.75,218.71 204.88,218.48 204.88,218.48 C204.88,218.48 205.01,218.26 205.01,218.26 C205.01,218.26 205.13,218.03 205.13,218.03 C205.13,218.03 205.26,217.8 205.26,217.8 C205.26,217.8 205.39,217.57 205.39,217.57 C205.39,217.57 205.52,217.35 205.52,217.35 C205.52,217.35 205.65,217.12 205.65,217.12 C205.65,217.12 205.78,216.89 205.78,216.89 C205.78,216.89 205.91,216.66 205.91,216.66 C205.91,216.66 206.04,216.44 206.04,216.44 C206.04,216.44 206.17,216.21 206.17,216.21 C206.17,216.21 206.3,215.98 206.3,215.98 C206.3,215.98 206.43,215.76 206.43,215.76 C206.43,215.76 206.56,215.53 206.56,215.53 C206.56,215.53 206.68,215.3 206.68,215.3 C206.68,215.3 206.81,215.07 206.81,215.07 C206.81,215.07 206.94,214.85 206.94,214.85 C206.94,214.85 207.07,214.62 207.07,214.62 C207.07,214.62 207.2,214.39 207.2,214.39 C207.2,214.39 207.33,214.17 207.33,214.17 C207.33,214.17 207.46,213.94 207.46,213.94 C207.46,213.94 207.59,213.71 207.59,213.71 C207.59,213.71 207.72,213.48 207.72,213.48 C207.72,213.48 207.85,213.26 207.85,213.26 C207.85,213.26 207.98,213.03 207.98,213.03 C207.98,213.03 208.11,212.8 208.11,212.8 C208.11,212.8 208.23,212.57 208.23,212.57 C208.23,212.57 208.36,212.35 208.36,212.35 C208.36,212.35 208.49,212.12 208.49,212.12 C208.49,212.12 208.62,211.89 208.62,211.89 C208.62,211.89 208.75,211.67 208.75,211.67 C208.75,211.67 208.88,211.44 208.88,211.44 C208.88,211.44 209.01,211.21 209.01,211.21 C209.01,211.21 209.14,210.98 209.14,210.98 C209.14,210.98 209.27,210.76 209.27,210.76 C209.27,210.76 209.4,210.53 209.4,210.53 C209.4,210.53 209.53,210.3 209.53,210.3 C209.53,210.3 209.66,210.08 209.66,210.08 C209.66,210.08 209.78,209.85 209.78,209.85 C209.78,209.85 209.91,209.62 209.91,209.62 C209.91,209.62 210.04,209.39 210.04,209.39 C210.04,209.39 210.17,209.17 210.17,209.17 C210.17,209.17 210.3,208.94 210.3,208.94 C210.3,208.94 210.43,208.71 210.43,208.71 C210.43,208.71 210.56,208.48 210.56,208.48 C210.56,208.48 210.69,208.26 210.69,208.26 C210.69,208.26 210.82,208.03 210.82,208.03 C210.82,208.03 210.95,207.8 210.95,207.8 C210.95,207.8 211.08,207.58 211.08,207.58 C211.08,207.58 211.21,207.35 211.21,207.35 C211.21,207.35 211.33,207.12 211.33,207.12 C211.33,207.12 211.46,206.89 211.46,206.89 C211.46,206.89 211.59,206.67 211.59,206.67 C211.59,206.67 211.72,206.44 211.72,206.44 C211.72,206.44 211.85,206.21 211.85,206.21 C211.85,206.21 211.98,205.98 211.98,205.98 C211.98,205.98 212.13,205.76 212.13,205.76 C212.13,205.76 212.27,205.54 212.27,205.54 C212.27,205.54 212.41,205.33 212.41,205.33 C212.41,205.33 212.57,205.12 212.57,205.12 C212.57,205.12 212.74,204.92 212.74,204.92 C212.74,204.92 212.91,204.72 212.91,204.72 C212.91,204.72 213.1,204.54 213.1,204.54 C213.1,204.54 213.29,204.36 213.29,204.36 C213.29,204.36 213.49,204.19 213.49,204.19 C213.49,204.19 213.69,204.03 213.69,204.03 C213.69,204.03 213.9,203.87 213.9,203.87 C213.9,203.87 214.12,203.73 214.12,203.73 C214.12,203.73 214.34,203.59 214.34,203.59 C214.34,203.59 214.57,203.46 214.57,203.46 C214.57,203.46 214.81,203.35 214.81,203.35 C214.81,203.35 215.04,203.24 215.04,203.24 C215.04,203.24 215.28,203.14 215.28,203.14 C215.28,203.14 215.53,203.06 215.53,203.06 C215.53,203.06 215.78,202.98 215.78,202.98 C215.78,202.98 216.03,202.91 216.03,202.91 C216.03,202.91 216.29,202.86 216.29,202.86 C216.29,202.86 216.55,202.82 216.55,202.82 C216.55,202.82 216.8,202.77 216.8,202.77 C216.8,202.77 217.07,202.76 217.07,202.76 C217.07,202.76 217.33,202.74 217.33,202.74 C217.33,202.74 217.59,202.73 217.59,202.73c " android:valueTo="M217.68 210.56 C217.68,210.56 217.81,210.57 217.81,210.57 C217.81,210.57 217.93,210.57 217.93,210.57 C217.93,210.57 218.06,210.58 218.06,210.58 C218.06,210.58 218.18,210.59 218.18,210.59 C218.18,210.59 218.31,210.59 218.31,210.59 C218.31,210.59 218.43,210.61 218.43,210.61 C218.43,210.61 218.56,210.63 218.56,210.63 C218.56,210.63 218.68,210.64 218.68,210.64 C218.68,210.64 218.81,210.66 218.81,210.66 C218.81,210.66 218.93,210.68 218.93,210.68 C218.93,210.68 219.05,210.7 219.05,210.7 C219.05,210.7 219.18,210.72 219.18,210.72 C219.18,210.72 219.3,210.75 219.3,210.75 C219.3,210.75 219.42,210.78 219.42,210.78 C219.42,210.78 219.54,210.81 219.54,210.81 C219.54,210.81 219.66,210.84 219.66,210.84 C219.66,210.84 219.79,210.87 219.79,210.87 C219.79,210.87 219.91,210.91 219.91,210.91 C219.91,210.91 220.03,210.95 220.03,210.95 C220.03,210.95 220.14,210.99 220.14,210.99 C220.14,210.99 220.26,211.04 220.26,211.04 C220.26,211.04 220.38,211.08 220.38,211.08 C220.38,211.08 220.5,211.12 220.5,211.12 C220.5,211.12 220.62,211.17 220.62,211.17 C220.62,211.17 220.73,211.22 220.73,211.22 C220.73,211.22 220.84,211.27 220.84,211.27 C220.84,211.27 220.96,211.32 220.96,211.32 C220.96,211.32 221.07,211.38 221.07,211.38 C221.07,211.38 221.19,211.43 221.19,211.43 C221.19,211.43 221.3,211.49 221.3,211.49 C221.3,211.49 221.41,211.55 221.41,211.55 C221.41,211.55 221.51,211.61 221.51,211.61 C221.51,211.61 221.62,211.68 221.62,211.68 C221.62,211.68 221.73,211.74 221.73,211.74 C221.73,211.74 221.84,211.8 221.84,211.8 C221.84,211.8 221.94,211.87 221.94,211.87 C221.94,211.87 222.05,211.94 222.05,211.94 C222.05,211.94 222.15,212.02 222.15,212.02 C222.15,212.02 222.25,212.09 222.25,212.09 C222.25,212.09 222.35,212.16 222.35,212.16 C222.35,212.16 222.46,212.23 222.46,212.23 C222.46,212.23 222.55,212.31 222.55,212.31 C222.55,212.31 222.65,212.4 222.65,212.4 C222.65,212.4 222.74,212.48 222.74,212.48 C222.74,212.48 222.84,212.56 222.84,212.56 C222.84,212.56 222.93,212.64 222.93,212.64 C222.93,212.64 223.03,212.72 223.03,212.72 C223.03,212.72 223.12,212.81 223.12,212.81 C223.12,212.81 223.21,212.9 223.21,212.9 C223.21,212.9 223.29,212.99 223.29,212.99 C223.29,212.99 223.38,213.08 223.38,213.08 C223.38,213.08 223.47,213.17 223.47,213.17 C223.47,213.17 223.55,213.26 223.55,213.26 C223.55,213.26 223.63,213.36 223.63,213.36 C223.63,213.36 223.71,213.46 223.71,213.46 C223.71,213.46 223.79,213.56 223.79,213.56 C223.79,213.56 223.87,213.66 223.87,213.66 C223.87,213.66 223.95,213.75 223.95,213.75 C223.95,213.75 224.03,213.85 224.03,213.85 C224.03,213.85 224.09,213.96 224.09,213.96 C224.09,213.96 224.16,214.06 224.16,214.06 C224.16,214.06 224.23,214.17 224.23,214.17 C224.23,214.17 224.3,214.27 224.3,214.27 C224.3,214.27 224.37,214.38 224.37,214.38 C224.37,214.38 224.44,214.48 224.44,214.48 C224.44,214.48 224.5,214.59 224.5,214.59 C224.5,214.59 224.56,214.7 224.56,214.7 C224.56,214.7 224.62,214.81 224.62,214.81 C224.62,214.81 224.68,214.93 224.68,214.93 C224.68,214.93 224.74,215.04 224.74,215.04 C224.74,215.04 224.79,215.15 224.79,215.15 C224.79,215.15 224.84,215.26 224.84,215.26 C224.84,215.26 224.89,215.38 224.89,215.38 C224.89,215.38 224.94,215.5 224.94,215.5 C224.94,215.5 224.99,215.61 224.99,215.61 C224.99,215.61 225.04,215.73 225.04,215.73 C225.04,215.73 225.08,215.84 225.08,215.84 C225.08,215.84 225.12,215.96 225.12,215.96 C225.12,215.96 225.16,216.08 225.16,216.08 C225.16,216.08 225.19,216.2 225.19,216.2 C225.19,216.2 225.23,216.32 225.23,216.32 C225.23,216.32 225.27,216.44 225.27,216.44 C225.27,216.44 225.3,216.56 225.3,216.56 C225.3,216.56 225.33,216.69 225.33,216.69 C225.33,216.69 225.35,216.81 225.35,216.81 C225.35,216.81 225.38,216.93 225.38,216.93 C225.38,216.93 225.41,217.06 225.41,217.06 C225.41,217.06 225.43,217.18 225.43,217.18 C225.43,217.18 225.46,217.3 225.46,217.3 C225.46,217.3 225.47,217.43 225.47,217.43 C225.47,217.43 225.49,217.55 225.49,217.55 C225.49,217.55 225.5,217.68 225.5,217.68 C225.5,217.68 225.52,217.8 225.52,217.8 C225.52,217.8 225.52,217.93 225.52,217.93 C225.52,217.93 225.53,218.05 225.53,218.05 C225.53,218.05 225.54,218.18 225.54,218.18 C225.54,218.18 225.54,218.3 225.54,218.3 C225.54,218.3 225.55,218.43 225.55,218.43 C225.55,218.43 225.55,218.55 225.55,218.55 C225.55,218.55 225.55,218.68 225.55,218.68 C225.55,218.68 225.54,218.8 225.54,218.8 C225.54,218.8 225.54,218.93 225.54,218.93 C225.54,218.93 225.53,219.05 225.53,219.05 C225.53,219.05 225.52,219.18 225.52,219.18 C225.52,219.18 225.52,219.31 225.52,219.31 C225.52,219.31 225.5,219.43 225.5,219.43 C225.5,219.43 225.48,219.55 225.48,219.55 C225.48,219.55 225.47,219.68 225.47,219.68 C225.47,219.68 225.45,219.8 225.45,219.8 C225.45,219.8 225.43,219.93 225.43,219.93 C225.43,219.93 225.41,220.05 225.41,220.05 C225.41,220.05 225.39,220.17 225.39,220.17 C225.39,220.17 225.36,220.3 225.36,220.3 C225.36,220.3 225.33,220.42 225.33,220.42 C225.33,220.42 225.3,220.54 225.3,220.54 C225.3,220.54 225.27,220.66 225.27,220.66 C225.27,220.66 225.24,220.78 225.24,220.78 C225.24,220.78 225.2,220.9 225.2,220.9 C225.2,220.9 225.16,221.02 225.16,221.02 C225.16,221.02 225.12,221.14 225.12,221.14 C225.12,221.14 225.08,221.26 225.08,221.26 C225.08,221.26 225.03,221.38 225.03,221.38 C225.03,221.38 224.99,221.5 224.99,221.5 C224.99,221.5 224.95,221.61 224.95,221.61 C224.95,221.61 224.89,221.73 224.89,221.73 C224.89,221.73 224.84,221.84 224.84,221.84 C224.84,221.84 224.79,221.96 224.79,221.96 C224.79,221.96 224.73,222.07 224.73,222.07 C224.73,222.07 224.68,222.18 224.68,222.18 C224.68,222.18 224.62,222.29 224.62,222.29 C224.62,222.29 224.56,222.4 224.56,222.4 C224.56,222.4 224.5,222.51 224.5,222.51 C224.5,222.51 224.44,222.62 224.44,222.62 C224.44,222.62 224.37,222.73 224.37,222.73 C224.37,222.73 224.31,222.84 224.31,222.84 C224.31,222.84 224.24,222.94 224.24,222.94 C224.24,222.94 224.17,223.05 224.17,223.05 C224.17,223.05 224.09,223.15 224.09,223.15 C224.09,223.15 224.02,223.25 224.02,223.25 C224.02,223.25 223.95,223.35 223.95,223.35 C223.95,223.35 223.88,223.45 223.88,223.45 C223.88,223.45 223.8,223.55 223.8,223.55 C223.8,223.55 223.71,223.65 223.71,223.65 C223.71,223.65 223.63,223.74 223.63,223.74 C223.63,223.74 223.55,223.84 223.55,223.84 C223.55,223.84 223.47,223.93 223.47,223.93 C223.47,223.93 223.39,224.03 223.39,224.03 C223.39,224.03 223.3,224.12 223.3,224.12 C223.3,224.12 223.21,224.2 223.21,224.2 C223.21,224.2 223.12,224.29 223.12,224.29 C223.12,224.29 223.03,224.38 223.03,224.38 C223.03,224.38 222.94,224.46 222.94,224.46 C222.94,224.46 222.85,224.55 222.85,224.55 C222.85,224.55 222.75,224.63 222.75,224.63 C222.75,224.63 222.65,224.71 222.65,224.71 C222.65,224.71 222.55,224.79 222.55,224.79 C222.55,224.79 222.46,224.87 222.46,224.87 C222.46,224.87 222.36,224.95 222.36,224.95 C222.36,224.95 222.26,225.02 222.26,225.02 C222.26,225.02 222.15,225.09 222.15,225.09 C222.15,225.09 222.05,225.16 222.05,225.16 C222.05,225.16 221.94,225.23 221.94,225.23 C221.94,225.23 221.84,225.3 221.84,225.3 C221.84,225.3 221.74,225.37 221.74,225.37 C221.74,225.37 221.63,225.44 221.63,225.44 C221.63,225.44 221.52,225.5 221.52,225.5 C221.52,225.5 221.41,225.56 221.41,225.56 C221.41,225.56 221.3,225.62 221.3,225.62 C221.3,225.62 221.19,225.68 221.19,225.68 C221.19,225.68 221.08,225.73 221.08,225.73 C221.08,225.73 220.96,225.79 220.96,225.79 C220.96,225.79 220.85,225.84 220.85,225.84 C220.85,225.84 220.73,225.89 220.73,225.89 C220.73,225.89 220.62,225.94 220.62,225.94 C220.62,225.94 220.5,225.99 220.5,225.99 C220.5,225.99 220.38,226.03 220.38,226.03 C220.38,226.03 220.27,226.08 220.27,226.08 C220.27,226.08 220.15,226.12 220.15,226.12 C220.15,226.12 220.03,226.15 220.03,226.15 C220.03,226.15 219.91,226.19 219.91,226.19 C219.91,226.19 219.79,226.23 219.79,226.23 C219.79,226.23 219.67,226.27 219.67,226.27 C219.67,226.27 219.55,226.3 219.55,226.3 C219.55,226.3 219.42,226.33 219.42,226.33 C219.42,226.33 219.3,226.35 219.3,226.35 C219.3,226.35 219.18,226.38 219.18,226.38 C219.18,226.38 219.06,226.4 219.06,226.4 C219.06,226.4 218.93,226.43 218.93,226.43 C218.93,226.43 218.81,226.45 218.81,226.45 C218.81,226.45 218.68,226.47 218.68,226.47 C218.68,226.47 218.56,226.49 218.56,226.49 C218.56,226.49 218.44,226.5 218.44,226.5 C218.44,226.5 218.31,226.52 218.31,226.52 C218.31,226.52 218.19,226.52 218.19,226.52 C218.19,226.52 218.06,226.53 218.06,226.53 C218.06,226.53 217.93,226.53 217.93,226.53 C217.93,226.53 217.81,226.54 217.81,226.54 C217.81,226.54 217.68,226.55 217.68,226.55 C217.68,226.55 217.56,226.55 217.56,226.55 C217.56,226.55 217.43,226.55 217.43,226.55 C217.43,226.55 217.31,226.54 217.31,226.54 C217.31,226.54 217.18,226.53 217.18,226.53 C217.18,226.53 217.05,226.53 217.05,226.53 C217.05,226.53 216.93,226.52 216.93,226.52 C216.93,226.52 216.8,226.52 216.8,226.52 C216.8,226.52 216.68,226.5 216.68,226.5 C216.68,226.5 216.55,226.48 216.55,226.48 C216.55,226.48 216.43,226.46 216.43,226.46 C216.43,226.46 216.31,226.45 216.31,226.45 C216.31,226.45 216.18,226.43 216.18,226.43 C216.18,226.43 216.06,226.41 216.06,226.41 C216.06,226.41 215.93,226.38 215.93,226.38 C215.93,226.38 215.81,226.35 215.81,226.35 C215.81,226.35 215.69,226.32 215.69,226.32 C215.69,226.32 215.57,226.29 215.57,226.29 C215.57,226.29 215.45,226.26 215.45,226.26 C215.45,226.26 215.32,226.23 215.32,226.23 C215.32,226.23 215.2,226.2 215.2,226.2 C215.2,226.2 215.09,226.16 215.09,226.16 C215.09,226.16 214.97,226.12 214.97,226.12 C214.97,226.12 214.85,226.07 214.85,226.07 C214.85,226.07 214.73,226.03 214.73,226.03 C214.73,226.03 214.61,225.99 214.61,225.99 C214.61,225.99 214.5,225.94 214.5,225.94 C214.5,225.94 214.38,225.89 214.38,225.89 C214.38,225.89 214.27,225.84 214.27,225.84 C214.27,225.84 214.15,225.79 214.15,225.79 C214.15,225.79 214.04,225.73 214.04,225.73 C214.04,225.73 213.93,225.68 213.93,225.68 C213.93,225.68 213.81,225.62 213.81,225.62 C213.81,225.62 213.71,225.56 213.71,225.56 C213.71,225.56 213.6,225.5 213.6,225.5 C213.6,225.5 213.49,225.43 213.49,225.43 C213.49,225.43 213.38,225.37 213.38,225.37 C213.38,225.37 213.27,225.31 213.27,225.31 C213.27,225.31 213.17,225.24 213.17,225.24 C213.17,225.24 213.06,225.16 213.06,225.16 C213.06,225.16 212.96,225.09 212.96,225.09 C212.96,225.09 212.86,225.02 212.86,225.02 C212.86,225.02 212.76,224.95 212.76,224.95 C212.76,224.95 212.65,224.87 212.65,224.87 C212.65,224.87 212.56,224.79 212.56,224.79 C212.56,224.79 212.46,224.71 212.46,224.71 C212.46,224.71 212.37,224.63 212.37,224.63 C212.37,224.63 212.27,224.55 212.27,224.55 C212.27,224.55 212.18,224.47 212.18,224.47 C212.18,224.47 212.08,224.38 212.08,224.38 C212.08,224.38 211.99,224.3 211.99,224.3 C211.99,224.3 211.91,224.2 211.91,224.2 C211.91,224.2 211.82,224.11 211.82,224.11 C211.82,224.11 211.73,224.02 211.73,224.02 C211.73,224.02 211.64,223.93 211.64,223.93 C211.64,223.93 211.56,223.84 211.56,223.84 C211.56,223.84 211.48,223.75 211.48,223.75 C211.48,223.75 211.4,223.65 211.4,223.65 C211.4,223.65 211.32,223.55 211.32,223.55 C211.32,223.55 211.24,223.45 211.24,223.45 C211.24,223.45 211.16,223.35 211.16,223.35 C211.16,223.35 211.09,223.26 211.09,223.26 C211.09,223.26 211.02,223.15 211.02,223.15 C211.02,223.15 210.95,223.05 210.95,223.05 C210.95,223.05 210.88,222.94 210.88,222.94 C210.88,222.94 210.81,222.84 210.81,222.84 C210.81,222.84 210.74,222.73 210.74,222.73 C210.74,222.73 210.67,222.63 210.67,222.63 C210.67,222.63 210.61,222.52 210.61,222.52 C210.61,222.52 210.55,222.4 210.55,222.4 C210.55,222.4 210.49,222.29 210.49,222.29 C210.49,222.29 210.43,222.18 210.43,222.18 C210.43,222.18 210.38,222.07 210.38,222.07 C210.38,222.07 210.32,221.96 210.32,221.96 C210.32,221.96 210.27,221.84 210.27,221.84 C210.27,221.84 210.22,221.73 210.22,221.73 C210.22,221.73 210.17,221.61 210.17,221.61 C210.17,221.61 210.12,221.5 210.12,221.5 C210.12,221.5 210.08,221.38 210.08,221.38 C210.08,221.38 210.03,221.26 210.03,221.26 C210.03,221.26 209.99,221.14 209.99,221.14 C209.99,221.14 209.96,221.02 209.96,221.02 C209.96,221.02 209.92,220.9 209.92,220.9 C209.92,220.9 209.88,220.78 209.88,220.78 C209.88,220.78 209.84,220.67 209.84,220.67 C209.84,220.67 209.81,220.54 209.81,220.54 C209.81,220.54 209.78,220.42 209.78,220.42 C209.78,220.42 209.76,220.3 209.76,220.3 C209.76,220.3 209.73,220.18 209.73,220.18 C209.73,220.18 209.71,220.05 209.71,220.05 C209.71,220.05 209.68,219.93 209.68,219.93 C209.68,219.93 209.66,219.81 209.66,219.81 C209.66,219.81 209.64,219.68 209.64,219.68 C209.64,219.68 209.62,219.56 209.62,219.56 C209.62,219.56 209.61,219.43 209.61,219.43 C209.61,219.43 209.59,219.31 209.59,219.31 C209.59,219.31 209.59,219.18 209.59,219.18 C209.59,219.18 209.58,219.06 209.58,219.06 C209.58,219.06 209.58,218.93 209.58,218.93 C209.58,218.93 209.57,218.81 209.57,218.81 C209.57,218.81 209.56,218.68 209.56,218.68 C209.56,218.68 209.56,218.56 209.56,218.56 C209.56,218.56 209.56,218.43 209.56,218.43 C209.56,218.43 209.57,218.3 209.57,218.3 C209.57,218.3 209.58,218.18 209.58,218.18 C209.58,218.18 209.58,218.05 209.58,218.05 C209.58,218.05 209.59,217.93 209.59,217.93 C209.59,217.93 209.59,217.8 209.59,217.8 C209.59,217.8 209.61,217.68 209.61,217.68 C209.61,217.68 209.63,217.55 209.63,217.55 C209.63,217.55 209.65,217.43 209.65,217.43 C209.65,217.43 209.66,217.31 209.66,217.31 C209.66,217.31 209.68,217.18 209.68,217.18 C209.68,217.18 209.7,217.06 209.7,217.06 C209.7,217.06 209.73,216.93 209.73,216.93 C209.73,216.93 209.76,216.81 209.76,216.81 C209.76,216.81 209.79,216.69 209.79,216.69 C209.79,216.69 209.82,216.57 209.82,216.57 C209.82,216.57 209.85,216.45 209.85,216.45 C209.85,216.45 209.88,216.32 209.88,216.32 C209.88,216.32 209.91,216.2 209.91,216.2 C209.91,216.2 209.95,216.08 209.95,216.08 C209.95,216.08 210,215.97 210,215.97 C210,215.97 210.04,215.85 210.04,215.85 C210.04,215.85 210.08,215.73 210.08,215.73 C210.08,215.73 210.12,215.61 210.12,215.61 C210.12,215.61 210.17,215.49 210.17,215.49 C210.17,215.49 210.22,215.38 210.22,215.38 C210.22,215.38 210.27,215.27 210.27,215.27 C210.27,215.27 210.33,215.15 210.33,215.15 C210.33,215.15 210.38,215.04 210.38,215.04 C210.38,215.04 210.43,214.92 210.43,214.92 C210.43,214.92 210.49,214.81 210.49,214.81 C210.49,214.81 210.55,214.7 210.55,214.7 C210.55,214.7 210.61,214.6 210.61,214.6 C210.61,214.6 210.68,214.49 210.68,214.49 C210.68,214.49 210.74,214.38 210.74,214.38 C210.74,214.38 210.8,214.27 210.8,214.27 C210.8,214.27 210.87,214.17 210.87,214.17 C210.87,214.17 210.95,214.06 210.95,214.06 C210.95,214.06 211.02,213.96 211.02,213.96 C211.02,213.96 211.09,213.86 211.09,213.86 C211.09,213.86 211.16,213.76 211.16,213.76 C211.16,213.76 211.24,213.65 211.24,213.65 C211.24,213.65 211.32,213.56 211.32,213.56 C211.32,213.56 211.4,213.46 211.4,213.46 C211.4,213.46 211.48,213.37 211.48,213.37 C211.48,213.37 211.56,213.27 211.56,213.27 C211.56,213.27 211.64,213.18 211.64,213.18 C211.64,213.18 211.73,213.08 211.73,213.08 C211.73,213.08 211.82,212.99 211.82,212.99 C211.82,212.99 211.91,212.9 211.91,212.9 C211.91,212.9 212,212.82 212,212.82 C212,212.82 212.09,212.73 212.09,212.73 C212.09,212.73 212.18,212.64 212.18,212.64 C212.18,212.64 212.27,212.56 212.27,212.56 C212.27,212.56 212.36,212.48 212.36,212.48 C212.36,212.48 212.46,212.4 212.46,212.4 C212.46,212.4 212.56,212.32 212.56,212.32 C212.56,212.32 212.66,212.24 212.66,212.24 C212.66,212.24 212.76,212.16 212.76,212.16 C212.76,212.16 212.85,212.08 212.85,212.08 C212.85,212.08 212.96,212.02 212.96,212.02 C212.96,212.02 213.06,211.95 213.06,211.95 C213.06,211.95 213.17,211.88 213.17,211.88 C213.17,211.88 213.27,211.81 213.27,211.81 C213.27,211.81 213.38,211.74 213.38,211.74 C213.38,211.74 213.48,211.67 213.48,211.67 C213.48,211.67 213.6,211.61 213.6,211.61 C213.6,211.61 213.71,211.55 213.71,211.55 C213.71,211.55 213.82,211.49 213.82,211.49 C213.82,211.49 213.93,211.43 213.93,211.43 C213.93,211.43 214.04,211.37 214.04,211.37 C214.04,211.37 214.15,211.32 214.15,211.32 C214.15,211.32 214.27,211.27 214.27,211.27 C214.27,211.27 214.38,211.22 214.38,211.22 C214.38,211.22 214.5,211.17 214.5,211.17 C214.5,211.17 214.61,211.12 214.61,211.12 C214.61,211.12 214.73,211.07 214.73,211.07 C214.73,211.07 214.85,211.03 214.85,211.03 C214.85,211.03 214.97,210.99 214.97,210.99 C214.97,210.99 215.09,210.95 215.09,210.95 C215.09,210.95 215.21,210.92 215.21,210.92 C215.21,210.92 215.33,210.88 215.33,210.88 C215.33,210.88 215.45,210.84 215.45,210.84 C215.45,210.84 215.57,210.81 215.57,210.81 C215.57,210.81 215.69,210.78 215.69,210.78 C215.69,210.78 215.81,210.76 215.81,210.76 C215.81,210.76 215.93,210.73 215.93,210.73 C215.93,210.73 216.06,210.7 216.06,210.7 C216.06,210.7 216.18,210.68 216.18,210.68 C216.18,210.68 216.3,210.65 216.3,210.65 C216.3,210.65 216.43,210.64 216.43,210.64 C216.43,210.64 216.55,210.62 216.55,210.62 C216.55,210.62 216.68,210.61 216.68,210.61 C216.68,210.61 216.8,210.59 216.8,210.59 C216.8,210.59 216.93,210.59 216.93,210.59 C216.93,210.59 217.05,210.58 217.05,210.58 C217.05,210.58 217.18,210.58 217.18,210.58 C217.18,210.58 217.3,210.57 217.3,210.57 C217.3,210.57 217.43,210.56 217.43,210.56 C217.43,210.56 217.56,210.56 217.56,210.56 C217.56,210.56 217.68,210.56 217.68,210.56c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/pin_dot_shape_6_avd.xml b/packages/SystemUI/res/drawable/pin_dot_shape_6_avd.xml
new file mode 100644
index 0000000..e7ce426
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pin_dot_shape_6_avd.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="60dp" android:width="60dp" android:viewportHeight="60" android:viewportWidth="60"><group android:name="_R_G"><group android:name="_R_G_L_0_G" android:translateX="-187.543" android:translateY="-188.546"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="33" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="67" android:startOffset="0" android:valueFrom="M217.62 214.55 C217.62,214.55 217.68,214.55 217.68,214.55 C217.68,214.55 217.74,214.56 217.74,214.56 C217.74,214.56 217.81,214.56 217.81,214.56 C217.81,214.56 217.87,214.56 217.87,214.56 C217.87,214.56 217.93,214.57 217.93,214.57 C217.93,214.57 218,214.57 218,214.57 C218,214.57 218.06,214.58 218.06,214.58 C218.06,214.58 218.12,214.59 218.12,214.59 C218.12,214.59 218.18,214.6 218.18,214.6 C218.18,214.6 218.24,214.61 218.24,214.61 C218.24,214.61 218.31,214.62 218.31,214.62 C218.31,214.62 218.37,214.63 218.37,214.63 C218.37,214.63 218.43,214.65 218.43,214.65 C218.43,214.65 218.49,214.66 218.49,214.66 C218.49,214.66 218.55,214.68 218.55,214.68 C218.55,214.68 218.61,214.69 218.61,214.69 C218.61,214.69 218.67,214.71 218.67,214.71 C218.67,214.71 218.73,214.73 218.73,214.73 C218.73,214.73 218.79,214.75 218.79,214.75 C218.79,214.75 218.85,214.77 218.85,214.77 C218.85,214.77 218.91,214.79 218.91,214.79 C218.91,214.79 218.97,214.81 218.97,214.81 C218.97,214.81 219.03,214.83 219.03,214.83 C219.03,214.83 219.09,214.85 219.09,214.85 C219.09,214.85 219.15,214.88 219.15,214.88 C219.15,214.88 219.2,214.9 219.2,214.9 C219.2,214.9 219.26,214.93 219.26,214.93 C219.26,214.93 219.32,214.96 219.32,214.96 C219.32,214.96 219.37,214.98 219.37,214.98 C219.37,214.98 219.43,215.01 219.43,215.01 C219.43,215.01 219.48,215.05 219.48,215.05 C219.48,215.05 219.54,215.08 219.54,215.08 C219.54,215.08 219.59,215.11 219.59,215.11 C219.59,215.11 219.65,215.14 219.65,215.14 C219.65,215.14 219.7,215.17 219.7,215.17 C219.7,215.17 219.75,215.21 219.75,215.21 C219.75,215.21 219.81,215.24 219.81,215.24 C219.81,215.24 219.86,215.28 219.86,215.28 C219.86,215.28 219.91,215.32 219.91,215.32 C219.91,215.32 219.96,215.35 219.96,215.35 C219.96,215.35 220.01,215.39 220.01,215.39 C220.01,215.39 220.06,215.43 220.06,215.43 C220.06,215.43 220.11,215.47 220.11,215.47 C220.11,215.47 220.16,215.51 220.16,215.51 C220.16,215.51 220.2,215.55 220.2,215.55 C220.2,215.55 220.25,215.59 220.25,215.59 C220.25,215.59 220.3,215.63 220.3,215.63 C220.3,215.63 220.34,215.68 220.34,215.68 C220.34,215.68 220.39,215.72 220.39,215.72 C220.39,215.72 220.43,215.77 220.43,215.77 C220.43,215.77 220.47,215.81 220.47,215.81 C220.47,215.81 220.52,215.86 220.52,215.86 C220.52,215.86 220.56,215.9 220.56,215.9 C220.56,215.9 220.6,215.95 220.6,215.95 C220.6,215.95 220.64,216 220.64,216 C220.64,216 220.68,216.05 220.68,216.05 C220.68,216.05 220.72,216.1 220.72,216.1 C220.72,216.1 220.76,216.15 220.76,216.15 C220.76,216.15 220.8,216.2 220.8,216.2 C220.8,216.2 220.83,216.25 220.83,216.25 C220.83,216.25 220.87,216.3 220.87,216.3 C220.87,216.3 220.9,216.36 220.9,216.36 C220.9,216.36 220.94,216.41 220.94,216.41 C220.94,216.41 220.97,216.46 220.97,216.46 C220.97,216.46 221,216.51 221,216.51 C221,216.51 221.03,216.57 221.03,216.57 C221.03,216.57 221.06,216.63 221.06,216.63 C221.06,216.63 221.09,216.68 221.09,216.68 C221.09,216.68 221.12,216.74 221.12,216.74 C221.12,216.74 221.15,216.79 221.15,216.79 C221.15,216.79 221.18,216.85 221.18,216.85 C221.18,216.85 221.21,216.91 221.21,216.91 C221.21,216.91 221.23,216.96 221.23,216.96 C221.23,216.96 221.25,217.02 221.25,217.02 C221.25,217.02 221.28,217.08 221.28,217.08 C221.28,217.08 221.3,217.14 221.3,217.14 C221.3,217.14 221.33,217.2 221.33,217.2 C221.33,217.2 221.34,217.26 221.34,217.26 C221.34,217.26 221.36,217.32 221.36,217.32 C221.36,217.32 221.38,217.38 221.38,217.38 C221.38,217.38 221.4,217.44 221.4,217.44 C221.4,217.44 221.42,217.5 221.42,217.5 C221.42,217.5 221.44,217.56 221.44,217.56 C221.44,217.56 221.45,217.62 221.45,217.62 C221.45,217.62 221.46,217.68 221.46,217.68 C221.46,217.68 221.48,217.74 221.48,217.74 C221.48,217.74 221.49,217.8 221.49,217.8 C221.49,217.8 221.5,217.87 221.5,217.87 C221.5,217.87 221.51,217.93 221.51,217.93 C221.51,217.93 221.52,217.99 221.52,217.99 C221.52,217.99 221.53,218.05 221.53,218.05 C221.53,218.05 221.54,218.11 221.54,218.11 C221.54,218.11 221.54,218.18 221.54,218.18 C221.54,218.18 221.55,218.24 221.55,218.24 C221.55,218.24 221.55,218.3 221.55,218.3 C221.55,218.3 221.55,218.37 221.55,218.37 C221.55,218.37 221.56,218.43 221.56,218.43 C221.56,218.43 221.56,218.49 221.56,218.49 C221.56,218.49 221.56,218.55 221.56,218.55 C221.56,218.55 221.56,218.62 221.56,218.62 C221.56,218.62 221.56,218.68 221.56,218.68 C221.56,218.68 221.55,218.74 221.55,218.74 C221.55,218.74 221.55,218.81 221.55,218.81 C221.55,218.81 221.55,218.87 221.55,218.87 C221.55,218.87 221.54,218.93 221.54,218.93 C221.54,218.93 221.54,218.99 221.54,218.99 C221.54,218.99 221.53,219.06 221.53,219.06 C221.53,219.06 221.52,219.12 221.52,219.12 C221.52,219.12 221.51,219.18 221.51,219.18 C221.51,219.18 221.5,219.24 221.5,219.24 C221.5,219.24 221.49,219.3 221.49,219.3 C221.49,219.3 221.48,219.37 221.48,219.37 C221.48,219.37 221.46,219.43 221.46,219.43 C221.46,219.43 221.45,219.49 221.45,219.49 C221.45,219.49 221.43,219.55 221.43,219.55 C221.43,219.55 221.42,219.61 221.42,219.61 C221.42,219.61 221.4,219.67 221.4,219.67 C221.4,219.67 221.39,219.73 221.39,219.73 C221.39,219.73 221.37,219.79 221.37,219.79 C221.37,219.79 221.34,219.85 221.34,219.85 C221.34,219.85 221.32,219.91 221.32,219.91 C221.32,219.91 221.3,219.97 221.3,219.97 C221.3,219.97 221.28,220.03 221.28,220.03 C221.28,220.03 221.26,220.09 221.26,220.09 C221.26,220.09 221.23,220.14 221.23,220.14 C221.23,220.14 221.21,220.2 221.21,220.2 C221.21,220.2 221.18,220.26 221.18,220.26 C221.18,220.26 221.15,220.32 221.15,220.32 C221.15,220.32 221.13,220.37 221.13,220.37 C221.13,220.37 221.1,220.43 221.1,220.43 C221.1,220.43 221.07,220.48 221.07,220.48 C221.07,220.48 221.03,220.54 221.03,220.54 C221.03,220.54 221,220.59 221,220.59 C221,220.59 220.97,220.65 220.97,220.65 C220.97,220.65 220.94,220.7 220.94,220.7 C220.94,220.7 220.9,220.75 220.9,220.75 C220.9,220.75 220.87,220.8 220.87,220.8 C220.87,220.8 220.83,220.86 220.83,220.86 C220.83,220.86 220.8,220.91 220.8,220.91 C220.8,220.91 220.76,220.96 220.76,220.96 C220.76,220.96 220.72,221.01 220.72,221.01 C220.72,221.01 220.68,221.06 220.68,221.06 C220.68,221.06 220.64,221.11 220.64,221.11 C220.64,221.11 220.6,221.15 220.6,221.15 C220.6,221.15 220.56,221.2 220.56,221.2 C220.56,221.2 220.52,221.25 220.52,221.25 C220.52,221.25 220.48,221.3 220.48,221.3 C220.48,221.3 220.43,221.34 220.43,221.34 C220.43,221.34 220.39,221.38 220.39,221.38 C220.39,221.38 220.34,221.43 220.34,221.43 C220.34,221.43 220.3,221.47 220.3,221.47 C220.3,221.47 220.25,221.52 220.25,221.52 C220.25,221.52 220.21,221.56 220.21,221.56 C220.21,221.56 220.16,221.6 220.16,221.6 C220.16,221.6 220.11,221.64 220.11,221.64 C220.11,221.64 220.06,221.68 220.06,221.68 C220.06,221.68 220.01,221.72 220.01,221.72 C220.01,221.72 219.96,221.76 219.96,221.76 C219.96,221.76 219.91,221.8 219.91,221.8 C219.91,221.8 219.86,221.83 219.86,221.83 C219.86,221.83 219.81,221.87 219.81,221.87 C219.81,221.87 219.75,221.9 219.75,221.9 C219.75,221.9 219.7,221.93 219.7,221.93 C219.7,221.93 219.65,221.97 219.65,221.97 C219.65,221.97 219.6,222 219.6,222 C219.6,222 219.54,222.03 219.54,222.03 C219.54,222.03 219.49,222.06 219.49,222.06 C219.49,222.06 219.43,222.09 219.43,222.09 C219.43,222.09 219.37,222.12 219.37,222.12 C219.37,222.12 219.32,222.15 219.32,222.15 C219.32,222.15 219.26,222.18 219.26,222.18 C219.26,222.18 219.21,222.2 219.21,222.2 C219.21,222.2 219.15,222.23 219.15,222.23 C219.15,222.23 219.09,222.25 219.09,222.25 C219.09,222.25 219.03,222.28 219.03,222.28 C219.03,222.28 218.97,222.3 218.97,222.3 C218.97,222.3 218.91,222.32 218.91,222.32 C218.91,222.32 218.85,222.34 218.85,222.34 C218.85,222.34 218.79,222.36 218.79,222.36 C218.79,222.36 218.73,222.38 218.73,222.38 C218.73,222.38 218.67,222.4 218.67,222.4 C218.67,222.4 218.61,222.42 218.61,222.42 C218.61,222.42 218.55,222.44 218.55,222.44 C218.55,222.44 218.49,222.45 218.49,222.45 C218.49,222.45 218.43,222.46 218.43,222.46 C218.43,222.46 218.37,222.47 218.37,222.47 C218.37,222.47 218.31,222.49 218.31,222.49 C218.31,222.49 218.25,222.5 218.25,222.5 C218.25,222.5 218.18,222.51 218.18,222.51 C218.18,222.51 218.12,222.52 218.12,222.52 C218.12,222.52 218.06,222.53 218.06,222.53 C218.06,222.53 218,222.54 218,222.54 C218,222.54 217.93,222.54 217.93,222.54 C217.93,222.54 217.87,222.55 217.87,222.55 C217.87,222.55 217.81,222.55 217.81,222.55 C217.81,222.55 217.75,222.55 217.75,222.55 C217.75,222.55 217.68,222.56 217.68,222.56 C217.68,222.56 217.62,222.56 217.62,222.56 C217.62,222.56 217.56,222.56 217.56,222.56 C217.56,222.56 217.49,222.56 217.49,222.56 C217.49,222.56 217.43,222.56 217.43,222.56 C217.43,222.56 217.37,222.55 217.37,222.55 C217.37,222.55 217.3,222.55 217.3,222.55 C217.3,222.55 217.24,222.55 217.24,222.55 C217.24,222.55 217.18,222.54 217.18,222.54 C217.18,222.54 217.12,222.54 217.12,222.54 C217.12,222.54 217.05,222.53 217.05,222.53 C217.05,222.53 216.99,222.52 216.99,222.52 C216.99,222.52 216.93,222.51 216.93,222.51 C216.93,222.51 216.87,222.5 216.87,222.5 C216.87,222.5 216.81,222.49 216.81,222.49 C216.81,222.49 216.74,222.48 216.74,222.48 C216.74,222.48 216.68,222.46 216.68,222.46 C216.68,222.46 216.62,222.45 216.62,222.45 C216.62,222.45 216.56,222.43 216.56,222.43 C216.56,222.43 216.5,222.42 216.5,222.42 C216.5,222.42 216.44,222.4 216.44,222.4 C216.44,222.4 216.38,222.38 216.38,222.38 C216.38,222.38 216.32,222.36 216.32,222.36 C216.32,222.36 216.26,222.34 216.26,222.34 C216.26,222.34 216.2,222.32 216.2,222.32 C216.2,222.32 216.14,222.3 216.14,222.3 C216.14,222.3 216.08,222.28 216.08,222.28 C216.08,222.28 216.02,222.26 216.02,222.26 C216.02,222.26 215.97,222.23 215.97,222.23 C215.97,222.23 215.91,222.2 215.91,222.2 C215.91,222.2 215.85,222.18 215.85,222.18 C215.85,222.18 215.79,222.15 215.79,222.15 C215.79,222.15 215.74,222.12 215.74,222.12 C215.74,222.12 215.68,222.1 215.68,222.1 C215.68,222.1 215.63,222.06 215.63,222.06 C215.63,222.06 215.57,222.03 215.57,222.03 C215.57,222.03 215.52,222 215.52,222 C215.52,222 215.46,221.97 215.46,221.97 C215.46,221.97 215.41,221.94 215.41,221.94 C215.41,221.94 215.36,221.9 215.36,221.9 C215.36,221.9 215.31,221.87 215.31,221.87 C215.31,221.87 215.25,221.83 215.25,221.83 C215.25,221.83 215.2,221.79 215.2,221.79 C215.2,221.79 215.15,221.76 215.15,221.76 C215.15,221.76 215.1,221.72 215.1,221.72 C215.1,221.72 215.05,221.68 215.05,221.68 C215.05,221.68 215,221.64 215,221.64 C215,221.64 214.96,221.6 214.96,221.6 C214.96,221.6 214.91,221.56 214.91,221.56 C214.91,221.56 214.86,221.52 214.86,221.52 C214.86,221.52 214.81,221.48 214.81,221.48 C214.81,221.48 214.77,221.43 214.77,221.43 C214.77,221.43 214.73,221.39 214.73,221.39 C214.73,221.39 214.68,221.34 214.68,221.34 C214.68,221.34 214.64,221.3 214.64,221.3 C214.64,221.3 214.59,221.25 214.59,221.25 C214.59,221.25 214.55,221.2 214.55,221.2 C214.55,221.2 214.51,221.15 214.51,221.15 C214.51,221.15 214.47,221.11 214.47,221.11 C214.47,221.11 214.43,221.06 214.43,221.06 C214.43,221.06 214.39,221.01 214.39,221.01 C214.39,221.01 214.35,220.96 214.35,220.96 C214.35,220.96 214.31,220.91 214.31,220.91 C214.31,220.91 214.28,220.86 214.28,220.86 C214.28,220.86 214.25,220.81 214.25,220.81 C214.25,220.81 214.21,220.75 214.21,220.75 C214.21,220.75 214.18,220.7 214.18,220.7 C214.18,220.7 214.14,220.65 214.14,220.65 C214.14,220.65 214.11,220.59 214.11,220.59 C214.11,220.59 214.08,220.54 214.08,220.54 C214.08,220.54 214.05,220.48 214.05,220.48 C214.05,220.48 214.02,220.43 214.02,220.43 C214.02,220.43 213.99,220.37 213.99,220.37 C213.99,220.37 213.96,220.32 213.96,220.32 C213.96,220.32 213.93,220.26 213.93,220.26 C213.93,220.26 213.91,220.2 213.91,220.2 C213.91,220.2 213.88,220.14 213.88,220.14 C213.88,220.14 213.86,220.09 213.86,220.09 C213.86,220.09 213.83,220.03 213.83,220.03 C213.83,220.03 213.81,219.97 213.81,219.97 C213.81,219.97 213.79,219.91 213.79,219.91 C213.79,219.91 213.77,219.85 213.77,219.85 C213.77,219.85 213.75,219.79 213.75,219.79 C213.75,219.79 213.73,219.73 213.73,219.73 C213.73,219.73 213.71,219.67 213.71,219.67 C213.71,219.67 213.69,219.61 213.69,219.61 C213.69,219.61 213.68,219.55 213.68,219.55 C213.68,219.55 213.66,219.49 213.66,219.49 C213.66,219.49 213.65,219.43 213.65,219.43 C213.65,219.43 213.64,219.37 213.64,219.37 C213.64,219.37 213.62,219.31 213.62,219.31 C213.62,219.31 213.61,219.24 213.61,219.24 C213.61,219.24 213.6,219.18 213.6,219.18 C213.6,219.18 213.59,219.12 213.59,219.12 C213.59,219.12 213.58,219.06 213.58,219.06 C213.58,219.06 213.57,218.99 213.57,218.99 C213.57,218.99 213.57,218.93 213.57,218.93 C213.57,218.93 213.56,218.87 213.56,218.87 C213.56,218.87 213.56,218.81 213.56,218.81 C213.56,218.81 213.56,218.74 213.56,218.74 C213.56,218.74 213.56,218.68 213.56,218.68 C213.56,218.68 213.55,218.62 213.55,218.62 C213.55,218.62 213.55,218.55 213.55,218.55 C213.55,218.55 213.55,218.49 213.55,218.49 C213.55,218.49 213.56,218.43 213.56,218.43 C213.56,218.43 213.56,218.37 213.56,218.37 C213.56,218.37 213.56,218.3 213.56,218.3 C213.56,218.3 213.56,218.24 213.56,218.24 C213.56,218.24 213.57,218.18 213.57,218.18 C213.57,218.18 213.57,218.12 213.57,218.12 C213.57,218.12 213.58,218.05 213.58,218.05 C213.58,218.05 213.59,217.99 213.59,217.99 C213.59,217.99 213.6,217.93 213.6,217.93 C213.6,217.93 213.61,217.87 213.61,217.87 C213.61,217.87 213.62,217.8 213.62,217.8 C213.62,217.8 213.63,217.74 213.63,217.74 C213.63,217.74 213.65,217.68 213.65,217.68 C213.65,217.68 213.66,217.62 213.66,217.62 C213.66,217.62 213.68,217.56 213.68,217.56 C213.68,217.56 213.69,217.5 213.69,217.5 C213.69,217.5 213.71,217.44 213.71,217.44 C213.71,217.44 213.73,217.38 213.73,217.38 C213.73,217.38 213.75,217.32 213.75,217.32 C213.75,217.32 213.77,217.26 213.77,217.26 C213.77,217.26 213.79,217.2 213.79,217.2 C213.79,217.2 213.81,217.14 213.81,217.14 C213.81,217.14 213.83,217.08 213.83,217.08 C213.83,217.08 213.85,217.02 213.85,217.02 C213.85,217.02 213.88,216.96 213.88,216.96 C213.88,216.96 213.91,216.91 213.91,216.91 C213.91,216.91 213.93,216.85 213.93,216.85 C213.93,216.85 213.96,216.79 213.96,216.79 C213.96,216.79 213.99,216.74 213.99,216.74 C213.99,216.74 214.02,216.68 214.02,216.68 C214.02,216.68 214.05,216.63 214.05,216.63 C214.05,216.63 214.08,216.57 214.08,216.57 C214.08,216.57 214.11,216.52 214.11,216.52 C214.11,216.52 214.14,216.46 214.14,216.46 C214.14,216.46 214.17,216.41 214.17,216.41 C214.17,216.41 214.21,216.36 214.21,216.36 C214.21,216.36 214.24,216.3 214.24,216.3 C214.24,216.3 214.28,216.25 214.28,216.25 C214.28,216.25 214.32,216.2 214.32,216.2 C214.32,216.2 214.35,216.15 214.35,216.15 C214.35,216.15 214.39,216.1 214.39,216.1 C214.39,216.1 214.43,216.05 214.43,216.05 C214.43,216.05 214.47,216 214.47,216 C214.47,216 214.51,215.96 214.51,215.96 C214.51,215.96 214.55,215.91 214.55,215.91 C214.55,215.91 214.59,215.86 214.59,215.86 C214.59,215.86 214.64,215.81 214.64,215.81 C214.64,215.81 214.68,215.77 214.68,215.77 C214.68,215.77 214.73,215.72 214.73,215.72 C214.73,215.72 214.77,215.68 214.77,215.68 C214.77,215.68 214.82,215.64 214.82,215.64 C214.82,215.64 214.86,215.59 214.86,215.59 C214.86,215.59 214.91,215.55 214.91,215.55 C214.91,215.55 214.96,215.51 214.96,215.51 C214.96,215.51 215,215.47 215,215.47 C215,215.47 215.05,215.43 215.05,215.43 C215.05,215.43 215.1,215.39 215.1,215.39 C215.1,215.39 215.15,215.35 215.15,215.35 C215.15,215.35 215.2,215.31 215.2,215.31 C215.2,215.31 215.25,215.28 215.25,215.28 C215.25,215.28 215.31,215.24 215.31,215.24 C215.31,215.24 215.36,215.21 215.36,215.21 C215.36,215.21 215.41,215.17 215.41,215.17 C215.41,215.17 215.46,215.14 215.46,215.14 C215.46,215.14 215.52,215.11 215.52,215.11 C215.52,215.11 215.57,215.08 215.57,215.08 C215.57,215.08 215.63,215.05 215.63,215.05 C215.63,215.05 215.68,215.02 215.68,215.02 C215.68,215.02 215.74,214.99 215.74,214.99 C215.74,214.99 215.79,214.96 215.79,214.96 C215.79,214.96 215.85,214.93 215.85,214.93 C215.85,214.93 215.91,214.9 215.91,214.9 C215.91,214.9 215.97,214.88 215.97,214.88 C215.97,214.88 216.02,214.86 216.02,214.86 C216.02,214.86 216.08,214.83 216.08,214.83 C216.08,214.83 216.14,214.81 216.14,214.81 C216.14,214.81 216.2,214.78 216.2,214.78 C216.2,214.78 216.26,214.77 216.26,214.77 C216.26,214.77 216.32,214.75 216.32,214.75 C216.32,214.75 216.38,214.73 216.38,214.73 C216.38,214.73 216.44,214.71 216.44,214.71 C216.44,214.71 216.5,214.69 216.5,214.69 C216.5,214.69 216.56,214.67 216.56,214.67 C216.56,214.67 216.62,214.66 216.62,214.66 C216.62,214.66 216.68,214.65 216.68,214.65 C216.68,214.65 216.74,214.63 216.74,214.63 C216.74,214.63 216.81,214.62 216.81,214.62 C216.81,214.62 216.87,214.61 216.87,214.61 C216.87,214.61 216.93,214.6 216.93,214.6 C216.93,214.6 216.99,214.59 216.99,214.59 C216.99,214.59 217.05,214.58 217.05,214.58 C217.05,214.58 217.12,214.57 217.12,214.57 C217.12,214.57 217.18,214.57 217.18,214.57 C217.18,214.57 217.24,214.56 217.24,214.56 C217.24,214.56 217.3,214.56 217.3,214.56 C217.3,214.56 217.37,214.56 217.37,214.56 C217.37,214.56 217.43,214.55 217.43,214.55 C217.43,214.55 217.49,214.55 217.49,214.55 C217.49,214.55 217.56,214.55 217.56,214.55 C217.56,214.55 217.62,214.55 217.62,214.55c " android:valueTo="M217.7 202.08 C217.7,202.08 217.97,202.09 217.97,202.09 C217.97,202.09 218.23,202.13 218.23,202.13 C218.23,202.13 218.49,202.16 218.49,202.16 C218.49,202.16 218.75,202.22 218.75,202.22 C218.75,202.22 219.01,202.28 219.01,202.28 C219.01,202.28 219.26,202.36 219.26,202.36 C219.26,202.36 219.51,202.44 219.51,202.44 C219.51,202.44 219.75,202.54 219.75,202.54 C219.75,202.54 219.99,202.65 219.99,202.65 C219.99,202.65 220.23,202.77 220.23,202.77 C220.23,202.77 220.46,202.9 220.46,202.9 C220.46,202.9 220.68,203.05 220.68,203.05 C220.68,203.05 220.9,203.2 220.9,203.2 C220.9,203.2 221.11,203.35 221.11,203.35 C221.11,203.35 221.33,203.51 221.33,203.51 C221.33,203.51 221.54,203.66 221.54,203.66 C221.54,203.66 221.75,203.82 221.75,203.82 C221.75,203.82 221.97,203.97 221.97,203.97 C221.97,203.97 222.18,204.13 222.18,204.13 C222.18,204.13 222.4,204.28 222.4,204.28 C222.4,204.28 222.61,204.44 222.61,204.44 C222.61,204.44 222.83,204.59 222.83,204.59 C222.83,204.59 223.04,204.75 223.04,204.75 C223.04,204.75 223.25,204.9 223.25,204.9 C223.25,204.9 223.47,205.06 223.47,205.06 C223.47,205.06 223.68,205.21 223.68,205.21 C223.68,205.21 223.9,205.37 223.9,205.37 C223.9,205.37 224.11,205.52 224.11,205.52 C224.11,205.52 224.33,205.68 224.33,205.68 C224.33,205.68 224.54,205.83 224.54,205.83 C224.54,205.83 224.75,205.98 224.75,205.98 C224.75,205.98 224.97,206.14 224.97,206.14 C224.97,206.14 225.18,206.29 225.18,206.29 C225.18,206.29 225.4,206.45 225.4,206.45 C225.4,206.45 225.61,206.6 225.61,206.6 C225.61,206.6 225.83,206.76 225.83,206.76 C225.83,206.76 226.04,206.91 226.04,206.91 C226.04,206.91 226.25,207.07 226.25,207.07 C226.25,207.07 226.47,207.22 226.47,207.22 C226.47,207.22 226.68,207.38 226.68,207.38 C226.68,207.38 226.9,207.53 226.9,207.53 C226.9,207.53 227.11,207.69 227.11,207.69 C227.11,207.69 227.32,207.84 227.32,207.84 C227.32,207.84 227.54,208 227.54,208 C227.54,208 227.75,208.15 227.75,208.15 C227.75,208.15 227.96,208.31 227.96,208.31 C227.96,208.31 228.18,208.46 228.18,208.46 C228.18,208.46 228.39,208.62 228.39,208.62 C228.39,208.62 228.61,208.78 228.61,208.78 C228.61,208.78 228.82,208.93 228.82,208.93 C228.82,208.93 229.03,209.09 229.03,209.09 C229.03,209.09 229.25,209.24 229.25,209.24 C229.25,209.24 229.46,209.4 229.46,209.4 C229.46,209.4 229.67,209.55 229.67,209.55 C229.67,209.55 229.89,209.71 229.89,209.71 C229.89,209.71 230.1,209.86 230.1,209.86 C230.1,209.86 230.32,210.02 230.32,210.02 C230.32,210.02 230.53,210.17 230.53,210.17 C230.53,210.17 230.74,210.33 230.74,210.33 C230.74,210.33 230.96,210.49 230.96,210.49 C230.96,210.49 231.17,210.64 231.17,210.64 C231.17,210.64 231.38,210.8 231.38,210.8 C231.38,210.8 231.6,210.95 231.6,210.95 C231.6,210.95 231.81,211.11 231.81,211.11 C231.81,211.11 232.03,211.26 232.03,211.26 C232.03,211.26 232.24,211.42 232.24,211.42 C232.24,211.42 232.44,211.59 232.44,211.59 C232.44,211.59 232.65,211.75 232.65,211.75 C232.65,211.75 232.84,211.94 232.84,211.94 C232.84,211.94 233.03,212.12 233.03,212.12 C233.03,212.12 233.2,212.32 233.2,212.32 C233.2,212.32 233.37,212.53 233.37,212.53 C233.37,212.53 233.52,212.74 233.52,212.74 C233.52,212.74 233.67,212.96 233.67,212.96 C233.67,212.96 233.8,213.19 233.8,213.19 C233.8,213.19 233.93,213.42 233.93,213.42 C233.93,213.42 234.04,213.66 234.04,213.66 C234.04,213.66 234.14,213.9 234.14,213.9 C234.14,213.9 234.24,214.15 234.24,214.15 C234.24,214.15 234.31,214.4 234.31,214.4 C234.31,214.4 234.39,214.66 234.39,214.66 C234.39,214.66 234.44,214.92 234.44,214.92 C234.44,214.92 234.49,215.18 234.49,215.18 C234.49,215.18 234.51,215.44 234.51,215.44 C234.51,215.44 234.54,215.7 234.54,215.7 C234.54,215.7 234.54,215.96 234.54,215.96 C234.54,215.96 234.54,216.23 234.54,216.23 C234.54,216.23 234.52,216.49 234.52,216.49 C234.52,216.49 234.49,216.76 234.49,216.76 C234.49,216.76 234.46,217.02 234.46,217.02 C234.46,217.02 234.4,217.28 234.4,217.28 C234.4,217.28 234.34,217.53 234.34,217.53 C234.34,217.53 234.26,217.79 234.26,217.79 C234.26,217.79 234.18,218.04 234.18,218.04 C234.18,218.04 234.1,218.29 234.1,218.29 C234.1,218.29 234.02,218.54 234.02,218.54 C234.02,218.54 233.94,218.79 233.94,218.79 C233.94,218.79 233.86,219.04 233.86,219.04 C233.86,219.04 233.78,219.29 233.78,219.29 C233.78,219.29 233.69,219.55 233.69,219.55 C233.69,219.55 233.61,219.8 233.61,219.8 C233.61,219.8 233.53,220.05 233.53,220.05 C233.53,220.05 233.45,220.3 233.45,220.3 C233.45,220.3 233.37,220.55 233.37,220.55 C233.37,220.55 233.29,220.8 233.29,220.8 C233.29,220.8 233.21,221.05 233.21,221.05 C233.21,221.05 233.12,221.31 233.12,221.31 C233.12,221.31 233.04,221.56 233.04,221.56 C233.04,221.56 232.96,221.81 232.96,221.81 C232.96,221.81 232.88,222.06 232.88,222.06 C232.88,222.06 232.8,222.31 232.8,222.31 C232.8,222.31 232.72,222.56 232.72,222.56 C232.72,222.56 232.64,222.81 232.64,222.81 C232.64,222.81 232.55,223.07 232.55,223.07 C232.55,223.07 232.47,223.32 232.47,223.32 C232.47,223.32 232.39,223.57 232.39,223.57 C232.39,223.57 232.31,223.82 232.31,223.82 C232.31,223.82 232.23,224.07 232.23,224.07 C232.23,224.07 232.15,224.32 232.15,224.32 C232.15,224.32 232.06,224.57 232.06,224.57 C232.06,224.57 231.98,224.83 231.98,224.83 C231.98,224.83 231.9,225.08 231.9,225.08 C231.9,225.08 231.82,225.33 231.82,225.33 C231.82,225.33 231.74,225.58 231.74,225.58 C231.74,225.58 231.65,225.83 231.65,225.83 C231.65,225.83 231.57,226.08 231.57,226.08 C231.57,226.08 231.49,226.33 231.49,226.33 C231.49,226.33 231.41,226.58 231.41,226.58 C231.41,226.58 231.32,226.83 231.32,226.83 C231.32,226.83 231.24,227.08 231.24,227.08 C231.24,227.08 231.16,227.34 231.16,227.34 C231.16,227.34 231.08,227.59 231.08,227.59 C231.08,227.59 230.99,227.84 230.99,227.84 C230.99,227.84 230.91,228.09 230.91,228.09 C230.91,228.09 230.83,228.34 230.83,228.34 C230.83,228.34 230.75,228.59 230.75,228.59 C230.75,228.59 230.67,228.84 230.67,228.84 C230.67,228.84 230.58,229.09 230.58,229.09 C230.58,229.09 230.5,229.35 230.5,229.35 C230.5,229.35 230.42,229.6 230.42,229.6 C230.42,229.6 230.34,229.85 230.34,229.85 C230.34,229.85 230.25,230.1 230.25,230.1 C230.25,230.1 230.17,230.35 230.17,230.35 C230.17,230.35 230.09,230.6 230.09,230.6 C230.09,230.6 230.01,230.85 230.01,230.85 C230.01,230.85 229.92,231.1 229.92,231.1 C229.92,231.1 229.83,231.35 229.83,231.35 C229.83,231.35 229.73,231.6 229.73,231.6 C229.73,231.6 229.61,231.83 229.61,231.83 C229.61,231.83 229.49,232.07 229.49,232.07 C229.49,232.07 229.36,232.29 229.36,232.29 C229.36,232.29 229.21,232.52 229.21,232.52 C229.21,232.52 229.06,232.73 229.06,232.73 C229.06,232.73 228.89,232.94 228.89,232.94 C228.89,232.94 228.72,233.13 228.72,233.13 C228.72,233.13 228.54,233.32 228.54,233.32 C228.54,233.32 228.34,233.51 228.34,233.51 C228.34,233.51 228.14,233.68 228.14,233.68 C228.14,233.68 227.94,233.84 227.94,233.84 C227.94,233.84 227.72,233.99 227.72,233.99 C227.72,233.99 227.5,234.14 227.5,234.14 C227.5,234.14 227.27,234.27 227.27,234.27 C227.27,234.27 227.04,234.39 227.04,234.39 C227.04,234.39 226.79,234.5 226.79,234.5 C226.79,234.5 226.55,234.6 226.55,234.6 C226.55,234.6 226.3,234.68 226.3,234.68 C226.3,234.68 226.05,234.76 226.05,234.76 C226.05,234.76 225.79,234.82 225.79,234.82 C225.79,234.82 225.53,234.88 225.53,234.88 C225.53,234.88 225.27,234.92 225.27,234.92 C225.27,234.92 225.01,234.95 225.01,234.95 C225.01,234.95 224.74,234.96 224.74,234.96 C224.74,234.96 224.48,234.96 224.48,234.96 C224.48,234.96 224.22,234.96 224.22,234.96 C224.22,234.96 223.95,234.96 223.95,234.96 C223.95,234.96 223.69,234.96 223.69,234.96 C223.69,234.96 223.42,234.96 223.42,234.96 C223.42,234.96 223.16,234.96 223.16,234.96 C223.16,234.96 222.89,234.96 222.89,234.96 C222.89,234.96 222.63,234.96 222.63,234.96 C222.63,234.96 222.37,234.97 222.37,234.97 C222.37,234.97 222.1,234.97 222.1,234.97 C222.1,234.97 221.84,234.97 221.84,234.97 C221.84,234.97 221.57,234.97 221.57,234.97 C221.57,234.97 221.31,234.97 221.31,234.97 C221.31,234.97 221.04,234.97 221.04,234.97 C221.04,234.97 220.78,234.97 220.78,234.97 C220.78,234.97 220.52,234.97 220.52,234.97 C220.52,234.97 220.25,234.97 220.25,234.97 C220.25,234.97 219.99,234.97 219.99,234.97 C219.99,234.97 219.72,234.97 219.72,234.97 C219.72,234.97 219.46,234.97 219.46,234.97 C219.46,234.97 219.19,234.97 219.19,234.97 C219.19,234.97 218.93,234.97 218.93,234.97 C218.93,234.97 218.67,234.97 218.67,234.97 C218.67,234.97 218.4,234.97 218.4,234.97 C218.4,234.97 218.14,234.97 218.14,234.97 C218.14,234.97 217.87,234.97 217.87,234.97 C217.87,234.97 217.61,234.97 217.61,234.97 C217.61,234.97 217.34,234.97 217.34,234.97 C217.34,234.97 217.08,234.97 217.08,234.97 C217.08,234.97 216.82,234.97 216.82,234.97 C216.82,234.97 216.55,234.97 216.55,234.97 C216.55,234.97 216.29,234.97 216.29,234.97 C216.29,234.97 216.02,234.97 216.02,234.97 C216.02,234.97 215.76,234.97 215.76,234.97 C215.76,234.97 215.49,234.97 215.49,234.97 C215.49,234.97 215.23,234.97 215.23,234.97 C215.23,234.97 214.97,234.97 214.97,234.97 C214.97,234.97 214.7,234.97 214.7,234.97 C214.7,234.97 214.44,234.97 214.44,234.97 C214.44,234.97 214.17,234.97 214.17,234.97 C214.17,234.97 213.91,234.97 213.91,234.97 C213.91,234.97 213.64,234.97 213.64,234.97 C213.64,234.97 213.38,234.97 213.38,234.97 C213.38,234.97 213.12,234.97 213.12,234.97 C213.12,234.97 212.85,234.97 212.85,234.97 C212.85,234.97 212.59,234.96 212.59,234.96 C212.59,234.96 212.32,234.96 212.32,234.96 C212.32,234.96 212.06,234.96 212.06,234.96 C212.06,234.96 211.79,234.96 211.79,234.96 C211.79,234.96 211.53,234.96 211.53,234.96 C211.53,234.96 211.27,234.96 211.27,234.96 C211.27,234.96 211,234.96 211,234.96 C211,234.96 210.74,234.96 210.74,234.96 C210.74,234.96 210.47,234.96 210.47,234.96 C210.47,234.96 210.21,234.95 210.21,234.95 C210.21,234.95 209.94,234.93 209.94,234.93 C209.94,234.93 209.68,234.9 209.68,234.9 C209.68,234.9 209.42,234.86 209.42,234.86 C209.42,234.86 209.16,234.8 209.16,234.8 C209.16,234.8 208.91,234.74 208.91,234.74 C208.91,234.74 208.66,234.66 208.66,234.66 C208.66,234.66 208.41,234.56 208.41,234.56 C208.41,234.56 208.17,234.46 208.17,234.46 C208.17,234.46 207.93,234.35 207.93,234.35 C207.93,234.35 207.69,234.22 207.69,234.22 C207.69,234.22 207.47,234.08 207.47,234.08 C207.47,234.08 207.25,233.94 207.25,233.94 C207.25,233.94 207.04,233.78 207.04,233.78 C207.04,233.78 206.83,233.62 206.83,233.62 C206.83,233.62 206.63,233.44 206.63,233.44 C206.63,233.44 206.44,233.26 206.44,233.26 C206.44,233.26 206.27,233.06 206.27,233.06 C206.27,233.06 206.09,232.86 206.09,232.86 C206.09,232.86 205.93,232.65 205.93,232.65 C205.93,232.65 205.78,232.44 205.78,232.44 C205.78,232.44 205.64,232.21 205.64,232.21 C205.64,232.21 205.51,231.98 205.51,231.98 C205.51,231.98 205.39,231.75 205.39,231.75 C205.39,231.75 205.28,231.51 205.28,231.51 C205.28,231.51 205.18,231.26 205.18,231.26 C205.18,231.26 205.09,231.01 205.09,231.01 C205.09,231.01 205.01,230.76 205.01,230.76 C205.01,230.76 204.93,230.51 204.93,230.51 C204.93,230.51 204.85,230.26 204.85,230.26 C204.85,230.26 204.76,230.01 204.76,230.01 C204.76,230.01 204.68,229.76 204.68,229.76 C204.68,229.76 204.6,229.51 204.6,229.51 C204.6,229.51 204.52,229.26 204.52,229.26 C204.52,229.26 204.43,229.01 204.43,229.01 C204.43,229.01 204.35,228.75 204.35,228.75 C204.35,228.75 204.27,228.5 204.27,228.5 C204.27,228.5 204.19,228.25 204.19,228.25 C204.19,228.25 204.1,228 204.1,228 C204.1,228 204.02,227.75 204.02,227.75 C204.02,227.75 203.94,227.5 203.94,227.5 C203.94,227.5 203.86,227.25 203.86,227.25 C203.86,227.25 203.78,227 203.78,227 C203.78,227 203.69,226.74 203.69,226.74 C203.69,226.74 203.61,226.49 203.61,226.49 C203.61,226.49 203.53,226.24 203.53,226.24 C203.53,226.24 203.45,225.99 203.45,225.99 C203.45,225.99 203.36,225.74 203.36,225.74 C203.36,225.74 203.28,225.49 203.28,225.49 C203.28,225.49 203.2,225.24 203.2,225.24 C203.2,225.24 203.12,224.99 203.12,224.99 C203.12,224.99 203.03,224.74 203.03,224.74 C203.03,224.74 202.95,224.48 202.95,224.48 C202.95,224.48 202.87,224.23 202.87,224.23 C202.87,224.23 202.79,223.98 202.79,223.98 C202.79,223.98 202.71,223.73 202.71,223.73 C202.71,223.73 202.63,223.48 202.63,223.48 C202.63,223.48 202.54,223.23 202.54,223.23 C202.54,223.23 202.46,222.98 202.46,222.98 C202.46,222.98 202.38,222.72 202.38,222.72 C202.38,222.72 202.3,222.47 202.3,222.47 C202.3,222.47 202.22,222.22 202.22,222.22 C202.22,222.22 202.14,221.97 202.14,221.97 C202.14,221.97 202.06,221.72 202.06,221.72 C202.06,221.72 201.97,221.47 201.97,221.47 C201.97,221.47 201.89,221.22 201.89,221.22 C201.89,221.22 201.81,220.96 201.81,220.96 C201.81,220.96 201.73,220.71 201.73,220.71 C201.73,220.71 201.65,220.46 201.65,220.46 C201.65,220.46 201.57,220.21 201.57,220.21 C201.57,220.21 201.49,219.96 201.49,219.96 C201.49,219.96 201.4,219.71 201.4,219.71 C201.4,219.71 201.32,219.46 201.32,219.46 C201.32,219.46 201.24,219.2 201.24,219.2 C201.24,219.2 201.16,218.95 201.16,218.95 C201.16,218.95 201.08,218.7 201.08,218.7 C201.08,218.7 201,218.45 201,218.45 C201,218.45 200.92,218.2 200.92,218.2 C200.92,218.2 200.83,217.95 200.83,217.95 C200.83,217.95 200.76,217.7 200.76,217.7 C200.76,217.7 200.69,217.44 200.69,217.44 C200.69,217.44 200.62,217.18 200.62,217.18 C200.62,217.18 200.58,216.92 200.58,216.92 C200.58,216.92 200.54,216.66 200.54,216.66 C200.54,216.66 200.52,216.4 200.52,216.4 C200.52,216.4 200.5,216.14 200.5,216.14 C200.5,216.14 200.5,215.87 200.5,215.87 C200.5,215.87 200.52,215.61 200.52,215.61 C200.52,215.61 200.54,215.34 200.54,215.34 C200.54,215.34 200.58,215.08 200.58,215.08 C200.58,215.08 200.62,214.82 200.62,214.82 C200.62,214.82 200.69,214.57 200.69,214.57 C200.69,214.57 200.76,214.31 200.76,214.31 C200.76,214.31 200.84,214.06 200.84,214.06 C200.84,214.06 200.93,213.81 200.93,213.81 C200.93,213.81 201.05,213.57 201.05,213.57 C201.05,213.57 201.16,213.33 201.16,213.33 C201.16,213.33 201.29,213.11 201.29,213.11 C201.29,213.11 201.43,212.88 201.43,212.88 C201.43,212.88 201.58,212.67 201.58,212.67 C201.58,212.67 201.74,212.45 201.74,212.45 C201.74,212.45 201.91,212.25 201.91,212.25 C201.91,212.25 202.09,212.06 202.09,212.06 C202.09,212.06 202.27,211.87 202.27,211.87 C202.27,211.87 202.47,211.69 202.47,211.69 C202.47,211.69 202.67,211.52 202.67,211.52 C202.67,211.52 202.88,211.36 202.88,211.36 C202.88,211.36 203.1,211.21 203.1,211.21 C203.1,211.21 203.31,211.05 203.31,211.05 C203.31,211.05 203.52,210.9 203.52,210.9 C203.52,210.9 203.74,210.74 203.74,210.74 C203.74,210.74 203.95,210.58 203.95,210.58 C203.95,210.58 204.16,210.43 204.16,210.43 C204.16,210.43 204.38,210.27 204.38,210.27 C204.38,210.27 204.59,210.12 204.59,210.12 C204.59,210.12 204.81,209.96 204.81,209.96 C204.81,209.96 205.02,209.81 205.02,209.81 C205.02,209.81 205.23,209.65 205.23,209.65 C205.23,209.65 205.45,209.5 205.45,209.5 C205.45,209.5 205.66,209.34 205.66,209.34 C205.66,209.34 205.87,209.19 205.87,209.19 C205.87,209.19 206.09,209.03 206.09,209.03 C206.09,209.03 206.3,208.88 206.3,208.88 C206.3,208.88 206.52,208.72 206.52,208.72 C206.52,208.72 206.73,208.57 206.73,208.57 C206.73,208.57 206.94,208.41 206.94,208.41 C206.94,208.41 207.16,208.25 207.16,208.25 C207.16,208.25 207.37,208.1 207.37,208.1 C207.37,208.1 207.58,207.94 207.58,207.94 C207.58,207.94 207.8,207.79 207.8,207.79 C207.8,207.79 208.01,207.63 208.01,207.63 C208.01,207.63 208.23,207.48 208.23,207.48 C208.23,207.48 208.44,207.32 208.44,207.32 C208.44,207.32 208.65,207.17 208.65,207.17 C208.65,207.17 208.87,207.01 208.87,207.01 C208.87,207.01 209.08,206.86 209.08,206.86 C209.08,206.86 209.3,206.7 209.3,206.7 C209.3,206.7 209.51,206.55 209.51,206.55 C209.51,206.55 209.73,206.39 209.73,206.39 C209.73,206.39 209.94,206.24 209.94,206.24 C209.94,206.24 210.15,206.08 210.15,206.08 C210.15,206.08 210.37,205.93 210.37,205.93 C210.37,205.93 210.58,205.77 210.58,205.77 C210.58,205.77 210.8,205.62 210.8,205.62 C210.8,205.62 211.01,205.46 211.01,205.46 C211.01,205.46 211.23,205.31 211.23,205.31 C211.23,205.31 211.44,205.16 211.44,205.16 C211.44,205.16 211.65,205 211.65,205 C211.65,205 211.87,204.85 211.87,204.85 C211.87,204.85 212.08,204.69 212.08,204.69 C212.08,204.69 212.3,204.54 212.3,204.54 C212.3,204.54 212.51,204.38 212.51,204.38 C212.51,204.38 212.73,204.23 212.73,204.23 C212.73,204.23 212.94,204.07 212.94,204.07 C212.94,204.07 213.15,203.92 213.15,203.92 C213.15,203.92 213.37,203.76 213.37,203.76 C213.37,203.76 213.58,203.61 213.58,203.61 C213.58,203.61 213.8,203.45 213.8,203.45 C213.8,203.45 214.01,203.3 214.01,203.3 C214.01,203.3 214.23,203.14 214.23,203.14 C214.23,203.14 214.45,203 214.45,203 C214.45,203 214.67,202.86 214.67,202.86 C214.67,202.86 214.9,202.73 214.9,202.73 C214.9,202.73 215.14,202.61 215.14,202.61 C215.14,202.61 215.38,202.51 215.38,202.51 C215.38,202.51 215.63,202.41 215.63,202.41 C215.63,202.41 215.88,202.33 215.88,202.33 C215.88,202.33 216.13,202.26 216.13,202.26 C216.13,202.26 216.39,202.2 216.39,202.2 C216.39,202.2 216.65,202.15 216.65,202.15 C216.65,202.15 216.91,202.11 216.91,202.11 C216.91,202.11 217.18,202.09 217.18,202.09 C217.18,202.09 217.44,202.08 217.44,202.08 C217.44,202.08 217.7,202.08 217.7,202.08c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="283" android:startOffset="67" android:valueFrom="M217.7 202.08 C217.7,202.08 217.97,202.09 217.97,202.09 C217.97,202.09 218.23,202.13 218.23,202.13 C218.23,202.13 218.49,202.16 218.49,202.16 C218.49,202.16 218.75,202.22 218.75,202.22 C218.75,202.22 219.01,202.28 219.01,202.28 C219.01,202.28 219.26,202.36 219.26,202.36 C219.26,202.36 219.51,202.44 219.51,202.44 C219.51,202.44 219.75,202.54 219.75,202.54 C219.75,202.54 219.99,202.65 219.99,202.65 C219.99,202.65 220.23,202.77 220.23,202.77 C220.23,202.77 220.46,202.9 220.46,202.9 C220.46,202.9 220.68,203.05 220.68,203.05 C220.68,203.05 220.9,203.2 220.9,203.2 C220.9,203.2 221.11,203.35 221.11,203.35 C221.11,203.35 221.33,203.51 221.33,203.51 C221.33,203.51 221.54,203.66 221.54,203.66 C221.54,203.66 221.75,203.82 221.75,203.82 C221.75,203.82 221.97,203.97 221.97,203.97 C221.97,203.97 222.18,204.13 222.18,204.13 C222.18,204.13 222.4,204.28 222.4,204.28 C222.4,204.28 222.61,204.44 222.61,204.44 C222.61,204.44 222.83,204.59 222.83,204.59 C222.83,204.59 223.04,204.75 223.04,204.75 C223.04,204.75 223.25,204.9 223.25,204.9 C223.25,204.9 223.47,205.06 223.47,205.06 C223.47,205.06 223.68,205.21 223.68,205.21 C223.68,205.21 223.9,205.37 223.9,205.37 C223.9,205.37 224.11,205.52 224.11,205.52 C224.11,205.52 224.33,205.68 224.33,205.68 C224.33,205.68 224.54,205.83 224.54,205.83 C224.54,205.83 224.75,205.98 224.75,205.98 C224.75,205.98 224.97,206.14 224.97,206.14 C224.97,206.14 225.18,206.29 225.18,206.29 C225.18,206.29 225.4,206.45 225.4,206.45 C225.4,206.45 225.61,206.6 225.61,206.6 C225.61,206.6 225.83,206.76 225.83,206.76 C225.83,206.76 226.04,206.91 226.04,206.91 C226.04,206.91 226.25,207.07 226.25,207.07 C226.25,207.07 226.47,207.22 226.47,207.22 C226.47,207.22 226.68,207.38 226.68,207.38 C226.68,207.38 226.9,207.53 226.9,207.53 C226.9,207.53 227.11,207.69 227.11,207.69 C227.11,207.69 227.32,207.84 227.32,207.84 C227.32,207.84 227.54,208 227.54,208 C227.54,208 227.75,208.15 227.75,208.15 C227.75,208.15 227.96,208.31 227.96,208.31 C227.96,208.31 228.18,208.46 228.18,208.46 C228.18,208.46 228.39,208.62 228.39,208.62 C228.39,208.62 228.61,208.78 228.61,208.78 C228.61,208.78 228.82,208.93 228.82,208.93 C228.82,208.93 229.03,209.09 229.03,209.09 C229.03,209.09 229.25,209.24 229.25,209.24 C229.25,209.24 229.46,209.4 229.46,209.4 C229.46,209.4 229.67,209.55 229.67,209.55 C229.67,209.55 229.89,209.71 229.89,209.71 C229.89,209.71 230.1,209.86 230.1,209.86 C230.1,209.86 230.32,210.02 230.32,210.02 C230.32,210.02 230.53,210.17 230.53,210.17 C230.53,210.17 230.74,210.33 230.74,210.33 C230.74,210.33 230.96,210.49 230.96,210.49 C230.96,210.49 231.17,210.64 231.17,210.64 C231.17,210.64 231.38,210.8 231.38,210.8 C231.38,210.8 231.6,210.95 231.6,210.95 C231.6,210.95 231.81,211.11 231.81,211.11 C231.81,211.11 232.03,211.26 232.03,211.26 C232.03,211.26 232.24,211.42 232.24,211.42 C232.24,211.42 232.44,211.59 232.44,211.59 C232.44,211.59 232.65,211.75 232.65,211.75 C232.65,211.75 232.84,211.94 232.84,211.94 C232.84,211.94 233.03,212.12 233.03,212.12 C233.03,212.12 233.2,212.32 233.2,212.32 C233.2,212.32 233.37,212.53 233.37,212.53 C233.37,212.53 233.52,212.74 233.52,212.74 C233.52,212.74 233.67,212.96 233.67,212.96 C233.67,212.96 233.8,213.19 233.8,213.19 C233.8,213.19 233.93,213.42 233.93,213.42 C233.93,213.42 234.04,213.66 234.04,213.66 C234.04,213.66 234.14,213.9 234.14,213.9 C234.14,213.9 234.24,214.15 234.24,214.15 C234.24,214.15 234.31,214.4 234.31,214.4 C234.31,214.4 234.39,214.66 234.39,214.66 C234.39,214.66 234.44,214.92 234.44,214.92 C234.44,214.92 234.49,215.18 234.49,215.18 C234.49,215.18 234.51,215.44 234.51,215.44 C234.51,215.44 234.54,215.7 234.54,215.7 C234.54,215.7 234.54,215.96 234.54,215.96 C234.54,215.96 234.54,216.23 234.54,216.23 C234.54,216.23 234.52,216.49 234.52,216.49 C234.52,216.49 234.49,216.76 234.49,216.76 C234.49,216.76 234.46,217.02 234.46,217.02 C234.46,217.02 234.4,217.28 234.4,217.28 C234.4,217.28 234.34,217.53 234.34,217.53 C234.34,217.53 234.26,217.79 234.26,217.79 C234.26,217.79 234.18,218.04 234.18,218.04 C234.18,218.04 234.1,218.29 234.1,218.29 C234.1,218.29 234.02,218.54 234.02,218.54 C234.02,218.54 233.94,218.79 233.94,218.79 C233.94,218.79 233.86,219.04 233.86,219.04 C233.86,219.04 233.78,219.29 233.78,219.29 C233.78,219.29 233.69,219.55 233.69,219.55 C233.69,219.55 233.61,219.8 233.61,219.8 C233.61,219.8 233.53,220.05 233.53,220.05 C233.53,220.05 233.45,220.3 233.45,220.3 C233.45,220.3 233.37,220.55 233.37,220.55 C233.37,220.55 233.29,220.8 233.29,220.8 C233.29,220.8 233.21,221.05 233.21,221.05 C233.21,221.05 233.12,221.31 233.12,221.31 C233.12,221.31 233.04,221.56 233.04,221.56 C233.04,221.56 232.96,221.81 232.96,221.81 C232.96,221.81 232.88,222.06 232.88,222.06 C232.88,222.06 232.8,222.31 232.8,222.31 C232.8,222.31 232.72,222.56 232.72,222.56 C232.72,222.56 232.64,222.81 232.64,222.81 C232.64,222.81 232.55,223.07 232.55,223.07 C232.55,223.07 232.47,223.32 232.47,223.32 C232.47,223.32 232.39,223.57 232.39,223.57 C232.39,223.57 232.31,223.82 232.31,223.82 C232.31,223.82 232.23,224.07 232.23,224.07 C232.23,224.07 232.15,224.32 232.15,224.32 C232.15,224.32 232.06,224.57 232.06,224.57 C232.06,224.57 231.98,224.83 231.98,224.83 C231.98,224.83 231.9,225.08 231.9,225.08 C231.9,225.08 231.82,225.33 231.82,225.33 C231.82,225.33 231.74,225.58 231.74,225.58 C231.74,225.58 231.65,225.83 231.65,225.83 C231.65,225.83 231.57,226.08 231.57,226.08 C231.57,226.08 231.49,226.33 231.49,226.33 C231.49,226.33 231.41,226.58 231.41,226.58 C231.41,226.58 231.32,226.83 231.32,226.83 C231.32,226.83 231.24,227.08 231.24,227.08 C231.24,227.08 231.16,227.34 231.16,227.34 C231.16,227.34 231.08,227.59 231.08,227.59 C231.08,227.59 230.99,227.84 230.99,227.84 C230.99,227.84 230.91,228.09 230.91,228.09 C230.91,228.09 230.83,228.34 230.83,228.34 C230.83,228.34 230.75,228.59 230.75,228.59 C230.75,228.59 230.67,228.84 230.67,228.84 C230.67,228.84 230.58,229.09 230.58,229.09 C230.58,229.09 230.5,229.35 230.5,229.35 C230.5,229.35 230.42,229.6 230.42,229.6 C230.42,229.6 230.34,229.85 230.34,229.85 C230.34,229.85 230.25,230.1 230.25,230.1 C230.25,230.1 230.17,230.35 230.17,230.35 C230.17,230.35 230.09,230.6 230.09,230.6 C230.09,230.6 230.01,230.85 230.01,230.85 C230.01,230.85 229.92,231.1 229.92,231.1 C229.92,231.1 229.83,231.35 229.83,231.35 C229.83,231.35 229.73,231.6 229.73,231.6 C229.73,231.6 229.61,231.83 229.61,231.83 C229.61,231.83 229.49,232.07 229.49,232.07 C229.49,232.07 229.36,232.29 229.36,232.29 C229.36,232.29 229.21,232.52 229.21,232.52 C229.21,232.52 229.06,232.73 229.06,232.73 C229.06,232.73 228.89,232.94 228.89,232.94 C228.89,232.94 228.72,233.13 228.72,233.13 C228.72,233.13 228.54,233.32 228.54,233.32 C228.54,233.32 228.34,233.51 228.34,233.51 C228.34,233.51 228.14,233.68 228.14,233.68 C228.14,233.68 227.94,233.84 227.94,233.84 C227.94,233.84 227.72,233.99 227.72,233.99 C227.72,233.99 227.5,234.14 227.5,234.14 C227.5,234.14 227.27,234.27 227.27,234.27 C227.27,234.27 227.04,234.39 227.04,234.39 C227.04,234.39 226.79,234.5 226.79,234.5 C226.79,234.5 226.55,234.6 226.55,234.6 C226.55,234.6 226.3,234.68 226.3,234.68 C226.3,234.68 226.05,234.76 226.05,234.76 C226.05,234.76 225.79,234.82 225.79,234.82 C225.79,234.82 225.53,234.88 225.53,234.88 C225.53,234.88 225.27,234.92 225.27,234.92 C225.27,234.92 225.01,234.95 225.01,234.95 C225.01,234.95 224.74,234.96 224.74,234.96 C224.74,234.96 224.48,234.96 224.48,234.96 C224.48,234.96 224.22,234.96 224.22,234.96 C224.22,234.96 223.95,234.96 223.95,234.96 C223.95,234.96 223.69,234.96 223.69,234.96 C223.69,234.96 223.42,234.96 223.42,234.96 C223.42,234.96 223.16,234.96 223.16,234.96 C223.16,234.96 222.89,234.96 222.89,234.96 C222.89,234.96 222.63,234.96 222.63,234.96 C222.63,234.96 222.37,234.97 222.37,234.97 C222.37,234.97 222.1,234.97 222.1,234.97 C222.1,234.97 221.84,234.97 221.84,234.97 C221.84,234.97 221.57,234.97 221.57,234.97 C221.57,234.97 221.31,234.97 221.31,234.97 C221.31,234.97 221.04,234.97 221.04,234.97 C221.04,234.97 220.78,234.97 220.78,234.97 C220.78,234.97 220.52,234.97 220.52,234.97 C220.52,234.97 220.25,234.97 220.25,234.97 C220.25,234.97 219.99,234.97 219.99,234.97 C219.99,234.97 219.72,234.97 219.72,234.97 C219.72,234.97 219.46,234.97 219.46,234.97 C219.46,234.97 219.19,234.97 219.19,234.97 C219.19,234.97 218.93,234.97 218.93,234.97 C218.93,234.97 218.67,234.97 218.67,234.97 C218.67,234.97 218.4,234.97 218.4,234.97 C218.4,234.97 218.14,234.97 218.14,234.97 C218.14,234.97 217.87,234.97 217.87,234.97 C217.87,234.97 217.61,234.97 217.61,234.97 C217.61,234.97 217.34,234.97 217.34,234.97 C217.34,234.97 217.08,234.97 217.08,234.97 C217.08,234.97 216.82,234.97 216.82,234.97 C216.82,234.97 216.55,234.97 216.55,234.97 C216.55,234.97 216.29,234.97 216.29,234.97 C216.29,234.97 216.02,234.97 216.02,234.97 C216.02,234.97 215.76,234.97 215.76,234.97 C215.76,234.97 215.49,234.97 215.49,234.97 C215.49,234.97 215.23,234.97 215.23,234.97 C215.23,234.97 214.97,234.97 214.97,234.97 C214.97,234.97 214.7,234.97 214.7,234.97 C214.7,234.97 214.44,234.97 214.44,234.97 C214.44,234.97 214.17,234.97 214.17,234.97 C214.17,234.97 213.91,234.97 213.91,234.97 C213.91,234.97 213.64,234.97 213.64,234.97 C213.64,234.97 213.38,234.97 213.38,234.97 C213.38,234.97 213.12,234.97 213.12,234.97 C213.12,234.97 212.85,234.97 212.85,234.97 C212.85,234.97 212.59,234.96 212.59,234.96 C212.59,234.96 212.32,234.96 212.32,234.96 C212.32,234.96 212.06,234.96 212.06,234.96 C212.06,234.96 211.79,234.96 211.79,234.96 C211.79,234.96 211.53,234.96 211.53,234.96 C211.53,234.96 211.27,234.96 211.27,234.96 C211.27,234.96 211,234.96 211,234.96 C211,234.96 210.74,234.96 210.74,234.96 C210.74,234.96 210.47,234.96 210.47,234.96 C210.47,234.96 210.21,234.95 210.21,234.95 C210.21,234.95 209.94,234.93 209.94,234.93 C209.94,234.93 209.68,234.9 209.68,234.9 C209.68,234.9 209.42,234.86 209.42,234.86 C209.42,234.86 209.16,234.8 209.16,234.8 C209.16,234.8 208.91,234.74 208.91,234.74 C208.91,234.74 208.66,234.66 208.66,234.66 C208.66,234.66 208.41,234.56 208.41,234.56 C208.41,234.56 208.17,234.46 208.17,234.46 C208.17,234.46 207.93,234.35 207.93,234.35 C207.93,234.35 207.69,234.22 207.69,234.22 C207.69,234.22 207.47,234.08 207.47,234.08 C207.47,234.08 207.25,233.94 207.25,233.94 C207.25,233.94 207.04,233.78 207.04,233.78 C207.04,233.78 206.83,233.62 206.83,233.62 C206.83,233.62 206.63,233.44 206.63,233.44 C206.63,233.44 206.44,233.26 206.44,233.26 C206.44,233.26 206.27,233.06 206.27,233.06 C206.27,233.06 206.09,232.86 206.09,232.86 C206.09,232.86 205.93,232.65 205.93,232.65 C205.93,232.65 205.78,232.44 205.78,232.44 C205.78,232.44 205.64,232.21 205.64,232.21 C205.64,232.21 205.51,231.98 205.51,231.98 C205.51,231.98 205.39,231.75 205.39,231.75 C205.39,231.75 205.28,231.51 205.28,231.51 C205.28,231.51 205.18,231.26 205.18,231.26 C205.18,231.26 205.09,231.01 205.09,231.01 C205.09,231.01 205.01,230.76 205.01,230.76 C205.01,230.76 204.93,230.51 204.93,230.51 C204.93,230.51 204.85,230.26 204.85,230.26 C204.85,230.26 204.76,230.01 204.76,230.01 C204.76,230.01 204.68,229.76 204.68,229.76 C204.68,229.76 204.6,229.51 204.6,229.51 C204.6,229.51 204.52,229.26 204.52,229.26 C204.52,229.26 204.43,229.01 204.43,229.01 C204.43,229.01 204.35,228.75 204.35,228.75 C204.35,228.75 204.27,228.5 204.27,228.5 C204.27,228.5 204.19,228.25 204.19,228.25 C204.19,228.25 204.1,228 204.1,228 C204.1,228 204.02,227.75 204.02,227.75 C204.02,227.75 203.94,227.5 203.94,227.5 C203.94,227.5 203.86,227.25 203.86,227.25 C203.86,227.25 203.78,227 203.78,227 C203.78,227 203.69,226.74 203.69,226.74 C203.69,226.74 203.61,226.49 203.61,226.49 C203.61,226.49 203.53,226.24 203.53,226.24 C203.53,226.24 203.45,225.99 203.45,225.99 C203.45,225.99 203.36,225.74 203.36,225.74 C203.36,225.74 203.28,225.49 203.28,225.49 C203.28,225.49 203.2,225.24 203.2,225.24 C203.2,225.24 203.12,224.99 203.12,224.99 C203.12,224.99 203.03,224.74 203.03,224.74 C203.03,224.74 202.95,224.48 202.95,224.48 C202.95,224.48 202.87,224.23 202.87,224.23 C202.87,224.23 202.79,223.98 202.79,223.98 C202.79,223.98 202.71,223.73 202.71,223.73 C202.71,223.73 202.63,223.48 202.63,223.48 C202.63,223.48 202.54,223.23 202.54,223.23 C202.54,223.23 202.46,222.98 202.46,222.98 C202.46,222.98 202.38,222.72 202.38,222.72 C202.38,222.72 202.3,222.47 202.3,222.47 C202.3,222.47 202.22,222.22 202.22,222.22 C202.22,222.22 202.14,221.97 202.14,221.97 C202.14,221.97 202.06,221.72 202.06,221.72 C202.06,221.72 201.97,221.47 201.97,221.47 C201.97,221.47 201.89,221.22 201.89,221.22 C201.89,221.22 201.81,220.96 201.81,220.96 C201.81,220.96 201.73,220.71 201.73,220.71 C201.73,220.71 201.65,220.46 201.65,220.46 C201.65,220.46 201.57,220.21 201.57,220.21 C201.57,220.21 201.49,219.96 201.49,219.96 C201.49,219.96 201.4,219.71 201.4,219.71 C201.4,219.71 201.32,219.46 201.32,219.46 C201.32,219.46 201.24,219.2 201.24,219.2 C201.24,219.2 201.16,218.95 201.16,218.95 C201.16,218.95 201.08,218.7 201.08,218.7 C201.08,218.7 201,218.45 201,218.45 C201,218.45 200.92,218.2 200.92,218.2 C200.92,218.2 200.83,217.95 200.83,217.95 C200.83,217.95 200.76,217.7 200.76,217.7 C200.76,217.7 200.69,217.44 200.69,217.44 C200.69,217.44 200.62,217.18 200.62,217.18 C200.62,217.18 200.58,216.92 200.58,216.92 C200.58,216.92 200.54,216.66 200.54,216.66 C200.54,216.66 200.52,216.4 200.52,216.4 C200.52,216.4 200.5,216.14 200.5,216.14 C200.5,216.14 200.5,215.87 200.5,215.87 C200.5,215.87 200.52,215.61 200.52,215.61 C200.52,215.61 200.54,215.34 200.54,215.34 C200.54,215.34 200.58,215.08 200.58,215.08 C200.58,215.08 200.62,214.82 200.62,214.82 C200.62,214.82 200.69,214.57 200.69,214.57 C200.69,214.57 200.76,214.31 200.76,214.31 C200.76,214.31 200.84,214.06 200.84,214.06 C200.84,214.06 200.93,213.81 200.93,213.81 C200.93,213.81 201.05,213.57 201.05,213.57 C201.05,213.57 201.16,213.33 201.16,213.33 C201.16,213.33 201.29,213.11 201.29,213.11 C201.29,213.11 201.43,212.88 201.43,212.88 C201.43,212.88 201.58,212.67 201.58,212.67 C201.58,212.67 201.74,212.45 201.74,212.45 C201.74,212.45 201.91,212.25 201.91,212.25 C201.91,212.25 202.09,212.06 202.09,212.06 C202.09,212.06 202.27,211.87 202.27,211.87 C202.27,211.87 202.47,211.69 202.47,211.69 C202.47,211.69 202.67,211.52 202.67,211.52 C202.67,211.52 202.88,211.36 202.88,211.36 C202.88,211.36 203.1,211.21 203.1,211.21 C203.1,211.21 203.31,211.05 203.31,211.05 C203.31,211.05 203.52,210.9 203.52,210.9 C203.52,210.9 203.74,210.74 203.74,210.74 C203.74,210.74 203.95,210.58 203.95,210.58 C203.95,210.58 204.16,210.43 204.16,210.43 C204.16,210.43 204.38,210.27 204.38,210.27 C204.38,210.27 204.59,210.12 204.59,210.12 C204.59,210.12 204.81,209.96 204.81,209.96 C204.81,209.96 205.02,209.81 205.02,209.81 C205.02,209.81 205.23,209.65 205.23,209.65 C205.23,209.65 205.45,209.5 205.45,209.5 C205.45,209.5 205.66,209.34 205.66,209.34 C205.66,209.34 205.87,209.19 205.87,209.19 C205.87,209.19 206.09,209.03 206.09,209.03 C206.09,209.03 206.3,208.88 206.3,208.88 C206.3,208.88 206.52,208.72 206.52,208.72 C206.52,208.72 206.73,208.57 206.73,208.57 C206.73,208.57 206.94,208.41 206.94,208.41 C206.94,208.41 207.16,208.25 207.16,208.25 C207.16,208.25 207.37,208.1 207.37,208.1 C207.37,208.1 207.58,207.94 207.58,207.94 C207.58,207.94 207.8,207.79 207.8,207.79 C207.8,207.79 208.01,207.63 208.01,207.63 C208.01,207.63 208.23,207.48 208.23,207.48 C208.23,207.48 208.44,207.32 208.44,207.32 C208.44,207.32 208.65,207.17 208.65,207.17 C208.65,207.17 208.87,207.01 208.87,207.01 C208.87,207.01 209.08,206.86 209.08,206.86 C209.08,206.86 209.3,206.7 209.3,206.7 C209.3,206.7 209.51,206.55 209.51,206.55 C209.51,206.55 209.73,206.39 209.73,206.39 C209.73,206.39 209.94,206.24 209.94,206.24 C209.94,206.24 210.15,206.08 210.15,206.08 C210.15,206.08 210.37,205.93 210.37,205.93 C210.37,205.93 210.58,205.77 210.58,205.77 C210.58,205.77 210.8,205.62 210.8,205.62 C210.8,205.62 211.01,205.46 211.01,205.46 C211.01,205.46 211.23,205.31 211.23,205.31 C211.23,205.31 211.44,205.16 211.44,205.16 C211.44,205.16 211.65,205 211.65,205 C211.65,205 211.87,204.85 211.87,204.85 C211.87,204.85 212.08,204.69 212.08,204.69 C212.08,204.69 212.3,204.54 212.3,204.54 C212.3,204.54 212.51,204.38 212.51,204.38 C212.51,204.38 212.73,204.23 212.73,204.23 C212.73,204.23 212.94,204.07 212.94,204.07 C212.94,204.07 213.15,203.92 213.15,203.92 C213.15,203.92 213.37,203.76 213.37,203.76 C213.37,203.76 213.58,203.61 213.58,203.61 C213.58,203.61 213.8,203.45 213.8,203.45 C213.8,203.45 214.01,203.3 214.01,203.3 C214.01,203.3 214.23,203.14 214.23,203.14 C214.23,203.14 214.45,203 214.45,203 C214.45,203 214.67,202.86 214.67,202.86 C214.67,202.86 214.9,202.73 214.9,202.73 C214.9,202.73 215.14,202.61 215.14,202.61 C215.14,202.61 215.38,202.51 215.38,202.51 C215.38,202.51 215.63,202.41 215.63,202.41 C215.63,202.41 215.88,202.33 215.88,202.33 C215.88,202.33 216.13,202.26 216.13,202.26 C216.13,202.26 216.39,202.2 216.39,202.2 C216.39,202.2 216.65,202.15 216.65,202.15 C216.65,202.15 216.91,202.11 216.91,202.11 C216.91,202.11 217.18,202.09 217.18,202.09 C217.18,202.09 217.44,202.08 217.44,202.08 C217.44,202.08 217.7,202.08 217.7,202.08c " android:valueTo="M217.68 210.56 C217.68,210.56 217.81,210.57 217.81,210.57 C217.81,210.57 217.93,210.57 217.93,210.57 C217.93,210.57 218.06,210.58 218.06,210.58 C218.06,210.58 218.18,210.59 218.18,210.59 C218.18,210.59 218.31,210.59 218.31,210.59 C218.31,210.59 218.43,210.61 218.43,210.61 C218.43,210.61 218.56,210.63 218.56,210.63 C218.56,210.63 218.68,210.64 218.68,210.64 C218.68,210.64 218.81,210.66 218.81,210.66 C218.81,210.66 218.93,210.68 218.93,210.68 C218.93,210.68 219.05,210.7 219.05,210.7 C219.05,210.7 219.18,210.72 219.18,210.72 C219.18,210.72 219.3,210.75 219.3,210.75 C219.3,210.75 219.42,210.78 219.42,210.78 C219.42,210.78 219.54,210.81 219.54,210.81 C219.54,210.81 219.66,210.84 219.66,210.84 C219.66,210.84 219.79,210.87 219.79,210.87 C219.79,210.87 219.91,210.91 219.91,210.91 C219.91,210.91 220.03,210.95 220.03,210.95 C220.03,210.95 220.14,210.99 220.14,210.99 C220.14,210.99 220.26,211.04 220.26,211.04 C220.26,211.04 220.38,211.08 220.38,211.08 C220.38,211.08 220.5,211.12 220.5,211.12 C220.5,211.12 220.62,211.17 220.62,211.17 C220.62,211.17 220.73,211.22 220.73,211.22 C220.73,211.22 220.84,211.27 220.84,211.27 C220.84,211.27 220.96,211.32 220.96,211.32 C220.96,211.32 221.07,211.38 221.07,211.38 C221.07,211.38 221.19,211.43 221.19,211.43 C221.19,211.43 221.3,211.49 221.3,211.49 C221.3,211.49 221.41,211.55 221.41,211.55 C221.41,211.55 221.51,211.61 221.51,211.61 C221.51,211.61 221.62,211.68 221.62,211.68 C221.62,211.68 221.73,211.74 221.73,211.74 C221.73,211.74 221.84,211.8 221.84,211.8 C221.84,211.8 221.94,211.87 221.94,211.87 C221.94,211.87 222.05,211.94 222.05,211.94 C222.05,211.94 222.15,212.02 222.15,212.02 C222.15,212.02 222.25,212.09 222.25,212.09 C222.25,212.09 222.35,212.16 222.35,212.16 C222.35,212.16 222.46,212.23 222.46,212.23 C222.46,212.23 222.55,212.31 222.55,212.31 C222.55,212.31 222.65,212.4 222.65,212.4 C222.65,212.4 222.74,212.48 222.74,212.48 C222.74,212.48 222.84,212.56 222.84,212.56 C222.84,212.56 222.93,212.64 222.93,212.64 C222.93,212.64 223.03,212.72 223.03,212.72 C223.03,212.72 223.12,212.81 223.12,212.81 C223.12,212.81 223.21,212.9 223.21,212.9 C223.21,212.9 223.29,212.99 223.29,212.99 C223.29,212.99 223.38,213.08 223.38,213.08 C223.38,213.08 223.47,213.17 223.47,213.17 C223.47,213.17 223.55,213.26 223.55,213.26 C223.55,213.26 223.63,213.36 223.63,213.36 C223.63,213.36 223.71,213.46 223.71,213.46 C223.71,213.46 223.79,213.56 223.79,213.56 C223.79,213.56 223.87,213.66 223.87,213.66 C223.87,213.66 223.95,213.75 223.95,213.75 C223.95,213.75 224.03,213.85 224.03,213.85 C224.03,213.85 224.09,213.96 224.09,213.96 C224.09,213.96 224.16,214.06 224.16,214.06 C224.16,214.06 224.23,214.17 224.23,214.17 C224.23,214.17 224.3,214.27 224.3,214.27 C224.3,214.27 224.37,214.38 224.37,214.38 C224.37,214.38 224.44,214.48 224.44,214.48 C224.44,214.48 224.5,214.59 224.5,214.59 C224.5,214.59 224.56,214.7 224.56,214.7 C224.56,214.7 224.62,214.81 224.62,214.81 C224.62,214.81 224.68,214.93 224.68,214.93 C224.68,214.93 224.74,215.04 224.74,215.04 C224.74,215.04 224.79,215.15 224.79,215.15 C224.79,215.15 224.84,215.26 224.84,215.26 C224.84,215.26 224.89,215.38 224.89,215.38 C224.89,215.38 224.94,215.5 224.94,215.5 C224.94,215.5 224.99,215.61 224.99,215.61 C224.99,215.61 225.04,215.73 225.04,215.73 C225.04,215.73 225.08,215.84 225.08,215.84 C225.08,215.84 225.12,215.96 225.12,215.96 C225.12,215.96 225.16,216.08 225.16,216.08 C225.16,216.08 225.19,216.2 225.19,216.2 C225.19,216.2 225.23,216.32 225.23,216.32 C225.23,216.32 225.27,216.44 225.27,216.44 C225.27,216.44 225.3,216.56 225.3,216.56 C225.3,216.56 225.33,216.69 225.33,216.69 C225.33,216.69 225.35,216.81 225.35,216.81 C225.35,216.81 225.38,216.93 225.38,216.93 C225.38,216.93 225.41,217.06 225.41,217.06 C225.41,217.06 225.43,217.18 225.43,217.18 C225.43,217.18 225.46,217.3 225.46,217.3 C225.46,217.3 225.47,217.43 225.47,217.43 C225.47,217.43 225.49,217.55 225.49,217.55 C225.49,217.55 225.5,217.68 225.5,217.68 C225.5,217.68 225.52,217.8 225.52,217.8 C225.52,217.8 225.52,217.93 225.52,217.93 C225.52,217.93 225.53,218.05 225.53,218.05 C225.53,218.05 225.54,218.18 225.54,218.18 C225.54,218.18 225.54,218.3 225.54,218.3 C225.54,218.3 225.55,218.43 225.55,218.43 C225.55,218.43 225.55,218.55 225.55,218.55 C225.55,218.55 225.55,218.68 225.55,218.68 C225.55,218.68 225.54,218.8 225.54,218.8 C225.54,218.8 225.54,218.93 225.54,218.93 C225.54,218.93 225.53,219.05 225.53,219.05 C225.53,219.05 225.52,219.18 225.52,219.18 C225.52,219.18 225.52,219.31 225.52,219.31 C225.52,219.31 225.5,219.43 225.5,219.43 C225.5,219.43 225.48,219.55 225.48,219.55 C225.48,219.55 225.47,219.68 225.47,219.68 C225.47,219.68 225.45,219.8 225.45,219.8 C225.45,219.8 225.43,219.93 225.43,219.93 C225.43,219.93 225.41,220.05 225.41,220.05 C225.41,220.05 225.39,220.17 225.39,220.17 C225.39,220.17 225.36,220.3 225.36,220.3 C225.36,220.3 225.33,220.42 225.33,220.42 C225.33,220.42 225.3,220.54 225.3,220.54 C225.3,220.54 225.27,220.66 225.27,220.66 C225.27,220.66 225.24,220.78 225.24,220.78 C225.24,220.78 225.2,220.9 225.2,220.9 C225.2,220.9 225.16,221.02 225.16,221.02 C225.16,221.02 225.12,221.14 225.12,221.14 C225.12,221.14 225.08,221.26 225.08,221.26 C225.08,221.26 225.03,221.38 225.03,221.38 C225.03,221.38 224.99,221.5 224.99,221.5 C224.99,221.5 224.95,221.61 224.95,221.61 C224.95,221.61 224.89,221.73 224.89,221.73 C224.89,221.73 224.84,221.84 224.84,221.84 C224.84,221.84 224.79,221.96 224.79,221.96 C224.79,221.96 224.73,222.07 224.73,222.07 C224.73,222.07 224.68,222.18 224.68,222.18 C224.68,222.18 224.62,222.29 224.62,222.29 C224.62,222.29 224.56,222.4 224.56,222.4 C224.56,222.4 224.5,222.51 224.5,222.51 C224.5,222.51 224.44,222.62 224.44,222.62 C224.44,222.62 224.37,222.73 224.37,222.73 C224.37,222.73 224.31,222.84 224.31,222.84 C224.31,222.84 224.24,222.94 224.24,222.94 C224.24,222.94 224.17,223.05 224.17,223.05 C224.17,223.05 224.09,223.15 224.09,223.15 C224.09,223.15 224.02,223.25 224.02,223.25 C224.02,223.25 223.95,223.35 223.95,223.35 C223.95,223.35 223.88,223.45 223.88,223.45 C223.88,223.45 223.8,223.55 223.8,223.55 C223.8,223.55 223.71,223.65 223.71,223.65 C223.71,223.65 223.63,223.74 223.63,223.74 C223.63,223.74 223.55,223.84 223.55,223.84 C223.55,223.84 223.47,223.93 223.47,223.93 C223.47,223.93 223.39,224.03 223.39,224.03 C223.39,224.03 223.3,224.12 223.3,224.12 C223.3,224.12 223.21,224.2 223.21,224.2 C223.21,224.2 223.12,224.29 223.12,224.29 C223.12,224.29 223.03,224.38 223.03,224.38 C223.03,224.38 222.94,224.46 222.94,224.46 C222.94,224.46 222.85,224.55 222.85,224.55 C222.85,224.55 222.75,224.63 222.75,224.63 C222.75,224.63 222.65,224.71 222.65,224.71 C222.65,224.71 222.55,224.79 222.55,224.79 C222.55,224.79 222.46,224.87 222.46,224.87 C222.46,224.87 222.36,224.95 222.36,224.95 C222.36,224.95 222.26,225.02 222.26,225.02 C222.26,225.02 222.15,225.09 222.15,225.09 C222.15,225.09 222.05,225.16 222.05,225.16 C222.05,225.16 221.94,225.23 221.94,225.23 C221.94,225.23 221.84,225.3 221.84,225.3 C221.84,225.3 221.74,225.37 221.74,225.37 C221.74,225.37 221.63,225.44 221.63,225.44 C221.63,225.44 221.52,225.5 221.52,225.5 C221.52,225.5 221.41,225.56 221.41,225.56 C221.41,225.56 221.3,225.62 221.3,225.62 C221.3,225.62 221.19,225.68 221.19,225.68 C221.19,225.68 221.08,225.73 221.08,225.73 C221.08,225.73 220.96,225.79 220.96,225.79 C220.96,225.79 220.85,225.84 220.85,225.84 C220.85,225.84 220.73,225.89 220.73,225.89 C220.73,225.89 220.62,225.94 220.62,225.94 C220.62,225.94 220.5,225.99 220.5,225.99 C220.5,225.99 220.38,226.03 220.38,226.03 C220.38,226.03 220.27,226.08 220.27,226.08 C220.27,226.08 220.15,226.12 220.15,226.12 C220.15,226.12 220.03,226.15 220.03,226.15 C220.03,226.15 219.91,226.19 219.91,226.19 C219.91,226.19 219.79,226.23 219.79,226.23 C219.79,226.23 219.67,226.27 219.67,226.27 C219.67,226.27 219.55,226.3 219.55,226.3 C219.55,226.3 219.42,226.33 219.42,226.33 C219.42,226.33 219.3,226.35 219.3,226.35 C219.3,226.35 219.18,226.38 219.18,226.38 C219.18,226.38 219.06,226.4 219.06,226.4 C219.06,226.4 218.93,226.43 218.93,226.43 C218.93,226.43 218.81,226.45 218.81,226.45 C218.81,226.45 218.68,226.47 218.68,226.47 C218.68,226.47 218.56,226.49 218.56,226.49 C218.56,226.49 218.44,226.5 218.44,226.5 C218.44,226.5 218.31,226.52 218.31,226.52 C218.31,226.52 218.19,226.52 218.19,226.52 C218.19,226.52 218.06,226.53 218.06,226.53 C218.06,226.53 217.93,226.53 217.93,226.53 C217.93,226.53 217.81,226.54 217.81,226.54 C217.81,226.54 217.68,226.55 217.68,226.55 C217.68,226.55 217.56,226.55 217.56,226.55 C217.56,226.55 217.43,226.55 217.43,226.55 C217.43,226.55 217.31,226.54 217.31,226.54 C217.31,226.54 217.18,226.53 217.18,226.53 C217.18,226.53 217.05,226.53 217.05,226.53 C217.05,226.53 216.93,226.52 216.93,226.52 C216.93,226.52 216.8,226.52 216.8,226.52 C216.8,226.52 216.68,226.5 216.68,226.5 C216.68,226.5 216.55,226.48 216.55,226.48 C216.55,226.48 216.43,226.46 216.43,226.46 C216.43,226.46 216.31,226.45 216.31,226.45 C216.31,226.45 216.18,226.43 216.18,226.43 C216.18,226.43 216.06,226.41 216.06,226.41 C216.06,226.41 215.93,226.38 215.93,226.38 C215.93,226.38 215.81,226.35 215.81,226.35 C215.81,226.35 215.69,226.32 215.69,226.32 C215.69,226.32 215.57,226.29 215.57,226.29 C215.57,226.29 215.45,226.26 215.45,226.26 C215.45,226.26 215.32,226.23 215.32,226.23 C215.32,226.23 215.2,226.2 215.2,226.2 C215.2,226.2 215.09,226.16 215.09,226.16 C215.09,226.16 214.97,226.12 214.97,226.12 C214.97,226.12 214.85,226.07 214.85,226.07 C214.85,226.07 214.73,226.03 214.73,226.03 C214.73,226.03 214.61,225.99 214.61,225.99 C214.61,225.99 214.5,225.94 214.5,225.94 C214.5,225.94 214.38,225.89 214.38,225.89 C214.38,225.89 214.27,225.84 214.27,225.84 C214.27,225.84 214.15,225.79 214.15,225.79 C214.15,225.79 214.04,225.73 214.04,225.73 C214.04,225.73 213.93,225.68 213.93,225.68 C213.93,225.68 213.81,225.62 213.81,225.62 C213.81,225.62 213.71,225.56 213.71,225.56 C213.71,225.56 213.6,225.5 213.6,225.5 C213.6,225.5 213.49,225.43 213.49,225.43 C213.49,225.43 213.38,225.37 213.38,225.37 C213.38,225.37 213.27,225.31 213.27,225.31 C213.27,225.31 213.17,225.24 213.17,225.24 C213.17,225.24 213.06,225.16 213.06,225.16 C213.06,225.16 212.96,225.09 212.96,225.09 C212.96,225.09 212.86,225.02 212.86,225.02 C212.86,225.02 212.76,224.95 212.76,224.95 C212.76,224.95 212.65,224.87 212.65,224.87 C212.65,224.87 212.56,224.79 212.56,224.79 C212.56,224.79 212.46,224.71 212.46,224.71 C212.46,224.71 212.37,224.63 212.37,224.63 C212.37,224.63 212.27,224.55 212.27,224.55 C212.27,224.55 212.18,224.47 212.18,224.47 C212.18,224.47 212.08,224.38 212.08,224.38 C212.08,224.38 211.99,224.3 211.99,224.3 C211.99,224.3 211.91,224.2 211.91,224.2 C211.91,224.2 211.82,224.11 211.82,224.11 C211.82,224.11 211.73,224.02 211.73,224.02 C211.73,224.02 211.64,223.93 211.64,223.93 C211.64,223.93 211.56,223.84 211.56,223.84 C211.56,223.84 211.48,223.75 211.48,223.75 C211.48,223.75 211.4,223.65 211.4,223.65 C211.4,223.65 211.32,223.55 211.32,223.55 C211.32,223.55 211.24,223.45 211.24,223.45 C211.24,223.45 211.16,223.35 211.16,223.35 C211.16,223.35 211.09,223.26 211.09,223.26 C211.09,223.26 211.02,223.15 211.02,223.15 C211.02,223.15 210.95,223.05 210.95,223.05 C210.95,223.05 210.88,222.94 210.88,222.94 C210.88,222.94 210.81,222.84 210.81,222.84 C210.81,222.84 210.74,222.73 210.74,222.73 C210.74,222.73 210.67,222.63 210.67,222.63 C210.67,222.63 210.61,222.52 210.61,222.52 C210.61,222.52 210.55,222.4 210.55,222.4 C210.55,222.4 210.49,222.29 210.49,222.29 C210.49,222.29 210.43,222.18 210.43,222.18 C210.43,222.18 210.38,222.07 210.38,222.07 C210.38,222.07 210.32,221.96 210.32,221.96 C210.32,221.96 210.27,221.84 210.27,221.84 C210.27,221.84 210.22,221.73 210.22,221.73 C210.22,221.73 210.17,221.61 210.17,221.61 C210.17,221.61 210.12,221.5 210.12,221.5 C210.12,221.5 210.08,221.38 210.08,221.38 C210.08,221.38 210.03,221.26 210.03,221.26 C210.03,221.26 209.99,221.14 209.99,221.14 C209.99,221.14 209.96,221.02 209.96,221.02 C209.96,221.02 209.92,220.9 209.92,220.9 C209.92,220.9 209.88,220.78 209.88,220.78 C209.88,220.78 209.84,220.67 209.84,220.67 C209.84,220.67 209.81,220.54 209.81,220.54 C209.81,220.54 209.78,220.42 209.78,220.42 C209.78,220.42 209.76,220.3 209.76,220.3 C209.76,220.3 209.73,220.18 209.73,220.18 C209.73,220.18 209.71,220.05 209.71,220.05 C209.71,220.05 209.68,219.93 209.68,219.93 C209.68,219.93 209.66,219.81 209.66,219.81 C209.66,219.81 209.64,219.68 209.64,219.68 C209.64,219.68 209.62,219.56 209.62,219.56 C209.62,219.56 209.61,219.43 209.61,219.43 C209.61,219.43 209.59,219.31 209.59,219.31 C209.59,219.31 209.59,219.18 209.59,219.18 C209.59,219.18 209.58,219.06 209.58,219.06 C209.58,219.06 209.58,218.93 209.58,218.93 C209.58,218.93 209.57,218.81 209.57,218.81 C209.57,218.81 209.56,218.68 209.56,218.68 C209.56,218.68 209.56,218.56 209.56,218.56 C209.56,218.56 209.56,218.43 209.56,218.43 C209.56,218.43 209.57,218.3 209.57,218.3 C209.57,218.3 209.58,218.18 209.58,218.18 C209.58,218.18 209.58,218.05 209.58,218.05 C209.58,218.05 209.59,217.93 209.59,217.93 C209.59,217.93 209.59,217.8 209.59,217.8 C209.59,217.8 209.61,217.68 209.61,217.68 C209.61,217.68 209.63,217.55 209.63,217.55 C209.63,217.55 209.65,217.43 209.65,217.43 C209.65,217.43 209.66,217.31 209.66,217.31 C209.66,217.31 209.68,217.18 209.68,217.18 C209.68,217.18 209.7,217.06 209.7,217.06 C209.7,217.06 209.73,216.93 209.73,216.93 C209.73,216.93 209.76,216.81 209.76,216.81 C209.76,216.81 209.79,216.69 209.79,216.69 C209.79,216.69 209.82,216.57 209.82,216.57 C209.82,216.57 209.85,216.45 209.85,216.45 C209.85,216.45 209.88,216.32 209.88,216.32 C209.88,216.32 209.91,216.2 209.91,216.2 C209.91,216.2 209.95,216.08 209.95,216.08 C209.95,216.08 210,215.97 210,215.97 C210,215.97 210.04,215.85 210.04,215.85 C210.04,215.85 210.08,215.73 210.08,215.73 C210.08,215.73 210.12,215.61 210.12,215.61 C210.12,215.61 210.17,215.49 210.17,215.49 C210.17,215.49 210.22,215.38 210.22,215.38 C210.22,215.38 210.27,215.27 210.27,215.27 C210.27,215.27 210.33,215.15 210.33,215.15 C210.33,215.15 210.38,215.04 210.38,215.04 C210.38,215.04 210.43,214.92 210.43,214.92 C210.43,214.92 210.49,214.81 210.49,214.81 C210.49,214.81 210.55,214.7 210.55,214.7 C210.55,214.7 210.61,214.6 210.61,214.6 C210.61,214.6 210.68,214.49 210.68,214.49 C210.68,214.49 210.74,214.38 210.74,214.38 C210.74,214.38 210.8,214.27 210.8,214.27 C210.8,214.27 210.87,214.17 210.87,214.17 C210.87,214.17 210.95,214.06 210.95,214.06 C210.95,214.06 211.02,213.96 211.02,213.96 C211.02,213.96 211.09,213.86 211.09,213.86 C211.09,213.86 211.16,213.76 211.16,213.76 C211.16,213.76 211.24,213.65 211.24,213.65 C211.24,213.65 211.32,213.56 211.32,213.56 C211.32,213.56 211.4,213.46 211.4,213.46 C211.4,213.46 211.48,213.37 211.48,213.37 C211.48,213.37 211.56,213.27 211.56,213.27 C211.56,213.27 211.64,213.18 211.64,213.18 C211.64,213.18 211.73,213.08 211.73,213.08 C211.73,213.08 211.82,212.99 211.82,212.99 C211.82,212.99 211.91,212.9 211.91,212.9 C211.91,212.9 212,212.82 212,212.82 C212,212.82 212.09,212.73 212.09,212.73 C212.09,212.73 212.18,212.64 212.18,212.64 C212.18,212.64 212.27,212.56 212.27,212.56 C212.27,212.56 212.36,212.48 212.36,212.48 C212.36,212.48 212.46,212.4 212.46,212.4 C212.46,212.4 212.56,212.32 212.56,212.32 C212.56,212.32 212.66,212.24 212.66,212.24 C212.66,212.24 212.76,212.16 212.76,212.16 C212.76,212.16 212.85,212.08 212.85,212.08 C212.85,212.08 212.96,212.02 212.96,212.02 C212.96,212.02 213.06,211.95 213.06,211.95 C213.06,211.95 213.17,211.88 213.17,211.88 C213.17,211.88 213.27,211.81 213.27,211.81 C213.27,211.81 213.38,211.74 213.38,211.74 C213.38,211.74 213.48,211.67 213.48,211.67 C213.48,211.67 213.6,211.61 213.6,211.61 C213.6,211.61 213.71,211.55 213.71,211.55 C213.71,211.55 213.82,211.49 213.82,211.49 C213.82,211.49 213.93,211.43 213.93,211.43 C213.93,211.43 214.04,211.37 214.04,211.37 C214.04,211.37 214.15,211.32 214.15,211.32 C214.15,211.32 214.27,211.27 214.27,211.27 C214.27,211.27 214.38,211.22 214.38,211.22 C214.38,211.22 214.5,211.17 214.5,211.17 C214.5,211.17 214.61,211.12 214.61,211.12 C214.61,211.12 214.73,211.07 214.73,211.07 C214.73,211.07 214.85,211.03 214.85,211.03 C214.85,211.03 214.97,210.99 214.97,210.99 C214.97,210.99 215.09,210.95 215.09,210.95 C215.09,210.95 215.21,210.92 215.21,210.92 C215.21,210.92 215.33,210.88 215.33,210.88 C215.33,210.88 215.45,210.84 215.45,210.84 C215.45,210.84 215.57,210.81 215.57,210.81 C215.57,210.81 215.69,210.78 215.69,210.78 C215.69,210.78 215.81,210.76 215.81,210.76 C215.81,210.76 215.93,210.73 215.93,210.73 C215.93,210.73 216.06,210.7 216.06,210.7 C216.06,210.7 216.18,210.68 216.18,210.68 C216.18,210.68 216.3,210.65 216.3,210.65 C216.3,210.65 216.43,210.64 216.43,210.64 C216.43,210.64 216.55,210.62 216.55,210.62 C216.55,210.62 216.68,210.61 216.68,210.61 C216.68,210.61 216.8,210.59 216.8,210.59 C216.8,210.59 216.93,210.59 216.93,210.59 C216.93,210.59 217.05,210.58 217.05,210.58 C217.05,210.58 217.18,210.58 217.18,210.58 C217.18,210.58 217.3,210.57 217.3,210.57 C217.3,210.57 217.43,210.56 217.43,210.56 C217.43,210.56 217.56,210.56 217.56,210.56 C217.56,210.56 217.68,210.56 217.68,210.56c " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="500" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/udfps_enroll_checkmark.xml b/packages/SystemUI/res/drawable/udfps_enroll_checkmark.xml
deleted file mode 100644
index f8169d3..0000000
--- a/packages/SystemUI/res/drawable/udfps_enroll_checkmark.xml
+++ /dev/null
@@ -1,35 +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="54dp"
-        android:height="54dp"
-        android:viewportWidth="54"
-        android:viewportHeight="54">
-    <path
-        android:pathData="M26.9999,3.9619C39.7029,3.9619 50.0369,14.2969 50.0369,26.9999C50.0369,39.7029 39.7029,50.0379 26.9999,50.0379C14.2969,50.0379 3.9629,39.7029 3.9629,26.9999C3.9629,14.2969 14.2969,3.9619 26.9999,3.9619Z"
-        android:fillColor="?android:colorBackground"
-        android:fillType="evenOdd"/>
-    <path
-        android:pathData="M27,0C12.088,0 0,12.088 0,27C0,41.912 12.088,54 27,54C41.912,54 54,41.912 54,27C54,12.088 41.912,0 27,0ZM27,3.962C39.703,3.962 50.037,14.297 50.037,27C50.037,39.703 39.703,50.038 27,50.038C14.297,50.038 3.963,39.703 3.963,27C3.963,14.297 14.297,3.962 27,3.962Z"
-        android:fillColor="@color/udfps_enroll_progress"
-        android:fillType="evenOdd"/>
-    <path
-        android:pathData="M23.0899,38.8534L10.4199,26.1824L13.2479,23.3544L23.0899,33.1974L41.2389,15.0474L44.0679,17.8754L23.0899,38.8534Z"
-        android:fillColor="@color/udfps_enroll_progress"
-        android:fillType="evenOdd"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/activity_rear_display_education.xml b/packages/SystemUI/res/layout/activity_rear_display_education.xml
index f5fc48c..094807e 100644
--- a/packages/SystemUI/res/layout/activity_rear_display_education.xml
+++ b/packages/SystemUI/res/layout/activity_rear_display_education.xml
@@ -41,9 +41,10 @@
     </androidx.cardview.widget.CardView>
 
     <TextView
+        android:id="@+id/rear_display_title_text_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/rear_display_fold_bottom_sheet_title"
+        android:text="@string/rear_display_folded_bottom_sheet_title"
         android:textAppearance="@style/TextAppearance.Dialog.Title"
         android:lineSpacingExtra="2sp"
         android:paddingTop="@dimen/rear_display_title_top_padding"
@@ -54,7 +55,7 @@
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/rear_display_bottom_sheet_description"
+        android:text="@string/rear_display_folded_bottom_sheet_description"
         android:textAppearance="@style/TextAppearance.Dialog.Body"
         android:lineSpacingExtra="2sp"
         android:translationY="-1.24sp"
diff --git a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
index 6de06f7..e970bc5 100644
--- a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
+++ b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
@@ -42,9 +42,10 @@
     </androidx.cardview.widget.CardView>
 
     <TextView
+        android:id="@+id/rear_display_title_text_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/rear_display_unfold_bottom_sheet_title"
+        android:text="@string/rear_display_unfolded_bottom_sheet_title"
         android:textAppearance="@style/TextAppearance.Dialog.Title"
         android:lineSpacingExtra="2sp"
         android:paddingTop="@dimen/rear_display_title_top_padding"
@@ -55,21 +56,11 @@
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:text="@string/rear_display_bottom_sheet_description"
+        android:text="@string/rear_display_unfolded_bottom_sheet_description"
         android:textAppearance="@style/TextAppearance.Dialog.Body"
         android:lineSpacingExtra="2sp"
         android:translationY="-1.24sp"
         android:gravity="center_horizontal|top"
     />
 
-    <TextView
-        android:id="@+id/rear_display_warning_text_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/rear_display_bottom_sheet_warning"
-        android:textAppearance="@style/TextAppearance.Dialog.Body"
-        android:lineSpacingExtra="2sp"
-        android:gravity="center_horizontal|top"
-    />
-
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/app_clips_screenshot.xml b/packages/SystemUI/res/layout/app_clips_screenshot.xml
new file mode 100644
index 0000000..5155b77
--- /dev/null
+++ b/packages/SystemUI/res/layout/app_clips_screenshot.xml
@@ -0,0 +1,105 @@
+<?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.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:background="@null"
+    android:id="@+id/root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/save"
+        style="@android:style/Widget.DeviceDefault.Button.Colored"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:text="@string/app_clips_save_add_to_note"
+        android:layout_marginStart="8dp"
+        android:background="@drawable/overlay_button_background"
+        android:textColor="?android:textColorSecondary"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/preview" />
+
+    <Button
+        android:id="@+id/cancel"
+        style="@android:style/Widget.DeviceDefault.Button.Colored"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:text="@android:string/cancel"
+        android:layout_marginStart="6dp"
+        android:background="@drawable/overlay_button_background"
+        android:textColor="?android:textColorSecondary"
+        app:layout_constraintStart_toEndOf="@id/save"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/preview" />
+
+    <ImageView
+        android:id="@+id/preview"
+        android:layout_width="0px"
+        android:layout_height="0px"
+        android:paddingHorizontal="48dp"
+        android:paddingTop="8dp"
+        android:paddingBottom="42dp"
+        android:contentDescription="@string/screenshot_preview_description"
+        app:layout_constrainedHeight="true"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintTop_toBottomOf="@id/save"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        tools:background="?android:colorBackground"
+        tools:minHeight="100dp"
+        tools:minWidth="100dp" />
+
+    <com.android.systemui.screenshot.CropView
+        android:id="@+id/crop_view"
+        android:layout_width="0px"
+        android:layout_height="0px"
+        android:paddingTop="8dp"
+        android:paddingBottom="42dp"
+        app:layout_constrainedHeight="true"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintTop_toTopOf="@id/preview"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:handleThickness="@dimen/screenshot_crop_handle_thickness"
+        app:handleColor="?android:attr/colorAccent"
+        app:scrimColor="?android:colorBackgroundFloating"
+        app:scrimAlpha="128"
+        app:containerBackgroundColor="?android:colorBackgroundFloating"
+        tools:background="?android:colorBackground"
+        tools:minHeight="100dp"
+        tools:minWidth="100dp" />
+
+    <com.android.systemui.screenshot.MagnifierView
+        android:id="@+id/magnifier"
+        android:visibility="invisible"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:elevation="2dp"
+        app:layout_constraintTop_toTopOf="@id/preview"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:handleThickness="@dimen/screenshot_crop_handle_thickness"
+        app:handleColor="?android:attr/colorAccent"
+        app:scrimColor="?android:colorBackgroundFloating"
+        app:scrimAlpha="128"
+        app:borderThickness="4dp"
+        app:borderColor="#fff" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/controls_with_favorites.xml b/packages/SystemUI/res/layout/controls_with_favorites.xml
index ded6f93..aa211bf 100644
--- a/packages/SystemUI/res/layout/controls_with_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_with_favorites.xml
@@ -20,7 +20,6 @@
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="horizontal"
-      android:layout_marginTop="@dimen/controls_top_margin"
       android:layout_marginBottom="@dimen/controls_header_bottom_margin">
 
     <!-- make sure the header stays centered in the layout by adding a spacer -->
@@ -78,6 +77,7 @@
         android:layout_weight="1"
         android:orientation="vertical"
         android:clipChildren="true"
+        android:paddingHorizontal="16dp"
         android:scrollbars="none">
     <include layout="@layout/global_actions_controls_list_view" />
 
@@ -88,8 +88,6 @@
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1"
-      android:layout_marginLeft="@dimen/global_actions_side_margin"
-      android:layout_marginRight="@dimen/global_actions_side_margin"
       android:background="@drawable/controls_panel_background"
       android:visibility="gone"
       />
diff --git a/packages/SystemUI/res/layout/keyguard_pin_shape_hinting_view.xml b/packages/SystemUI/res/layout/keyguard_pin_shape_hinting_view.xml
new file mode 100644
index 0000000..aab9870
--- /dev/null
+++ b/packages/SystemUI/res/layout/keyguard_pin_shape_hinting_view.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
+  -->
+<com.android.keyguard.PinShapeHintingView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:gravity="center"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+</com.android.keyguard.PinShapeHintingView>
diff --git a/packages/SystemUI/res/layout/keyguard_pin_shape_non_hinting_view.xml b/packages/SystemUI/res/layout/keyguard_pin_shape_non_hinting_view.xml
new file mode 100644
index 0000000..cba1db0
--- /dev/null
+++ b/packages/SystemUI/res/layout/keyguard_pin_shape_non_hinting_view.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
+  -->
+<com.android.keyguard.PinShapeNonHintingView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:gravity="center"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+</com.android.keyguard.PinShapeNonHintingView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
index aaa372a..e39f1a9 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
@@ -18,6 +18,7 @@
 
 <!-- LinearLayout -->
 <com.android.systemui.statusbar.policy.KeyguardUserDetailItemView
+        android:id="@+id/user_item"
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:systemui="http://schemas.android.com/apk/res-auto"
         android:layout_width="wrap_content"
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 d49b9f1..a650512 100644
--- a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
@@ -152,5 +152,16 @@
             android:button="@drawable/media_output_item_check_box"
             android:visibility="gone"
             />
+        <ImageView
+            android:id="@+id/media_output_item_end_click_icon"
+            android:src="@drawable/media_output_status_edit_session"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:focusable="false"
+            android:importantForAccessibility="no"
+            android:layout_gravity="center"
+            android:indeterminate="true"
+            android:indeterminateOnly="true"
+            android:visibility="gone"/>
     </FrameLayout>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
index 4483db8..02186fc 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
@@ -27,22 +27,28 @@
         android:layout_height="wrap_content"
         />
 
-    <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView
-        android:id="@+id/icon_glow_ripple"
+    <FrameLayout
+        android:id="@+id/icon_container_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        />
-
-    <!-- Add a bottom margin to avoid the glow of the icon ripple from being cropped by screen
-     bounds while animating with the icon -->
-    <com.android.internal.widget.CachingIconView
-        android:id="@+id/app_icon"
-        android:background="@drawable/media_ttt_chip_background_receiver"
-        android:layout_width="@dimen/media_ttt_icon_size_receiver"
-        android:layout_height="@dimen/media_ttt_icon_size_receiver"
-        android:layout_gravity="center|bottom"
         android:alpha="0.0"
-        android:layout_marginBottom="@dimen/media_ttt_receiver_icon_bottom_margin"
-        />
+        >
+        <com.android.systemui.media.taptotransfer.receiver.ReceiverChipRippleView
+            android:id="@+id/icon_glow_ripple"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            />
+
+        <!-- Add a bottom margin to avoid the glow of the icon ripple from being cropped by screen
+        bounds while animating with the icon -->
+        <com.android.internal.widget.CachingIconView
+            android:id="@+id/app_icon"
+            android:background="@drawable/media_ttt_chip_background_receiver"
+            android:layout_width="@dimen/media_ttt_icon_size_receiver"
+            android:layout_height="@dimen/media_ttt_icon_size_receiver"
+            android:layout_gravity="center|bottom"
+            android:layout_marginBottom="@dimen/media_ttt_receiver_icon_bottom_margin"
+            />
+    </FrameLayout>
 
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/qs_user_detail_item.xml b/packages/SystemUI/res/layout/qs_user_detail_item.xml
index 7c86bc7..ad129e8 100644
--- a/packages/SystemUI/res/layout/qs_user_detail_item.xml
+++ b/packages/SystemUI/res/layout/qs_user_detail_item.xml
@@ -18,6 +18,7 @@
 
 <!-- LinearLayout -->
 <com.android.systemui.qs.tiles.UserDetailItemView
+        android:id="@+id/user_item"
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:systemui="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml b/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml
index 2567176..130472d 100644
--- a/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml
+++ b/packages/SystemUI/res/layout/screen_record_dialog_audio_source.xml
@@ -23,7 +23,7 @@
     <TextView
         android:id="@+id/screen_recording_dialog_source_text"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textSize="14sp"
diff --git a/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml b/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml
index e2b8d33..9d9f5c2 100644
--- a/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml
+++ b/packages/SystemUI/res/layout/screen_record_dialog_audio_source_selected.xml
@@ -22,7 +22,7 @@
     android:layout_weight="1">
     <TextView
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:text="@string/screenrecord_audio_label"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:fontFamily="@*android:string/config_headlineFontFamily"
@@ -30,7 +30,7 @@
     <TextView
         android:id="@+id/screen_recording_dialog_source_text"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:textColor="?android:attr/textColorSecondary"
         android:textAppearance="?android:attr/textAppearanceSmall"/>
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/screen_record_options.xml b/packages/SystemUI/res/layout/screen_record_options.xml
index 3f0eea9..6cc72dd 100644
--- a/packages/SystemUI/res/layout/screen_record_options.xml
+++ b/packages/SystemUI/res/layout/screen_record_options.xml
@@ -67,7 +67,7 @@
             android:importantForAccessibility="no"/>
         <TextView
             android:layout_width="0dp"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:minHeight="48dp"
             android:layout_weight="1"
             android:gravity="center_vertical"
diff --git a/packages/SystemUI/res/layout/screenshot_static.xml b/packages/SystemUI/res/layout/screenshot_static.xml
index a748e29..7e9202c 100644
--- a/packages/SystemUI/res/layout/screenshot_static.xml
+++ b/packages/SystemUI/res/layout/screenshot_static.xml
@@ -149,6 +149,8 @@
         app:layout_constraintTop_toBottomOf="@id/guideline"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintWidth_max="450dp"
+        app:layout_constraintHorizontal_bias="0"
         >
         <include layout="@layout/screenshot_work_profile_first_run" />
         <include layout="@layout/screenshot_detection_notice" />
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 2c08f5d..356b36f 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -39,8 +39,11 @@
 
     <com.android.systemui.statusbar.notification.row.NotificationContentView
         android:id="@+id/expanded"
-       android:layout_width="match_parent"
-       android:layout_height="wrap_content" />
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:minHeight="@dimen/notification_content_min_height"
+        android:gravity="center_vertical"
+        />
 
     <com.android.systemui.statusbar.notification.row.NotificationContentView
         android:id="@+id/expandedPublic"
diff --git a/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml b/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
index de43a5e..4799f8c 100644
--- a/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
+++ b/packages/SystemUI/res/layout/udfps_fpm_empty_view.xml
@@ -19,4 +19,12 @@
     android:id="@+id/udfps_animation_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
+    <!-- The layout height/width are placeholders, which will be overwritten by
+     FingerprintSensorPropertiesInternal. -->
+    <View
+        android:id="@+id/udfps_enroll_accessibility_view"
+        android:layout_gravity="center"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:contentDescription="@string/accessibility_fingerprint_label"/>
 </com.android.systemui.biometrics.UdfpsFpmEmptyView>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 6bb51bbb..8dad853 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ondergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linkergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Regtergrens <xliff:g id="PERCENT">%1$d</xliff:g> persent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Werkskermskote word in die <xliff:g id="APP">%1$s</xliff:g>-app gestoor"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Gestoor in <xliff:g id="APP">%1$s</xliff:g> in die werkprofiel"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Lêers"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> het hierdie skermskoot bespeur."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en ander oop apps het hierdie skermskoot bespeur."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Voeg by nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skermopnemer"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Gesig is herken. Druk die ontsluitikoon om oop te maak."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Ontsluit met gesig"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Gesig is herken"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Beweeg links"</item>
-    <item msgid="5558598599408514296">"Beweeg af"</item>
-    <item msgid="4844142668312841831">"Beweeg regs"</item>
-    <item msgid="5640521437931460125">"Beweeg op"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swiep op om weer te probeer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontsluit om NFC te gebruik"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Kies program om kontroles by te voeg"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrole bygevoeg.}other{# kontroles bygevoeg.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Verwyder"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Voeg <xliff:g id="APPNAME">%s</xliff:g> by?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Wanneer jy <xliff:g id="APPNAME">%s</xliff:g> byvoeg, kan dit kontroles en inhoud by hierdie paneel voeg. Jy kan in sommige apps kies watter kontroles hier verskyn."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"As gunsteling gemerk"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"As gunsteling gemerk; posisie <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"As gunsteling ontmerk"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Maak <xliff:g id="APP_LABEL">%1$s</xliff:g> oop"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Speel <xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Speel <xliff:g id="SONG_NAME">%1$s</xliff:g> vanaf <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Vir jou"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Ontdoen"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Beweeg nader om op <xliff:g id="DEVICENAME">%1$s</xliff:g> te speel"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Beweeg nader aan <xliff:g id="DEVICENAME">%1$s</xliff:g> om hier te speel"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Iets is fout. Probeer weer."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Laai tans"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Saai jou media uit"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Saai tans <xliff:g id="APP_LABEL">%1$s</xliff:g> uit"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrole is nie beskikbaar nie"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer weer"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Voeg kontroles by"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Wysig kontroles"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Voeg app by"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Voeg uitvoere by"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Groep"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 toestel gekies"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Luidsprekers en skerms"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde toestelle"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vereis premiumrekening"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan nie uitsaai nie"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan nie stoor nie. Probeer weer."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan nie stoor nie."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Bounommer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Bounommer is na knipbord gekopieer."</string>
     <string name="basic_status" msgid="2315371112182658176">"Maak gesprek oop"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera is af"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofoon is af"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera en mikrofoon is af"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent luister"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# kennisgewing}other{# kennisgewings}}"</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">"Neem notas"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Gee eenmalige toegang"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Moenie toelaat nie"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Toestelloglêers teken aan wat op jou toestel gebeur. Apps kan hierdie loglêers gebruik om kwessies op te spoor en reg te stel.\n\nSommige loglêers bevat dalk sensitiewe inligting, en daarom moet jy toegang tot alle toestelloglêers net gee aan apps wat jy vertrou. \n\nHierdie app het steeds toegang tot sy eie loglêers as jy nie vir hierdie app toegang tot alle toestelloglêers gee nie. Jou toestelvervaardiger het dalk steeds toegang tot sommige loglêers of inligting op jou toestel."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Kom meer te wete"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Kom meer te wete by <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Maak <xliff:g id="APPNAME">%1$s</xliff:g> oop"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Die app opgestel is"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Minstens een kaart by Wallet gevoeg is"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Skakel oor na werkprofiel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Maak toe"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Sluitskerminstellings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 45e83c0..db7fdb2a 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"የታች ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"የግራ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"የቀኝ ወሰን <xliff:g id="PERCENT">%1$d</xliff:g> በመቶ"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"የሥራ ቅጽበታዊ ገጽ እይታዎች በ<xliff:g id="APP">%1$s</xliff:g> መተግበሪያ ውስጥ ይቀመጣሉ"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"<xliff:g id="APP">%1$s</xliff:g> ውስጥ የስራ መገለጫው ውስጥ ተቀምጧል"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ፋይሎች"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ይህን ቅጽበታዊ ገጽ እይታ ለይቷል።"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> እና ሌሎች ክፍት መተግበሪያዎች ይህን ቅጽበታዊ ገጽ እይታ ለይተዋል።"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ወደ ማስታወሻ አክል"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"የማያ መቅጃ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገጽ ቀረጻን በማሰናዳት ላይ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገጽ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"መልክ ተለይቶ ታውቋል። ለመክፈት የመክፈቻ አዶውን ይጫኑ።"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"በመልክ ተከፍቷል"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"መልክ ተለይቶ ታውቋል"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ወደ ግራ ውሰድ"</item>
-    <item msgid="5558598599408514296">"ወደ ታች ውሰድ"</item>
-    <item msgid="4844142668312841831">"ወደ ቀኝ ውሰድ"</item>
-    <item msgid="5640521437931460125">"ወደ ላይ ውሰድ"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCን ለመጠቀም ይክፈቱ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ይህ መሣሪያ የድርጅትዎ ነው"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"መቆጣጠሪያዎችን ለማከል መተግበሪያ ይምረጡ"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ቁጥጥር ታክሏል።}one{# ቁጥጥር ታክሏል።}other{# ቁጥጥሮች ታክለዋል።}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ይታከል?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g>ን ሲያክሉ መቆጣጠሪያዎችን እና ይዘትን ወደዚህ ፓነል ሊያክል ይችላል። በአንዳንድ መተግበሪያዎች ውስጥ የትኛዎቹ መቆጣጠሪያዎች እዚህ ላይ እንደሚታዩ መምረጥ ይችላሉ።"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ተወዳጅ አልተደረገም"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ክፈት"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> ያጫውቱ"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ከ<xliff:g id="APP_LABEL">%2$s</xliff:g> ያጫውቱ"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ለእርስዎ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ቀልብስ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"በ<xliff:g id="DEVICENAME">%1$s</xliff:g> ላይ ለማጫወት ጠጋ ያድርጉ"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"እዚህ ለማጫወት ወደ <xliff:g id="DEVICENAME">%1$s</xliff:g> ጠጋ ይበሉ"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"የሆነ ችግር ተፈጥሯል። እንደገና ይሞክሩ።"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"በመጫን ላይ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ጡባዊ"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"የእርስዎን ሚዲያ cast በማድረግ ላይ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g>ን Cast በማድረግ ላይ"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"መቆጣጠሪያ አይገኝም"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"ስህተት፣ እንደገና ይሞክሩ"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"መቆጣጠሪያዎችን አክል"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"መቆጣጠሪያዎችን ያርትዑ"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"መተግበሪያ አክል"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ውጽዓቶችን ያክሉ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ቡድን"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 መሣሪያ ተመርጧል"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ድምጽ ማውጫዎች እና ማሳያዎች"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"የተጠቆሙ መሣሪያዎች"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ፕሪሚየም መለያ ይጠይቃል"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"መሰራጨት አይችልም"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ማስቀመጥ አልተቻለም። እንደገና ይሞክሩ።"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ማስቀመጥ አልተቻለም።"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"የግንብ ቁጥር"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"የገንባ ቁጥር ወደ ቅንጥብ ሰሌዳ ተቀድቷል።"</string>
     <string name="basic_status" msgid="2315371112182658176">"ውይይት ይክፈቱ"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ካሜራ ጠፍቷል"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ማይክሮፎን ጠፍቷል"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ካሜራ እና ማይክሮፎን ጠፍተዋል"</string>
+    <string name="dream_overlay_status_bar_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_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">"Notetaking"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"የአንድ ጊዜ መዳረሻን ፍቀድ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"አትፍቀድ"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"የመሣሪያ ምዝግብ ማስታወሻዎች በመሣሪያዎ ላይ ምን እንደሚከሰት ይመዘግባሉ። መተግበሪያዎች ችግሮችን ለማግኘት እና ለማስተካከል እነዚህን ምዝግብ ማስታወሻዎች መጠቀም ይችላሉ።\n\nአንዳንድ ምዝግብ ማስታወሻዎች ልዩ ጥንቃቄ የሚያስፈልገው መረጃ ሊይዙ ይችላሉ ስለዚህ ለሚያምኗቸው መተግበሪያዎች ብቻ ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርሱ ይፍቀዱላቸው። \n\nይህ መተግበሪያ ሁሉንም የመሣሪያ ምዝግብ ማስታወሻዎች እንዲደርስ ካልፈቀዱለት አሁንም የራሱን ምዝግብ ማስታወሻዎች መድረስ ይችላል። የእርስዎ መሣሪያ አምራች አሁንም በመሣሪያዎ ላይ አንዳንድ ምዝግብ ማስታወሻዎችን ወይም መረጃዎችን ሊደርስ ይችላል።"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"የበለጠ ለመረዳት"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> ላይ የበለጠ ይወቁ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ይክፈቱ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• መተግበሪያው ተዋቅሯል"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ቢያንስ አንድ ካርድ ወደ Wallet ታክሏል"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"የሥራ መመሪያዎ እርስዎ ከሥራ መገለጫው ብቻ ጥሪ እንዲያደርጉ ይፈቅድልዎታል"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ወደ የሥራ መገለጫ ቀይር"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ዝጋ"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"የማያ ገጽ ቁልፍ ቅንብሮች"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index eeaf5d7..ebc3896 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"الحد السفلى <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"الحد الأيسر <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"الحد الأيمن <xliff:g id="PERCENT">%1$d</xliff:g> في المئة"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"يتم حفظ لقطات الشاشة الخاصة بالعمل في تطبيق \"<xliff:g id="APP">%1$s</xliff:g>\"."</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"تم حفظ لقطة الشاشة في \"<xliff:g id="APP">%1$s</xliff:g>\" في الملف الشخصي للعمل."</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"الملفات"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" لقطة الشاشة هذه."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" والتطبيقات المفتوحة الأخرى لقطة الشاشة هذه."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"إضافة إلى الملاحظة"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"مسجّل الشاشة"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"تم التعرّف على الوجه. اضغط على رمز فتح القفل لفتح الجهاز."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"تم فتح قفل جهازك عند تقريبه من وجهك."</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"تم التعرّف على الوجه."</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"نقل لليسار"</item>
-    <item msgid="5558598599408514296">"نقل للأسفل"</item>
-    <item msgid="4844142668312841831">"نقل لليمين"</item>
-    <item msgid="5640521437931460125">"نقل للأعلى"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏افتح قفل الشاشة لاستخدام تقنية NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string>
@@ -820,11 +817,11 @@
     <string name="accessibility_floating_button_undo" msgid="511112888715708241">"تراجع"</string>
     <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"تمت إزالة اختصار <xliff:g id="FEATURE_NAME">%s</xliff:g>."</string>
     <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{تمت إزالة اختصار واحد.}zero{تمت إزالة # اختصار.}two{تمت إزالة اختصارَين.}few{تمت إزالة # اختصارات.}many{تمت إزالة # اختصارًا.}other{تمت إزالة # اختصار.}}"</string>
-    <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"نقل إلى أعلى يمين الشاشة"</string>
-    <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"نقل إلى أعلى يسار الشاشة"</string>
-    <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"نقل إلى أسفل يمين الشاشة"</string>
-    <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"نقل إلى أسفل يسار الشاشة"</string>
-    <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"نقله إلى الحافة وإخفاؤه"</string>
+    <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"النقل إلى أعلى يمين الشاشة"</string>
+    <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"النقل إلى أعلى يسار الشاشة"</string>
+    <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"النقل إلى أسفل يمين الشاشة"</string>
+    <string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"النقل إلى أسفل يسار الشاشة"</string>
+    <string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"النقل إلى الحافة والإخفاء"</string>
     <string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"نقله إلى خارج الحافة وإظهاره"</string>
     <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"إزالة"</string>
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"إيقاف/تفعيل"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"اختيار تطبيق لإضافة عناصر التحكّم"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{تمت إضافة عنصر تحكّم واحد.}zero{تمت إضافة # عنصر تحكّم.}two{تمت إضافة عنصرَي تحكّم.}few{تمت إضافة # عناصر تحكّم.}many{تمت إضافة # عنصر تحكّم.}other{تمت إضافة # عنصر تحكّم.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"تمت الإزالة"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"هل تريد إضافة \"<xliff:g id="APPNAME">%s</xliff:g>\"؟"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"عند إضافة تطبيق \"<xliff:g id="APPNAME">%s</xliff:g>\"، يمكنه إضافة عناصر تحكّم ومحتوى إلى هذه اللوحة. في بعض التطبيقات، يمكنك اختيار عناصر التحكّم التي تظهر هنا."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"فتح <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"اقتراحات لك"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"تراجع"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"عليك الاقتراب لتشغيل الوسائط على <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"للتشغيل هنا، عليك الاقتراب من \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\"."</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"حدث خطأ. يُرجى إعادة المحاولة."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"جارٍ التحميل"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"جهاز لوحي"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"غير نشط، تحقّق من التطبيق."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"لم يتم العثور عليه."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"عنصر التحكّم غير متوفّر"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"حدث خطأ، يُرجى إعادة المحاولة."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"إضافة عناصر تحكّم"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"تعديل عناصر التحكّم"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"إضافة تطبيق"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"إضافة مخرجات"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"مجموعة"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"تم اختيار جهاز واحد."</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"مكبّرات الصوت والشاشات"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"الأجهزة المقترَحة"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"يجب استخدام حساب مدفوع."</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"يتعذّر البث"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"لا يمكن إجراء الحفظ. يُرجى إعادة المحاولة."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"لا يمكن إجراء الحفظ."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"رقم الإصدار"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
     <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"الكاميرا غير مفعّلة"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"الميكروفون غير مفعّل"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"الكاميرا والميكروفون غير مفعّلين."</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"‏يستمع \"مساعد Google\" إليك الآن."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{إشعار واحد}zero{# إشعار}two{إشعاران}few{# إشعارات}many{# إشعارًا}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"السماح بالوصول إلى السجلّ لمرة واحدة"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"عدم السماح"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ترصد سجلّات الجهاز ما يحدث على جهازك. يمكن أن تستخدم التطبيقات هذه السجلّات لتحديد المشاكل وحلّها.\n\nقد تحتوي بعض السجلّات على معلومات حساسة، ولذلك يجب عدم السماح بالوصول إلى جميع سجلّات الجهاز إلا للتطبيقات التي تثق بها. \n\nإذا لم تسمح بوصول هذا التطبيق إلى جميع سجلّات الجهاز، يظل بإمكان التطبيق الوصول إلى سجلّاته. ويظل بإمكان الشركة المصنِّعة لجهازك الوصول إلى بعض السجلّات أو المعلومات المتوفّرة على جهازك."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"مزيد من المعلومات"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"مزيد من المعلومات على <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"فتح \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• إعداد التطبيق"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"‏• إضافة بطاقة واحدة على الأقل إلى \"محفظة Google\""</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"تسمح لك سياسة العمل بإجراء المكالمات الهاتفية من الملف الشخصي للعمل فقط."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"التبديل إلى الملف الشخصي للعمل"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"إغلاق"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"إعدادات شاشة القفل"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 56f7e8e..533cf59 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"তলৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"বাওঁফালৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"সোঁফালৰ সীমা <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"<xliff:g id="APP">%1$s</xliff:g> এপ্‌টোত কৰ্মস্থানৰ স্ক্ৰীনশ্বটসমূহ ছেভ কৰা হয়"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"<xliff:g id="APP">%1$s</xliff:g> কৰ্মস্থানৰ প্ৰ’ফাইলত ছেভ কৰা হৈছে"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ফাইল"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>এ এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> আৰু আন খোলা এপ্‌সমূহে এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"টোকাত যোগ দিয়ক"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। খুলিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"মুখাৱয়ব চিনাক্ত কৰা হৈছে"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"বাওঁফাললৈ নিয়ক"</item>
-    <item msgid="5558598599408514296">"তললৈ নিয়ক"</item>
-    <item msgid="4844142668312841831">"সোঁফাললৈ নিয়ক"</item>
-    <item msgid="5640521437931460125">"ওপৰলৈ নিয়ক"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"নিয়ন্ত্ৰণসমূহ যোগ কৰিবলৈ এপ্‌ বাছনি কৰক"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}one{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}other{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ দিবনে?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"আপুনি <xliff:g id="APPNAME">%s</xliff:g> যোগ দিলে, ই এই পেনেলত নিয়ন্ত্ৰণ আৰু সমল যোগ দিব পাৰে। কিছুমান এপত আপুনি কোনবোৰ নিয়ন্ত্ৰণ ইয়াত দেখা পোৱা যাব সেয়া বাছনি কৰিব পাৰে।"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল, স্থান <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"অপ্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> খোলক"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ কৰক"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>ত <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ কৰক"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"আপোনাৰ বাবে"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"আনডু কৰক"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ত প্লে’ কৰিবলৈ ওচৰলৈ যাওক"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ইয়াত প্লে’ কৰিবলৈ, <xliff:g id="DEVICENAME">%1$s</xliff:g>ৰ ওচৰলৈ যাওক"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"কিবা ভুল হ’ল। পুনৰ চেষ্টা কৰক।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ল’ড হৈ আছে"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"টেবলেট"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্‌টো পৰীক্ষা কৰক"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"নিয়ন্ত্ৰণটো উপলব্ধ নহয়"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"আসোঁৱাহ হৈছে, আকৌ চেষ্টা কৰক"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"নিয়ন্ত্ৰণসমূহ যোগ দিয়ক"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"নিয়ন্ত্ৰণসমূহ সম্পাদনা কৰক"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"এপ্‌ যোগ দিয়ক"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"আউটপুটসমূহ যোগ দিয়ক"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"গোট"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"১ টা ডিভাইচ বাছনি কৰা হৈছে"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পীকাৰ আৰু ডিছপ্লে’"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"পৰামৰ্শ হিচাপে পোৱা ডিভাইচ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium একাউণ্টৰ আৱশ্যক"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্ৰচাৰ কৰিব নোৱাৰি"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ছেভ কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ছেভ কৰিব নোৱাৰি।"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ডৰ নম্বৰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ক্লিপব’ৰ্ডলৈ বিল্ডৰ নম্বৰ প্ৰতিলিপি কৰা হ’ল।"</string>
     <string name="basic_status" msgid="2315371112182658176">"বাৰ্তালাপ খোলক"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"কেমেৰা অফ আছে"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"মাইক অফ আছে"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"কেমেৰা আৰু মাইক অফ হৈ আছে"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistantএ শুনি আছে"</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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"কেৱল এবাৰ এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"অনুমতি নিদিব"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"আপোনাৰ ডিভাইচত কি কি ঘটে সেয়া ডিভাইচ লগে ৰেকৰ্ড কৰে। এপ্‌সমূহে সমস্যা বিচাৰিবলৈ আৰু সমাধান কৰিবলৈ এই লগসমূহ ব্যৱহাৰ কৰিব পাৰে।\n\nকিছুমান লগত সংবেদনশীল তথ্য থাকিব পাৰে, গতিকে কেৱল আপুনি বিশ্বাস কৰা এপকহে আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি দিয়ক। \n\nআপুনি যদি এই এপ্‌টোক আটাইবোৰ ডিভাইচ লগ এক্সেছ কৰাৰ অনুমতি নিদিয়ে, তথাপিও ই নিজৰ লগসমূহ এক্সেছ কৰিব পাৰিব। আপোনাৰ ডিভাইচৰ নিৰ্মাতাই তথাপিও হয়তো আপোনাৰ ডিভাইচটোত থকা কিছু লগ অথবা তথ্য এক্সেছ কৰিব পাৰিব।"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"অধিক জানক"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>ত অধিক জানক"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• এপ্‌টো ছেট আপ কৰা হৈছে"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletত অতি কমেও এখন কাৰ্ড যোগ দিয়া হৈছে"</string>
@@ -1054,11 +1059,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• অতি কমেও এটা ডিভাইচ উপলব্ধ"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শ্বৰ্টকাটটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল কৰক"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এতিয়াই লুটিয়াই দিয়ক"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"এতিয়াই ফ্লিপ কৰক"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"উন্নত ছেল্ফিৰ বাবে ফ’নটো আনফ’ল্ড কৰক"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"উন্নত ছেল্ফিৰ বাবে সন্মুখৰ ডিছপ্লে’ লুটিয়াই দিবনে?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"উন্নত ছেল্ফিৰ বাবে সন্মুখৰ ডিছপ্লে’ ফ্লিপ কৰিবনে?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"অধিক ৰিজ’লিউশ্বনৰ বহল ফট’ৰ বাবে পিছফালে থকা কেমেৰাটো ব্যৱহাৰ কৰক।"</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ই স্ক্ৰীনখন অফ হ’ব"</b></string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ এই স্ক্ৰীনখন অফ হ’ব"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"জপাব পৰা ডিভাইচৰ জাপ খুলি থকা হৈছে"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"জপাব পৰা ডিভাইচৰ ওলোটাই থকা হৈছে"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> বেটাৰী বাকী আছে"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"আপোনাৰ কৰ্মস্থানৰ নীতিয়ে আপোনাক কেৱল কৰ্মস্থানৰ প্ৰ’ফাইলৰ পৰা ফ’ন কল কৰিবলৈ দিয়ে"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"কৰ্মস্থানৰ প্ৰ’ফাইললৈ সলনি কৰক"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ কৰক"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"লক স্ক্ৰীনৰ ছেটিং"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 6b5ad2a..58ea41b 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Aşağı sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sol sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sağ sərhəd <xliff:g id="PERCENT">%1$d</xliff:g> faiz"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"İş skrinşotları <xliff:g id="APP">%1$s</xliff:g> tətbiqində saxlanılır"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"İş profilində <xliff:g id="APP">%1$s</xliff:g> tətbiqində saxlanıb"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fayllar"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu skrinşotu aşkarladı."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> və digər açıq tətbiqlər bu skrinşotu aşkarladı."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qeydə əlavə edin"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Yazıcısı"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
@@ -178,7 +181,7 @@
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> üzərindən qoşuldu."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> cihazına qoşulub."</string>
     <string name="accessibility_not_connected" msgid="4061305616351042142">"Qoşulu deyil."</string>
-    <string name="data_connection_roaming" msgid="375650836665414797">"Rominq"</string>
+    <string name="data_connection_roaming" msgid="375650836665414797">"Rouminq"</string>
     <string name="cell_data_off" msgid="4886198950247099526">"Deaktiv"</string>
     <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Uçuş rejimi"</string>
     <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN aktivdir."</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb açın."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Üz ilə kiliddən çıxarılıb"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Üz tanınıb"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Sola köçürün"</item>
-    <item msgid="5558598599408514296">"Aşağı köçürün"</item>
-    <item msgid="4844142668312841831">"Sağa köçürün"</item>
-    <item msgid="5640521437931460125">"Yuxarı köçürün"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC istifadə etmək üçün kiliddən çıxarın"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz təşkilatınıza məxsusdur"</string>
@@ -645,7 +642,7 @@
     <item msgid="2681220472659720036">"Mübadilə buferi"</item>
     <item msgid="4795049793625565683">"Açar kodu"</item>
     <item msgid="80697951177515644">"Çevirin, klaviatura dəyişdirici"</item>
-    <item msgid="7626977989589303588">"Heç bir"</item>
+    <item msgid="7626977989589303588">"Heç biri"</item>
   </string-array>
   <string-array name="nav_bar_layouts">
     <item msgid="9156773083127904112">"Normal"</item>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Kontrol əlavə etmək üçün tətbiq seçin"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# nizamlayıcı əlavə edilib.}other{# nizamlayıcı əlavə edilib.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Silinib"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> əlavə edilsin?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> əlavə etdiyiniz zaman, o, bu panelə nizamlayıcılar və məzmun əlavə edə bilər. Bəzi tətbiqlərdə burada hansı nizamlayıcıların göstərilməsini seçə bilərsiniz."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Sevimlilərə əlavə edilib"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Sevimlilərə əlavə edilib, sıra: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Sevimlilərdən silinib"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> tətbiqini açın"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> mahnısını <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudun"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> mahnısını <xliff:g id="APP_LABEL">%2$s</xliff:g> tətbiqindən oxudun"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Sizin üçün"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Geri qaytarın"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oxutmaq üçün yaxınlaşın"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Burada oxutmaq üçün <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaxınlaşdırın"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Xəta oldu. Yenə cəhd edin."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Yüklənir"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planşet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Nəzarət əlçatan deyil"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Xəta, yenidən cəhd edin"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Vidcet əlavə edin"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Vidcetlərə düzəliş edin"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tətbiq əlavə edin"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Nəticələri əlavə edin"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Qrup"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 cihaz seçilib"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hesab tələb edilir"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayımlamaq mümkün deyil"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Yadda saxlamaq mümkün deyil. Yenə cəhd edin."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Yadda saxlamaq mümkün deyil."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Montaj nömrəsi"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versiya nömrəsi mübadilə buferinə kopyalandı."</string>
     <string name="basic_status" msgid="2315371112182658176">"Açıq söhbət"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera deaktivdir"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon deaktivdir"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera və mikrofon deaktivdir"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent dinləyir"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildiriş}other{# bildiriş}}"</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">"Qeyd tutma"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Birdəfəlik girişə icazə verin"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"İcazə verməyin"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Cihaz qeydləri cihazınızda baş verənləri qeyd edir. Tətbiqlər problemləri tapmaq və həll etmək üçün bu qeydlərdən istifadə edə bilər.\n\nBəzi qeydlərdə həssas məlumatlar ola bilər, ona görə də yalnız etibar etdiyiniz tətbiqlərin bütün cihaz qeydlərinə giriş etməsinə icazə verin. \n\nBu tətbiqin bütün cihaz qeydlərinə girişinə icazə verməsəniz, o, hələ də öz qeydlərinə giriş edə bilər. Cihaz istehsalçınız hələ də cihazınızda bəzi qeydlərə və ya məlumatlara giriş edə bilər."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Ətraflı məlumat"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Ətraflı məlumat: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini açın"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Tətbiq ayarlanmalıdır"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Pulqabına ən azı bir kart əlavə edilməlidir"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"İş profilinə keçin"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bağlayın"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Kilid ekranı ayarları"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 3f9f3ec..3161e11 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Leva ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna ivica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Snimci ekrana za posao se čuvaju u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Sačuvano je u aplikaciji <xliff:g id="APP">%1$s</xliff:g> na poslovnom profilu"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fajlovi"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u belešku"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice prepoznato. Pritisnite ikonu otključavanja da biste otvorili."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Otključano je licem"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Lice je prepoznato"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Pomerite nalevo"</item>
-    <item msgid="5558598599408514296">"Pomerite nadole"</item>
-    <item msgid="4844142668312841831">"Pomerite nadesno"</item>
-    <item msgid="5640521437931460125">"Pomerite nagore"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju za dodavanje kontrola"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li da dodate <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Kada dodate aplikaciju <xliff:g id="APPNAME">%s</xliff:g>, ona može da dodaje kontrole i sadržaj u ovo okno. U nekim aplikacijama možete da izaberete koje će se kontrole ovde prikazivati."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno je iz omiljenih"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Opozovi"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da biste puštali muziku na: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Da biste puštali sadržaj ovde, približite uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo je do greške. Probajte ponovo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Učitava se"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Greška. Probajte ponovo"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Izmeni kontrole"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodaj aplikaciju"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajte izlaze"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izabran je 1 uređaj"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahteva premijum nalog"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitovanje nije uspelo"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Čuvanje nije uspelo. Probajte ponovo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Čuvanje nije uspelo."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u privremenu memoriju."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvorite konverzaciju"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je isključena"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je isključen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Pomoćnik sluša"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obaveštenje}one{# obaveštenje}few{# obaveštenja}other{# obaveštenja}}"</string>
     <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="note_task_button_label" msgid="8718616095800343136">"Pravljenje beležaka"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Dozvoli jednokratan pristup"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne dozvoli"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Evidencije uređaja registruju šta se dešava na uređaju. Aplikacije mogu da koriste te evidencije da bi pronašle i rešile probleme.\n\nNeke evidencije mogu da sadrže osetljive informacije, pa pristup svim evidencijama uređaja treba da dozvoljavate samo aplikacijama u koje imate poverenja. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim evidencijama uređaja, ona i dalje može da pristupa sopstvenim evidencijama. Proizvođač uređaja će možda i dalje moći da pristupa nekim evidencijama ili informacijama na uređaju."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saznajte više"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saznajte više na <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• da je aplikacija podešena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• da je u Novčanik dodata barem jedna kartica"</string>
@@ -1054,7 +1059,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• da je dostupan barem jedan uređaj"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrnite"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon za bolji selfi"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Želite da obrnete na prednji ekran za bolji selfi?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru da biste snimili širu sliku sa višom rezolucijom."</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Pređi na poslovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Podešavanja zaključanog ekrana"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index d4dc17b..bf084bd 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ніжняя граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Левая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Правая граніца: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Працоўныя здымкі экрана захаваны ў праграме \"<xliff:g id="APP">%1$s</xliff:g>\""</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Захавана ў праграму \"<xliff:g id="APP">%1$s</xliff:g>\" (у працоўным профілі)"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файлы"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Праграма \"<xliff:g id="APPNAME">%1$s</xliff:g>\" выявіла гэты здымак экрана."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> і іншыя адкрытыя праграмы выявілі гэты здымак экрана."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Дадаць у нататку"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запіс экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Твар распазнаны. Для адкрыцця націсніце значок разблакіроўкі."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Разблакіравана распазнаваннем твару"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Твар распазнаны"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Перамясціце палец улева"</item>
-    <item msgid="5558598599408514296">"Перамясціце палец ніжэй"</item>
-    <item msgid="4844142668312841831">"Перамясціце палец управа"</item>
-    <item msgid="5640521437931460125">"Перамясціце палец уверх"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Прагартайце ўверх, каб паўтарыць спробу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Разблакіруйце, каб выкарыстоўваць NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Гэта прылада належыць вашай арганізацыі"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Выберыце праграму для дадавання элементаў кіравання"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Дададзены # элемент кіравання.}one{Дададзена # элемента кіравання.}few{Дададзена # элементы кіравання.}many{Дададзена # элементаў кіравання.}other{Дададзена # элемента кіравання.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Выдалена"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Дадаць праграму \"<xliff:g id="APPNAME">%s</xliff:g>\"?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Калі вы дадасце праграму \"<xliff:g id="APPNAME">%s</xliff:g>\", яна зможа дадаваць на гэту панэль налады і змесціва. Для некаторых праграм вы зможаце выбраць, якія налады будуць тут паказвацца."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дададзена ў абранае"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Дададзена ў абранае, пазіцыя <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Выдалена з абранага"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Адкрыйце праграму \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Прайграйце кампазіцыю \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) з дапамогай праграмы \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\""</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Прайграйце кампазіцыю \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" з дапамогай праграмы \"<xliff:g id="APP_LABEL">%2$s</xliff:g>\""</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Для вас"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Адрабіць"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Каб прайграць мультымедыя на прыладзе \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", наблізьцеся да яе"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Каб прайграць тут, падыдзіце бліжэй да прылады \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нешта пайшло не так. Паўтарыце спробу."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Ідзе загрузка"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшэт"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактыўна, праверце праграму"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не знойдзена"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Кіраванне недаступнае"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Памылка, паўтарыце спробу"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Дадаць элементы кіравання"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Змяніць элементы кіравання"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Дадаць праграму"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Дадайце прылады вываду"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Выбрана 1 прылада"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Дынамікі і дысплэі"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Прылады, якія падтрымліваюцца"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Патрабуецца платны ўліковы запіс"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не ўдалося запусціць трансляцыю"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не ўдалося захаваць. Паўтарыце спробу."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не ўдалося захаваць."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Нумар зборкі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Нумар зборкі скапіраваны ў буфер абмену."</string>
     <string name="basic_status" msgid="2315371112182658176">"Адкрытая размова"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера выключана"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Мікрафон выключаны"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера і мікрафон выключаны"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Памочнік слухае"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# апавяшчэнне}one{# апавяшчэнне}few{# апавяшчэнні}many{# апавяшчэнняў}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Дазволіць аднаразовы доступ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дазваляць"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Журналы прылад запісваюць усё, што адбываецца на вашай прыладзе. Праграмы выкарыстоўваюць гэтыя журналы для пошуку і выпраўлення памылак.\n\nУ некаторых журналах можа ўтрымлівацца канфідэнцыяльная інфармацыя, таму дазваляйце доступ да ўсіх журналаў прылады толькі тым праграмам, якім вы давяраеце. \n\nКалі вы не дасцё гэтай праграме доступу да ўсіх журналаў прылад, у яе ўсё роўна застанецца доступ да ўласных журналаў. Для вытворцы вашай прылады будуць даступнымі некаторыя журналы і інфармацыя на вашай прыладзе."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Даведацца больш"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Даведайцеся больш на старонцы <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Адкрыць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Праграма наладжана."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• У Кашалёк дададзена хаця б адна картка."</string>
@@ -1056,7 +1061,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Пераключыць"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Каб атрымаць лепшае сэлфі, раскрыйце тэлефон"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Пераключыць на пярэднюю камеру для лепшага сэлфі?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Пераключыць на пярэдні дысплэй для лепшага сэлфі?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Каб зрабіць шырэйшае фота з больш высокай раздзяляльнасцю, скарыстайце заднюю камеру."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Гэты экран будзе выключаны"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складная прылада ў раскладзеным выглядзе"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Згодна з палітыкай вашай арганізацыі, рабіць тэлефонныя выклікі дазволена толькі з працоўнага профілю"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пераключыцца на працоўны профіль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыць"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Налады экрана блакіроўкі"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2141a47..d159273 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Долна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лява граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Дясна граница: <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Екранните снимки, направени в служебния потребителски профил, се запазват в приложението „<xliff:g id="APP">%1$s</xliff:g>“"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Запазена в(ъв) <xliff:g id="APP">%1$s</xliff:g> в служебния потребителски профил"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> установи заснемането на тази екранна снимка."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени приложения установиха заснемането на тази екранна снимка."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавяне към бележката"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запис на екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лицето бе разпознато. Отворете чрез иконата за отключване."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Отключено с лице"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Лицето бе разпознато"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Преместване наляво"</item>
-    <item msgid="5558598599408514296">"Преместване надолу"</item>
-    <item msgid="4844142668312841831">"Преместване надясно"</item>
-    <item msgid="5640521437931460125">"Преместване нагоре"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Плъзнете бързо нагоре, за да опитате отново"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отключете, за да използвате NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Това устройство принадлежи на организацията ви"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Изберете приложение, за да добавите контроли"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавена е # контрола.}other{Добавени са # контроли.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се добави ли <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Когато добавите <xliff:g id="APPNAME">%s</xliff:g>, приложението може да добави контроли и съдържание към този панел. Някои приложения ви дават възможност да избирате кои контроли да се показват тук."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено като любимо – позиция <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не е означено като любимо"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отваряне на <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пускане на <xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пускане на <xliff:g id="SONG_NAME">%1$s</xliff:g> от <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"За вас"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Отмяна"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Преместете се по-близо, за да се възпроизведе на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"За възпроизвеждане тук се приближете до <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нещо се обърка. Опитайте отново."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Зарежда се"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е налице"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Опитайте отново"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Добавяне на контроли"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Редактиране на контролите"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Добавяне на приложение"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Добавяне на изходящи устройства"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 избрано устройство"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Високоговорители и екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени устройства"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Необходим е платен профил"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Предаването не е възможно"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се запази. Опитайте отново."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се запази."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер на компилацията"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номерът на компилацията е копиран в буферната памет."</string>
     <string name="basic_status" msgid="2315371112182658176">"Отворен разговор"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камерата е изключена"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофонът е изключен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонът са изключени"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Асистент слуша"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# известие}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Разрешаване на еднократен достъп"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Забраняване"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"В регистрационните файлове за устройството се записва какво се извършва на него. Приложенията могат да използват тези регистрационни файлове, за да откриват и отстраняват проблеми.\n\nНякои регистрационни файлове за устройството може да съдържат поверителна информация, затова разрешавайте достъп до всички тях само на приложения, на които имате доверие. \n\nАко не разрешите на това приложение достъп до всички регистрационни файлове за устройството, то пак може да осъществява достъп до собствените си регистрационни файлове. Възможно е производителят на устройството да продължи да има достъп до някои регистрационни файлове или информация на устройството ви."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Научете повече"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Научете повече на адрес <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отваряне на <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Приложението е настроено."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• В Wallet е добавена поне една карта."</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Служебните правила ви дават възможност да извършвате телефонни обаждания само от служебния потребителски профил"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Превключване към служебния потребителски профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затваряне"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Настройки за заключения екран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 691293c..4a67a52 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"নিচের প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"বাঁ প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> শতাংশ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ডান প্রান্ত থেকে <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"অফিসের স্ক্রিনশট <xliff:g id="APP">%1$s</xliff:g> অ্যাপে সেভ করা হয়"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"অফিস প্রোফাইলের মধ্যে <xliff:g id="APP">%1$s</xliff:g>-এ সেভ করা হয়েছে"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ফাইল"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, এই স্ক্রিনশট শনাক্ত করেছে।"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> এবং খোলা থাকা অন্য অ্যাপ এই স্ক্রিনশট শনাক্ত করেছে।"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"নোটে যোগ করুন"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্রিন রেকর্ডার"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ফেস শনাক্ত করা হয়েছে। খোলার জন্য আনলক আইকন প্রেস করুন।"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ফেস দেখিয়ে আনলক করা হয়েছে"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ফেস চিনে নেওয়া হয়েছে"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"বাঁদিকে সরান"</item>
-    <item msgid="5558598599408514296">"নিচে নামান"</item>
-    <item msgid="4844142668312841831">"ডানদিকে সরান"</item>
-    <item msgid="5640521437931460125">"উপরে তুলুন"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"কন্ট্রোল যোগ করতে অ্যাপ বেছে নিন"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#টি কন্ট্রোল যোগ করা হয়েছে।}one{#টি কন্ট্রোল যোগ করা হয়েছে।}other{#টি কন্ট্রোল যোগ করা হয়েছে।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ করবেন?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"আপনি <xliff:g id="APPNAME">%s</xliff:g> যোগ করলে, এই প্যানেলে এটি কন্ট্রোল ও কন্টেন্ট যোগ করতে পারবে। কিছু অ্যাপের ক্ষেত্রে, এখানে কোন কোন কন্ট্রোল দেখা যাবে আপনি তা নিয়ন্ত্রণ করতে পারবেন।"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"পছন্দসই হিসেবে চিহ্নিত করেছেন, অবস্থান <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"পছন্দসই থেকে সরিয়ে দিয়েছেন"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> অ্যাপ খুলুন"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%2$s</xliff:g> অ্যাপে চালান"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"আপনার জন্য"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"আগের অবস্থায় ফিরুন"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>-এ চালাতে আরও কাছে আনুন"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"এখানে চালানোর জন্য আপনার ডিভাইস <xliff:g id="DEVICENAME">%1$s</xliff:g>-এর কাছে নিয়ে যান"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"কোনও সমস্যা হয়েছে। আবার চেষ্টা করুন।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"লোড করা হচ্ছে"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ট্যাবলেট"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"বন্ধ আছে, অ্যাপ চেক করুন"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"খুঁজে পাওয়া যায়নি"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"কন্ট্রোল উপলভ্য নেই"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"সমস্যা হয়েছে, আবার চেষ্টা করুন"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"কন্ট্রোল যোগ করুন"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"কন্ট্রোল এডিট করুন"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"অ্যাপ যোগ করুন"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"আউটপুট যোগ করুন"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"গ্রুপ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"১টি ডিভাইস বেছে নেওয়া হয়েছে"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"স্পিকার &amp; ডিসপ্লে"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"সাজেস্ট করা ডিভাইস"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"প্রিমিয়াম অ্যাকাউন্ট প্রয়োজন"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"সম্প্রচার করা যাচ্ছে না"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"সেভ করা যাচ্ছে না। আবার চেষ্টা করুন।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"সেভ করা যাচ্ছে না।"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"বিল্ড নম্বর"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"বিল্ড নম্বর ক্লিপবোর্ডে কপি করা হয়েছে।"</string>
     <string name="basic_status" msgid="2315371112182658176">"খোলা কথোপকথন"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ক্যামেরা বন্ধ করা আছে"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"মাইক্রোফোন বন্ধ করা আছে"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ক্যামেরা ও মাইক্রোফোন বন্ধ আছে"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant শুনছে"</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">"Notetaking"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"এককালীন অ্যাক্সেসের অনুমতি দিন"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"অনুমতি দেবেন না"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ডিভাইস লগে আপনার ডিভাইসে করা অ্যাক্টিভিটি রেকর্ড করা হয়। অ্যাপ সমস্যা খুঁজে তা সমাধান করতে এইসব লগ ব্যবহার করতে পারে।\n\nকিছু লগে সংবেদনশীল তথ্য থাকতে পারে, তাই বিশ্বাস করেন শুধুমাত্র এমন অ্যাপকেই সব ডিভাইসের লগ অ্যাক্সেসের অনুমতি দিন। \n\nআপনি এই অ্যাপকে ডিভাইসের সব লগ অ্যাক্সেস করার অনুমতি না দিলেও, এটি নিজে লগ অ্যাক্সেস করতে পারবে। ডিভাইস প্রস্তুতকারকও আপনার ডিভাইসের কিছু লগ বা তথ্য হয়ত অ্যাক্সেস করতে পারবে।"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"আরও জানুন"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"আরও জানতে <xliff:g id="URL">%s</xliff:g>-এ যান"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খুলুন"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• অ্যাপ সেট-আপ করা হয়ে গেছে"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• অন্তত একটি কার্ড Wallet-এ যোগ করা হয়েছে"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"কাজ সংক্রান্ত নীতি, আপনাকে শুধুমাত্র অফিস প্রোফাইল থেকে কল করার অনুমতি দেয়"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"অফিস প্রোফাইলে পাল্টে নিন"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"বন্ধ করুন"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"লক স্ক্রিন সেটিংস"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 57c0a23..00cab87 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donja granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Lijeva granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desna granica <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Poslovni snimci ekrana se pohranjuju u aplikaciji <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Sačuvano je u aplikaciji <xliff:g id="APP">%1$s</xliff:g> na radnom profilu"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fajlovi"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u bilješku"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice prepoznato. Pritisnite ikonu za otklj. da otvorite."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Otključano je licem"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Lice je prepoznato"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Pomjeranje ulijevo"</item>
-    <item msgid="5558598599408514296">"Pomjeranje nadolje"</item>
-    <item msgid="4844142668312841831">"Pomjeranje udesno"</item>
-    <item msgid="5640521437931460125">"Pomjeranje nagore"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Prevucite prema gore da pokušate ponovo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da koristite NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
@@ -832,8 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Odaberite aplikaciju da dodate kontrole"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
-    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
-    <string name="controls_panel_authorization" msgid="4540047176861801815">"Kada dodate aplikaciju <xliff:g id="APPNAME">%s</xliff:g>, može dodati kontrole i sadržaj na ovu ploču. U nekim aplikacijama možete odabrati koje se kontrole prikazuju ovdje."</string>
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Kada dodate aplikaciju <xliff:g id="APPNAME">%s</xliff:g>, ona može dodavati kontrole i sadržaj na ovu ploču. U nekim aplikacijama možete odabrati koje kontrole se prikazuju ovdje."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u omiljeno"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u omiljeno, pozicija <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno iz omiljenog"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvorite aplikaciju <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproducirajte pjesmu <xliff:g id="SONG_NAME">%1$s</xliff:g> pomoću aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Poništi"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite da reproducirate na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Da reproducirate ovdje, približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije uredu. Pokušajte ponovo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Učitavanje"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitiranje medijskih sadržaja"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Emitiranje aplikacije <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
@@ -900,7 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Greška, pokušajte ponovo"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj kontrole"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Uredi kontrole"</string>
-    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodavanje aplikacije"</string>
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodaj aplikaciju"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajte izlaze"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Odabran je 1 uređaj"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i ekrani"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahtijeva premijum račun"</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>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nije moguće emitirati"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nije moguće sačuvati. Pokušajte ponovo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nije moguće sačuvati."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj verzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj verzije je kopiran u međumemoriju."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je isključena"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je isključen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera i mikrofon su isključeni"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent sluša"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavještenje}one{# obavještenje}few{# obavještenja}other{# obavještenja}}"</string>
     <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="note_task_button_label" msgid="8718616095800343136">"Pisanje bilješki"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Dozvoli jednokratan pristup"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nemoj dozvoliti"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Zapisnici uređaja bilježe šta se dešava na uređaju. Aplikacije mogu koristiti te zapisnike da pronađu i isprave probleme.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, zato pristup svim zapisnicima uređaja dozvolite samo aplikacijama kojima vjerujete. \n\nAko ne dozvolite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač uređaja će možda i dalje biti u stanju pristupiti nekim zapisnicima ili podacima na uređaju."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saznajte više"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saznajte više na <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvori aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacija je postavljena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Najmanje jedna kartica je dodana u Novčanik"</string>
@@ -1054,7 +1060,7 @@
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni sada"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Raširite telefon za bolji selfi"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnuti na prednji ekran radi boljeg selfija?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite stražnju kameru za širu fotografiju veće rezolucije."</string>
+    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Koristite zadnju kameru za širu fotografiju veće rezolucije."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Ekran će se isključiti"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Sklopivi uređaj se rasklapa"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Sklopivi uređaj se obrće"</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Pređite na radni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Postavke zaključavanja ekrana"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index e5563c0..64965ed 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Marge inferior <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Marge esquerre <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Marge dret <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Les captures de pantalla de treball es desen a l\'aplicació <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"S\'ha desat al perfil de treball de <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fitxers"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectat aquesta captura de pantalla."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i altres aplicacions obertes han detectat aquesta captura de pantalla."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Afegeix a una nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravació de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
@@ -216,7 +219,7 @@
     <string name="accessibility_sensors_off_active" msgid="2619725434618911551">"Sensors desactivats"</string>
     <string name="accessibility_clear_all" msgid="970525598287244592">"Esborra totes les notificacions."</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{# notificació més a l\'interior.}many{# more notifications inside.}other{# notificacions més a l\'interior.}}"</string>
+    <string name="notification_group_overflow_description" msgid="7176322877233433278">"{count,plural, =1{# notificació més a l\'interior.}many{# notificacions més a l\'interior.}other{# notificacions més a l\'interior.}}"</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"La pantalla està bloquejada en orientació horitzontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"La pantalla està bloquejada en orientació vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Capsa de postres"</string>
@@ -264,7 +267,7 @@
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Punt d\'accés Wi-Fi"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"S\'està activant…"</string>
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Estalvi dades activat"</string>
-    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositiu}many{# devices}other{# dispositius}}"</string>
+    <string name="quick_settings_hotspot_secondary_label_num_devices" msgid="7536823087501239457">"{count,plural, =1{# dispositiu}many{# dispositius}other{# dispositius}}"</string>
     <string name="quick_settings_flashlight_label" msgid="4904634272006284185">"Llanterna"</string>
     <string name="quick_settings_flashlight_camera_in_use" msgid="4820591564526512571">"Càmera en ús"</string>
     <string name="quick_settings_cellular_detail_title" msgid="792977203299358893">"Dades mòbils"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"S\'ha reconegut la cara. Prem la icona per obrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"S\'ha desbloquejat amb la cara"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"S\'ha reconegut la cara"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mou cap a l\'esquerra"</item>
-    <item msgid="5558598599408514296">"Mou cap avall"</item>
-    <item msgid="4844142668312841831">"Mou cap a la dreta"</item>
-    <item msgid="5640521437931460125">"Mou cap amunt"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string>
@@ -376,7 +373,7 @@
     <string name="guest_notification_session_active" msgid="5567273684713471450">"Estàs en mode de convidat"</string>
     <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"En afegir un usuari nou, se sortirà del mode de convidat i se suprimiran totes les aplicacions i dades de la sessió de convidat actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"S\'ha assolit el límit d\'usuaris"</string>
-    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Només es pot crear 1 usuari.}many{You can add up to # users.}other{Pots afegir fins a # usuaris.}}"</string>
+    <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Només es pot crear 1 usuari.}many{Pots afegir fins a # usuaris.}other{Pots afegir fins a # usuaris.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Vols suprimir l\'usuari?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Totes les aplicacions i les dades d\'aquest usuari se suprimiran."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Suprimeix"</string>
@@ -579,8 +576,8 @@
     <string name="notification_menu_snooze_action" msgid="5415729610393475019">"Recorda-m\'ho"</string>
     <string name="snooze_undo" msgid="2738844148845992103">"Desfés"</string>
     <string name="snoozed_for_time" msgid="7586689374860469469">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
-    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# hores}many{# hours}other{# hores}}"</string>
-    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}many{# minutes}other{# minuts}}"</string>
+    <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{# hora}=2{# hores}many{# hores}other{# hores}}"</string>
+    <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{# minut}many{# minuts}other{# minuts}}"</string>
     <string name="battery_detail_switch_title" msgid="6940976502957380405">"Estalvi de bateria"</string>
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"Botó <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Inici"</string>
@@ -830,12 +827,10 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"commuta"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Controls de dispositius"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Selecciona l\'aplicació per afegir controls"</string>
-    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}many{# controls added.}other{S\'han afegit # controls.}}"</string>
+    <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}many{S\'han afegit # controls.}other{S\'han afegit # controls.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vols afegir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"En afegir <xliff:g id="APPNAME">%s</xliff:g>, podrà afegir controls i contingut en aquest tauler. En algunes aplicacions, pots triar quins controls es mostren aquí."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Afegit als preferits, posició <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Suprimit dels preferits"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Obre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reprodueix <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reprodueix <xliff:g id="SONG_NAME">%1$s</xliff:g> des de l\'aplicació <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Per a tu"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfés"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Mou més a prop per reproduir a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Per reproduir contingut aquí, apropa\'l a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"S\'ha produït un error. Torna-ho a provar."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"S\'està carregant"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tauleta"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no està disponible"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Error; torna-ho a provar"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Afegeix controls"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Edita els controls"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Afegeix una aplicació"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Afegeix sortides"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositiu seleccionat"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requereix un compte prèmium"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No es pot emetre"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No es pot desar. Torna-ho a provar."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No es pot desar."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilació"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"El número de compilació s\'ha copiat al porta-retalls."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa oberta"</string>
@@ -1001,7 +1003,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Afegeix la icona"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"No afegeixis la icona"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Selecciona un usuari"</string>
-    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplicació està activa}many{# apps are active}other{# aplicacions estan actives}}"</string>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# aplicació està activa}many{# aplicacions estan actives}other{# aplicacions estan actives}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Informació nova"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Aplicacions actives"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Aquestes aplicacions estan actives i executant-se, fins i tot quan no les utilitzes. Això en millora la funcionalitat, però també pot afectar la durada de la bateria."</string>
@@ -1031,7 +1033,8 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"La càmera està desactivada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"El micròfon està desactivat"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Càmera i micròfon desactivats"</string>
-    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}many{# notifications}other{# notificacions}}"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'assistent t\'escolta"</string>
+    <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificació}many{# notificacions}other{# notificacions}}"</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">"Presa de notes"</string>
     <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permet l\'accés únic"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permetis"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Els registres del dispositiu inclouen informació sobre tot allò que passa al teu dispositiu. Les aplicacions poden utilitzar aquests registres per detectar i corregir problemes.\n\nÉs possible que alguns registres continguin informació sensible; per això només has de donar-hi accés a les aplicacions de confiança. \n\nEncara que no permetis que aquesta aplicació pugui accedir a tots els registres del dispositiu, podrà accedir als seus propis registres. És possible que el fabricant del dispositiu també tingui accés a alguns registres o a informació del teu dispositiu."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Més informació"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Més informació a <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Obre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• L\'aplicació està configurada."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Almenys s\'ha afegit una targeta a Wallet."</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Canvia al perfil de treball"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tanca"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Configuració pantalla de bloqueig"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c099f66..98b7a7d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Dolní okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Levý okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Pravý okraj <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Pracovní snímky obrazovky se ukládají do aplikace <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Uloženo v aplikaci <xliff:g id="APP">%1$s</xliff:g> v pracovním profilu"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Soubory"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> objevila tento snímek obrazovky."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ostatní otevřené aplikace objevily tento snímek obrazovky."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Přidat do poznámky"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Odemknuto obličejem"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Obličej rozpoznán"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Přesunout doleva"</item>
-    <item msgid="5558598599408514296">"Přesunout dolů"</item>
-    <item msgid="4844142668312841831">"Přesunout doprava"</item>
-    <item msgid="5640521437931460125">"Přesunout nahoru"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Přejetím nahoru to zkusíte znovu"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC vyžaduje odemknutou obrazovku"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikaci, pro kterou chcete přidat ovládací prvky"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Byl přidán # ovládací prvek.}few{Byly přidány # ovládací prvky.}many{Bylo přidáno # ovládacího prvku.}other{Bylo přidáno # ovládacích prvků.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Odstraněno"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Přidat aplikaci <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Když přidáte aplikaci <xliff:g id="APPNAME">%s</xliff:g>, může do tohoto panelu přidat ovládací prvky a obsah. V některých aplikacích si můžete vybrat, které ovládací prvky se zde zobrazí."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Přidáno do oblíbených"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Přidáno do oblíbených na pozici <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odebráno z oblíbených"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otevřít aplikaci <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Přehrát skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Přehrát skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> z aplikace <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pro vás"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Vrátit zpět"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pokud chcete přehrávat na zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>, přibližte se k němu"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pokud obsah chcete přehrát na tomto zařízení, přesuňte ho blíže k zařízení <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Došlo k chybě. Zkuste to znovu."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Načítání"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Odesílání médií"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Odesílání aplikace <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládání není k dispozici"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Chyba, zkuste to znovu"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Přidat ovládací prvky"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Upravit ovládací prvky"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Přidat aplikaci"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Přidání výstupů"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Je vybráno 1 zařízení"</string>
@@ -919,7 +916,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vyžaduje prémiový účet"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Vysílání se nezdařilo"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Uložení se nezdařilo. Zkuste to znovu."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Uložení se nezdařilo."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo sestavení"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo sestavení bylo zkopírováno do schránky."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otevřít konverzaci"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je vypnutá"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je vypnutý"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparát a mikrofon jsou vypnuté"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent poslouchá"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# oznámení}few{# oznámení}many{# oznámení}other{# oznámení}}"</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">"Poznámky"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Povolit jednorázový přístup"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nepovolovat"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Do protokolů zařízení se zaznamenává, co se na zařízení děje. Aplikace tyto protokoly mohou používat k vyhledání a odstranění problémů.\n\nNěkteré protokoly mohou zahrnovat citlivé údaje. Přístup k protokolům zařízení proto povolte pouze aplikacím, kterým důvěřujete. \n\nPokud této aplikaci nepovolíte přístup ke všem protokolům zařízení, bude mít stále přístup ke svým vlastním protokolům. Výrobce zařízení může mít stále přístup k některým protokolům nebo informacím na vašem zařízení."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Další informace"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Další informace najdete na adrese <xliff:g id="URL">%s</xliff:g>."</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otevřít <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikace je nastavena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Do Peněženky byla přidána alespoň jedna karta"</string>
@@ -1056,7 +1059,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušit"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočit"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozložte telefon, selfie bude lepší"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočit na přední fotoaparát pro lepší selfie?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočit na přední displej pro lepší selfie?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocí zadního fotoaparátu pořiďte širší fotku s vyšším rozlišením."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Tato obrazovka se vypne"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozkládání rozkládacího zařízení"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Přepnout na pracovní profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavřít"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavení obrazovky uzamčení"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index c50202d..75e0f39 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nederste kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Højre kant: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Screenshots, der tages via arbejdsprofilen, gemmer i appen <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Gemt i <xliff:g id="APP">%1$s</xliff:g> på arbejdsprofilen"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registreret dette screenshot."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åbne apps har registreret dette screenshot."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Føj til note"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skærmoptagelse"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansigt genkendt. Tryk på oplåsningsikonet for at åbne."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Låst op via ansigtsgenkendelse"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Ansigtet er genkendt"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Flyt til venstre"</item>
-    <item msgid="5558598599408514296">"Flyt ned"</item>
-    <item msgid="4844142668312841831">"Flyt til højre"</item>
-    <item msgid="5640521437931460125">"Flyt op"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Vælg en app for at tilføje styring"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# styringselement er tilføjet.}one{# styringselement er tilføjet.}other{# styringselementer er tilføjet.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vil du tilføje <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Når du tilføjer <xliff:g id="APPNAME">%s</xliff:g>, kan den føje styringselementer og indhold til dette panel. I nogle apps kan du vælge, hvilke styringselementer der vises her."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Angivet som favorit"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Angivet som favorit. Position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet fra favoritter"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Åbn <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Afspil <xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Afspil <xliff:g id="SONG_NAME">%1$s</xliff:g> via <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Til dig"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Fortryd"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ryk tættere på for at afspille på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"For at afspille her skal enheden tættere på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Noget gik galt. Prøv igen."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Indlæser"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Styringselement ikke tilgængeligt"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Der opstod en fejl. Prøv igen"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Tilføj styring"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Rediger styring"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tilføj app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tilføj medieudgange"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Der er valgt 1 enhed"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Kræver Premium-konto"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Der kan ikke udsendes en fællesbesked"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Der kan ikke gemmes. Prøv igen."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Der kan ikke gemmes."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummeret blev kopieret til udklipsholderen."</string>
     <string name="basic_status" msgid="2315371112182658176">"Åben samtale"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kameraet er slukket"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofonen er slået fra"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er slået fra"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google Assistent lytter med"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikation}one{# notifikation}other{# notifikationer}}"</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">"Notetagning"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Tillad engangsadgang"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Tillad ikke"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Enhedslogs registrerer, hvad der sker på din enhed. Apps kan bruge disse logs til at finde og løse problemer.\n\nNogle logs kan indeholde følsomme oplysninger, så giv kun apps, du har tillid til, adgang til alle enhedslogs. \n\nSelvom du ikke giver denne app adgang til alle enhedslogs, kan den stadig tilgå sine egne logs. Producenten af din enhed kan muligvis fortsat tilgå visse logs eller oplysninger på din enhed."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Få flere oplysninger"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Få flere oplysninger på <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åbn <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Appen er konfigureret"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Mindst ét kort er føjet til Wallet"</string>
@@ -1058,7 +1063,7 @@
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Fold telefonen ud for at tage en bedre selfie"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruge frontkameraet for at få bedre selfie?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Brug bagsidekameraet for at få et bredere billede med højere opløsning."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ *Denne skærm slukkes"</b></string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skærm slukkes"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Foldbar enhed foldes ud"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Foldbar enhed vendes om"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteri tilbage"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Skift til arbejdsprofil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Luk"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Indstillinger for låseskærm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 0ac3f4b..bfeded8 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Unterer Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linker Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Rechter Rand <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Mit einem Arbeitsprofil aufgenommene Screenshots werden in der App „<xliff:g id="APP">%1$s</xliff:g>“ gespeichert"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"In <xliff:g id="APP">%1$s</xliff:g> im Arbeitsprofil gespeichert"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Dateien"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> hat diesen Screenshot erkannt."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> und andere geöffnete Apps haben diesen Screenshot erkannt."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Zu Notiz hinzufügen"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Bildschirmaufzeichnung"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
@@ -183,9 +186,9 @@
     <string name="accessibility_airplane_mode" msgid="1899529214045998505">"Flugmodus"</string>
     <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN an."</string>
     <string name="accessibility_battery_level" msgid="5143715405241138822">"Akku bei <xliff:g id="NUMBER">%d</xliff:g> Prozent."</string>
-    <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="6548654589315074529">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g> Prozent, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="8892191177774027364">"Akku wird aufgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> Prozent."</string>
-    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Akku bei <xliff:g id="PERCENTAGE">%d</xliff:g>. Zum Schutz des Akkus wurde das Laden pausiert."</string>
+    <string name="accessibility_battery_level_charging_paused" msgid="3560711496775146763">"Akku bei <xliff:g id="PERCENTAGE">%d</xliff:g> Prozent. Zum Schutz des Akkus wurde das Laden pausiert."</string>
     <string name="accessibility_battery_level_charging_paused_with_estimate" msgid="2223541217743647858">"Akku bei <xliff:g id="PERCENTAGE">%1$d</xliff:g>. <xliff:g id="TIME">%2$s</xliff:g>. Zum Schutz des Akkus wurde das Laden pausiert."</string>
     <string name="accessibility_overflow_action" msgid="8555835828182509104">"Alle Benachrichtigungen ansehen"</string>
     <string name="accessibility_tty_enabled" msgid="1123180388823381118">"Schreibtelefonie aktiviert"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Gesicht erkannt. Tippe zum Öffnen auf das Symbol „Entsperren“."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Gerät mit Gesicht entsperrt"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Gesicht erkannt"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Nach links bewegen"</item>
-    <item msgid="5558598599408514296">"Nach unten bewegen"</item>
-    <item msgid="4844142668312841831">"Nach rechts bewegen"</item>
-    <item msgid="5640521437931460125">"Nach oben bewegen"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"App zum Hinzufügen von Steuerelementen auswählen"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> hinzufügen?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Wenn du <xliff:g id="APPNAME">%s</xliff:g> hinzufügst, kann diese App Einstellungen und Inhalte zu diesem Bereich hinzufügen. In einigen Apps kannst du festlegen, welche Einstellungen hier angezeigt werden sollen."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Aus Favoriten entfernt"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> öffnen"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergeben"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> über <xliff:g id="APP_LABEL">%2$s</xliff:g> wiedergeben"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Für mich"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Rückgängig machen"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gehe für die Wiedergabe näher an „<xliff:g id="DEVICENAME">%1$s</xliff:g>“ heran"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Für eine Wiedergabe auf diesem Gerät muss es näher bei <xliff:g id="DEVICENAME">%1$s</xliff:g> sein"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Ein Fehler ist aufgetreten. Versuch es noch einmal."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Wird geladen"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"Tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv – sieh in der App nach"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nicht gefunden"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Steuerelement nicht verfügbar"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Fehler – versuch es noch mal"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Steuerelemente hinzufügen"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Steuerelemente bearbeiten"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"App hinzufügen"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ausgabegeräte hinzufügen"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Ein Gerät ausgewählt"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium-Konto erforderlich"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Übertragung nicht möglich"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Speichern nicht möglich. Versuche es noch einmal."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Speichern nicht möglich."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build-Nummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build-Nummer in Zwischenablage kopiert."</string>
     <string name="basic_status" msgid="2315371112182658176">"Offene Unterhaltung"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera ist deaktiviert"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon ist deaktiviert"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera und Mikrofon ausgeschaltet"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant hört zu"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# Benachrichtigung}other{# Benachrichtigungen}}"</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">"Notizen machen"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Einmaligen Zugriff erlauben"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nicht erlauben"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"In Geräteprotokollen wird aufgezeichnet, welche Aktionen auf deinem Gerät ausgeführt werden. Apps können diese Protokolle verwenden, um Probleme zu finden und zu beheben.\n\nEinige Protokolle enthalten unter Umständen vertrauliche Informationen. Daher solltest du nur vertrauenswürdigen Apps den Zugriff auf alle Geräteprotokolle erlauben. \n\nWenn du dieser App keinen Zugriff auf alle Geräteprotokolle gewährst, kann sie trotzdem auf ihre eigenen Protokolle zugreifen. Dein Gerätehersteller hat möglicherweise auch Zugriff auf einige Protokolle oder Informationen auf deinem Gerät."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Weitere Informationen"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Weitere Informationen unter <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> öffnen"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Die App ist eingerichtet"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet wurde mindestens eine Karte hinzugefügt"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Zum Arbeitsprofil wechseln"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Schließen"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Sperrbildschirm-Einstellungen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index eb0abea..ffe26bd 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Κάτω όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Αριστερό όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Δεξί όριο <xliff:g id="PERCENT">%1$d</xliff:g> τοις εκατό"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Τα στιγμιότυπα οθόνης εργασίας αποθηκεύονται στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Αποθηκεύτηκε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> στο προφίλ εργασίας"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Αρχεία"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> εντόπισε αυτό το στιγμιότυπο οθόνης."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> και άλλες ανοικτές εφαρμογές εντόπισαν το στιγμιότυπο οθόνης."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Προσθήκη σε σημείωση"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Εγγραφή οθόνης"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Το πρόσωπο αναγνωρ. Πατήστ. το εικον. ξεκλειδ. για άνοιγμα."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Ξεκλείδωμα με αναγνώριση προσώπου"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Το πρόσωπο αναγνωρίστηκε"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Μετακίνηση αριστερά"</item>
-    <item msgid="5558598599408514296">"Μετακίνηση κάτω"</item>
-    <item msgid="4844142668312841831">"Μετακίνηση δεξιά"</item>
-    <item msgid="5640521437931460125">"Μετακίνηση επάνω"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ξεκλείδωμα για χρήση του NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Επιλογή εφαρμογής για προσθήκη στοιχείων ελέγχου"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Προστέθηκε # στοιχείο ελέγχου.}other{Προστέθηκαν # στοιχεία ελέγχου.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Καταργήθηκε"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Προσθήκη <xliff:g id="APPNAME">%s</xliff:g>;"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Όταν προσθέσετε την εφαρμογή <xliff:g id="APPNAME">%s</xliff:g>, μπορεί να προσθέσει στοιχεία ελέγχου και περιεχόμενο σε αυτό το πλαίσιο. Σε ορισμένες εφαρμογές, μπορείτε να επιλέξετε ποια στοιχεία ελέγχου θα εμφανίζονται εδώ."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Προστέθηκε στα αγαπημένα"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Προστέθηκε στα αγαπημένα, στη θέση <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Αφαιρέθηκε από τα αγαπημένα"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Άνοιγμα της εφαρμογής <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Για εσάς"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Αναίρεση"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Πλησιάστε για αναπαραγωγή στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Για να γίνει αναπαραγωγή εδώ, μετακινηθείτε πιο κοντά στη συσκευή <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Παρουσιάστηκε κάποιο πρόβλημα. Δοκιμάστε ξανά."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Φόρτωση"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Μετάδοση των μέσων σας"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Μετάδοση <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Μη διαθέσιμο στοιχείο ελέγχου"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Σφάλμα, προσπαθήστε ξανά."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Προσθήκη στοιχείων ελέγχου"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Επεξεργασία στοιχείων ελέγχου"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Προσθήκη εφαρμογής"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Προσθήκη εξόδων"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Ομάδα"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Επιλέχτηκε 1 συσκευή"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Ηχεία και οθόνες"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Προτεινόμενες συσκευές"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Απαιτεί λογαριασμό premium"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Δεν είναι δυνατή η μετάδοση"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Δεν είναι δυνατή η αποθήκευση. Δοκιμάστε ξανά."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Δεν είναι δυνατή η αποθήκευση."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Αριθμός έκδοσης"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Ο αριθμός έκδοσης αντιγράφηκε στο πρόχειρο."</string>
     <string name="basic_status" msgid="2315371112182658176">"Άνοιγμα συνομιλίας"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Η κάμερα είναι απενεργοποιημένη"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Το μικρόφωνο είναι απενεργοποιημένο"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Η κάμερα και το μικρόφωνο έχουν απενεργοποιηθεί"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Ο Βοηθός ακούει"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ειδοποίηση}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Να επιτρέπεται η πρόσβαση για μία φορά"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Να μην επιτρέπεται"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Τα αρχεία καταγραφής συσκευής καταγράφουν ό,τι συμβαίνει στη συσκευή σας. Οι εφαρμογές μπορούν να χρησιμοποιούν αυτά τα αρχεία καταγραφής για να εντοπίζουν και να διορθώνουν ζητήματα.\n\nΟρισμένα αρχεία καταγραφής ενδέχεται να περιέχουν ευαίσθητες πληροφορίες. Ως εκ τούτου, επιτρέψτε την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής μόνο στις εφαρμογές που εμπιστεύεστε. \n\nΕάν δεν επιτρέψετε σε αυτήν την εφαρμογή την πρόσβαση σε όλα τα αρχεία καταγραφής συσκευής, η εφαρμογή εξακολουθεί να έχει πρόσβαση στα δικά της αρχεία καταγραφής. Ο κατασκευαστής της συσκευής σας ενδέχεται να εξακολουθεί να έχει πρόσβαση σε ορισμένα αρχεία καταγραφής ή ορισμένες πληροφορίες στη συσκευή σας."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Μάθετε περισσότερα"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Μάθετε περισσότερα στο <xliff:g id="URL">%s</xliff:g>."</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Άνοιγμα <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Η εφαρμογή έχει ρυθμιστεί"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Έχει προστεθεί τουλάχιστον μία κάρτα στο Πορτοφόλι"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Η πολιτική εργασίας σάς επιτρέπει να πραγματοποιείτε τηλεφωνικές κλήσεις μόνο από το προφίλ εργασίας σας."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Εναλλαγή σε προφίλ εργασίας"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Κλείσιμο"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Ρυθμίσεις κλειδώματος οθόνης"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index cad3b47..b789da1 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Unlocked by face"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Face recognised"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Move left"</item>
-    <item msgid="5558598599408514296">"Move down"</item>
-    <item msgid="4844142668312841831">"Move right"</item>
-    <item msgid="5640521437931460125">"Move up"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For you"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Casting your media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Casting <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers &amp; displays"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</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">"Notetaking"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index c41a164..4688869 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> percent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognized. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Unlocked by face"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Face recognized"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Move left"</item>
-    <item msgid="5558598599408514296">"Move down"</item>
-    <item msgid="4844142668312841831">"Move right"</item>
-    <item msgid="5640521437931460125">"Move up"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organization"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For You"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Casting your media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Casting <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers &amp; Displays"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested Devices"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting"</string>
@@ -928,6 +927,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"Use at least 4 characters"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"Use fewer than 16 characters"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1028,6 +1029,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</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">"Notetaking"</string>
@@ -1043,6 +1045,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
@@ -1066,6 +1070,5 @@
     <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_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index cad3b47..b789da1 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Unlocked by face"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Face recognised"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Move left"</item>
-    <item msgid="5558598599408514296">"Move down"</item>
-    <item msgid="4844142668312841831">"Move right"</item>
-    <item msgid="5640521437931460125">"Move up"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For you"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Casting your media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Casting <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers &amp; displays"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</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">"Notetaking"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index cad3b47..b789da1 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bottom boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Left boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Right boundary <xliff:g id="PERCENT">%1$d</xliff:g> per cent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Work screenshots are saved in the <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saved in <xliff:g id="APP">%1$s</xliff:g> in the work profile"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Face recognised. Press the unlock icon to open."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Unlocked by face"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Face recognised"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Move left"</item>
-    <item msgid="5558598599408514296">"Move down"</item>
-    <item msgid="4844142668312841831">"Move right"</item>
-    <item msgid="5640521437931460125">"Move up"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Open <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Play <xliff:g id="SONG_NAME">%1$s</xliff:g> from <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For you"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Move closer to play on <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"To play here, move closer to <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Something went wrong. Try again."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Loading"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Casting your media"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Casting <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactive, check app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Not found"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control is unavailable"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers &amp; displays"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Suggested devices"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requires premium account"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Can’t broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Can’t save. Try again."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Can’t save."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Build number"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Build number copied to clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Open conversation"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera is off"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mic is off"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera and mic are off"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant is listening"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}other{# notifications}}"</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">"Notetaking"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Allow one-time access"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Don’t allow"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Device logs record what happens on your device. Apps can use these logs to find and fix issues.\n\nSome logs may contain sensitive info, so only allow apps that you trust to access all device logs. \n\nIf you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• The app is set up"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• At least one card has been added to Wallet"</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Switch to work profile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Close"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lock screen settings"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 059a5fa..0493b38 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎Bottom boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎Left boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎Right boundary ‎‏‎‎‏‏‎<xliff:g id="PERCENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ percent‎‏‎‎‏‎"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎Work screenshots are saved in the ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ app‎‏‎‎‏‎"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎Saved in ‎‏‎‎‏‏‎<xliff:g id="APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ in the work profile‎‏‎‎‏‎"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎Files‎‏‎‎‏‎"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ detected this screenshot.‎‏‎‎‏‎"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and other open apps detected this screenshot.‎‏‎‎‏‎"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎Add to note‎‏‎‎‏‎"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎Screen Recorder‎‏‎‎‏‎"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎Processing screen recording‎‏‎‎‏‎"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎Ongoing notification for a screen record session‎‏‎‎‏‎"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎Face recognized. Press the unlock icon to open.‎‏‎‎‏‎"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎Unlocked by face‎‏‎‎‏‎"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎Face recognized‎‏‎‎‏‎"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎Move left‎‏‎‎‏‎"</item>
-    <item msgid="5558598599408514296">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎Move down‎‏‎‎‏‎"</item>
-    <item msgid="4844142668312841831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‎Move right‎‏‎‎‏‎"</item>
-    <item msgid="5640521437931460125">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎Move up‎‏‎‎‏‎"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎Swipe up to try again‎‏‎‎‏‎"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎Unlock to use NFC‎‏‎‎‏‎"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎This device belongs to your organization‎‏‎‎‏‎"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎Open ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎Play ‎‏‎‎‏‏‎<xliff:g id="SONG_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ by ‎‏‎‎‏‏‎<xliff:g id="ARTIST_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ from ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‎Play ‎‏‎‎‏‏‎<xliff:g id="SONG_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ from ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎For You‎‏‎‎‏‎"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‎‎Undo‎‏‎‎‏‎"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎Move closer to play on ‎‏‎‎‏‏‎<xliff:g id="DEVICENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎To play here, move closer to ‎‏‎‎‏‏‎<xliff:g id="DEVICENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‎Something went wrong. Try again.‎‏‎‎‏‎"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎Loading‎‏‎‎‏‎"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‏‎tablet‎‏‎‎‏‎"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎Casting your media‎‏‎‎‏‎"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎Casting ‎‏‎‎‏‏‎<xliff:g id="APP_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎Inactive, check app‎‏‎‎‏‎"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎Not found‎‏‎‎‏‎"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎Control is unavailable‎‏‎‎‏‎"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$d</xliff:g>‎‏‎‎‏‏‏‎%%‎‏‎‎‏‎"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎Speakers &amp; Displays‎‏‎‎‏‎"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎Suggested Devices‎‏‎‎‏‎"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎Requires premium account‎‏‎‎‏‎"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎How broadcasting works‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎Broadcast‎‏‎‎‏‎"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting‎‏‎‎‏‎"</string>
@@ -928,6 +927,8 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎Can’t broadcast‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎Can’t save. Try again.‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎Can’t save.‎‏‎‎‏‎"</string>
+    <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‎Use at least 4 characters‎‏‎‎‏‎"</string>
+    <string name="media_output_broadcast_code_hint_no_more_than_max" msgid="9181869364856175638">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎Use fewer than 16 characters‎‏‎‎‏‎"</string>
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎Build number‎‏‎‎‏‎"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎Build number copied to clipboard.‎‏‎‎‏‎"</string>
     <string name="basic_status" msgid="2315371112182658176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎Open conversation‎‏‎‎‏‎"</string>
@@ -1028,6 +1029,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎Camera is off‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎Mic is off‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎Camera and mic are off‎‏‎‎‏‎"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‎‎Assistant is listening‎‏‎‎‏‎"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎# notifications‎‏‎‎‏‎}}"</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">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎Notetaking‎‏‎‎‏‎"</string>
@@ -1043,6 +1045,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎Allow one-time access‎‏‎‎‏‎"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎Don’t allow‎‏‎‎‏‎"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎Device logs record what happens on your device. Apps can use these logs to find and fix issues.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Some logs may contain sensitive info, so only allow apps you trust to access all device logs. ‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If you don’t allow this app to access all device logs, it can still access its own logs. Your device manufacturer may still be able to access some logs or info on your device.‎‏‎‎‏‎"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎Learn more‎‏‎‎‏‎"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎Learn more at ‎‏‎‎‏‏‎<xliff:g id="URL">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎Open ‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎• The app is set up‎‏‎‎‏‎"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎• At least one card has been added to Wallet‎‏‎‎‏‎"</string>
@@ -1066,6 +1070,5 @@
     <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_action" msgid="2937701298133010724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎Switch to work profile‎‏‎‎‏‎"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎Close‎‏‎‎‏‎"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎Lock screen settings‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 706248b..98ccea0 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Límite inferior: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Límite izquierdo: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Límite derecho: <xliff:g id="PERCENT">%1$d</xliff:g> por ciento"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Las capturas de pantalla de trabajo se guardan en la app de <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Se guardó en <xliff:g id="APP">%1$s</xliff:g> en el perfil de trabajo"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectó que tomaste una captura de pantalla."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras apps en ejecución detectaron que tomaste una captura de pantalla."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Agregar a la nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabadora de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rostro reconocido. Presiona el desbloqueo para abrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Se desbloqueó con el rostro"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Se reconoció el rostro"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mover hacia la izquierda"</item>
-    <item msgid="5558598599408514296">"Mover hacia abajo"</item>
-    <item msgid="4844142668312841831">"Mover hacia la derecha"</item>
-    <item msgid="5640521437931460125">"Mover hacia arriba"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volver a intentarlo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea el dispositivo para usar NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Elige la app para agregar los controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Se agregó # control.}many{Se agregaron # controles.}other{Se agregaron # controles.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitados"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Quieres agregar <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Si agregas la app de <xliff:g id="APPNAME">%s</xliff:g>, se incluirán controles y contenido en este panel. Algunas apps te permiten elegir qué controles mostrar aquí."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está en favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está en favoritos en la posición <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"No está en favoritos"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproducir <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para ti"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Deshacer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate para reproducir en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducir aquí, acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Se produjo un error. Vuelve a intentarlo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"El control no está disponible"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Error. Vuelve a intentarlo."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Agregar controles"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Agregar app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Agregar salidas"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Se seleccionó 1 dispositivo"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requiere una cuenta premium"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Error al iniciar transmisión"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Vuelve a intentarlo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Se copió el número de compilación en el portapapeles."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"La cámara está desactivada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"El micrófono está desactivado"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están apagados"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistente está escuchando"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}many{# notificaciones}other{# notificaciones}}"</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">"Tomar notas"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acceso por única vez"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permitir"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Los registros del dispositivo permiten documentar lo que sucede en él. Las apps pueden usar estos registros para encontrar y solucionar problemas.\n\nEs posible que algunos registros del dispositivo contengan información sensible, por lo que solo permitimos que accedan a todos ellos apps de tu confianza. \n\nSi no permites que esta app acceda a todos los registros del dispositivo, aún puede acceder a sus propios registros. Además, es posible que el fabricante del dispositivo acceda a algunos registros o información en tu dispositivo."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Más información"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Más información en <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Se configuró la app."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Se agregó al menos una tarjeta a la Billetera."</string>
@@ -1056,7 +1061,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para tomar una selfie mejor"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Cambiar a pantalla frontal para mejores selfies?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Girar a pantalla frontal para mejores selfies?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para tomar una foto más amplia y con mejor resolución."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable siendo desplegado"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Config. de pantalla de bloqueo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 458cd38..c385bd1 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite inferior"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite izquierdo"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> por ciento del límite derecho"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Las capturas de pantalla de trabajo se guardan en la aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Se ha guardado en el perfil de trabajo de <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Archivos"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectado esta captura de pantalla."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras aplicaciones abiertas han detectado esta captura de pantalla."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Añadir a nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabación de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Cara reconocida. Pulsa el icono de desbloquear para abrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Desbloqueado con la cara"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Cara reconocida"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mover hacia la izquierda"</item>
-    <item msgid="5558598599408514296">"Mover hacia abajo"</item>
-    <item msgid="4844142668312841831">"Mover hacia la derecha"</item>
-    <item msgid="5640521437931460125">"Mover hacia arriba"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Añadir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Si añades <xliff:g id="APPNAME">%s</xliff:g>, podrá añadir controles y contenido a este panel. En algunas aplicaciones, puedes elegir qué controles aparecen aquí."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Añadido a favoritos (posición <xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Quitado de favoritos"</string>
@@ -886,13 +881,18 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Poner <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para ti"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Deshacer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Acércate a <xliff:g id="DEVICENAME">%1$s</xliff:g> para reproducir contenido ahí"</string>
-    <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducirlo, acércate al dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string>
+    <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducirlo aquí, acércate al dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string>
     <string name="media_transfer_playing_different_device" msgid="7186806382609785610">"Reproduciendo en <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_transfer_failed" msgid="7955354964610603723">"Se ha producido un error. Inténtalo de nuevo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Control no disponible"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Error: Vuelve a intentarlo"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Añadir controles"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Añadir aplicación"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Añadir dispositivos de salida"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo seleccionado"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requiere una cuenta premium"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"No se puede emitir"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"No se puede guardar. Inténtalo de nuevo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"No se puede guardar."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número de compilación copiado en el portapapeles."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversación abierta"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"La cámara está desactivada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"El micrófono está desactivado"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"La cámara y el micrófono están desactivados"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"El Asistente está escuchando"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}many{# notificaciones}other{# notificaciones}}"</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">"Tomar notas"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir el acceso una vez"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"No permitir"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Los registros del dispositivo documentan lo que sucede en tu dispositivo. Las aplicaciones pueden usar estos registros para encontrar y solucionar problemas.\n\nComo algunos registros pueden contener información sensible, es mejor que solo permitas que accedan a ellos las aplicaciones en las que confíes. \n\nAunque no permitas que esta aplicación acceda a todos los registros del dispositivo, aún podrá acceder a sus propios registros. El fabricante de tu dispositivo aún puede acceder a algunos registros o información de tu dispositivo."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Más información"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Más información en <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• La aplicación debe estar configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Se debe haber añadido al menos una tarjeta a Wallet"</string>
@@ -1054,10 +1059,10 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Al menos un dispositivo debe estar disponible"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén pulsado el acceso directo"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Girar ahora"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Usar ahora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Despliega el teléfono para hacer un selfie mejor"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"¿Usar pantalla frontal para hacer mejores selfies?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para hacer una foto más amplia y con mayor resolución."</string>
+    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Usa la cámara trasera para hacer fotos más amplias y con mayor resolución."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Esta pantalla se apagará"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo plegable desplegándose"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo plegable mostrado desde varios ángulos"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Cambiar al perfil de trabajo"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Cerrar"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Ajustes de pantalla de bloqueo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 82bb481..dc6361d 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alapiir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vasak piir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Parem piir: <xliff:g id="PERCENT">%1$d</xliff:g> protsenti"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Töö ekraanipildid salvestatakse rakendusse <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salvestati tööprofiilil rakendusse <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> tuvastas selle ekraanipildi."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja muud avatud rakendused tuvastasid selle ekraanipildi."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisa märkmesse"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekraanisalvesti"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Nägu tuvastati. Avamiseks vajutage avamise ikooni."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Avati näoga"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Nägu tuvastati"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Teisalda vasakule"</item>
-    <item msgid="5558598599408514296">"Teisalda alla"</item>
-    <item msgid="4844142668312841831">"Teisalda paremale"</item>
-    <item msgid="5640521437931460125">"Teisalda üles"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Valige juhtelementide lisamiseks rakendus"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Lisati # juhtnupp.}other{Lisati # juhtnuppu.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Kas lisada <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Kui lisate rakenduse <xliff:g id="APPNAME">%s</xliff:g>, saab see sellele paneelile lisada juhtelemendid ja sisu. Mõnes rakenduses saate valida, millised juhtelemendid siin kuvatakse."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisatud lemmikuks, positsioon <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eemaldatud lemmikute hulgast"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Rakenduse <xliff:g id="APP_LABEL">%1$s</xliff:g> avamine"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Esita lugu <xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Esita lugu <xliff:g id="SONG_NAME">%1$s</xliff:g> rakenduses <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Teile"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Võta tagasi"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Liikuge lähemale, et seadmes <xliff:g id="DEVICENAME">%1$s</xliff:g> esitada"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Siin esitamiseks minge seadmele <xliff:g id="DEVICENAME">%1$s</xliff:g> lähemale"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Midagi läks valesti. Proovige uuesti."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Laadimine"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tahvelarvuti"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Juhtelement pole saadaval"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Ilmnes viga, proovige uuesti"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Lisa juhtelemente"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Muuda juhtelemente"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Rakenduse lisamine"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Väljundite lisamine"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupp"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 seade on valitud"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Kõlarid ja ekraanid"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Soovitatud seadmed"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vajalik on tasuline konto"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kuidas ülekandmine toimib?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Ülekanne"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Teie läheduses olevad inimesed, kellel on ühilduvad Bluetooth-seadmed, saavad kuulata teie ülekantavat meediat"</string>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei saa üle kanda"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ei saa salvestada. Proovige uuesti."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ei saa salvestada."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Järgunumber"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Järgunumber kopeeriti lõikelauale."</string>
     <string name="basic_status" msgid="2315371112182658176">"Avage vestlus"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kaamera on välja lülitatud"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon on välja lülitatud"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kaamera ja mikrofon on välja lülitatud"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent kuulab"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# märguanne}other{# märguannet}}"</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">"Märkmete tegemine"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Luba ühekordne juurdepääs"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ära luba"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Seadmelogid jäädvustavad, mis teie seadmes toimub. Rakendused saavad neid logisid kasutada probleemide tuvastamiseks ja lahendamiseks.\n\nMõned logid võivad sisaldada tundlikku teavet, seega lubage juurdepääs kõigile seadmelogidele ainult rakendustele, mida usaldate. \n\nKui te ei luba sellel rakendusel kõigile seadmelogidele juurde pääseda, pääseb see siiski juurde oma logidele. Teie seadme tootja võib teie seadmes siiski teatud logidele või teabele juurde pääseda."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lisateave"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lisateave: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ava <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Rakendus on seadistatud"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Vähemalt üks kaart on Walletisse lisatud"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Lülitu tööprofiilile"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sule"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lukustuskuva seaded"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index ebbc8db..0bc82bd 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -32,13 +32,13 @@
     <string name="battery_saver_start_action" msgid="8353766979886287140">"Aktibatu"</string>
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Ez, eskerrik asko"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Biratu pantaila automatikoki"</string>
-    <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
+    <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?\nAplikazioak ez du grabatzeko baimenik, baina baliteke USB bidezko gailu horren bidez audioa grabatzea."</string>
-    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
+    <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> kudeatzeko?"</string>
     <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Aplikazioak ez du grabatzeko baimenik, baina baliteke USB bidezko gailu honen bidez audioa grabatzea. <xliff:g id="APPLICATION">%1$s</xliff:g> gailu honekin erabiliz gero, baliteke deiak, jakinarazpenak eta alarmak ez entzutea."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"<xliff:g id="APPLICATION">%1$s</xliff:g> gailu honekin erabiliz gero, baliteke deiak, jakinarazpenak eta alarmak ez entzutea."</string>
-    <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> erabiltzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> kudeatzeko?"</string>
     <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> erabiltzeko?\nAplikazioak ez du grabatzeko baimenik, baina baliteke audioa grabatzea USB bidezko gailu horren bidez."</string>
     <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> kudeatzeko?"</string>
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Beheko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Ezkerreko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Eskuineko ertza: ehuneko <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Laneko pantaila-argazkiak <xliff:g id="APP">%1$s</xliff:g> aplikazioan gordetzen dira"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Laneko profilaren <xliff:g id="APP">%1$s</xliff:g> aplikazioan gorde da"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fitxategiak"</string>
+    <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>
     <string name="screenrecord_name" msgid="2596401223859996572">"Pantaila-grabagailua"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
@@ -298,9 +301,9 @@
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Gailuaren kamera eta mikrofonoa desblokeatu nahi dituzu?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Mikrofonoa atzitzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dute."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kamera atzitzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dute."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kamera edo mikrofonoa atzitzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dituzte."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Mikrofonoa erabiltzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dute."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Kamera erabiltzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dute."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Kamera edo mikrofonoa erabiltzeko baimena duten aplikazio eta zerbitzu guztiek erabili ahalko dituzte."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Blokeatuta dago mikrofonoa"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Blokeatuta dago kamera"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Blokeatuta daude mikrofonoa eta kamera"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ezagutu da aurpegia. Irekitzeko, sakatu desblokeatzeko ikonoa."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Aurpegiaren bidez desblokeatu da"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Ezagutu da aurpegia"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Eraman ezkerrera"</item>
-    <item msgid="5558598599408514296">"Eraman behera"</item>
-    <item msgid="4844142668312841831">"Eraman eskuinera"</item>
-    <item msgid="5640521437931460125">"Eraman gora"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFCa erabiltzeko"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Aukeratu aplikazio bat kontrolatzeko aukerak gehitzeko"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Kontrolatzeko # aukera gehitu da.}other{Kontrolatzeko # aukera gehitu dira.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Kenduta"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> gehitu nahi duzu?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> gehitzen duzunean, kontrolatzeko aukerak eta edukia gehi ditzake panelean. Aplikazio batzuetan, hemen zein kontrolatzeko aukera agertzen diren aukera dezakezu."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gogokoetan dago"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>. gogokoa da"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Ez dago gogokoetan"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ireki <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Erreproduzitu <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> bidez"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Erreproduzitu <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g> bidez"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Zuretzat"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desegin"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Gertura ezazu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailuan erreproduzitzeko"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Hemen erreproduzitzeko, hurbildu <xliff:g id="DEVICENAME">%1$s</xliff:g> gailura"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Arazoren bat izan da. Saiatu berriro."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Kargatzen"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tableta"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ez dago erabilgarri kontrolatzeko aukera"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Errorea. Saiatu berriro."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Gehitu aukerak"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editatu aukerak"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Gehitu aplikazio bat"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Gehitu irteerak"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Taldea"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 gailu hautatu da"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Bozgorailuak eta pantailak"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Iradokitako gailuak"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium kontu bat behar da"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ezin da iragarri"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ezin da gorde. Saiatu berriro."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ezin da gorde."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Konpilazio-zenbakia"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Kopiatu da konpilazio-zenbakia arbelean."</string>
     <string name="basic_status" msgid="2315371112182658176">"Elkarrizketa irekia"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera desaktibatuta dago"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofonoa desaktibatuta dago"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera eta mikrofonoa desaktibatuta daude"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Laguntzailea entzuten ari da"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# jakinarazpen}other{# jakinarazpen}}"</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">"Oharrak idaztea"</string>
@@ -1042,10 +1045,12 @@
     <string name="bt_le_audio_broadcast_dialog_unknown_name" msgid="3791472237793443044">"Ezezaguna"</string>
     <string name="dream_time_complication_12_hr_time_format" msgid="4691197486690291529">"h:mm"</string>
     <string name="dream_time_complication_24_hr_time_format" msgid="6248280719733640813">"kk:mm"</string>
-    <string name="log_access_confirmation_title" msgid="4843557604739943395">"Gailuko erregistro guztiak atzitzeko baimena eman nahi diozu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioari?"</string>
+    <string name="log_access_confirmation_title" msgid="4843557604739943395">"Gailuko erregistro guztiak erabiltzeko baimena eman nahi diozu <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> aplikazioari?"</string>
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Eman behin erabiltzeko baimena"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ez eman baimenik"</string>
-    <string name="log_access_confirmation_body" msgid="6883031912003112634">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak atzitzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak atzitzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak atzitu ahalko ditu. Gainera, baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk atzitu ahal izatea."</string>
+    <string name="log_access_confirmation_body" msgid="6883031912003112634">"Gailuko erregistroetan gailuan gertatzen den guztia gordetzen da. Arazoak bilatu eta konpontzeko erabil ditzakete aplikazioek erregistro horiek.\n\nBaliteke erregistro batzuek kontuzko informazioa edukitzea. Beraz, eman gailuko erregistro guztiak erabiltzeko baimena fidagarritzat jotzen dituzun aplikazioei bakarrik. \n\nNahiz eta gailuko erregistro guztiak erabiltzeko baimena ez eman aplikazio honi, aplikazioak hari dagozkion erregistroak atzitu ahalko ditu. Gainera, baliteke gailuaren fabrikatzaileak gailuko erregistro edo datu batzuk atzitu ahal izatea."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lortu informazio gehiago"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lortu informazio gehiago <xliff:g id="URL">%s</xliff:g> helbidean"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikazioa konfiguratuta dago."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Diru-zorroa zerbitzuan gutxienez txartel bat gehitu da."</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Aldatu laneko profilera"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Itxi"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Pantaila blokeatuaren ezarpenak"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index ab78224..c5fba0b 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"مرز پایین <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"مرز سمت چپ <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"مرز سمت راست <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"نماگرفت‌های نمایه کاری در برنامه <xliff:g id="APP">%1$s</xliff:g> ذخیره می‌شوند"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"در برنامه <xliff:g id="APP">%1$s</xliff:g> در نمایه کاری ذخیره شد"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> این نماگرفت را تشخیص داد."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> و سایر برنامه‌های باز این نماگرفت را تشخیص دادند."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"افزودن به یادداشت"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ضبط‌کننده صفحه‌نمایش"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحه‌نمایش"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"چهره شناسایی شد. برای باز کردن، نماد قفل‌گشایی را فشار دهید."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"قفل با چهره باز شد"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"چهره شناسایی شد"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"انتقال به‌چپ"</item>
-    <item msgid="5558598599408514296">"انتقال به‌پایین"</item>
-    <item msgid="4844142668312841831">"انتقال به‌راست"</item>
-    <item msgid="5640521437931460125">"انتقال به‌بالا"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند به‌بالا بکشید"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏برای استفاده از NFC، قفل را باز کنید"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"این دستگاه به سازمان شما تعلق دارد"</string>
@@ -819,7 +816,7 @@
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"برای پنهان کردن موقتی دکمه، آن را به لبه ببرید"</string>
     <string name="accessibility_floating_button_undo" msgid="511112888715708241">"واگرد"</string>
     <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"میان‌بر «<xliff:g id="FEATURE_NAME">%s</xliff:g>» برداشته شد"</string>
-    <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{میان‌بر # برداشته شد}one{میان‌بر # برداشته شد}other{میان‌بر # برداشته شد}}"</string>
+    <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{میان‌بر «#» برداشته شد}one{میان‌بر «#» برداشته شد}other{میان‌بر «#» برداشته شد}}"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"انتقال به بالا سمت راست"</string>
     <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"انتقال به بالا سمت چپ"</string>
     <string name="accessibility_floating_button_action_move_bottom_left" msgid="8063394111137429725">"انتقال به پایین سمت راست"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"انتخاب برنامه برای افزودن کنترل‌ها"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنترل اضافه شد.}one{# کنترل اضافه شد.}other{# کنترل اضافه شد.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> افزوده شود؟"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"وقتی <xliff:g id="APPNAME">%s</xliff:g> را اضافه می‌کنید، می‌تواند کنترل‌ها و محتوا را به این پانل اضافه کند. در برخی‌از برنامه‌ها می‌توانید انتخاب کنید چه کنترل‌هایی در اینجا نشان داده شود."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"اضافه‌شده به موارد دلخواه، جایگاه <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"حذف‌شده از موارد دلخواه"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"باز کردن <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> را ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش کنید"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> را ازطریق <xliff:g id="APP_LABEL">%2$s</xliff:g> پخش کنید"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"برای شما"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"واگرد"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"برای پخش در <xliff:g id="DEVICENAME">%1$s</xliff:g> به دستگاه نزدیک‌تر شوید"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"برای پخش در اینجا، به <xliff:g id="DEVICENAME">%1$s</xliff:g> نزدیک‌تر شوید"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"مشکلی پیش آمد. دوباره امتحان کنید."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"درحال بار کردن"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"رایانه لوحی"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"کنترل دردسترس نیست"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"خطا، دوباره امتحان کنید"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"افزودن کنترل‌ها"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"ویرایش کنترل‌ها"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"افزودن برنامه"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"افزودن خروجی"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"گروه"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"۱ دستگاه انتخاب شد"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"بلندگوها و نمایشگرها"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"دستگاه‌های پیشنهادی"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"حساب ممتاز لازم است"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"همه‌فرستی انجام نشد"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ذخیره نشد. دوباره امتحان کنید."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ذخیره نشد."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"شماره ساخت"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
     <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
@@ -984,7 +986,7 @@
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"موقتاً متصل است"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"اتصال ضعیف"</string>
     <string name="mobile_data_off_summary" msgid="3663995422004150567">"داده تلفن همراه به‌طور خودکار متصل نخواهد شد"</string>
-    <string name="mobile_data_no_connection" msgid="1713872434869947377">"اتصال برقرار نیست"</string>
+    <string name="mobile_data_no_connection" msgid="1713872434869947377">"اتصال اینترنت موجود نیست"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"شبکه دیگری وجود ندارد"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"شبکه‌ای در دسترس نیست"</string>
     <string name="turn_on_wifi" msgid="1308379840799281023">"Wi-Fi"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"دوربین خاموش است"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"میکروفون خاموش است"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"دوربین و میکروفون خاموش هستند"</string>
+    <string name="dream_overlay_status_bar_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_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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"مجاز کردن دسترسی یک‌باره"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"اجازه نمی‌دهم"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"گزارش‌های دستگاه آنچه را در دستگاهتان رخ می‌دهد ثبت می‌کند. برنامه‌ها می‌توانند از این گزارش‌ها برای پیدا کردن مشکلات و رفع آن‌ها استفاده کنند.\n\nبرخی‌از گزارش‌ها ممکن است حاوی اطلاعات حساس باشند، بنابراین فقط به برنامه‌های مورداعتمادتان اجازه دسترسی به همه گزارش‌های دستگاه را بدهید. \n\nاگر به این برنامه اجازه ندهید به همه گزارش‌های دستگاه دسترسی داشته باشد، همچنان می‌تواند به گزارش‌های خودش دسترسی داشته باشد. سازنده دستگاه نیز ممکن است همچنان بتواند به برخی‌از گزارش‌ها یا اطلاعات دستگاهتان دسترسی داشته باشد."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"بیشتر بدانید"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"در <xliff:g id="URL">%s</xliff:g> اطلاعات بیشتری دریافت کنید"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"باز کردن <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• برنامه راه‌اندازی شده باشد"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• حداقل یک کارت به «کیف پول» اضافه شده باشد"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"خط‌مشی کاری شما فقط به برقراری تماس ازطریق نمایه کاری اجازه می‌دهد"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"رفتن به نمایه کاری"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"بستن"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"تنظیمات صفحه قفل"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index b84ca4f..d5d2121 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alareuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vasen reuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oikea reuna <xliff:g id="PERCENT">%1$d</xliff:g> prosenttia"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Työprofiilin kuvakaappaukset tallennetaan sovellukseen: <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Tallennettu työprofiiliin tässä sovelluksessa: <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> havaitsi tämän kuvakaappauksen."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja jotkin muut sovellukset havaitsivat tämän kuvakaappauksen."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisää muistiinpanoon"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Näytön tallentaja"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Avattu kasvojen avulla"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Kasvot tunnistettu"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Siirrä vasemmalle"</item>
-    <item msgid="5558598599408514296">"Siirrä alas"</item>
-    <item msgid="4844142668312841831">"Siirrä oikealle"</item>
-    <item msgid="5640521437931460125">"Siirrä ylös"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Yritä uudelleen pyyhkäisemällä ylös"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Avaa lukitus, jotta voit käyttää NFC:tä"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Valitse sovellus lisätäksesi säätimiä"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# säädin lisätty.}other{# säädintä lisätty.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Poistettu"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Lisätäänkö <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Kun <xliff:g id="APPNAME">%s</xliff:g> lisätään, se voi lisätä asetuksia ja sisältöä tähän paneeliin. Joissakin sovelluksissa voit valita, mitä asetukset näkyvät täällä."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisätty suosikkeihin"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisätty suosikkeihin sijalle <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Poistettu suosikeista"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Avaa <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Soita <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) sovelluksessa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Soita <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="APP_LABEL">%2$s</xliff:g>)"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Sinulle"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Kumoa"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Siirry lähemmäs, jotta <xliff:g id="DEVICENAME">%1$s</xliff:g> voi toistaa tämän"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Siirry lähemmäs laitetta (<xliff:g id="DEVICENAME">%1$s</xliff:g>) toistaaksesi täällä"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Jotain meni pieleen. Yritä uudelleen."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Latautuminen"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tabletti"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Striimataan mediaa"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Striimataan <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Epäaktiivinen, tarkista sovellus"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ei löydy"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ohjain ei ole käytettävissä"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Virhe, yritä uudelleen"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Lisää säätimiä"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Muokkaa säätimiä"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Lisää sovellus"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Lisää toistotapoja"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Ryhmä"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 laite valittu"</string>
@@ -919,7 +916,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Edellyttää premium-tiliä"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ei voi lähettää"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tallennus ei onnistu. Yritä uudelleen."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tallennus ei onnistu."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Koontiversion numero"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Koontiversion numero kopioitu leikepöydälle"</string>
     <string name="basic_status" msgid="2315371112182658176">"Avaa keskustelu"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera on poissa päältä"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofoni on poissa päältä"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ja mikrofoni ovat pois päältä"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant kuuntelee"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ilmoitus}other{# ilmoitusta}}"</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">"Muistiinpanojen tekeminen"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Salli kertaluonteinen pääsy"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Älä salli"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Laitteen tapahtumat tallentuvat laitelokeihin. Niiden avulla sovellukset voivat löytää ja korjata ongelmia.\n\nJotkin lokit voivat sisältää arkaluontoista tietoa, joten salli pääsy kaikkiin laitelokeihin vain sovelluksille, joihin luotat. \n\nJos et salli tälle sovellukselle pääsyä kaikkiin laitelokeihin, sillä on kuitenkin pääsy sen omiin lokeihin. Laitteen valmistajalla voi olla pääsy joihinkin lokeihin tai tietoihin laitteella."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lue lisää"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lue lisää: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Avaa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Sovellus on otettu käyttöön"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Ainakin yksi kortti on lisätty Walletiin"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Vaihda työprofiiliin"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sulje"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lukitusnäytön asetukset"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index a60d961..5d7b7f7 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inférieure : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite gauche : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite droite : <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Les captures d\'écran du profil professionnel sont enregistrées dans l\'application <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Enregistré dans <xliff:g id="APP">%1$s</xliff:g> dans le profil professionnel"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fichiers"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applications ouvertes ont détecté cette capture d\'écran."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à l\'application de prise de notes"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Visage reconnu. Appuyez sur Déverrouiller pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Déverrouillé avec le visage"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Visage reconnu"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Déplacer vers la gauche"</item>
-    <item msgid="5558598599408514296">"Déplacer vers le bas"</item>
-    <item msgid="4844142668312841831">"Déplacer vers la droite"</item>
-    <item msgid="5640521437931460125">"Déplacer vers le haut"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la CCP"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# de commandes ajoutées.}other{# commandes ajoutées.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Lorsque vous ajoutez <xliff:g id="APPNAME">%s</xliff:g>, elle peut ajouter des commandes et du contenu à ce panneau. Dans certaines applications, vous pouvez choisir les commandes qui s\'affichent ici."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ouvrez <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Lecture de <xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Lecture de <xliff:g id="SONG_NAME">%1$s</xliff:g> à partir de <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pour vous"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Annuler"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous pour faire jouer le contenu sur <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pour faire jouer le contenu ici, rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Une erreur s\'est produite. Réessayez."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement en cours…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablette"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une application"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Un appareil sélectionné"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nécessite un compte payant"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de version"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Le numéro de version a été copié dans le presse-papiers."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ouvrir la conversation"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"L\'appareil photo est désactivé"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Le micro est désactivé"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"L\'appareil photo et le micro sont désactivés"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'Assistant est à l\'écoute"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}many{# de notifications}other{# notifications}}"</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">"Prise de note"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Autoriser un accès unique"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne pas autoriser"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applications peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applications auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette application à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"En savoir plus"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"En savoir plus : <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• que cette application est configurée;"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• qu\'au moins une carte a été ajoutée à Portefeuille."</string>
@@ -1069,6 +1074,5 @@
     <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="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Paramètres écran de verrouillage"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1a37657..ec9d7e9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inférieure : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite gauche : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite droite : <xliff:g id="PERCENT">%1$d</xliff:g> pour cent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Les captures d\'écran du profil professionnel sont enregistrées dans l\'appli <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Enregistré dans <xliff:g id="APP">%1$s</xliff:g>, dans le profil professionnel"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fichiers"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applis ouvertes ont détecté cette capture d\'écran."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à la note"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour ouvrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Déverrouillé par le visage"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Visage reconnu"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Déplacer vers la gauche"</item>
-    <item msgid="5558598599408514296">"Déplacer vers le bas"</item>
-    <item msgid="4844142668312841831">"Déplacer vers la droite"</item>
-    <item msgid="5640521437931460125">"Déplacer vers le haut"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser le NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# commandes ajoutées.}other{# commandes ajoutées.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g> ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Lorsque vous ajoutez l\'appli <xliff:g id="APPNAME">%s</xliff:g>, elle peut ajouter des commandes et contenus dans ce panneau. Dans certaines applis, vous pouvez choisir les commandes à afficher ici."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Ouvre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Mets <xliff:g id="SONG_NAME">%1$s</xliff:g> depuis <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pour vous"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Annuler"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Rapprochez-vous de votre <xliff:g id="DEVICENAME">%1$s</xliff:g> pour y lire le contenu"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pour lancer la lecture ici, rapprochez-vous de <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Un problème est survenu. Réessayez."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Chargement…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablette"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Commande indisponible"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une appli"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 appareil sélectionné"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nécessite un compte premium"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossible de diffuser"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossible d\'enregistrer. Réessayez."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossible d\'enregistrer."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numéro de build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numéro de build copié dans le presse-papiers."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversation ouverte"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Caméra désactivée"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Micro désactivé"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Appareil photo et micro désactivés"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'Assistant écoute"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}many{# notifications}other{# notifications}}"</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">"Prendre des notes"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Autoriser un accès unique"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne pas autoriser"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux enregistrent ce qui se passe sur votre appareil. Les applis peuvent les utiliser pour rechercher et résoudre des problèmes.\n\nCertains journaux pouvant contenir des infos sensibles, autorisez uniquement les applis de confiance à accéder à tous les journaux de l\'appareil. \n\nSi vous refusez à cette appli l\'accès à tous les journaux de l\'appareil, elle a quand même accès aux siens. Le fabricant de l\'appareil peut accéder à certains journaux ou certaines infos sur votre appareil."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"En savoir plus"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Pour en savoir plus, rendez-vous sur <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• L\'appli est configurée"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Au moins une carte a été ajoutée à Wallet"</string>
@@ -1054,11 +1059,11 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Au moins un appareil est disponible"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Appuyez de manière prolongée sur raccourci"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner maintenant"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Retourner"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Déplier le téléphone pour un meilleur selfie"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passer à l\'écran frontal pour un meilleur selfie ?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez la caméra arrière pour prendre une photo plus large avec une résolution supérieure."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Cet écran sera désactivé"</b></string>
+    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilisez la caméra arrière pour prendre une photo plus large d\'une résolution supérieure."</string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Cet écran s\'éteindra"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Appareil pliable qui est déplié"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Appareil pliable qui est retourné"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> de batterie restante"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fermer"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Paramètres écran de verrouillage"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index cb1a8cb..e2633ad 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Bordo inferior: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Bordo esquerdo: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Bordo dereito: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"As capturas de pantalla do perfil de traballo gárdanse na aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Captura de pantalla gardada na aplicación <xliff:g id="APP">%1$s</xliff:g> do perfil de traballo"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ficheiros"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectou esta captura de pantalla."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outras aplicacións abertas detectaron esta captura de pantalla."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engadir a unha nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravadora da pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación en curso sobre unha sesión de gravación de pantalla"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Recoñeceuse a cara. Preme a icona de desbloquear para abrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Usouse o desbloqueo facial"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Recoñeceuse a cara"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mover cara á esquerda"</item>
-    <item msgid="5558598599408514296">"Mover cara abaixo"</item>
-    <item msgid="4844142668312841831">"Mover cara á dereita"</item>
-    <item msgid="5640521437931460125">"Mover cara arriba"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Pasa o dedo cara arriba para tentalo de novo"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea o dispositivo para utilizar a NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización."</string>
@@ -543,10 +540,8 @@
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sen son nin vibración"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Sen son nin vibración, e aparecen máis abaixo na sección de conversas"</string>
-    <!-- no translation found for notification_channel_summary_default (777294388712200605) -->
-    <skip />
-    <!-- no translation found for notification_channel_summary_default_with_bubbles (3482483084451555344) -->
-    <skip />
+    <string name="notification_channel_summary_default" msgid="777294388712200605">"Poderían facer que o dispositivo soe ou vibre en función da súa configuración"</string>
+    <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Poderían facer que o dispositivo soe ou vibre en función da súa configuración. As conversas de <xliff:g id="APP_NAME">%1$s</xliff:g> móstranse en burbullas de forma predeterminada."</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Fai que o sistema determine se a notificación debe emitir un son ou unha vibración"</string>
     <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Estado:&lt;/b&gt; ascendeuse a Predeterminada"</string>
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Estado:&lt;/b&gt; o nivel diminuíuse a Silencioso"</string>
@@ -834,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolle unha aplicación para engadir controis"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Engadiuse # control.}other{Engadíronse # controis.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitouse"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Queres engadir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Cando engadas a aplicación <xliff:g id="APPNAME">%s</xliff:g>, poderá incluír controis e contido neste panel Nalgunhas aplicacións, podes escoller os controis que se mostrarán aquí."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está entre os controis favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está entre os controis favoritos (posición: <xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Non está entre os controis favoritos"</string>
@@ -888,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abre <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproduce <xliff:g id="SONG_NAME">%1$s</xliff:g> en <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para ti"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfacer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Achega o dispositivo para reproducir o contido en: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproducir o contido aquí, achégate ao dispositivo (<xliff:g id="DEVICENAME">%1$s</xliff:g>)"</string>
@@ -895,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Produciuse un erro. Téntao de novo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Cargando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tableta"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O control non está dispoñible"</string>
@@ -904,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Erro. Téntao de novo"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Engadir controis"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editar controis"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Engadir aplicación"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Engadir saídas"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Seleccionouse 1 dispositivo"</string>
@@ -921,8 +918,6 @@
     <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_status_require_premium (5691200962588753380) -->
-    <skip />
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funcionan as difusións?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Difusión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As persoas que estean preto de ti e que dispoñan de dispositivos Bluetooth compatibles poden escoitar o contido multimedia que difundas"</string>
@@ -934,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Non se puido iniciar a emisión"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Non se puido gardar a información. Téntao de novo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Non se pode gardar a información."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número de compilación"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Copiouse o número de compilación no portapapeis."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -1034,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"A cámara está apagada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"O micrófono está desactivado"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A cámara e o micrófono están desactivados"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Asistente está escoitando"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificación}other{# notificacións}}"</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">"Toma de notas"</string>
@@ -1049,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acceso unha soa vez"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Non permitir"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os rexistros do dispositivo dan conta do que ocorre neste. As aplicacións poden usalos para buscar problemas e solucionalos.\n\nAlgúns poden conter información confidencial, polo que che recomendamos que só permitas que accedan a todos os rexistros do dispositivo as aplicacións nas que confíes. \n\nEsta aplicación pode acceder aos seus propios rexistros aínda que non lle permitas acceder a todos. É posible que o fabricante do dispositivo teña acceso a algúns rexistros ou á información do teu dispositivo."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Máis información"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Máis información en <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• A aplicación debe estar configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Ten que haber polo menos unha tarxeta engadida a Wallet"</string>
@@ -1067,16 +1069,10 @@
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Batería restante: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <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>
-    <!-- no translation found for video_camera (7654002575156149298) -->
-    <skip />
-    <!-- no translation found for call_from_work_profile_title (6991157106804289643) -->
-    <skip />
-    <!-- no translation found for call_from_work_profile_text (3458704745640229638) -->
-    <skip />
-    <!-- no translation found for call_from_work_profile_action (2937701298133010724) -->
-    <skip />
-    <!-- no translation found for call_from_work_profile_close (7927067108901068098) -->
-    <skip />
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <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_action" msgid="2937701298133010724">"Cambiar ao perfil de traballo"</string>
+    <string name="call_from_work_profile_close" msgid="7927067108901068098">"Pechar"</string>
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Configuración pantalla bloqueo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 78aa0f5..45ed81b 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"નીચેની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ડાબી બાજુની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"જમણી બાજુની સીમા <xliff:g id="PERCENT">%1$d</xliff:g> ટકા"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ઑફિસના સ્ક્રીનશૉટ <xliff:g id="APP">%1$s</xliff:g> ઍપમાં સાચવવામાં આવે છે"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ઑફિસની પ્રોફાઇલમાં <xliff:g id="APP">%1$s</xliff:g>માં સાચવવામાં આવ્યો"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ફાઇલો"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> અને કામ કરતી અન્ય ઍપ દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"નોંધમાં ઉમેરો"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"સ્ક્રીન રેકોર્ડર"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ચહેરો ઓળખ્યો. ખોલવા માટે \'અનલૉક કરો\' આઇકન દબાવો."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ચહેરા દ્વારા અનલૉક કર્યું"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ચહેરો ઓળખ્યો"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ડાબે ખસેડો"</item>
-    <item msgid="5558598599408514296">"નીચે ખસેડો"</item>
-    <item msgid="4844142668312841831">"જમણે ખસેડો"</item>
-    <item msgid="5640521437931460125">"ઉપર ખસેડો"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"નિયંત્રણો ઉમેરવા માટે ઍપ પસંદ કરો"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# નિયંત્રણ ઉમેર્યું.}one{# નિયંત્રણ ઉમેર્યું.}other{# નિયંત્રણ ઉમેર્યા.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"કાઢી નાખ્યું"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ઉમેરીએ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"જ્યારે તમે <xliff:g id="APPNAME">%s</xliff:g> ઉમેરો, ત્યારે તે આ પૅનલમાં નિયંત્રણો અને કન્ટેન્ટ ઉમેરી શકે છે. કેટલીક ઍપમાં, અહીં કયા નિયંત્રણો દેખાય તે તમે પસંદ કરી શકો છો."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"મનપસંદમાં ઉમેર્યું"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"મનપસંદમાં ઉમેર્યું, સ્થાન <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"મનપસંદમાંથી કાઢી નાખ્યું"</string>
@@ -853,7 +848,7 @@
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"અન્ય"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"ડિવાઇસનાં નિયંત્રણોમાં ઉમેરો"</string>
     <string name="controls_dialog_ok" msgid="2770230012857881822">"ઉમેરો"</string>
-    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> દ્વારા સૂચન કરેલા"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> દ્વારા સૂચવેલા"</string>
     <string name="controls_tile_locked" msgid="731547768182831938">"ડિવાઇસ લૉક કરેલું છે"</string>
     <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"લૉક સ્ક્રીનમાંથી ડિવાઇસ બતાવીએ અને નિયંત્રિત કરીએ?"</string>
     <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"તમે તમારા બાહ્ય ડિવાઇસ માટેના નિયંત્રણો લૉક સ્ક્રીન પર ઉમેરી શકો છો.\n\nતમારી ડિવાઇસ ઍપ કદાચ તમને તમારો ફોન કે ટૅબ્લેટ અનલૉક કર્યા વિના અમુક ડિવાઇસ નિયંત્રિત કરવાની મંજૂરી આપી શકે.\n\nતમે ગમે ત્યારે સેટિંગમાં જઈને ફેરફાર કરી શકો છો."</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ખોલો"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> પર <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચલાવો"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"તમારા માટે"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"છેલ્લો ફેરફાર રદ કરો"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> પર ચલાવવા માટે વધુ નજીક ખસેડો"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"અહીં ચલાવવા માટે, <xliff:g id="DEVICENAME">%1$s</xliff:g>ની નજીક લાવો"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"કંઈક ખોટું થયું. ફરી પ્રયાસ કરો."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"લોડ થઈ રહ્યું છે"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ટૅબ્લેટ"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"નિષ્ક્રિય, ઍપને ચેક કરો"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"મળ્યું નથી"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"નિયંત્રણ ઉપલબ્ધ નથી"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"ભૂલ, ફરીથી પ્રયાસ કરો"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"નિયંત્રણો ઉમેરો"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"નિયંત્રણોમાં ફેરફાર કરો"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ઍપ ઉમેરો"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"આઉટપુટ ઉમેરો"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ગ્રૂપ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ડિવાઇસ પસંદ કર્યું"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"સ્પીકર અને ડિસ્પ્લે"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"સૂચવેલા ડિવાઇસ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium એકાઉન્ટ જરૂરી છે"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"બ્રોડકાસ્ટ કરી શકતા નથી"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"સાચવી શકતા નથી. ફરી પ્રયાસ કરો."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"સાચવી શકતા નથી."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"બિલ્ડ નંબર"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"બિલ્ડ નંબર ક્લિપબૉર્ડ પર કૉપિ કર્યો."</string>
     <string name="basic_status" msgid="2315371112182658176">"વાતચીત ખોલો"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"કૅમેરા બંધ છે"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"માઇક્રોફોન બંધ છે"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"કૅમેરા અને માઇક બંધ છે"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant સાંભળી રહ્યું છે"</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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"એક-વખતના ઍક્સેસની મંજૂરી આપો"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"મંજૂરી આપશો નહીં"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"તમારા ડિવાઇસ પર થતી કામગીરીને ડિવાઇસ લૉગ રેકોર્ડ કરે છે. ઍપ આ લૉગનો ઉપયોગ સમસ્યાઓ શોધી તેનું નિરાકરણ કરવા માટે કરી શકે છે.\n\nઅમુક લૉગમાં સંવેદનશીલ માહિતી હોઈ શકે, આથી ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી માત્ર તમારી વિશ્વાસપાત્ર ઍપને જ આપો. \n\nજો તમે આ ઍપને ડિવાઇસનો બધો લૉગ ઍક્સેસ કરવાની મંજૂરી ન આપો, તો પણ તે તેના પોતાના લૉગ ઍક્સેસ કરી શકે છે. તમારા ડિવાઇસના નિર્માતા હજી પણ કદાચ તમારા ડિવાઇસ પર અમુક લૉગ અથવા માહિતી ઍક્સેસ કરી શકે છે."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"વધુ જાણો"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> પરથી વધુ જાણો"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ખોલો"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ઍપનું સેટઅપ કરેલું છે"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ઓછામાં ઓછું એક કાર્ડ વૉલેટમાં ઉમેરેલું છે"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"તમારી ઑફિસની પૉલિસી તમને માત્ર ઑફિસની પ્રોફાઇલ પરથી જ ફોન કૉલ કરવાની મંજૂરી આપે છે"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"બંધ કરો"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"લૉક સ્ક્રીનના સેટિંગ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index c0d89f9..f13ba41 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"निचले किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"बाएं किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"दाएं किनारे से <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"वर्क प्रोफ़ाइल से लिए गए स्क्रीनशॉट, <xliff:g id="APP">%1$s</xliff:g> ऐप्लिकेशन में सेव किए गए हैं"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"वर्क प्रोफ़ाइल में मौजूद <xliff:g id="APP">%1$s</xliff:g> में सेव किया गया है"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> को इस स्क्रीनशॉट का पता चला है."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> और खुले हुए अन्य ऐप्लिकेशन को इस स्क्रीनशॉट का पता चला है."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोट में जोड़ें"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रिकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"चेहरे की पहचान हो गई. डिवाइस खोलने के लिए अनलॉक आइकॉन को टैप करें."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"चेहरे से अनलॉक किया गया"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"चेहरे की पहचान हो गई"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"बाईं ओर ले जाएं"</item>
-    <item msgid="5558598599408514296">"नीचे ले जाएं"</item>
-    <item msgid="4844142668312841831">"दाईं ओर ले जाएं"</item>
-    <item msgid="5640521437931460125">"ऊपर ले जाएं"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए स्क्रीन को अनलॉक करें"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"कंट्रोल जोड़ने के लिए ऐप्लिकेशन चुनें"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ना है?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ने पर, वह इस पैनल पर कुछ कंट्रोल और कॉन्टेंट दिखा सकता है. कुछ ऐप्लिकेशन के लिए यह चुना जा सकता है कि वे इस पैनल पर कौनसे कंट्रोल दिखाएं."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"पसंदीदा से हटाया गया"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> खोलें"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चलाएं"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> पर, <xliff:g id="SONG_NAME">%1$s</xliff:g> चलाएं"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"आपके लिए सुझाव"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"पहले जैसा करें"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> पर मीडिया चलाने के लिए, अपने डिवाइस को उसके पास ले जाएं"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"मीडिया ट्रांसफ़र करने के लिए, <xliff:g id="DEVICENAME">%1$s</xliff:g> के करीब जाएं"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"कोई गड़बड़ी हुई. फिर से कोशिश करें."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"लोड हो रहा है"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"टैबलेट"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"कंट्रोल मौजूद नहीं है"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"गड़बड़ी हुई, फिर से कोशिश करें"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"कंट्राेल जोड़ें"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"कंट्रोल में बदलाव करें"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ऐप्लिकेशन जोड़ें"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट जोड़ें"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ग्रुप"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"एक डिवाइस चुना गया"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर और डिसप्ले"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुझाए गए डिवाइस"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रीमियम खाता होना ज़रूरी है"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट नहीं किया जा सकता"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव नहीं किया जा सका. फिर से कोशिश करें."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव नहीं किया जा सका."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर को क्लिपबोर्ड पर कॉपी किया गया."</string>
     <string name="basic_status" msgid="2315371112182658176">"ऐसी बातचीत जिसमें इंटरैक्शन डेटा मौजूद नहीं है"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"कैमरा बंद है"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"माइक्रोफ़ोन बंद है"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कैमरा और माइक बंद हैं"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant सुन रही है"</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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"एक बार ऐक्सेस करने की अनुमति दें"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमति न दें"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"डिवाइस लॉग में आपके डिवाइस पर की गई कार्रवाइयां रिकॉर्ड होती हैं. ऐप्लिकेशन, इन लॉग का इस्तेमाल गड़बड़ियां ढूंढने और उन्हें सही करने के लिए करता है.\n\nकुछ लॉग में संवेदनशील जानकारी हो सकती है. इसलिए, सिर्फ़ भरोसेमंद ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस दें. \n\nअगर इस ऐप्लिकेशन को डिवाइस के सभी लॉग का ऐक्सेस नहीं दिया जाता है, तब भी यह डिवाइस पर मौजूद अपने लॉग ऐक्सेस कर सकता है. डिवाइस को बनाने वाली कंपनी अब भी डिवाइस के कुछ लॉग या जानकारी को ऐक्सेस कर सकती है."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ज़्यादा जानें"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"ज़्यादा जानने के लिए <xliff:g id="URL">%s</xliff:g> पर जाएं"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> खोलें"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ऐप्लिकेशन को सेट अप किया गया है"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet में कम से कम एक कार्ड जोड़ा गया है"</string>
@@ -1054,7 +1059,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• कम से कम एक डिवाइस उपलब्ध है"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"शॉर्टकट को दबाकर रखें"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"रद्द करें"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"कैमरा अभी स्विच करें"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"अभी स्विच करें"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"बेहतर सेल्फ़ी के लिए फ़ोन को अनफ़ोल्ड करें"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"बेहतर सेल्फ़ी के लिए फ़्रंट डिसप्ले पर स्विच करें?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"वाइड ऐंगल में हाई रिज़ॉल्यूशन वाली फ़ोटो लेने के लिए, पीछे का कैमरा इस्तेमाल करें."</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ऑफ़िस की नीति के तहत, वर्क प्रोफ़ाइल होने पर ही फ़ोन कॉल किए जा सकते हैं"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"वर्क प्रोफ़ाइल पर स्विच करें"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करें"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"लॉक स्क्रीन की सेटिंग"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index cdf6e57..8f6e95c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Donji rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Lijevi rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Desni rub <xliff:g id="PERCENT">%1$d</xliff:g> posto"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Snimke zaslona s poslovnog profila spremaju se u aplikaciju <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Spremljeno u aplikaciju <xliff:g id="APP">%1$s</xliff:g> u poslovnom profilu"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Datoteke"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> otkrila je ovu snimku zaslona."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije otkrile su ovu snimku zaslona."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj bilješci"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste otvorili."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Otključano licem"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Lice je prepoznato"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Pomicanje ulijevo"</item>
-    <item msgid="5558598599408514296">"Pomicanje prema dolje"</item>
-    <item msgid="4844142668312841831">"Pomicanje udesno"</item>
-    <item msgid="5640521437931460125">"Pomicanje prema gore"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Prijeđite prstom prema gore za ponovni pokušaj"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste upotrijebili NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvori <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Pustite <xliff:g id="SONG_NAME">%1$s</xliff:g> putem aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Poništi"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Približite se radi reprodukcije na uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Da biste reproducirali ovdje, približite se uređaju <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nešto nije u redu. Pokušajte ponovo."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Učitavanje"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Emitiranje medijskih sadržaja"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Emitiranje aplikacije <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrola nije dostupna"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvučnici i zasloni"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predloženi uređaji"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Zahtijeva račun s naplatom"</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>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Emitiranje nije uspjelo"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Spremanje nije uspjelo. Pokušajte ponovo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Spremanje nije uspjelo."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Broj međuverzije"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Broj međuverzije kopiran je u međuspremnik."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvoreni razgovor"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je isključena"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je isključen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat i mikrofon su isključeni"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent sluša"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obavijest}one{# obavijest}few{# obavijesti}other{# obavijesti}}"</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">"Pisanje bilježaka"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Omogući jednokratni pristup"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nemoj dopustiti"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"U zapisnicima uređaja bilježi se što se događa na uređaju. Aplikacije mogu koristiti te zapisnike kako bi pronašle i riješile poteškoće.\n\nNeki zapisnici mogu sadržavati osjetljive podatke, pa pristup svim zapisnicima uređaja odobrite samo pouzdanim aplikacijama. \n\nAko ne dopustite ovoj aplikaciji da pristupa svim zapisnicima uređaja, ona i dalje može pristupati svojim zapisnicima. Proizvođač vašeg uređaja i dalje može pristupati nekim zapisnicima ili podacima na vašem uređaju."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saznajte više"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saznajte više na <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacija je postavljena"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Najmanje jedna kartica dodana je u Wallet"</string>
@@ -1051,7 +1057,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Dostupan je najmanje jedan uređaj"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prečac za dodirnuti i zadržati"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Odustani"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Okreni odmah"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prebaci"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Otvorite telefon da biste snimili bolji selfie"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Prebaciti na prednji zaslon za bolji selfie?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Upotrijebite stražnji fotoaparat za širu fotografiju s višom razlučivošću."</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zatvori"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Postavke zaključanog zaslona"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c411a0a..74765cc 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alsó rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Bal oldali rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Jobb oldali rész <xliff:g id="PERCENT">%1$d</xliff:g> százaléka"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"A munkahelyi képernyőképeket a(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazásba menti a rendszer"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Mentve a(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás munkaprofiljába"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fájlok"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> észlelte ezt a képernyőképet."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> és más nyitott alkalmazások észlelték ezt a képernyőképet."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Hozzáadás jegyzethez"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Képernyőrögzítő"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Arc felismerve. Eszköz használata: Feloldás ikon."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Zárolás arccal feloldva"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Arc felismerve"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mozgatás balra"</item>
-    <item msgid="5558598599408514296">"Mozgatás lefelé"</item>
-    <item msgid="4844142668312841831">"Mozgatás jobbra"</item>
-    <item msgid="5640521437931460125">"Mozgatás felfelé"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Az NFC használatához oldja fel a képernyőzárat"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ez az eszköz az Ön szervezetének tulajdonában van"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Válasszon alkalmazást a vezérlők hozzáadásához"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# vezérlő hozzáadva.}other{# vezérlő hozzáadva.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Eltávolítva"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Hozzáadja a(z) <xliff:g id="APPNAME">%s</xliff:g> alkalmazást?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"A(z) <xliff:g id="APPNAME">%s</xliff:g> hozzáadását követően az alkalmazás vezérlőelemeket és tartalmakat adhat hozzá ehhez a panelhez. Egyes alkalmazásokban kiválasztható, hogy mely vezérlőelemek jelenjenek meg itt."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Hozzáadva a kedvencekhez"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Hozzáadva a kedvencekhez <xliff:g id="NUMBER">%d</xliff:g>. helyen"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eltávolítva a kedvencek közül"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> megnyitása"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című számának lejátszása innen: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> lejátszása innen: <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Neked"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Visszavonás"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Menjen közelebb, ha itt szeretné lejátszani: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ha szeretné itt lejátszani, helyezkedjen közelebb a következőhöz: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Hiba történt. Próbálkozzon újra."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Betöltés…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"táblagép"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"A médiatartalom átküldése folyamatban van"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> átküldése"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Nem hozzáférhető vezérlő"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Hiba történt. Próbálja újra."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Vezérlők hozzáadása"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Vezérlők szerkesztése"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Alkalmazás hozzáadása"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Kimenetek hozzáadása"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Csoport"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 eszköz kiválasztva"</string>
@@ -919,7 +916,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Prémiumfiók szükséges"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nem sikerült a közvetítés"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"A mentés nem sikerült. Próbálja újra."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"A mentés nem sikerült."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildszám"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildszám a vágólapra másolva."</string>
     <string name="basic_status" msgid="2315371112182658176">"Beszélgetés megnyitása"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"A kamera ki van kapcsolva"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"A mikrofon ki van kapcsolva"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A kamera és a mikrofon ki vannak kapcsolva"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"A Segéd figyel"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# értesítés}other{# értesítés}}"</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">"Jegyzetelés"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Egyszeri hozzáférés engedélyezése"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Tiltás"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Az eszköznaplók rögzítik, hogy mi történik az eszközén. Az alkalmazások ezeket a naplókat használhatják a problémák megkeresésére és kijavítására.\n\nBizonyos naplók bizalmas adatokat is tartalmazhatnak, ezért csak olyan alkalmazások számára engedélyezze az összes eszköznaplóhoz való hozzáférést, amelyekben megbízik. \n\nHa nem engedélyezi ennek az alkalmazásnak, hogy hozzáférjen az összes eszköznaplójához, az app továbbra is hozzáférhet a saját naplóihoz. Előfordulhat, hogy az eszköz gyártója továbbra is hozzáfér az eszközön található bizonyos naplókhoz és adatokhoz."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"További információ"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"További információ: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> megnyitása"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Az alkalmazás be van állítva"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Legalább egy kártya hozzá lett adva a Wallethez"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Váltás munkaprofilra"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Bezárás"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Lezárási képernyő beállításai"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 9186f12..7cad53b 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ներքևի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Ձախ կողմի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Աջ կողմի սահմանագիծը՝ <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Աշխատանքային սքրինշոթները պահվում են «<xliff:g id="APP">%1$s</xliff:g>» հավելվածում"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Սքրինշոթը պահվեց <xliff:g id="APP">%1$s</xliff:g>-ի աշխատանքային պրոֆիլում"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ֆայլեր"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը հայտնաբերել է այս սքրինշոթը։"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-ն ու բացված այլ հավելվածներ հայտնաբերել են այս սքրինշոթը։"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ավելացնել նշմանը"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Էկրանի տեսագրիչ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Դեմքը ճանաչվեց։ Բացելու համար սեղմեք ապակողպման պատկերակը։"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Ապակողպվեց դեմքով"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Դեմքը ճանաչվեց"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Տեղափոխել ձախ"</item>
-    <item msgid="5558598599408514296">"Տեղափոխել ներքև"</item>
-    <item msgid="4844142668312841831">"Տեղափոխել աջ"</item>
-    <item msgid="5640521437931460125">"Տեղափոխել վերև"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Սահեցրեք վերև՝ նորից փորձելու համար"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ապակողպեք՝ NFC-ն օգտագործելու համար"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Ընտրեք հավելված` կառավարման տարրեր ավելացնելու համար"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Ավելացվեց կառավարման # տարր։}one{Ավելացվեց կառավարման # տարր։}other{Ավելացվեց կառավարման # տարր։}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Հեռացված է"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ավելացնե՞լ <xliff:g id="APPNAME">%s</xliff:g> հավելվածը"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Եթե ավելացնեք <xliff:g id="APPNAME">%s</xliff:g> հավելվածը, այն կարող է կարգավորումներ և բովանդակություն ավելացնել այս վահանակում։ Որոշ հավելվածներում դուք կարող եք ընտրել, թե որ կարգավորումները ցուցադրվեն այստեղ։"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ավելացված է ընտրանիում"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ավելացված է ընտրանիում, դիրքը՝ <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Հեռացված է ընտրանուց"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Բացեք <xliff:g id="APP_LABEL">%1$s</xliff:g> հավելվածը"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Նվագարկել <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Նվագարկել <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="APP_LABEL">%2$s</xliff:g> հավելվածից"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Ձեզ համար"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Հետարկել"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ավելի մոտ եկեք՝ <xliff:g id="DEVICENAME">%1$s</xliff:g> սարքում նվագարկելու համար"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Այստեղ նվագարկելու համար մոտեցեք <xliff:g id="DEVICENAME">%1$s</xliff:g> սարքին"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Սխալ առաջացավ։ Նորից փորձեք։"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Բեռնվում է"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"պլանշետ"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Մեդիա բովանդակության հեռարձակում"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> հավելվածի հեռարձակում"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Ակտիվ չէ, ստուգեք հավելվածը"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Չի գտնվել"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Կառավարման տարրը հասանելի չէ"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Սխալ առաջացավ։ Նորից փորձեք։"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Ավելացնել կառավարման տարրեր"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Փոփոխել կառավարման տարրերը"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ավելացնել հավելված"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ավելացրեք մուտքագրման սարքեր"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Խումբ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Ընտրված է 1 սարք"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Բարձրախոսներ և էկրաններ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Առաջարկվող սարքեր"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Պահանջվում է պրեմիում հաշիվ"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Չհաջողվեց հեռարձակել"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Չհաջողվեց պահել։ Նորից փորձեք։"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Չհաջողվեց պահել։"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Կառուցման համարը"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Կառուցման համարը պատճենվեց սեղմատախտակին։"</string>
     <string name="basic_status" msgid="2315371112182658176">"Բաց զրույց"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Տեսախցիկն անջատված է"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Խոսափողն անջատված է"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Տեսախցիկը և խոսափողն անջատված են"</string>
+    <string name="dream_overlay_status_bar_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_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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Թույլատրել մեկանգամյա մուտքը"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Չթույլատրել"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Այն, ինչ տեղի է ունենում ձեր սարքում, գրանցվում է սարքի մատյաններում։ Հավելվածները կարող են դրանք օգտագործել անսարքությունները հայտնաբերելու և վերացնելու նպատակով։\n\nՔանի որ որոշ մատյաններ անձնական տեղեկություններ են պարունակում, խորհուրդ ենք տալիս հասանելի դարձնել ձեր սարքի բոլոր մատյանները միայն այն հավելվածներին, որոնց վստահում եք։ \n\nԵթե այս հավելվածին նման թույլտվություն չեք տվել, դրան նախկինի պես հասանելի կլինեն իր մատյանները։ Հնարավոր է՝ ձեր սարքի արտադրողին ևս հասանելի լինեն սարքի որոշ մատյաններ և տեղեկություններ։"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Իմանալ ավելին"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Իմացեք ավելին <xliff:g id="URL">%s</xliff:g> էջում"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Բացել <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Հավելվածը կարգավորված է"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Առնվազն մեկ քարտ ավելացված է Wallet-ում"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Ձեր աշխատանքային կանոնների համաձայն՝ դուք կարող եք զանգեր կատարել աշխատանքային պրոֆիլից"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Անցնել աշխատանքային պրոֆիլ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Փակել"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Կողպէկրանի կարգավորումներ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 1d0d3d6..f03dc0f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Batas bawah <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Batas kiri <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Batas kanan <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Screenshot dengan profil kerja disimpan di aplikasi <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Disimpan di <xliff:g id="APP">%1$s</xliff:g> di profil kerja"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"File"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> mendeteksi screenshot ini."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan aplikasi terbuka lainnya mendeteksi screenshot ini."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan ke catatan"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Perekam Layar"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Wajah dikenali. Tekan ikon buka kunci untuk membuka."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Kunci dibuka dengan wajah"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Wajah dikenali"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Pindah ke kiri"</item>
-    <item msgid="5558598599408514296">"Pindah ke bawah"</item>
-    <item msgid="4844142668312841831">"Pindah ke kanan"</item>
-    <item msgid="5640521437931460125">"Pindah ke atas"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Geser ke atas untuk mencoba lagi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Perangkat ini milik organisasi Anda"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Pilih aplikasi untuk menambahkan kontrol"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol ditambahkan.}other{# kontrol ditambahkan.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Jika Anda menambahkannya, <xliff:g id="APPNAME">%s</xliff:g> dapat menambahkan kontrol dan konten ke panel ini. Di beberapa aplikasi, Anda dapat memilih kontrol yang akan muncul di sini."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Difavoritkan, posisi <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Batal difavoritkan"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buka <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Putar <xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Putar <xliff:g id="SONG_NAME">%1$s</xliff:g> dari <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Untuk Anda"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Urungkan"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Dekatkan untuk memutar di <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Untuk memutar di sini, dekatkan ke <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Terjadi error. Coba lagi."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Memuat"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Nonaktif, periksa aplikasi"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol tidak tersedia"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Error, coba lagi"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Tambahkan kontrol"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Edit kontrol"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tambahkan aplikasi"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tambahkan output"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 perangkat dipilih"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Memerlukan akun premium"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat menyiarkan"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat menyimpan. Coba lagi."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat menyimpan."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nomor build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nomor versi disalin ke papan klip."</string>
     <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera nonaktif"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon nonaktif"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon nonaktif"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant sedang mendengarkan"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifikasi}other{# notifikasi}}"</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">"Pembuatan catatan"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Izinkan akses satu kali"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Jangan izinkan"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Log perangkat merekam hal-hal yang terjadi di perangkat Anda. Aplikasi dapat menggunakan log ini untuk menemukan dan memperbaiki masalah.\n\nBeberapa log mungkin berisi info sensitif, jadi hanya izinkan aplikasi yang Anda percayai untuk mengakses semua log perangkat. \n\nJika Anda tidak mengizinkan aplikasi ini mengakses semua log perangkat, aplikasi masih dapat mengakses log-nya sendiri. Produsen perangkat masih dapat mengakses beberapa log atau info di perangkat Anda."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Pelajari lebih lanjut"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Pelajari lebih lanjut di <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikasi disiapkan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Minimal satu kartu telah ditambahkan ke Wallet"</string>
@@ -1056,7 +1061,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Balik sekarang"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Bentangkan ponsel untuk selfie yang lebih baik"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Gunakan layar depan untuk selfie yang lebih baik?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Balik ke layar depan untuk selfie yang lebih bagus?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Gunakan kamera belakang untuk foto dengan resolusi lebih tinggi dan lebih lebar."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Layar ini akan dinonaktifkan"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Perangkat foldable sedang dibentangkan"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Beralih ke profil kerja"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Setelan layar kunci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index aabae2f..24c5e97 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Neðri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vinstri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Hægri mörk <xliff:g id="PERCENT">%1$d</xliff:g> prósent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Vinnuskjámyndir eru vistaðar í forritinu <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Vistað á vinnusniði í <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Skrár"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> greindi skjámyndina."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og önnur opin forrit greindu skjámyndina."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Bæta við glósu"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjáupptaka"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Andlitið var greint. Ýttu á opnunartáknið til að opna."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Opnað með andliti"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Andlitið var greint"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Færa til vinstri"</item>
-    <item msgid="5558598599408514296">"Færa niður"</item>
-    <item msgid="4844142668312841831">"Færa til hægri"</item>
-    <item msgid="5640521437931460125">"Færa upp"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Strjúktu upp til að reyna aftur"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Taktu úr lás til að nota NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Veldu forrit til að bæta við stýringum"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# stýringu bætt við.}one{# stýringu bætt við.}other{# stýringum bætt við.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Viltu bæta <xliff:g id="APPNAME">%s</xliff:g> við?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Þegar þú bætir <xliff:g id="APPNAME">%s</xliff:g> við getur það bætt stýringum og efni við þetta svæði. Í sumum forritum geturðu valið hvaða stýringar birtast hér."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Eftirlæti, staða <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjarlægt úr eftirlæti"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Opna <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spila <xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> í <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spila <xliff:g id="SONG_NAME">%1$s</xliff:g> í <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Fyrir þig"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Afturkalla"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Færðu nær til að spila í <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Farðu nær <xliff:g id="DEVICENAME">%1$s</xliff:g> til að spila hér"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Eitthvað fór úrskeiðis. Reyndu aftur."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Hleður"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"spjaldtölva"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Stýring er ekki tiltæk"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Villa, reyndu aftur"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Bæta við stýringum"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Breyta stýringum"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Bæta við forriti"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Bæta við úttaki"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Hópur"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 tæki valið"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Krefst úrvalsreiknings"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ekki hægt að senda út"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ekki hægt að vista. Reyndu aftur."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ekki hægt að vista."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Útgáfunúmer smíðar"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Útgáfunúmer smíðar afritað á klippiborð."</string>
     <string name="basic_status" msgid="2315371112182658176">"Opna samtal"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Slökkt er á myndavél"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Slökkt er á hljóðnema"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Slökkt á myndavél og hljóðnema"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Hjálparinn er að hlusta"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# tilkynning}one{# tilkynning}other{# tilkynningar}}"</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">"Glósugerð"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Leyfa aðgang í eitt skipti"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ekki leyfa"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Annálar tækisins skrá það sem gerist í tækinu. Forrit geta notað þessa annála til að finna og lagfæra vandamál.\n\nTilteknir annálar innihalda viðkvæmar upplýsingar og því skaltu einungis veita forritum sem þú treystir aðgang að öllum annálum tækisins. \n\nEf þú veitir þessu forriti ekki aðgang að öllum annálum tækisins hefur það áfram aðgang að eigin annálum. Framleiðandi tækisins getur þó hugsanlega opnað tiltekna annála eða upplýsingar í tækinu."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Nánar"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Nánar á <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Opna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Forritið er uppsett"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Að minnsta kosti einu korti var bætt við Veski"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Skipta yfir í vinnusnið"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Loka"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Stillingar fyrir lásskjá"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ced316f..bd34e74 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inferiore, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite sinistro, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite destro, <xliff:g id="PERCENT">%1$d</xliff:g> percento"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Gli screenshot acquisiti nel profilo di lavoro sono salvati nell\'app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salvato nell\'app <xliff:g id="APP">%1$s</xliff:g> nel profilo di lavoro"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"File"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha rilevato questo screenshot."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e altre app aperte hanno rilevato questo screenshot."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Aggiungi alla nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Volto riconosciuto. Premi l\'icona Sblocca per aprire."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Sbloccato con il volto"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Volto riconosciuto"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Sposta a sinistra"</item>
-    <item msgid="5558598599408514296">"Sposta giù"</item>
-    <item msgid="4844142668312841831">"Sposta a destra"</item>
-    <item msgid="5640521437931460125">"Sposta su"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Apri <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Riproduci <xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Riproduci <xliff:g id="SONG_NAME">%1$s</xliff:g> da <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Per te"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Annulla"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Avvicinati per riprodurre su <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Per riprodurre qui i contenuti, avvicinati a <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Si è verificato un errore. Riprova."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Caricamento in corso…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Trasmissione di contenuti multimediali"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Trasmissione di <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Il controllo non è disponibile"</string>
@@ -916,7 +916,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Occorre un account premium"</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>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Impossibile trasmettere"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Impossibile salvare. Riprova."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Impossibile salvare."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numero build copiato negli appunti."</string>
     <string name="basic_status" msgid="2315371112182658176">"Apri conversazione"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"La fotocamera è disattivata"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Il microfono è disattivato"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotocamera e microfono non attivi"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"L\'assistente è in ascolto"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notifica}many{# notifiche}other{# notifiche}}"</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">"Aggiunta di note"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Consenti accesso una tantum"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Non consentire"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"I log del dispositivo registrano tutto ciò che succede sul tuo dispositivo. Le app possono usare questi log per individuare problemi e correggerli.\n\nAlcuni log potrebbero contenere informazioni sensibili, quindi concedi l\'accesso a tutti i log del dispositivo soltanto alle app attendibili. \n\nSe le neghi l\'accesso a tutti i log del dispositivo, questa app può comunque accedere ai propri log. Il produttore del tuo dispositivo potrebbe essere comunque in grado di accedere ad alcuni log o informazioni sul dispositivo."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Scopri di più"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Scopri di più all\'indirizzo <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Apri <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• L\'app sia configurata"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Sia stata aggiunta almeno una carta a Wallet"</string>
@@ -1053,9 +1059,9 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annulla"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Gira ora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Apri il telefono per un selfie migliore"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Girare su display frontale per un selfie migliore?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Passare al display frontale per un selfie migliore?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Utilizza la fotocamera posteriore per una foto più ampia con maggiore risoluzione."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Questo schermo verrà disattivato"</b></string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Questo schermo verrà spento"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Dispositivo pieghevole che viene aperto"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Dispositivo pieghevole che viene capovolto"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> batteria rimanente"</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Passa a profilo di lavoro"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Chiudi"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Impostazioni schermata di blocco"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index dba7c4e..ff9e93f 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים התחתונים"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים השמאליים"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> אחוז מהשוליים הימניים"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"צילומי מסך בפרופיל העבודה נשמרים באפליקציה <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"נשמר באפליקציה <xliff:g id="APP">%1$s</xliff:g> בתוך פרופיל העבודה"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"קבצים"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> זיהתה את צילום המסך הזה."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> ואפליקציות פתוחות נוספות זיהו את צילום המסך הזה."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"הוספה לפתק"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"הפנים זוהו. יש ללחוץ על סמל ביטול הנעילה כדי לפתוח."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"הנעילה בוטלה באמצעות זיהוי הפנים"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"הפנים זוהו"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"הזזה שמאלה"</item>
-    <item msgid="5558598599408514296">"הזזה למטה"</item>
-    <item msgid="4844142668312841831">"הזזה ימינה"</item>
-    <item msgid="5640521437931460125">"הזזה למעלה"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏יש לבטל את הנעילה כדי להשתמש ב-NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"יש לבחור אפליקציה כדי להוסיף פקדים"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{נוסף אמצעי בקרה אחד (#).}one{נוספו # אמצעי בקרה.}two{נוספו # אמצעי בקרה.}other{נוספו # אמצעי בקרה.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"הוסר"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"להוסיף את <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"כשמוסיפים את האפליקציה <xliff:g id="APPNAME">%s</xliff:g>, היא תוכל להוסיף אמצעי בקרה ותוכן לחלונית הזו. חלק מהאפליקציות מאפשרות לבחור אילו אמצעי בקרה יוצגו כאן."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כמועדף, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"הוסר מהמועדפים"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"פתיחה של <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"הפעלת <xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"הפעלת <xliff:g id="SONG_NAME">%1$s</xliff:g> מ-<xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"בשבילך"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ביטול"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"צריך להתקרב כדי להפעיל מדיה במכשיר <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"כדי להפעיל במכשיר הזה, יש להתקרב אל <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"משהו השתבש. יש לנסות שוב."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"בטעינה"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"טאבלט"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"‏העברה (cast) של מדיה"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"‏מתבצעת העברה (cast) של <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"לא פעיל, יש לבדוק את האפליקציה"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"לא נמצא"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"הפקד לא זמין"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"שגיאה, יש לנסות שוב"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"הוספת פקדים"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"עריכת פקדים"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"הוספת אפליקציה"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"הוספת מכשירי פלט"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"קבוצה"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"נבחר מכשיר אחד"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"‎<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%‎‎"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"רמקולים ומסכים"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"הצעות למכשירים"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"נדרש חשבון פרימיום"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"לא ניתן לשדר"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"לא ניתן לשמור. כדאי לנסות שוב."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"לא ניתן לשמור."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"‏מספר Build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"‏מספר ה-Build הועתק ללוח."</string>
     <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"המצלמה כבויה"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"המיקרופון כבוי"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"‏Assistant מאזינה"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{התראה אחת}one{# התראות}two{# התראות}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"הרשאת גישה חד-פעמית"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"אין אישור"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ביומני המכשיר מתועדת הפעילות במכשיר. האפליקציות יכולות להשתמש ביומנים האלה כדי למצוא בעיות ולפתור אותן.\n\nהמידע בחלק מהיומנים יכול להיות רגיש, לכן יש לתת הרשאת גישה לכל היומנים של המכשיר רק לאפליקציות שסומכים עליהן. \n\nגם אם האפליקציה הזו לא תקבל הרשאת גישה לכל יומני המכשיר, היא תוכל לגשת ליומנים שלה. יכול להיות שליצרן המכשיר עדיין תהיה גישה לחלק מהיומנים או למידע במכשיר שלך."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"מידע נוסף"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"מידע נוסף זמין בכתובת <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"פתיחת <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• האפליקציה מוגדרת"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"‏• לפחות כרטיס אחד נוסף ל-Wallet"</string>
@@ -1054,7 +1057,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• יש לפחות מכשיר אחד זמין"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"מקש קיצור ללחיצה ארוכה"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ביטול"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"הפכת את המכשיר"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"אני רוצה להפוך"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"כדי לצלם תמונת סלפי טובה יותר, פותחים את הטלפון"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"להפוך למסך הקדמי כדי לצלם תמונת סלפי טובה יותר?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"במצלמה האחורית אפשר לצלם תמונה רחבה יותר ברזולוציה גבוהה יותר."</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"המדיניות של מקום העבודה מאפשרת לך לבצע שיחות טלפון רק מפרופיל העבודה"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"מעבר לפרופיל עבודה"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"סגירה"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"הגדרות מסך הנעילה"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index f88eb8b..c05e8b0 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下部の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右の境界線 <xliff:g id="PERCENT">%1$d</xliff:g> パーセント"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"仕事用のスクリーンショットは <xliff:g id="APP">%1$s</xliff:g> アプリに保存されます"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"仕事用プロファイルで <xliff:g id="APP">%1$s</xliff:g> に保存しました"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ファイル"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> がこのスクリーンショットを検出しました。"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> とその他の開いているアプリがこのスクリーンショットを検出しました。"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"メモに追加"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"スクリーン レコーダー"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"顔を認識しました。ロック解除アイコンを押して開きます。"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"顔でロック解除しました"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"顔を認識しました"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"左に移動"</item>
-    <item msgid="5558598599408514296">"下に移動"</item>
-    <item msgid="4844142668312841831">"右に移動"</item>
-    <item msgid="5640521437931460125">"上に移動"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string>
@@ -458,7 +455,7 @@
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"字幕のオーバーレイ"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"有効にする"</string>
     <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"無効にする"</string>
-    <string name="sound_settings" msgid="8874581353127418308">"サウンドとバイブレーション"</string>
+    <string name="sound_settings" msgid="8874581353127418308">"音とバイブレーション"</string>
     <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"設定"</string>
     <string name="screen_pinning_title" msgid="9058007390337841305">"アプリは固定されています"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"固定を解除するまで画面が常に表示されるようになります。[戻る] と [最近] を同時に押し続けると固定が解除されます。"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> を開く"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)を <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> を <xliff:g id="APP_LABEL">%2$s</xliff:g> で再生"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"おすすめ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"元に戻す"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>で再生するにはもっと近づけてください"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"このデバイスで再生するには、<xliff:g id="DEVICENAME">%1$s</xliff:g> にもっと近づけてください"</string>
@@ -891,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"エラーが発生しました。もう一度お試しください。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"読み込んでいます"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"タブレット"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"コントロールを使用できません"</string>
@@ -916,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"スピーカーとディスプレイ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"デバイスの候補"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"プレミアム アカウントが必要です"</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>
@@ -928,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ブロードキャストできません"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"保存できません。もう一度お試しください。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"保存できません。"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ビルド番号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ビルド番号をクリップボードにコピーしました。"</string>
     <string name="basic_status" msgid="2315371112182658176">"空の会話"</string>
@@ -1028,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"カメラは OFF です"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"マイクは OFF です"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"カメラとマイクが OFF です"</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{# 件の通知}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>
@@ -1043,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"1 回限りのアクセスを許可"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"許可しない"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"デバイスのログに、このデバイスで発生したことが記録されます。アプリは問題を検出、修正するためにこれらのログを使用することができます。\n\nログによっては機密性の高い情報が含まれている可能性があるため、すべてのデバイスログへのアクセスは信頼できるアプリにのみ許可してください。\n\nすべてのデバイスログへのアクセスを許可しなかった場合も、このアプリはアプリ独自のログにアクセスできます。また、デバイスのメーカーもデバイスの一部のログや情報にアクセスできる可能性があります。"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"詳細"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"詳しくは、<xliff:g id="URL">%s</xliff:g> をご覧ください"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> を開く"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• アプリが設定されている"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ウォーレットに追加されているカードが 1 枚以上ある"</string>
@@ -1051,7 +1059,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• 利用できるデバイスが 1 台以上ある"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ショートカットの長押しが必要です"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"キャンセル"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"切り替えましょう"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"切り替える"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"高画質で撮るにはスマートフォンを開いてください"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"前面ディスプレイに切り替えて綺麗に撮りましょう"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"高解像度で広い範囲を撮影するには、背面カメラを使用してください。"</string>
@@ -1066,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"仕事用ポリシーでは、通話の発信を仕事用プロファイルからのみに制限できます"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"仕事用プロファイルに切り替える"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"閉じる"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ロック画面の設定"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index dd4f03dc..72d0e1a 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ქვედა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"მარცხენა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"მარჯვენა ზღვარი: <xliff:g id="PERCENT">%1$d</xliff:g> პროცენტი"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"სამუშაო ეკრანის ანაბეჭდები ინახება <xliff:g id="APP">%1$s</xliff:g> აპში"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"შენახულია <xliff:g id="APP">%1$s</xliff:g>-ში სამსახურის პროფილში"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ფაილები"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა აღმოაჩინა ეკრანის ეს ანაბეჭდი"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა და სხვა გახსნილმა აპებმა აღმოაჩინეს ეკრანის ეს ანაბეჭდი."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"დაამატეთ შენიშვნა"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ეკრანის ჩამწერი"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ამოცნობილია სახით. გასახსნელად დააჭირეთ განბლოკვის ხატულას."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"განიბლოკა სახით"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"სახე ამოცნობილია"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"მარცხნივ გადატანა"</item>
-    <item msgid="5558598599408514296">"ქვემოთ გადატანა"</item>
-    <item msgid="4844142668312841831">"მარჯვნივ გადატანა"</item>
-    <item msgid="5640521437931460125">"ზემოთ გადატანა"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"განბლოკეთ NFC-ის გამოსაყენებლად"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"აირჩიეთ აპი მართვის საშუალებების დასამატებლად"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{დაემატა მართვის # საშუალება.}other{დაემატა მართვის # საშუალება.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ამოიშალა"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"გსურთ <xliff:g id="APPNAME">%s</xliff:g>-ის დამატება?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"როდესაც <xliff:g id="APPNAME">%s</xliff:g>-ს ამატებთ, მან შეიძლება დაამატოს მართვის საშუალებები და კონტენტი მოცემულ არეში. ზოგიერთ აპში შეგიძლიათ აირჩიოთ, რომელი მართვის საშუალებები უნდა გამოჩნდეს აქ."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"რჩეულებშია"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"რჩეულებშია, პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"რჩეულებიდან ამოღებულია"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"გახსენით <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"დაუკარით <xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"დაუკარით <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g>-დან"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"თქვენთვის"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"მოქმედ.გაუქმება"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"მიიტანეთ უფრო ახლოს, რომ დაუკრათ <xliff:g id="DEVICENAME">%1$s</xliff:g>-ზე"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"აქ სათამაშოდ, მიუახლოვდით <xliff:g id="DEVICENAME">%1$s</xliff:g>-ს"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"რაღაც შეცდომა მოხდა. ცადეთ ხელახლა."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"იტვირთება"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ტაბლეტი"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"მედიის ტრანსლირება"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"მიმდინარეობს <xliff:g id="APP_LABEL">%1$s</xliff:g>-ის ტრანსლირება"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"არააქტიურია, გადაამოწმეთ აპი"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ვერ მოიძებნა"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"კონტროლი მიუწვდომელია"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"შეცდომა, ისევ ცადეთ"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"მართვის საშუალებების დამატება"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"მართვის საშუალებათა რედაქტირება"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"აპის დამატება"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"მედია-გამოსავლების დამატება"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ჯგუფი"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"არჩეულია 1 მოწყობილობა"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"დინამიკები და დისპლეები"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"შემოთავაზებული მოწყობილობები"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"საჭიროა პრემიუმ-ანგარიში"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ტრანსლაცია შეუძლებელია"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"შენახვა ვერ ხერხდება. ცადეთ ხელახლა."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"შენახვა ვერ ხერხდება."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ანაწყობის ნომერი"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ანაწყობის ნომერი დაკოპირებულია გაცვლის ბუფერში."</string>
     <string name="basic_status" msgid="2315371112182658176">"მიმოწერის გახსნა"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"კამერა გამორთულია"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"მიკროფონი გამორთულია"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"კამერა და მიკროფონი გამორთულია"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ასისტენტი უსმენს"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# შეტყობინება}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ერთჯერადი წვდომის დაშვება"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"არ დაიშვას"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"მოწყობილობის ჟურნალში იწერება, რა ხდება ამ მოწყობილობაზე. აპებს შეუძლია ამ ჟურნალების გამოყენება პრობლემების აღმოსაჩენად და მოსაგვარებლად.\n\nზოგი ჟურნალი შეიძლება სენსიტიური ინფორმაციის მატარებელი იყოს, ამიტომაც მოწყობილობის ყველა ჟურნალზე წვდომა მხოლოდ სანდო აპებს მიანიჭეთ. \n\nთუ ამ აპს მოწყობილობის ყველა ჟურნალზე წვდომას არ მიანიჭებთ, მას მაინც ექნება წვდომა თქვენს ჟურნალებზე. თქვენი მოწყობილობის მწარმოებელს მაინც შეეძლება თქვენი მოწყობილობის ზოგიერთ ჟურნალსა თუ ინფორმაციაზე წვდომა."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"შეიტყვეთ მეტი"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"შეიტყვეთ მეტი აქ: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> აპის გახსნა"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• აპი დაყენებულია"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• საფულეში დამატებულია მინიმუმ ერთი ბარათი"</string>
@@ -1054,9 +1057,9 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• ხელმისაწვდომია მინიმუმ ერთი მოწყობილობა"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"შეხების დაamp; მოცდის მალსახმობი"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"გაუქმება"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"გადაატრიალეთ ახლა"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ახლა გადატრიალება"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"გაშალეთ ტელეფონი უკეთესი სელფისთვის"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"გადააბრუნეთ წინა ეკრანზე უკეთესი სელფის მისაღებად?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"გამოვიყენოთ წინა ეკრანი უკეთესი სელფის მისაღებად?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"გამოიყენეთ უკანა კამერა უფრო ფართო ფოტოს გადასაღებად მაღალი გარჩევადობით."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ეს ეკრანი გამოირთვება"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"დასაკეცი მოწყობილობა იხსნება"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"თქვენი სამსახურის წესები საშუალებას გაძლევთ, სატელეფონო ზარები განახორციელოთ მხოლოდ სამსახურის პროფილიდან"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"სამსახურის პროფილზე გადართვა"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"დახურვა"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ჩაკეტილი ეკრანის პარამეტრები"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index f4575f0..fa1af45 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Төменгі шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Сол жақ шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Оң жақ шектік сызық: <xliff:g id="PERCENT">%1$d</xliff:g> пайыз"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Жұмыс профилінен алынған скриншоттар <xliff:g id="APP">%1$s</xliff:g> қолданбасында сақталады."</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Жұмыс профиліндегі <xliff:g id="APP">%1$s</xliff:g> қолданбасында сақталған."</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасы осы скриншотты анықтады."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> және басқа да ашық қолданбалар осы скриншотты анықтады."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ескертпеге қосу"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Экран жазғыш"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Бет танылды. Ашу үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Бетпен ашылды."</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Бет танылды."</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Солға жылжыту"</item>
-    <item msgid="5558598599408514296">"Төмен жылжыту"</item>
-    <item msgid="4844142668312841831">"Оңға жылжыту"</item>
-    <item msgid="5640521437931460125">"Жоғары жылжыту"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Басқару элементтері қосылатын қолданбаны таңдаңыз"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасын қосу керек пе?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасын қосқан кезде, басқару элементтері мен контент осы панельге енгізіледі. Кейбір қолданбада басқару элементтерінің қайсысы осы жерде көрсетілетінін таңдай аласыз."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Таңдаулыларға қосылды, <xliff:g id="NUMBER">%d</xliff:g>-позиция"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Таңдаулылардан алып тасталды"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> қолданбасын ашу"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әнін ойнату"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> қолданбасында \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әнін ойнату"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Сіз үшін"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Қайтару"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысында музыка ойнату үшін оған жақындаңыз."</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Осы жерде ойнату үшін <xliff:g id="DEVICENAME">%1$s</xliff:g> құрылғысына жақындаңыз."</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Бірдеңе дұрыс болмады. Қайталап көріңіз."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Жүктеліп жатыр"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Басқару виджеті қолжетімсіз"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Қате шықты. Қайталап көріңіз."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Басқару элементтерін қосу"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Басқару элементтерін өзгерту"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Қолданба қосу"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Шығыс сигналдарды қосу"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Топ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 құрылғы таңдалды."</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер мен дисплейлер"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Ұсынылған құрылғылар"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Премиум аккаунт қажет"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Тарату мүмкін емес"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сақталмайды. Қайталап көріңіз."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сақталмайды."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Құрама нөмірі"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Құрама нөмірі буферге көшірілді."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ашық әңгіме"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера өшірулі."</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон өшірулі."</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера мен микрофон өшірулі"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant тыңдап тұр."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# хабарландыру}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Бір рет рұқсат беру"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Рұқсат бермеу"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Журналдарға құрылғыда не болып жатқаны жазылады. Қолданбалар бұл журналдарды қате тауып, түзету үшін пайдаланады.\n\nКейбір журналдарда құпия ақпарат болуы мүмкін. Сондықтан құрылғының барлық журналын пайдалану рұқсаты тек сенімді қолданбаларға берілуі керек. \n\nБұл қолданбаға құрылғының барлық журналын пайдалануға рұқсат бермесеңіз де, ол өзінің журналдарын пайдалана береді. Құрылғы өндірушісі де құрылғыдағы кейбір журналдарды немесе ақпаратты пайдалануы мүмкін."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Толық ақпарат"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Толық ақпарат: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ашу"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Қолданба реттелген"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet-ке кемінде бір карта қосылған"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жұмыс саясатыңызға сәйкес тек жұмыс профилінен қоңырау шалуға болады."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жұмыс профиліне ауысу"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабу"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Экран құлпының параметрлері"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index d5e31aa..c5545a8 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"បន្ទាត់បែងចែក​ខាងក្រោម <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"បន្ទាត់បែងចែក​ខាងឆ្វេង <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"បន្ទាត់បែងចែក​ខាងស្ដាំ <xliff:g id="PERCENT">%1$d</xliff:g> ភាគរយ"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"រូបថតអេក្រង់​ក្នុងកម្រងព័ត៌មានការងារ​ត្រូវបានរក្សាទុកនៅក្នុងកម្មវិធី <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"បានរក្សាទុកនៅក្នុង <xliff:g id="APP">%1$s</xliff:g> ក្នុងកម្រងព័ត៌មានការងារ"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ឯកសារ"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> បានរកឃើញ​រូបថតអេក្រង់នេះ។"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> និងកម្មវិធីដែលបើក​ផ្សេងទៀតបានរកឃើញ​រូបថតអេក្រង់នេះ។"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"បញ្ចូលទៅក្នុងកំណត់ចំណាំ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"មុខងារថត​វីដេអូអេក្រង់"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុង​ដំណើរការ​ការថតអេក្រង់"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹង​ដែល​កំពុង​ដំណើរការ​សម្រាប់​រយៈពេលប្រើ​ការថត​សកម្មភាព​អេក្រង់"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបើក។"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"បានដោះសោដោយប្រើមុខ"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"បានស្គាល់មុខ"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ផ្លាស់ទី​ទៅ​ឆ្វេង"</item>
-    <item msgid="5558598599408514296">"ផ្លាស់ទី​ចុះ​ក្រោម"</item>
-    <item msgid="4844142668312841831">"ផ្លាស់ទីទៅ​ស្តាំ"</item>
-    <item msgid="5640521437931460125">"ផ្លាស់ទី​ឡើង​លើ"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័ន​អ្នក"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"ជ្រើសរើស​កម្មវិធីដែលត្រូវបញ្ចូល​ផ្ទាំងគ្រប់គ្រង"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{បានបញ្ចូល​ការគ្រប់គ្រង #។}other{បានបញ្ចូល​ការគ្រប់គ្រង #។}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"បញ្ចូល <xliff:g id="APPNAME">%s</xliff:g> ឬ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"នៅពេលអ្នកបញ្ចូល <xliff:g id="APPNAME">%s</xliff:g> កម្មវិធីនេះអាចបញ្ចូលការគ្រប់គ្រង និងខ្លឹមសារទៅផ្ទាំងនេះបាន។ ក្នុងកម្មវិធីមួយចំនួន អ្នកអាចជ្រើសរើសឱ្យការគ្រប់គ្រងណាខ្លះបង្ហាញនៅទីនេះបាន។"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជា​សំណព្វ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"បានដាក់ជា​សំណព្វ ទីតាំង​ទី <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"បានដកចេញ​ពី​សំណព្វ"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"បើក <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"ចាក់ <xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"ចាក់ <xliff:g id="SONG_NAME">%1$s</xliff:g> ពី <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"សម្រាប់អ្នក"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ត្រឡប់វិញ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"រំកិលឱ្យកាន់តែជិត ដើម្បីចាក់នៅលើ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ដើម្បីចាក់នៅទីនេះ សូមខិតទៅជិត <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"មានអ្វីមួយខុសប្រក្រតី។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"កំពុងផ្ទុក"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ថេប្លេត"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើល​កម្មវិធី"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"រកមិន​ឃើញទេ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"មិនអាច​គ្រប់គ្រង​បានទេ"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"មានបញ្ហា សូម​ព្យាយាម​ម្តងទៀត"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"បញ្ចូល​ផ្ទាំងគ្រប់គ្រង"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"កែ​ផ្ទាំងគ្រប់គ្រង"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"បញ្ចូល​កម្មវិធី"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"បញ្ចូល​ឧបករណ៍​មេឌៀ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ក្រុម"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"បានជ្រើសរើស​ឧបករណ៍ 1"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ឧបករណ៍បំពងសំឡេង និងផ្ទាំងអេក្រង់"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ឧបករណ៍​ដែលបានណែនាំ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ត្រូវការគណនីលំដាប់ខ្ពស់"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"មិនអាចផ្សាយបានទេ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"មិនអាច​រក្សាទុក​បានទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"មិនអាច​រក្សាទុក​បានទេ។"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"លេខ​កំណែបង្កើត"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"បានចម្លងលេខ​កំណែបង្កើតទៅឃ្លីបបត។"</string>
     <string name="basic_status" msgid="2315371112182658176">"បើកការសន្ទនា"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"កាមេរ៉ា​ត្រូវបានបិទ"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"មីក្រូហ្វូន​ត្រូវ​បាន​បិទ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"កាមេរ៉ា និង​មីក្រូហ្វូន​ត្រូវបានបិទ"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google Assistant កំពុងស្តាប់"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{ការ​ជូន​ដំណឹង #}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"អនុញ្ញាតឱ្យចូលប្រើ​ប្រាស់តែមួយលើក"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"មិនអនុញ្ញាត"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"កំណត់ហេតុឧបករណ៍កត់ត្រាអ្វីដែលកើតឡើងនៅលើឧបករណ៍របស់អ្នក។ កម្មវិធីអាចប្រើកំណត់ហេតុទាំងនេះ ដើម្បីស្វែងរក និងដោះស្រាយបញ្ហាបាន។\n\nកំណត់ហេតុមួយចំនួនអាចមានព័ត៌មានរសើប ដូច្នេះសូមអនុញ្ញាតឱ្យចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់សម្រាប់តែកម្មវិធីដែលអ្នកទុកចិត្តប៉ុណ្ណោះ។ \n\nប្រសិនបើអ្នកមិនអនុញ្ញាតឱ្យកម្មវិធីនេះចូលប្រើកំណត់ហេតុឧបករណ៍ទាំងអស់ទេ កម្មវិធីនេះនៅតែអាចចូលប្រើកំណត់ហេតុរបស់ខ្លួនផ្ទាល់បាន។ ក្រុមហ៊ុន​ផលិត​ឧបករណ៍របស់អ្នក​ប្រហែលជា​នៅតែអាចចូលប្រើ​កំណត់ហេតុ ឬព័ត៌មានមួយចំនួន​នៅលើឧបករណ៍​របស់អ្នក​បានដដែល។"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ស្វែងយល់បន្ថែម"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"ស្វែងយល់​បន្ថែម​តាមរយៈ <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"បើក <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• កម្មវិធីត្រូវបានរៀបចំ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• កាតយ៉ាងតិចមួយត្រូវបានបញ្ចូលទៅក្នុង Wallet"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"គោលការណ៍ការងាររបស់អ្នកអនុញ្ញាតឱ្យអ្នកធ្វើការហៅទូរសព្ទបានតែពីកម្រងព័ត៌មានការងារប៉ុណ្ណោះ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ប្ដូរ​ទៅ​កម្រង​ព័ត៌មាន​ការងារ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"បិទ"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ការកំណត់​អេក្រង់ចាក់សោ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 687fa28..d468e6e 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ಕೆಳಗಿನ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ಎಡಭಾಗದ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ಬಲಭಾಗದ ಬೌಂಡರಿ ಶೇಕಡಾ <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"<xliff:g id="APP">%1$s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ಉಳಿಸಲಾದ ಕೆಲಸದ ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳು"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್‌ನಲ್ಲಿನ <xliff:g id="APP">%1$s</xliff:g> ನಲ್ಲಿ ಉಳಿಸಲಾಗಿದೆ"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ಫೈಲ್‌ಗಳು"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"ಈ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು <xliff:g id="APPNAME">%1$s</xliff:g> ಪತ್ತೆಹಚ್ಚಿದೆ."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ಹಾಗೂ ತೆರೆದಿರುವ ಇತರ ಆ್ಯಪ್‌ಗಳು ಈ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚಿವೆ."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ಟಿಪ್ಪಣಿಗೆ ಸೇರಿಸಿ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ತೆರೆಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ಮುಖದ ಮೂಲಕ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ಎಡಕ್ಕೆ ಸರಿಸಿ"</item>
-    <item msgid="5558598599408514296">"ಕೆಳಗೆ ಸರಿಸಿ"</item>
-    <item msgid="4844142668312841831">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</item>
-    <item msgid="5640521437931460125">"ಮೇಲಕ್ಕೆ ಸರಿಸಿ"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ನಿಯಂತ್ರಣವನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}one{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}other{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ಅನ್ನು ಸೇರಿಸಬೇಕೆ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"ನೀವು <xliff:g id="APPNAME">%s</xliff:g> ಅನ್ನು ಸೇರಿಸಿದಾಗ, ಅದು ಈ ಪ್ಯಾನೆಲ್‌ಗೆ ನಿಯಂತ್ರಣಗಳು ಮತ್ತು ವಿಷಯವನ್ನು ಸೇರಿಸಬಹುದು. ಕೆಲವು ಆ್ಯಪ್‌ಗಳಲ್ಲಿ, ಇಲ್ಲಿ ಯಾವ ನಿಯಂತ್ರಣಗಳು ಕಾಣಿಸಬೇಕು ಎಂಬುದನ್ನು ನೀವು ಆಯ್ಕೆಮಾಡಬಹುದು."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ಮೆಚ್ಚಲಾಗಿರುವುದು"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ಮೆಚ್ಚಲಾಗಿರುವುದು, ಸ್ಥಾನ <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ಮೆಚ್ಚಿನದಲ್ಲದ್ದು"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%2$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ನಿಮಗಾಗಿ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು ಅದರ ಹತ್ತಿರಕ್ಕೆ ಸರಿಯಿರಿ"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ಇಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲು, <xliff:g id="DEVICENAME">%1$s</xliff:g> ಸಮೀಪಕ್ಕೆ ಸರಿಯಿರಿ"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ಏನೋ ತಪ್ಪಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ಲೋಡ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ಟ್ಯಾಬ್ಲೆಟ್"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ನಿಮ್ಮ ಮಾಧ್ಯಮವನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ಅನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ನಿಷ್ಕ್ರಿಯ, ಆ್ಯಪ್ ಪರಿಶೀಲಿಸಿ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ಕಂಡುಬಂದಿಲ್ಲ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ನಿಯಂತ್ರಣ ಲಭ್ಯವಿಲ್ಲ"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"ದೋಷ, ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಿ"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"ನಿಯಂತ್ರಣಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ಆ್ಯಪ್ ಅನ್ನು ಸೇರಿಸಿ"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ಔಟ್‌ಪುಟ್‌ಗಳನ್ನು ಸೇರಿಸಿ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ಗುಂಪು"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ಸಾಧನವನ್ನು ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ಸ್ಪೀಕರ್‌ಗಳು ಮತ್ತು ಡಿಸ್‌ಪ್ಲೇಗಳು"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ಸೂಚಿಸಿದ ಸಾಧನಗಳು"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ಪ್ರೀಮಿಯಂ ಖಾತೆಯ ಅಗತ್ಯವಿದೆ"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ಪ್ರಸಾರ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ಬಿಲ್ಡ್ ಸಂಖ್ಯೆಯನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ನಲ್ಲಿ ನಕಲಿಸಲಾಗಿದೆ."</string>
     <string name="basic_status" msgid="2315371112182658176">"ಸಂಭಾಷಣೆಯನ್ನು ತೆರೆಯಿರಿ"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ಕ್ಯಾಮರಾ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="dream_overlay_status_bar_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_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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ಒಂದು ಬಾರಿಯ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ಅನುಮತಿಸಬೇಡಿ"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸಾಧನದ ಲಾಗ್‌ಗಳು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತವೆ. ಸಮಸ್ಯೆಗಳನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಮತ್ತು ಪರಿಹರಿಸಲು ಆ್ಯಪ್‌ಗಳು ಈ ಲಾಗ್ ಅನ್ನು ಬಳಸಬಹುದು.\n\nಕೆಲವು ಲಾಗ್‌ಗಳು ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು, ಆದ್ದರಿಂದ ನಿಮ್ಮ ವಿಶ್ವಾಸಾರ್ಹ ಆ್ಯಪ್‌ಗಳಿಗೆ ಮಾತ್ರ ಸಾಧನದ ಎಲ್ಲಾ ಲಾಗ್‌ಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಿ. \n\nಎಲ್ಲಾ ಸಾಧನ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನೀವು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸದಿದ್ದರೆ, ಅದು ಆಗಲೂ ತನ್ನದೇ ಆದ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ನಿಮ್ಮ ಸಾಧನ ತಯಾರಕರಿಗೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿನ ಕೆಲವು ಲಾಗ್‌ಗಳು ಅಥವಾ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು ಈಗಲೂ ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> ನಲ್ಲಿ ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ಆ್ಯಪ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ವಾಲೆಟ್‌ಗೆ ಕನಿಷ್ಠ ಒಂದು ಕಾರ್ಡ್ ಅನ್ನು ಸೇರಿಸಲಾಗಿದೆ"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ನಿಮ್ಮ ಕೆಲಸದ ನೀತಿಯು ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ನಿಂದ ಮಾತ್ರ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ಮುಚ್ಚಿರಿ"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 3631973..864bfda 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"하단 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"왼쪽 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"오른쪽 가장자리 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"직장 프로필의 스크린샷은 <xliff:g id="APP">%1$s</xliff:g> 앱에 저장됩니다."</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"직장 프로필의 <xliff:g id="APP">%1$s</xliff:g>에 저장되었습니다."</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"파일"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>에서 이 스크린샷을 감지했습니다."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 및 기타 공개 앱에서 이 스크린샷을 감지했습니다."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"메모에 추가"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"화면 녹화"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"얼굴이 인식되었습니다. 열려면 잠금 해제 아이콘을 누르세요."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"얼굴 인식으로 잠금 해제되었습니다."</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"얼굴이 인식되었습니다."</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"왼쪽으로 이동"</item>
-    <item msgid="5558598599408514296">"아래로 이동"</item>
-    <item msgid="4844142668312841831">"오른쪽으로 이동"</item>
-    <item msgid="5640521437931460125">"위로 이동"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"컨트롤을 추가할 앱을 선택하세요"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{설정이 #개 추가되었습니다.}other{설정이 #개 추가되었습니다.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>을(를) 추가할까요?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> 앱을 추가하면 이 패널에 컨트롤과 콘텐츠가 추가됩니다. 일부 앱에서는 여기 표시되는 컨트롤을 선택할 수 있습니다."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"즐겨찾기에 추가됨, 위치 <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"즐겨찾기에서 삭제됨"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> 열기"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>에서 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"추천"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"실행취소"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>에서 재생하려면 기기를 더 가까이로 옮기세요."</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"여기에서 재생하려면 <xliff:g id="DEVICENAME">%1$s</xliff:g>에 더 가까이 이동하세요."</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"문제가 발생했습니다. 다시 시도해 주세요."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"로드 중"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"태블릿"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"미디어 전송"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> 전송 중"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"컨트롤을 사용할 수 없음"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"오류. 다시 시도하세요."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"컨트롤 추가"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"컨트롤 수정"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"앱 추가"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"출력 추가"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"그룹"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"기기 1대 선택됨"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"스피커 및 디스플레이"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"추천 기기"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"프리미엄 계정 필요"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"방송할 수 없음"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"저장할 수 없습니다. 다시 시도해 주세요."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"저장할 수 없습니다."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"빌드 번호"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"빌드 번호가 클립보드에 복사되었습니다."</string>
     <string name="basic_status" msgid="2315371112182658176">"대화 열기"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"카메라 꺼짐"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"마이크 꺼짐"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"카메라 및 마이크가 사용 중지되었습니다."</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"어시스턴트가 대기 중입니다."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{알림 #개}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"일회성 액세스 허용"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"허용 안함"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"기기 로그에 기기에서 발생한 상황이 기록됩니다. 앱은 문제를 찾고 해결하는 데 이 로그를 사용할 수 있습니다.\n\n일부 로그는 민감한 정보를 포함할 수 있으므로 신뢰할 수 있는 앱만 모든 기기 로그에 액세스하도록 허용하세요. \n\n앱에 전체 기기 로그에 대한 액세스 권한을 부여하지 않아도 앱이 자체 로그에는 액세스할 수 있습니다. 기기 제조업체에서 일부 로그 또는 기기 내 정보에 액세스할 수도 있습니다."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"자세히 알아보기"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>에서 자세히 알아보기"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> 열기"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 앱이 설정되어 있습니다."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 1개 이상의 카드가 월렛에 추가되어 있습니다."</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"직장 정책이 직장 프로필에서만 전화를 걸도록 허용합니다."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"직장 프로필로 전환"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"닫기"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"잠금 화면 설정"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index f5b4a26..63e4151 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ылдый жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Сол жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Оң жагы <xliff:g id="PERCENT">%1$d</xliff:g> пайызга"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Жумуш скриншоттору <xliff:g id="APP">%1$s</xliff:g> колдонмосунда сакталат"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Жумуш профилиндеги <xliff:g id="APP">%1$s</xliff:g> колдонмосуна сакталды"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ушул скриншотту аныктады."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> жана ачылып турган башка колдонмолор ушул скриншотту аныктады."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Кыска жазууга кошуу"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Жүз таанылды. Эми кулпуну ачуу сүрөтчөсүн басыңыз."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Түзмөгүңүздү жүзүңүз менен ачтыңыз"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Жүз таанылды"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Солго жылдыруу"</item>
-    <item msgid="5558598599408514296">"Төмөн жылдыруу"</item>
-    <item msgid="4844142668312841831">"Оңго жылдыруу"</item>
-    <item msgid="5640521437931460125">"Жогору жылдыруу"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Кайталоо үчүн экранды өйдө сүрүңүз"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC колдонуу үчүн түзмөктүн кулпусун ачыңыз"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Башкаруу элементтери кошула турган колдонмону тандоо"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# көзөмөл кошулду.}other{# көзөмөл кошулду.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> кошулсунбу?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> колдонмосун кошсоңуз, ал бул панелге башкаруу элементтерин жана контентти кошо алат. Айрым колдонмолордо бул жерде көрүнүүчү башкаруу элементтерин тандай аласыз."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Сүйүктүүлөргө <xliff:g id="NUMBER">%d</xliff:g>-позицияга кошулду"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Сүйүктүүлөрдөн чыгарылды"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> колдонмосун ачуу"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ырын (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотуу"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ырын <xliff:g id="APP_LABEL">%2$s</xliff:g> колдонмосунан ойнотуу"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Сизге"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Кайтаруу"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүндө ойнотуу үчүн жакындатыңыз"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ушул жерде ойнотуу үчүн <xliff:g id="DEVICENAME">%1$s</xliff:g> түзмөгүнө жакындаңыз"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Бир жерден ката кетти. Кайра аракет кылыңыз."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Жүктөлүүдө"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Медиа тышкы экранга чыгарылууда"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> түзмөгүнө чыгарылууда"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Жигерсиз. Колдонмону текшериңиз"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Табылган жок"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Башкара албайсыз"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Ката, кайталап көрүңүз"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Башкаруу элементтерин кошуу"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Башкаруу элементтерин түзөтүү"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Колдонмо кошуу"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Медиа түзмөктөрдү кошуу"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Топ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 түзмөк тандалды"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Динамиктер жана дисплейлер"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Сунушталган түзмөктөр"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Премиум аккаунт талап кылынат"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Кабарлоого болбойт"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Сакталган жок. Кайталап көрүңүз."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Сакталган жок."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Курама номери"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Курама номери алмашуу буферине көчүрүлдү."</string>
     <string name="basic_status" msgid="2315371112182658176">"Ачык сүйлөшүү"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера өчүк"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон өчүк"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера жана микрофон өчүк"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Жардамчы угуп жатат"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# билдирме}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Бир жолу жеткиликтүү кылуу"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Тыюу салуу"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Түзмөктө аткарылган бардык аракеттер түзмөктүн таржымалдарында сакталып калат. Колдонмолор бул таржымалдарды колдонуп, маселелерди оңдошот.\n\nАйрым таржымалдарда купуя маалымат болушу мүмкүн, андыктан ишенимдүү колдонмолорго гана түзмөктөгү бардык таржымалдарды пайдаланууга уруксат бериңиз. \n\nЭгер бул колдонмого түзмөктөгү бардык таржымалдарга кирүүгө тыюу салсаңыз, ал өзүнүн таржымалдарын пайдалана берет. Түзмөктү өндүрүүчү түзмөгүңүздөгү айрым таржымалдарды же маалыматты көрө берет."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Кеңири маалымат"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Кеңири маалымат: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ачуу"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Колдонмо туураланды"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Капчыкка кеминде бир карта кошулду"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Жумуш саясатыңызга ылайык, жумуш профилинен гана чалууларды аткара аласыз"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Жумуш профилине которулуу"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Жабуу"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Кулпуланган экран параметрлери"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index fff2544..ac81dcc 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -64,4 +64,6 @@
 
     <dimen name="qs_panel_padding_top">@dimen/qqs_layout_margin_top</dimen>
     <dimen name="qs_panel_padding_top_combined_headers">@dimen/qs_panel_padding_top</dimen>
+
+    <dimen name="controls_padding_horizontal">16dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 8754166..43caaeb 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ຂອບເຂດທາງລຸ່ມ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ຂອບເຂດທາງຊ້າຍ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ຂອບເຂດທາງຂວາ <xliff:g id="PERCENT">%1$d</xliff:g> ເປີເຊັນ"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ຮູບໜ້າຈໍວຽກຖືກບັນທຶກຢູ່ໃນແອັບ <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ບັນທຶກໃນ <xliff:g id="APP">%1$s</xliff:g> ໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກແລ້ວ"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ໄຟລ໌"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ກວດພົບຮູບໜ້າຈໍນີ້."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ແລະ ແອັບອື່ນໆທີ່ເປີດຢູ່ກວດພົບຮູບໜ້າຈໍນີ້."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ເພີ່ມໃສ່ບັນທຶກ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອເປີດ."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ປົດລັອກດ້ວຍໃບໜ້າແລ້ວ"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ຈຳແນກໜ້າໄດ້ແລ້ວ"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ຍ້າຍໄປຊ້າຍ"</item>
-    <item msgid="5558598599408514296">"ຍ້າຍລົງ"</item>
-    <item msgid="4844142668312841831">"ຍ້າຍໄປຂວາ"</item>
-    <item msgid="5640521437931460125">"ຍ້າຍຂຶ້ນ"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ປົດລັອກເພື່ອໃຊ້ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"ເລືອກແອັບເພື່ອເພີ່ມການຄວບຄຸມ"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}other{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ລຶບອອກແລ້ວ"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"ເພີ່ມ <xliff:g id="APPNAME">%s</xliff:g> ບໍ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"ເມື່ອທ່ານເພີ່ມ <xliff:g id="APPNAME">%s</xliff:g>, ມັນຈະສາມາດເພີ່ມການຄວບຄຸມ ແລະ ເນື້ອຫາໃສ່ແຜງນີ້ໄດ້. ໃນບາງແອັບ, ທ່ານສາມາດເລືອກວ່າຈະໃຫ້ສ່ວນຄວບຄຸມໃດສະແດງຂຶ້ນຢູ່ບ່ອນນີ້ໄດ້."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ, ຕຳແໜ່ງ <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ຍົກເລີກລາຍການທີ່ມັກແລ້ວ"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"ເປີດ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"ຫຼິ້ນ <xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"ຫຼິ້ນ <xliff:g id="SONG_NAME">%1$s</xliff:g> ຈາກ <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ສຳລັບທ່ານ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ຍົກເລີກ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ຍ້າຍໄປໃກ້ຂຶ້ນເພື່ອຫຼິ້ນຢູ່ <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ເພື່ອຫຼິ້ນຢູ່ບ່ອນນີ້, ໃຫ້ເຂົ້າໃກ້ <xliff:g id="DEVICENAME">%1$s</xliff:g> ຫຼາຍຂຶ້ນ"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນ. ກະລຸນາລອງໃໝ່."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ກຳລັງໂຫຼດ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ແທັບເລັດ"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"ການ​ກຳ​ນົດ​ບົດ​ບາດ​ສື່​ຂອງ​ທ່ານ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"ການ​ກຳ​ນົດ​ບົດ​ບາດ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ບໍ່ເຮັດວຽກ, ກະລຸນາກວດສອບແອັບ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ບໍ່ພົບ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ບໍ່ສາມາດໃຊ້ການຄວບຄຸມໄດ້"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"​ຜິດ​ພາດ​, ກະລຸນາລອງໃໝ່"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"ເພີ່ມການຄວບຄຸມ"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"ແກ້ໄຂການຄວບຄຸມ"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ເພີ່ມແອັບ"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ເພີ່ມເອົ້າພຸດ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ກຸ່ມ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"ເລືອກ 1 ອຸປະກອນແລ້ວ"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ລຳໂພງ ແລະ ຈໍສະແດງຜົນ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ອຸປະກອນທີ່ແນະນຳ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ຕ້ອງໃຊ້ບັນຊີພຣີມຽມ"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ບໍ່ສາມາດອອກອາກາດໄດ້"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ບໍ່ສາມາດບັນທຶກໄດ້. ກະລຸນາລອງໃໝ່."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ບໍ່ສາມາດບັນທຶກໄດ້."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ໝາຍເລກສ້າງ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ສຳເນົາໝາຍເລກສ້າງໄປໃສ່ຄລິບບອດແລ້ວ."</string>
     <string name="basic_status" msgid="2315371112182658176">"ເປີດການສົນທະນາ"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ກ້ອງປິດຢູ່"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ໄມປິດຢູ່"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ປິດກ້ອງຖ່າຍຮູບ ແລະ ໄມແລ້ວ"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"ຜູ້ຊ່ວຍກຳລັງຟັງ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ການແຈ້ງເຕືອນ}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ອະນຸຍາດສິດເຂົ້າເຖິງແບບເທື່ອດຽວ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ບໍ່ອະນຸຍາດ"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ບັນທຶກຂອງອຸປະກອນຈະບັນທຶກສິ່ງທີ່ເກີດຂຶ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ແອັບສາມາດໃຊ້ບັນທຶກເຫຼົ່ານີ້ເພື່ອຊອກຫາ ແລະ ແກ້ໄຂບັນຫາໄດ້.\n\nບັນທຶກບາງຢ່າງອາດມີຂໍ້ມູນທີ່ລະອຽດອ່ອນ, ດັ່ງນັ້ນໃຫ້ອະນຸຍາດສະເພາະແອັບທີ່ທ່ານເຊື່ອຖືໄດ້ໃຫ້ເຂົ້າເຖິງບັນທຶກທັງໝົດຂອງອຸປະກອນເທົ່ານັ້ນ. \n\nຫາກທ່ານບໍ່ອະນຸຍາດໃຫ້ແອັບນີ້ເຂົ້າເຖິງບັນທຶກທັງໝົດຂອງອຸປະກອນ, ມັນຈະຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກຂອງຕົວມັນເອງໄດ້ຢູ່. ຜູ້ຜະລິດອຸປະກອນຂອງທ່ານອາດຍັງຄົງສາມາດເຂົ້າເຖິງບັນທຶກ ຫຼື ຂໍ້ມູນບາງຢ່າງຢູ່ອຸປະກອນຂອງທ່ານໄດ້."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ສຶກສາເພີ່ມເຕີມ"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"ສຶກສາເພີ່ມເຕີມຢູ່ <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"ເປີດ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ແອັບໄດ້ຮັບການຕັ້ງຄ່າແລ້ວ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ມີການເພີ່ມຢ່າງໜ້ອຍ 1 ບັດໃສ່ໃນ Wallet"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ນະໂຍບາຍບ່ອນເຮັດວຽກຂອງທ່ານອະນຸຍາດໃຫ້ທ່ານໂທລະສັບໄດ້ຈາກໂປຣໄຟລ໌ບ່ອນເຮັດວຽກເທົ່ານັ້ນ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ສະຫຼັບໄປໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ປິດ"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ການຕັ້ງຄ່າໜ້າຈໍລັອກ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index d42fc7a..a24eb50 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Apatinė riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kairioji riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Dešinioji riba – <xliff:g id="PERCENT">%1$d</xliff:g> proc."</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ekrano kopijos, užfiksuotos naudojantis darbo profiliu, išsaugomos programoje „<xliff:g id="APP">%1$s</xliff:g>“"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Išsaugota programoje „<xliff:g id="APP">%1$s</xliff:g>“ darbo profilyje"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Failai"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ aptiko šią ekrano kopiją."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ ir kitos atidarytos programos aptiko šią ekrano kopiją."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridėti prie užrašo"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrano vaizdo įrašytuvas"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Veidas atpažintas. Atidarykite paspaudę atrakin. piktogramą."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Atrakinta pagal veidą"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Veidas atpažintas"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Perkelti kairėn"</item>
-    <item msgid="5558598599408514296">"Perkelti žemyn"</item>
-    <item msgid="4844142668312841831">"Perkelti dešinėn"</item>
-    <item msgid="5640521437931460125">"Perkelti aukštyn"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Atidaryti „<xliff:g id="APP_LABEL">%1$s</xliff:g>“"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Leisti <xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Leisti „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ iš „<xliff:g id="APP_LABEL">%2$s</xliff:g>“"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Jums"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Anuliuoti"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Prieikite arčiau, kad galėtumėte leisti įrenginyje „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Jei norite leisti čia, eikite arčiau įrenginio „<xliff:g id="DEVICENAME">%1$s</xliff:g>“"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Kažkas ne taip. Bandykite dar kartą."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Įkeliama"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planšetinis kompiuteris"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Perduodama medija"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Perduodama programa „<xliff:g id="APP_LABEL">%1$s</xliff:g>“"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktyvu, patikrinkite progr."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nerasta"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Valdiklis nepasiekiamas"</string>
@@ -916,7 +916,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Reikalinga mokama paskyra"</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>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nepavyko transliuoti"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nepavyko išsaugoti. Bandykite dar kartą."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nepavyko išsaugoti."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijos numeris"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijos numeris nukopijuotas į iškarpinę."</string>
     <string name="basic_status" msgid="2315371112182658176">"Atidaryti pokalbį"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Fotoaparatas išjungtas"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofonas išjungtas"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Vaizdo kamera ir mikrofonas išjungti"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Padėjėjas klausosi"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pranešimas}one{# pranešimas}few{# pranešimai}many{# pranešimo}other{# pranešimų}}"</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">"Užrašų kūrimas"</string>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Leisti vienkartinę prieigą"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Neleisti"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Įrenginio žurnaluose įrašoma, kas įvyksta įrenginyje. Programos gali naudoti šiuos žurnalus, kai reikia surasti ir išspręsti problemas.\n\nKai kuriuose žurnaluose gali būti neskelbtinos informacijos, todėl visus įrenginio žurnalus leiskite pasiekti tik programoms, kuriomis pasitikite. \n\nJei neleisite šiai programai pasiekti visų įrenginio žurnalų, ji vis tiek galės pasiekti savo žurnalus. Įrenginio gamintojui vis tiek gali būti leidžiama pasiekti tam tikrus žurnalus ar informaciją jūsų įrenginyje."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Sužinokite daugiau"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Sužinokite daugiau adresu <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atidaryti „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Programa nustatyta"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Prie „Wallet“ pridėta bent viena kortelė"</string>
@@ -1066,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Perjungti į darbo profilį"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Uždaryti"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Užrakinimo ekrano nustatymai"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index d01cab9..f1486c4 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Apakšmala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kreisā mala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Labā mala: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Darba profila ekrānuzņēmumi tiek saglabāti lietotnē <xliff:g id="APP">%1$s</xliff:g>."</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Saglabāts lietotnē <xliff:g id="APP">%1$s</xliff:g> darba profilā"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Faili"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> konstatēja, ka tika veikts ekrānuzņēmums."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> un citas atvērtas lietotnes konstatēja, ka tika veikts ekrānuzņēmums."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pievienot piezīmei"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrāna ierakstītājs"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Seja atpazīta. Lai atvērtu, nospiediet atbloķēšanas ikonu."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Ierīce atbloķēta pēc sejas"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Seja atpazīta"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Pārvietojiet pirkstu pa kreisi"</item>
-    <item msgid="5558598599408514296">"Pārvietojiet pirkstu lejup"</item>
-    <item msgid="4844142668312841831">"Pārvietojiet pirkstu pa labi"</item>
-    <item msgid="5640521437931460125">"Pārvietojiet pirkstu augšup"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Izvēlieties lietotni, lai pievienotu vadīklas"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pievienota # vadīkla.}zero{Pievienotas # vadīklas.}one{Pievienota # vadīkla.}other{Pievienotas # vadīklas.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Noņemta"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vai pievienot lietotni <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Ja pievienosiet lietotni <xliff:g id="APPNAME">%s</xliff:g>, tā varēs pievienot vadīklas un saturu šim panelim. Dažās lietotnēs varat izvēlēties, kuras vadīklas šeit rādīt."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pievienota izlasei"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pievienota izlasei, <xliff:g id="NUMBER">%d</xliff:g>. pozīcija"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Noņemta no izlases"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Atveriet lietotni <xliff:g id="APP_LABEL">%1$s</xliff:g>."</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Atskaņojiet failu “<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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Atskaņojiet failu “<xliff:g id="SONG_NAME">%1$s</xliff:g>” no lietotnes <xliff:g id="APP_LABEL">%2$s</xliff:g>."</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Tieši jums"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Atsaukt"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Pārvietojiet savu ierīci tuvāk, lai atskaņotu mūziku ierīcē “<xliff:g id="DEVICENAME">%1$s</xliff:g>”."</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Lai atskaņotu šeit, jums jāatrodas tuvāk šai ierīcei: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Radās kļūda. Mēģiniet vēlreiz."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Notiek ielāde"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planšetdators"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktīva, pārbaudiet lietotni"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Netika atrasta"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Vadīkla nav pieejama"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Radās kļūda. Mēģiniet vēlreiz."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Pievienot vadīklas"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Rediģēt vadīklas"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Pievienot lietotni"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Izejas ierīču pievienošana"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Atlasīta viena ierīce"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nepieciešams maksas konts"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nevar apraidīt"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nevar saglabāt. Mēģiniet vēlreiz."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nevar saglabāt."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versijas numurs"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versijas numurs ir kopēts starpliktuvē."</string>
     <string name="basic_status" msgid="2315371112182658176">"Atvērt sarunu"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera ir izslēgta"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofons ir izslēgts"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera un mikrofons ir izslēgti"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistents klausās"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# paziņojums}zero{# paziņojumu}one{# paziņojums}other{# paziņojumi}}"</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">"Piezīmju pierakstīšana"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Atļaut vienreizēju piekļuvi"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Neatļaut"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Ierīces žurnālos tiek reģistrēti ierīces procesi un notikumi. Lietotņu izstrādātāji var izmantot šos žurnālus, lai atrastu un novērstu problēmas savās lietotnēs.\n\nDažos žurnālos var būt ietverta sensitīva informācija, tāpēc atļaujiet tikai uzticamām lietotnēm piekļūt visiem ierīces žurnāliem. \n\nJa neatļausiet šai lietotnei piekļūt visiem ierīces žurnāliem, lietotnes izstrādātājs joprojām varēs piekļūt pašas lietotnes žurnāliem. Iespējams, ierīces ražotājs joprojām varēs piekļūt noteiktiem žurnāliem vai informācijai jūsu ierīcē."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Uzzināt vairāk"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Uzziniet vairāk vietnē <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atvērt lietotni <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Lietotne ir iestatīta."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Makam ir pievienota vismaz viena karte."</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Pārslēgties uz darba profilu"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Aizvērt"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Bloķēšanas ekrāna iestatījumi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index f8e0151..9bec87f 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Долна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна граница <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Сликите од екранот во работниот профил се зачувуваат во апликацијата <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Зачувано во <xliff:g id="APP">%1$s</xliff:g> во работниот профил"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Датотеки"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ја откри оваа слика од екранот."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени апликации ја открија оваа слика од екранот."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај во белешка"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лицето е препознаено. Притиснете ја иконата за отклучување за да отворите."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Отклучено со лице"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Лицето е препознаено"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Премести налево"</item>
-    <item msgid="5558598599408514296">"Премести надолу"</item>
-    <item msgid="4844142668312841831">"Премести надесно"</item>
-    <item msgid="5640521437931460125">"Премести нагоре"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворете <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пуштете <xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пуштете <xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"За вас"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Врати"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближете се за да пуштите на <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"За да пуштате овде, приближете се до <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Нешто не е во ред. Обидете се повторно."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Се вчитува"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивна, провери апликација"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не е најдено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контролата не е достапна"</string>
@@ -916,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уреди"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Потребна е премиум сметка"</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>
@@ -928,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не може да се емитува"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не може да се зачува. Обидете се повторно."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не може да се зачува."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број на верзија"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Бројот на верзијата е копиран во привремената меморија."</string>
     <string name="basic_status" msgid="2315371112182658176">"Започни разговор"</string>
@@ -1028,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камерата е исклучена"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофонот е исклучен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камерата и микрофонот се исклучени"</string>
+    <string name="dream_overlay_status_bar_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_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>
@@ -1043,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Дозволи еднократен пристап"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дозволувај"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Дневниците за евиденција на уредот снимаат што се случува на вашиот уред. Апликациите може да ги користат овие дневници за евиденција за да наоѓаат и поправаат проблеми.\n\nНекои дневници за евиденција може да содржат чувствителни податоци, па затоа дозволете им пристап до сите дневници за евиденција на уредот само на апликациите во кои имате доверба. \n\nАко не ѝ дозволите на апликацијава да пристапува до сите дневници за евиденција на уредот, таа сепак ќе може да пристапува до сопствените дневници за евиденција. Производителот на вашиот уред можеби сепак ќе може да пристапува до некои дневници за евиденција или податоци на уредот."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Дознајте повеќе"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Дознајте повеќе на <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворете ја <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• апликацијата е поставена"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• најмалку една картичка е додадена во Wallet"</string>
@@ -1066,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Вашето работно правило ви дозволува да упатувате повици само од работниот профил"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Префрли се на работен профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Поставки за заклучен екран"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 96ebfd0..e388d6a 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"താഴെയുള്ള അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ഇടത് വശത്തെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"വലത് വശത്തെ അതിർത്തി <xliff:g id="PERCENT">%1$d</xliff:g> ശതമാനം"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ഔദ്യോഗിക പ്രൊഫൈലിന്റെ സ്ക്രീന്‍ഷോട്ടുകൾ <xliff:g id="APP">%1$s</xliff:g> ആപ്പിൽ സംരക്ഷിച്ചു"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ഔദ്യോഗിക പ്രൊഫൈലിൽ <xliff:g id="APP">%1$s</xliff:g> ആപ്പിൽ സംരക്ഷിച്ചു"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ഫയലുകൾ"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്ന ആപ്പും തുറന്നിരിക്കുന്ന മറ്റ് ആപ്പും ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"കുറിപ്പിലേക്ക് ചേർക്കുക"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"സ്ക്രീൻ റെക്കോർഡർ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"മുഖം തിരിച്ചറിഞ്ഞു. തുറക്കാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"മുഖം തിരിച്ചറിഞ്ഞു"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ഇടത്തേക്ക് നീക്കുക"</item>
-    <item msgid="5558598599408514296">"താഴേക്ക് നീക്കുക"</item>
-    <item msgid="4844142668312841831">"വലത്തേക്ക് നീക്കുക"</item>
-    <item msgid="5640521437931460125">"മുകളിലേക്ക് നീക്കുക"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"നിയന്ത്രണങ്ങൾ ചേർക്കാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# നിയന്ത്രണം ചേർത്തു.}other{# നിയന്ത്രണങ്ങൾ ചേർത്തു.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"നീക്കം ചെയ്‌തു"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ചേർക്കണോ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"നിങ്ങൾ <xliff:g id="APPNAME">%s</xliff:g> ചേർത്താൽ, അതിന് ഈ പാനലിലേക്ക് നിയന്ത്രണങ്ങളും ഉള്ളടക്കവും ചേർക്കാനാകും. ചില ആപ്പുകളിൽ, ഇവിടെ ഏത് നിയന്ത്രണങ്ങൾ ദൃശ്യമാകണമെന്ന് നിങ്ങൾക്ക് തിരഞ്ഞെടുക്കാനാകും."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"പ്രിയപ്പെട്ടതാക്കി"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"പ്രിയപ്പെട്ടതാക്കി, സ്ഥാനം <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"പ്രിയപ്പെട്ടതല്ലാതാക്കി"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> തുറക്കുക"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%2$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുക"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"നിങ്ങൾക്കുള്ളവ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"പഴയപടിയാക്കുക"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിൽ പ്ലേ ചെയ്യാൻ അടുത്തേക്ക് നീക്കുക"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ഇവിടെ പ്ലേ ചെയ്യാൻ <xliff:g id="DEVICENAME">%1$s</xliff:g> എന്നതിനടുത്തേക്ക് നീക്കുക"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"എന്തോ കുഴപ്പമുണ്ടായി. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ലോഡ് ചെയ്യുന്നു"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ടാബ്‌ലെറ്റ്"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"നിങ്ങളുടെ മീഡിയ കാസ്റ്റ് ചെയ്യുന്നു"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> കാസ്‌റ്റ് ചെയ്യുന്നു"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"നിഷ്‌ക്രിയം, ആപ്പ് പരിശോധിക്കൂ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"കണ്ടെത്തിയില്ല"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"നിയന്ത്രണം ലഭ്യമല്ല"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"പിശക്, വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"നിയന്ത്രണങ്ങൾ ചേർക്കുക"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"നിയന്ത്രണങ്ങൾ എഡിറ്റ് ചെയ്യുക"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ആപ്പ് ചേർക്കുക"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ഔട്ട്പുട്ടുകൾ ചേർക്കുക"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ഗ്രൂപ്പ്"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"ഒരു ഉപകരണം തിരഞ്ഞെടുത്തു"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"സ്‌പീക്കറുകളും ഡിസ്പ്ലേകളും"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"നിർദ്ദേശിച്ച ഉപകരണങ്ങൾ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"പ്രീമിയം അക്കൗണ്ട് ആവശ്യമാണ്"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ബ്രോഡ്‌കാസ്‌റ്റ് ചെയ്യാനാകുന്നില്ല"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"സംരക്ഷിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"സംരക്ഷിക്കാൻ കഴിയില്ല."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ബിൽഡ് നമ്പർ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ക്ലിപ്പ്ബോർഡിലേക്ക് ബിൽഡ് നമ്പർ പകർത്തി."</string>
     <string name="basic_status" msgid="2315371112182658176">"സംഭാഷണം തുറക്കുക"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ക്യാമറ ഓഫാണ്"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"മൈക്ക് ഓഫാണ്"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ക്യാമറയും മൈക്കും ഓഫാണ്"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant കേൾക്കുന്നു"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# അറിയിപ്പ്}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ഒറ്റത്തവണ ആക്‌സസ് അനുവദിക്കുക"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"അനുവദിക്കരുത്"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"നിങ്ങളുടെ ഉപകരണത്തിൽ സംഭവിക്കുന്ന കാര്യങ്ങൾ ഉപകരണ ലോഗുകൾ റെക്കോർഡ് ചെയ്യുന്നു. പ്രശ്‌നങ്ങൾ കണ്ടെത്തി പരിഹരിക്കുന്നതിന് ആപ്പുകൾക്ക് ഈ ലോഗുകൾ ഉപയോഗിക്കാൻ കഴിയും.\n\nചില ലോഗുകളിൽ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട വിവരങ്ങൾ അടങ്ങിയിരിക്കാൻ സാധ്യതയുള്ളതിനാൽ, എല്ലാ ഉപകരണ ലോഗുകളും ആക്സസ് ചെയ്യാനുള്ള അനുമതി നിങ്ങൾക്ക് വിശ്വാസമുള്ള ആപ്പുകൾക്ക് മാത്രം നൽകുക. \n\nഎല്ലാ ഉപകരണ ലോഗുകളും ആക്‌സസ് ചെയ്യാനുള്ള അനുവാദം നൽകിയില്ലെങ്കിലും, ഈ ആപ്പിന് അതിന്റെ സ്വന്തം ലോഗുകൾ ആക്‌സസ് ചെയ്യാനാകും. നിങ്ങളുടെ ഉപകരണ നിർമ്മാതാവിന് തുടർന്നും നിങ്ങളുടെ ഉപകരണത്തിലെ ചില ലോഗുകളോ വിവരങ്ങളോ ആക്‌സസ് ചെയ്യാനായേക്കും."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"കൂടുതലറിയുക"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> എന്നതിൽ കൂടുതലറിയുക"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> തുറക്കുക"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ആപ്പ് സജ്ജീകരിച്ചിട്ടുണ്ട്"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet-ലേക്ക് ഒരു കാർഡെങ്കിലും ചേർത്തിട്ടുണ്ട്"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ഔദ്യോഗിക പ്രൊഫൈലിൽ നിന്ന് മാത്രം ഫോൺ കോളുകൾ ചെയ്യാനാണ് നിങ്ങളുടെ ഔദ്യോഗിക നയം അനുവദിക്കുന്നത്"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"അടയ്ക്കുക"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ലോക്ക് സ്ക്രീൻ ക്രമീകരണം"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 5a552ad..e534342 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доод талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зүүн талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Баруун талын хязгаар <xliff:g id="PERCENT">%1$d</xliff:g> хувь"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ажлын дэлгэцийн агшнуудыг <xliff:g id="APP">%1$s</xliff:g> апп дээр хадгалсан"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Ажлын профайл дахь <xliff:g id="APP">%1$s</xliff:g>-д хадгалсан"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файлс"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> энэ дэлгэцийн агшныг илрүүлсэн."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> болон бусад нээлттэй апп энэ дэлгэцийн агшныг илрүүлсэн."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Тэмдэглэлд нэмэх"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Дэлгэцийн үйлдэл бичигч"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Царайг таньсан. Нээх бол түгжээг тайлах дүрсийг дарна уу."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Царайгаар түгжээг тайлсан"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Царайг таньсан"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Зүүн тийш зөөх"</item>
-    <item msgid="5558598599408514296">"Доош зөөх"</item>
-    <item msgid="4844142668312841831">"Баруун тийш зөөх"</item>
-    <item msgid="5640521437931460125">"Дээш зөөх"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Дахин оролдохын тулд дээш шударна уу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC-г ашиглахын тулд түгжээг тайлна уу"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Хяналтууд нэмэхийн тулд аппыг сонгоно уу"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# хяналт нэмсэн.}other{# хяналт нэмсэн.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Хассан"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>-г нэмэх үү?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Та <xliff:g id="APPNAME">%s</xliff:g>-г нэмэх үед энэ нь уг түр зуурын самбарт тохиргоо болон контент нэмэх боломжтой. Зарим аппад та энд ямар тохиргоог харуулахыг сонгох боломжтой."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>-р байршилд дуртай гэж тэмдэглэсэн"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Дургүй гэж тэмдэглэсэн"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>-г нээх"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g>-г <xliff:g id="APP_LABEL">%2$s</xliff:g> дээр тоглуулах"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Танд зориулсан"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Болих"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> дээр тоглуулахын тулд төхөөрөмжөө ойртуулна уу"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Энд тоглуулахын тулд <xliff:g id="DEVICENAME">%1$s</xliff:g> руу ойртуулна уу"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Алдаа гарлаа. Дахин оролдоно уу."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Ачаалж байна"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Хяналт боломжгүй байна"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Алдаа гарав, дахин оролдоно уу"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Хяналт нэмэх"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Хяналтыг өөрчлөх"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Апп нэмэх"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Гаралт нэмэх"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Бүлэг"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 төхөөрөмж сонгосон"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Чанга яригч ба дэлгэц"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Санал болгосон төхөөрөмжүүд"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Тусгай бүртгэл шаарддаг"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Нэвтрүүлэх боломжгүй"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Хадгалах боломжгүй. Дахин оролдоно уу."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Хадгалах боломжгүй."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Хийцийн дугаар"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Хийцийн дугаарыг түр санах ойд хуулсан."</string>
     <string name="basic_status" msgid="2315371112182658176">"Харилцан яриаг нээх"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камер унтраалттай байна"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон унтраалттай байна"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камер болон микрофон унтраалттай байна"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Туслах сонсож байна"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# мэдэгдэл}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Нэг удаагийн хандалтыг зөвшөөрөх"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Бүү зөвшөөр"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Төхөөрөмжийн лог нь таны төхөөрөмж дээр юу болж байгааг бичдэг. Аппууд эдгээр логийг асуудлыг олох болон засахад ашиглах боломжтой.\n\nЗарим лог эмзэг мэдээлэл агуулж байж магадгүй тул та зөвхөн итгэдэг аппууддаа төхөөрөмжийн бүх логт хандахыг зөвшөөрнө үү. \n\nХэрэв та энэ аппад төхөөрөмжийн бүх логт хандахыг зөвшөөрөхгүй бол энэ нь өөрийн логт хандах боломжтой хэвээр байх болно. Tаны төхөөрөмжийн үйлдвэрлэгч таны төхөөрөмж дээрх зарим лог эсвэл мэдээлэлд хандах боломжтой хэвээр байж магадгүй."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Нэмэлт мэдээлэл авах"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>-с нэмэлт мэдээлэл авна уу"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>-г нээх"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Аппыг тохируулсан"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Дор хаяж нэг картыг Wallet-д нэмсэн"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Таны ажлын бодлого танд зөвхөн ажлын профайлаас утасны дуудлага хийхийг зөвшөөрдөг"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Ажлын профайл руу сэлгэх"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Хаах"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Түгжигдсэн дэлгэцийн тохиргоо"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index a9e57f7..a023f0d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"खालील सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"डाव्या सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"उजव्या सीमेपासून <xliff:g id="PERCENT">%1$d</xliff:g> टक्के"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ऑफिससंबंधित स्क्रीनशॉट <xliff:g id="APP">%1$s</xliff:g> अ‍ॅपमध्ये सेव्ह केले आहेत"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"<xliff:g id="APP">%1$s</xliff:g> मधील कार्य प्रोफाइलमध्ये सेव्ह केला"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"फाइल"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ने हा स्क्रीनशॉट डिटेक्ट केला."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> आणि उघडलेल्या इतर अ‍ॅप्सनी हा स्क्रीनशॉट डिटेक्ट केला."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"टीप जोडा"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रेकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"चेहरा ओळखला आहे. उघडण्यासाठी अनलॉक करा आयकन दाबा."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"चेहऱ्याने अनलॉक केले आहे"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"चेहरा ओळखला आहे"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"डावीकडे हलवा"</item>
-    <item msgid="5558598599408514296">"खाली हलवा"</item>
-    <item msgid="4844142668312841831">"उजवीकडे हलवा"</item>
-    <item msgid="5640521437931460125">"वर हलवा"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"नियंत्रणे जोडण्यासाठी ॲप निवडा"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# नियंत्रण जोडले आहे.}other{# नियंत्रणे जोडली आहेत.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"काढून टाकले"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> जोडायचे आहे का?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"तुम्ही <xliff:g id="APPNAME">%s</xliff:g> जोडता, तेव्हा ते या पॅनलमध्ये नियंत्रणे आणि आशय जोडू शकते. येथे कोणती नियंत्रणे दाखवावीत ते तुम्ही काही अ‍ॅप्समध्ये निवडू शकता."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"आवडले"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"आवडले, स्थान <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"नावडले"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> उघडा"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> मध्ये <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले करा"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"तुमच्यासाठी"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"पहिल्यासारखे करा"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> वर प्ले करण्यासाठी जवळ जा"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"येथे प्ले करण्यासाठी, <xliff:g id="DEVICENAME">%1$s</xliff:g> च्या जवळ जा"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"काहीतरी चूक झाली. पुन्हा प्रयत्न करा."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"लोड करत आहे"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"टॅबलेट"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय, ॲप तपासा"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"आढळले नाही"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"नियंत्रण उपलब्ध नाही"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"एरर, पुन्हा प्रयत्न करा"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"नियंत्रणे जोडा"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"नियंत्रणे संपादित करा"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"अ‍ॅप जोडा"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट जोडा"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"गट"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"एक डिव्हाइस निवडले"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पीकर आणि डिस्प्ले"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सुचवलेली डिव्हाइस"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रीमियम खाते आवश्यक आहे"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ब्रॉडकास्ट करू शकत नाही"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेव्ह करू शकत नाही. पुन्हा प्रयत्न करा."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेव्ह करू शकत नाही."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नंबर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नंबर क्लिपबोर्डवर कॉपी केला."</string>
     <string name="basic_status" msgid="2315371112182658176">"संभाषण उघडा"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"कॅमेरा बंद आहे"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"माइक बंद आहे"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"कॅमेरा आणि माइक बंद आहेत"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant ऐकत आहे"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# सूचना}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"एक वेळ अ‍ॅक्सेसची अनुमती द्या"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमती देऊ नका"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"तुमच्या डिव्हाइसवर काय होते ते डिव्हाइस लॉग रेकॉर्ड करते. समस्या शोधण्यासाठी आणि त्यांचे निराकरण करण्यासाठी ॲप्स हे लॉग वापरू शकतात.\n\nकाही लॉगमध्ये संवेदनशील माहिती असू शकते, त्यामुळे फक्त तुमचा विश्वास असलेल्या ॲप्सना सर्व डिव्हाइस लॉग अ‍ॅक्सेस करण्याची अनुमती द्या. \n\nतुम्ही या ॲपला सर्व डिव्हाइस लॉग अ‍ॅक्सेस करण्याची अनुमती न दिल्यास, ते तरीही त्याचा स्वतःचा लॉग अ‍ॅक्सेस करू शकते. तुमच्या डिव्हाइसचा उत्पादक तरीही काही लॉग किंवा तुमच्या डिव्हाइसवरील माहिती अ‍ॅक्सेस करू शकतो."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"अधिक जाणून घ्या"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> येथे अधिक जाणून घ्या"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> उघडा"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• अ‍ॅप सेट करणे"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet मध्ये किमान एक कार्ड जोडणे"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"तुमचे कामाशी संबंधित धोरण तुम्हाला फक्त कार्य प्रोफाइलवरून फोन कॉल करन्याची अनुमती देते"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइलवर स्विच करा"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बंद करा"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"लॉक स्क्रीन सेटिंग्ज"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 9ffe823..7075a32 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Sempadan bawah <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sempadan kiri <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sempadan kanan <xliff:g id="PERCENT">%1$d</xliff:g> peratus"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Tangkapan skrin tugasan disimpan dalam apl <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Disimpan dalam <xliff:g id="APP">%1$s</xliff:g> dalam profil kerja"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fail"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> telah mengesan tangkapan skrin ini."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan apl lain yang dibuka telah mengesan tangkapan skrin ini."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan pada nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Perakam Skrin"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Wajah dicam. Tekan ikon buka kunci untuk membuka."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Dibuka kunci dengan wajah"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Wajah dicam"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Alih ke kiri"</item>
-    <item msgid="5558598599408514296">"Alih ke bawah"</item>
-    <item msgid="4844142668312841831">"Alih ke kanan"</item>
-    <item msgid="5640521437931460125">"Alih ke atas"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Leret ke atas untuk mencuba lagi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Peranti ini milik organisasi anda"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Pilih apl untuk menambahkan kawalan"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Apabila anda menambahkan <xliff:g id="APPNAME">%s</xliff:g>, apl ini boleh menambahkan kawalan dan kandungan pada panel ini. Dalam sesetengah apl, anda boleh memilih kawalan yang muncul di sini."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Dinyahgemari"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buka <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Mainkan <xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Mainkan <xliff:g id="SONG_NAME">%1$s</xliff:g> daripada <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Untuk Anda"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Buat asal"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Alihkan lebih dekat untuk bermain pada<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Untuk bermain di sini, bergerak lebih dekat kepada <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Kesilapan telah berlaku. Cuba lagi."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Memuatkan"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Menghantar media anda"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Menghantar <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kawalan tidak tersedia"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Ralat, cuba lagi"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Tambah kawalan"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Edit kawalan"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Tambahkan apl"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Tambah output"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Kumpulan"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 peranti dipilih"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Pembesar Suara &amp; Paparan"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Peranti yang Dicadangkan"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Memerlukan akaun premium"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara siaran berfungsi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Siarkan"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang berdekatan anda dengan peranti Bluetooth yang serasi boleh mendengar media yang sedang anda siarkan"</string>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Tidak dapat disiarkan"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Tidak dapat disimpan. Cuba lagi."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Tidak dapat disimpan."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nombor binaan"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nombor binaan disalin ke papan keratan."</string>
     <string name="basic_status" msgid="2315371112182658176">"Buka perbualan"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera dimatikan"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon dimatikan"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dan mikrofon dimatikan"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Pembantu sedang mendengar"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# pemberitahuan}other{# pemberitahuan}}"</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">"Pengambilan nota"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Benarkan akses satu kali"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Jangan benarkan"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Log peranti merekodkan perkara yang berlaku pada peranti anda. Apl boleh menggunakan log ini untuk menemukan dan membetulkan masalah.\n\nSesetengah log mungkin mengandungi maklumat sensitif, jadi hanya benarkan apl yang anda percaya untuk mengakses semua log peranti. \n\nJika anda tidak membenarkan apl ini mengakses semua log peranti, apl ini masih boleh mengakses log sendiri. Pengilang peranti anda mungkin masih dapat mengakses sesetengah log atau maklumat pada peranti anda."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Ketahui lebih lanjut"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Ketahui lebih lanjut di <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Apl disediakan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Sekurang-kurangnya satu kad telah ditambahkan pada Wallet"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Tukar kepada profil kerja"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Tutup"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Tetapan skrin kunci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 3ccac95..65345d0 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"အောက်ခြေအနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ဘယ်ဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ညာဘက်အနားသတ် <xliff:g id="PERCENT">%1$d</xliff:g> ရာခိုင်နှုန်း"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"အလုပ်နှင့်ဆိုင်သော ဖန်သားပြင်ဓာတ်ပုံများကို <xliff:g id="APP">%1$s</xliff:g> အက်ပ်တွင် သိမ်းသည်"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"အလုပ်ပရိုဖိုင်ရှိ <xliff:g id="APP">%1$s</xliff:g> တွင် သိမ်းထားသည်"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ဖိုင်များ"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> က ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> နှင့် အခြားဖွင့်ထားသော အက်ပ်များက ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"မှတ်စုတွင် ထည့်ရန်"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ဖန်သားပြင် ရိုက်ကူးမှု"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"မျက်နှာ မှတ်မိသည်။ ဖွင့်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"မျက်နှာဖြင့် ဖွင့်လိုက်သည်"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"မျက်နှာ မှတ်မိသည်"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ဘယ်ဘက်သို့ရွှေ့ရန်"</item>
-    <item msgid="5558598599408514296">"အောက်သို့ရွှေ့ရန်"</item>
-    <item msgid="4844142668312841831">"ညာဘက်သို့ရွှေ့ရန်"</item>
-    <item msgid="5640521437931460125">"အပေါ်သို့ရွှေ့ရန်"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ကို အသုံးပြုရန် လော့ခ်ဖွင့်ပါ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"ထိန်းချုပ်မှုများထည့်ရန် အက်ပ်ရွေးခြင်း"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}other{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ထည့်မလား။"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> ထည့်သောအခါ ၎င်းသည် ဤအကန့်တွင် သတ်မှတ်ချက်များနှင့် အကြောင်းအရာကို ထည့်နိုင်သည်။ အက်ပ်အချို့၌ မြင်ရမည့် သတ်မှတ်ချက်များကို ဤနေရာတွင် ရွေးနိုင်သည်။"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်၊ အဆင့် <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"အကြိုက်ဆုံးမှ ဖယ်ရှားထားသည်"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ကို ဖွင့်ပါ"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%2$s</xliff:g> တွင် ဖွင့်ပါ"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"သင့်အတွက်"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"နောက်ပြန်ရန်"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> တွင်ဖွင့်ရန် အနီးသို့ရွှေ့ပါ"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ဤနေရာတွင် ဖွင့်ရန် <xliff:g id="DEVICENAME">%1$s</xliff:g> အနီးသို့ ရွှေ့ပါ"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"တစ်ခုခုမှားသွားသည်။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ဖွင့်နေသည်"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"တက်ဘလက်"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"သင့်မီဒီယာကို ကာစ်လုပ်နေသည်"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ကို ကာစ်လုပ်နေသည်"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ရပ်နေသည်၊ အက်ပ်ကို စစ်ဆေးပါ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"မတွေ့ပါ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ထိန်းချုပ်မှု မရနိုင်ပါ"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"မှားသွားသည်၊ ပြန်စမ်းကြည့်ပါ"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"ထိန်းချုပ်မှုများ ထည့်ရန်"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"ထိန်းချုပ်မှုများ ပြင်ရန်"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"အက်ပ်ထည့်ရန်"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"မီဒီယာအထွက်များ ထည့်ရန်"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"အုပ်စု"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"စက်ပစ္စည်း ၁ ခုကို ရွေးချယ်ထားသည်"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"စပီကာနှင့် ဖန်သားပြင်များ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"အကြံပြုထားသော စက်ပစ္စည်းများ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ပရီမီယံအကောင့် လိုအပ်သည်"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ထုတ်လွှင့်၍ မရပါ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"သိမ်း၍မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"သိမ်း၍မရပါ။"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
     <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ကင်မရာ ပိတ်ထားသည်"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"မိုက်ပိတ်ထားသည်"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ကင်မရာနှင့် မိုက် ပိတ်ထားသည်"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant နားထောင်နေသည်"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{အကြောင်းကြားချက် # ခု}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"တစ်ခါသုံး ဝင်ခွင့်ပေးရန်"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ခွင့်မပြုပါ"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"သင့်စက်ရှိ အဖြစ်အပျက်များကို စက်မှတ်တမ်းများက မှတ်တမ်းတင်သည်။ အက်ပ်များက ပြဿနာများ ရှာဖွေပြီးဖြေရှင်းရန် ဤမှတ်တမ်းများကို သုံးနိုင်သည်။\n\nအချို့မှတ်တမ်းများတွင် သတိထားရမည့်အချက်အလက်များ ပါဝင်နိုင်သဖြင့် ယုံကြည်ရသည့် အက်ပ်များကိုသာ စက်မှတ်တမ်းအားလုံး သုံးခွင့်ပြုပါ။ \n\nဤအက်ပ်ကို စက်မှတ်တမ်းအားလုံး သုံးခွင့်မပြုသော်လည်း ၎င်းက ကိုယ်ပိုင်မှတ်တမ်းများ သုံးနိုင်သေးသည်။ သင့်စက်ရှိ အချို့မှတ်တမ်းများ (သို့) အချက်အလက်များကို သင့်စက်ထုတ်လုပ်သူက သုံးနိုင်ပါသေးသည်။"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ပိုမိုလေ့လာရန်"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> တွင် ပိုမိုလေ့လာရန်"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• အက်ပ်ကို စနစ်ထည့်သွင်းထားရမည်"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet တွင် အနည်းဆုံးကတ်တစ်ခု ထည့်ထားရမည်"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"သင့်အလုပ်မူဝါဒသည် သင့်အား အလုပ်ပရိုဖိုင်မှသာ ဖုန်းခေါ်ဆိုခွင့် ပြုသည်"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"အလုပ်ပရိုဖိုင်သို့ ပြောင်းရန်"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ပိတ်ရန်"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"လော့ခ်မျက်နှာပြင် ဆက်တင်များ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 44d97aa..d6d0b01 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Høyre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Jobbrelaterte skjermdumper lagres i <xliff:g id="APP">%1$s</xliff:g>-appen"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Lagret i <xliff:g id="APP">%1$s</xliff:g> i jobbprofilen"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registrert denne skjermdumpen."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åpne apper har registrert denne skjermdumpen."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Legg til i notat"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjermopptaker"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Låst opp med ansiktet"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Ansiktet er gjenkjent"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Flytt til venstre"</item>
-    <item msgid="5558598599408514296">"Flytt ned"</item>
-    <item msgid="4844142668312841831">"Flytt til høyre"</item>
-    <item msgid="5640521437931460125">"Flytt opp"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Sveip opp for å prøve igjen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås opp for å bruke NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Velg en app for å legge til kontroller"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll er lagt til.}other{# kontroller er lagt til.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vil du legge til <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Når du legger til <xliff:g id="APPNAME">%s</xliff:g>, kan den legge til kontroller og innhold i dette panelet. I noen apper kan du velge hvilke kontroller som vises her."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoritt"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favoritt, posisjon <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet som favoritt"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Åpne <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spill av <xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spill av <xliff:g id="SONG_NAME">%1$s</xliff:g> fra <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"For deg"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Angre"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytt nærmere for å spille av på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"For å spille av her, gå nærmere <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Noe gikk galt. Prøv på nytt."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Laster inn"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"nettbrett"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrollen er utilgjengelig"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"En feil oppsto. Prøv på nytt"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Legg til kontroller"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Endre kontroller"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Legg til app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Legg til utenheter"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Gruppe"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 enhet er valgt"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Krever en premium-konto"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan ikke kringkaste"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan ikke lagre. Prøv på nytt."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan ikke lagre."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delversjonsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delversjonsnummeret er kopiert til utklippstavlen."</string>
     <string name="basic_status" msgid="2315371112182658176">"Åpen samtale"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kameraet er av"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofonen er av"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera og mikrofon er av"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistenten lytter"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# varsel}other{# varsler}}"</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">"Notatskriving"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Gi éngangstilgang"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ikke tillat"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Enhetslogger registrerer det som skjer på enheten din. Apper kan bruke disse loggene til å finne og løse problemer.\n\nNoen logger kan inneholde sensitiv informasjon, så du bør bare gi tilgang til alle enhetslogger til apper du stoler på. \n\nHvis du ikke gir denne appen tilgang til alle enhetslogger, har den fortsatt tilgang til sine egne logger. Enhetsprodusenten kan fortsatt ha tilgang til visse logger eller noe informasjon på enheten din."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Finn ut mer"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Finn ut mer på <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åpne <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• appen er konfigurert"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• minst ett kort er lagt til i Wallet"</string>
@@ -1056,7 +1061,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vend nå"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Brett ut telefonen for å ta bedre selfier"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bytte til frontskjermen for bedre selfier?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vil du bruke frontkameraet for bedre selfier?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Bruk det bakovervendte kameraet for å ta bredere bilder med høyere oppløsning."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Denne skjermen slås av"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Bytt til jobbprofilen"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Lukk"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Innstillinger for låseskjermen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index b5ffc21..1c6435b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"फेदबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"बायाँ किनाराबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"दायाँ किनाराबाट <xliff:g id="PERCENT">%1$d</xliff:g> प्रतिशत"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"कार्य प्रोफाइल प्रयोग गरी लिइएका स्क्रिनसटहरू <xliff:g id="APP">%1$s</xliff:g> एपमा सेभ गरिन्छन्"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"कार्य प्रोफाइलअन्तर्गत <xliff:g id="APP">%1$s</xliff:g> मा सेभ गरियो"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ले यो स्क्रिनसट भेट्टाएको छ।"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> र खुला रहेका अन्य एपहरूले यो स्क्रिनसट भेट्टाएका छन्।"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोट एपमा सेभ गर्नुहोस्"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"अनुहार पहिचान गरियो। डिभाइस खोल्न अनलक आइकनमा थिच्नुहोस्।"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"अनुहार प्रयोग गरी अनलक गरियो"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"अनुहार पहिचान गरियो"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"बायाँ सार्नुहोस्"</item>
-    <item msgid="5558598599408514296">"तल सार्नुहोस्"</item>
-    <item msgid="4844142668312841831">"दायाँ सार्नुहोस्"</item>
-    <item msgid="5640521437931460125">"माथि सार्नुहोस्"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"कन्ट्रोल थप्नु पर्ने एप छान्नुहोस्"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कन्ट्रोल हालियो।}other{# वटा कन्ट्रोल हालियो।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"हटाइएको"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> हाल्ने हो?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"तपाईंले <xliff:g id="APPNAME">%s</xliff:g> हाल्नुभयो भने यसले यो प्यानलमा सेटिङ र सामग्री हाल्न सक्छ। तपाईं केही एपहरूमा यहाँ कुन कुन सेटिङ देखाउने भन्ने कुरा छनौट गर्न सक्नुहुन्छ।"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"मनपराइएको"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"मन पराइएका कुराहरूको <xliff:g id="NUMBER">%d</xliff:g> औँ स्थानमा"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"मन पर्ने कुराहरूको सूचीमा नराखिएको"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> खोल्नुहोस्"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%2$s</xliff:g> मा बजाउनुहोस्"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"तपाईंको लागि सिफारिस गरिएका"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"अन्डू गर्नुहोस्"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> मा प्ले गर्न आफ्नो डिभाइस नजिकै लैजानुहोस्"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"यो डिभाइसमा प्ले गर्न <xliff:g id="DEVICENAME">%1$s</xliff:g> को अझ नजिक जानुहोस्"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"केही चिज गडबड भयो। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"लोड हुँदै छ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ट्याब्लेट"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"तपाईंको मिडिया कास्ट गरिँदै छ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> कास्ट गरिँदै छ"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"निष्क्रिय छ, एप जाँच गर्नु…"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"फेला परेन"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"नियन्त्रण उपलब्ध छैन"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"त्रुटि भयो, फेरि प्रयास गर्नु…"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"कन्ट्रोल थप्नुहोस्"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"कन्ट्रोल सम्पादन गर्नुहोस्"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"एप हाल्नुहोस्"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"आउटपुट यन्त्रहरू थप्नुहोस्"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"समूह"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"१ यन्त्र चयन गरियो"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"स्पिकर तथा डिस्प्लेहरू"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"सिफारिस गरिएका डिभाइसहरू"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"प्रिमियम खाता चाहिन्छ"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"प्रसारण गर्न सकिएन"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"सेभ गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"सेभ गर्न सकिएन।"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"बिल्ड नम्बर"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"बिल्ड नम्बर कपी गरी क्लिपबोर्डमा सारियो।"</string>
     <string name="basic_status" msgid="2315371112182658176">"वार्तालाप खोल्नुहोस्"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"क्यामेरा अफ छ"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"माइक अफ छ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"क्यामेरा र माइक अफ छन्"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"सहायकले सुनिरहेको छ"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# वटा सूचना}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"एक पटक प्रयोग गर्ने अनुमति दिनुहोस्"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"अनुमति नदिनुहोस्"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"डिभाइसका लगले तपाईंको डिभाइसमा भएका विभिन्न गतिविधिको अभिलेख राख्छन्। एपहरू यी लगका आधारमा समस्या पत्ता लगाउन र तिनको समाधान गर्न सक्छन्।\n\nकेही लगहरूमा संवेदनशील जानकारी समावेश हुन सक्ने भएकाले आफूले भरोसा गर्ने एपलाई मात्र डिभाइसका सबै लग हेर्ने अनुमति दिनुहोस्। \n\nतपाईंले यो एपलाई डिभाइसका सबै लग हेर्ने अनुमति दिनुभएन भने पनि यसले आफ्नै लग भने हेर्न सक्छ। तपाईंको डिभाइसका उत्पादकले पनि तपाईंको डिभाइसमा भएका केही लग वा जानकारी हेर्न सक्ने सम्भावना हुन्छ।"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"थप जान्नुहोस्"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> मा गई थप जान्नुहोस्"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> खोल्नुहोस्"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• एप सेटअप गरिएको छ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet मा कम्तीमा एउटा कार्ड हालिएको छ"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"तपाईंको कामसम्बन्धी नीतिअनुसार कार्य प्रोफाइलबाट मात्र फोन कल गर्न सकिन्छ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"कार्य प्रोफाइल प्रयोग गर्नुहोस्"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"बन्द गर्नुहोस्"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"लक स्क्रिनसम्बन्धी सेटिङ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 08e1bf2..5efcef3 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -100,13 +100,4 @@
     <color name="accessibility_floating_menu_message_text">@*android:color/primary_text_default_material_dark</color>
 
     <color name="people_tile_background">@color/material_dynamic_secondary20</color>
-
-    <!-- UDFPS colors -->
-    <color name="udfps_enroll_icon">#7DA7F1</color>
-    <color name="udfps_moving_target_fill">#475670</color>
-    <!-- 50% of udfps_moving_target_fill-->
-    <color name="udfps_moving_target_fill_error">#80475670</color>
-    <color name="udfps_enroll_progress">#7DA7F1</color>
-    <color name="udfps_enroll_progress_help">#607DA7F1</color>
-    <color name="udfps_enroll_progress_help_with_talkback">#FFEE675C</color>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 221a9d8..d7954b7 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Ondergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Linkergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Rechtergrens <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Werkscreenshots worden opgeslagen in de <xliff:g id="APP">%1$s</xliff:g>-app"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Opgeslagen in <xliff:g id="APP">%1$s</xliff:g> in het werkprofiel."</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Bestanden"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> heeft dit screenshot waargenomen."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en andere geopende apps hebben dit screenshot waargenomen."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Toevoegen aan notitie"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Schermopname"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Ontgrendeld via gezicht"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Gezicht herkend"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Naar links verplaatsen"</item>
-    <item msgid="5558598599408514296">"Omlaag verplaatsen"</item>
-    <item msgid="4844142668312841831">"Naar rechts verplaatsen"</item>
-    <item msgid="5640521437931460125">"Omhoog verplaatsen"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swipe omhoog om het opnieuw te proberen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontgrendel het apparaat om NFC te gebruiken"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Kies de app waaraan je bedieningselementen wilt toevoegen"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# bedieningselement toegevoegd.}other{# bedieningselementen toegevoegd.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Verwijderd"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> toevoegen?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Als je <xliff:g id="APPNAME">%s</xliff:g> toevoegt, kan deze app bedieningselementen en content aan dit deelvenster toevoegen. In sommige apps kun je kiezen welke bedieningselementen hier worden getoond."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gemarkeerd als favoriet"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Gemarkeerd als favoriet, positie <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Verwijderd als favoriet"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> openen"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspelen via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> afspelen via <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Voor jou"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Ongedaan maken"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Houd dichter bij <xliff:g id="DEVICENAME">%1$s</xliff:g> om af te spelen"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ga dichter naar <xliff:g id="DEVICENAME">%1$s</xliff:g> toe om hier af te spelen"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Er is iets misgegaan. Probeer het opnieuw."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Laden"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Je media casten"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> casten"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Beheeroptie niet beschikbaar"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer het opnieuw"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Bedieningselementen toevoegen"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Bedieningselementen bewerken"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"App toevoegen"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Uitvoer toevoegen"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Groep"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Eén apparaat geselecteerd"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Speakers en schermen"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Voorgestelde apparaten"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Je hebt een premium account nodig"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitzenden werkt"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Uitzending"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mensen bij jou in de buurt met geschikte bluetooth-apparaten kunnen luisteren naar de media die je uitzendt"</string>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Kan niet uitzenden"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kan niet opslaan. Probeer het opnieuw."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kan niet opslaan."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Buildnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Buildnummer naar klembord gekopieerd."</string>
     <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera staat uit"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Microfoon staat uit"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera en microfoon staan uit"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"De Assistent luistert"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# melding}other{# meldingen}}"</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">"Aantekeningen maken"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Eenmalige toegang toestaan"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Niet toestaan"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Apparaatlogboeken leggen vast wat er op je apparaat gebeurt. Apps kunnen deze logboeken gebruiken om problemen op te sporen en te verhelpen.\n\nSommige logboeken kunnen gevoelige informatie bevatten, dus geef alleen apps die je vertrouwt toegang tot alle apparaatlogboeken. \n\nAls je deze app geen toegang tot alle apparaatlogboeken geeft, heeft de app nog wel toegang tot de eigen logboeken. De fabrikant van je apparaat heeft misschien nog steeds toegang tot bepaalde logboeken of informatie op je apparaat."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Meer informatie"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Ga voor meer informatie naar <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> openen"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• De app is ingesteld"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Er is ten minste één kaart aan Wallet toegevoegd"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Overschakelen naar werkprofiel"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Sluiten"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Instellingen vergrendelscherm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index e3314b3..d187ad6 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ନିମ୍ନ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ବାମ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ଡାହାଣ ସୀମାରେଖା <xliff:g id="PERCENT">%1$d</xliff:g> ଶତକଡ଼ା"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ୱାର୍କ ସ୍କ୍ରିନସଟଗୁଡ଼ିକୁ <xliff:g id="APP">%1$s</xliff:g> ଆପରେ ସେଭ କରାଯାଇଛି"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ୱାର୍କ ପ୍ରୋଫାଇଲରେ ଥିବା <xliff:g id="APP">%1$s</xliff:g>ରେ ସେଭ କରାଯାଇଛି"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ଫାଇଲଗୁଡ଼ିକ"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏବଂ ଅନ୍ୟ ଓପନ ଆପ୍ସ ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ନୋଟରେ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଖୋଲିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ବାମକୁ ମୁଭ କରନ୍ତୁ"</item>
-    <item msgid="5558598599408514296">"ତଳକୁ ମୁଭ କରନ୍ତୁ"</item>
-    <item msgid="4844142668312841831">"ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</item>
-    <item msgid="5640521437931460125">"ଉପରକୁ ମୁଭ କରନ୍ତୁ"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଯୋଗ କରିବାକୁ ଆପ୍ ବାଛନ୍ତୁ"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}other{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>କୁ ଯୋଗ କରିବେ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"ଯେତେବେଳେ ଆପଣ <xliff:g id="APPNAME">%s</xliff:g>କୁ ଯୋଗ କରନ୍ତି, ସେତେବେଳେ ଏହି ପେନେଲରେ ଏହା ନିୟନ୍ତ୍ରଣ ଏବଂ ବିଷୟବସ୍ତୁ ଯୋଗ କରିପାରିବ। କିଛି ଆପ୍ସରେ, ଏଠାରେ କେଉଁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଦେଖାଯିବ ତାହା ଆପଣ ବାଛିପାରିବେ।"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ପସନ୍ଦ କରାଯାଇଛି, ସ୍ଥିତି <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ନାପସନ୍ଦ କରାଯାଇଛି"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g>ରୁ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚଲାନ୍ତୁ"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ଆପଣଙ୍କ ପାଇଁ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ପୂର୍ବବତ୍ କରନ୍ତୁ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>ରେ ପ୍ଲେ କରିବା ପାଇଁ ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ଏଠାରେ ପ୍ଲେ କରିବା ପାଇଁ <xliff:g id="DEVICENAME">%1$s</xliff:g> ପାଖକୁ ମୁଭ କରନ୍ତୁ"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"କିଛି ତ୍ରୁଟି ହୋଇଛି। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ଲୋଡ ହେଉଛି"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ଟାବଲେଟ"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ନିୟନ୍ତ୍ରଣ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"ତ୍ରୁଟି ହୋଇଛି, ପୁଣି ଚେଷ୍ଟା କର"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ଏଡିଟ କରନ୍ତୁ"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ଆପ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ଆଉଟପୁଟ୍ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ଗୋଷ୍ଠୀ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1ଟି ଡିଭାଇସ୍ ଚୟନ କରାଯାଇଛି"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ପ୍ରସ୍ତାବିତ ଡିଭାଇସଗୁଡ଼ିକ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ପ୍ରିମିୟମ ଆକାଉଣ୍ଟ ଆବଶ୍ୟକ"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ବ୍ରଡକାଷ୍ଟ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ସେଭ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ବିଲ୍ଡ ନମ୍ୱର"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"କ୍ଲିପବୋର୍ଡକୁ କପି କରାଯାଇଥିବା ବିଲ୍ଡ ନମ୍ୱର।"</string>
     <string name="basic_status" msgid="2315371112182658176">"ବାର୍ତ୍ତାଳାପ ଖୋଲନ୍ତୁ"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"କ୍ୟାମେରା ବନ୍ଦ ଅଛି"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ମାଇକ ବନ୍ଦ ଅଛି"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"କ୍ୟାମେରା ଏବଂ ମାଇକ ବନ୍ଦ ଅଛି"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant ଶୁଣୁଛି"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{#ଟି ବିଜ୍ଞପ୍ତି}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ଗୋଟିଏ-ଥର ଆକ୍ସେସ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଯାହା ହୁଏ ତାହା ଡିଭାଇସ ଲଗଗୁଡ଼ିକ ରେକର୍ଡ କରେ। ସମସ୍ୟାଗୁଡ଼ିକୁ ଖୋଜି ସମାଧାନ କରିବାକୁ ଆପ୍ସ ଏହି ଲଗଗୁଡ଼ିକୁ ବ୍ୟବହାର କରିପାରିବ।\n\nକିଛି ଲଗରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଥାଇପାରେ, ତେଣୁ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଆପଣ ବିଶ୍ୱାସ କରୁଥିବା ଆପ୍ସକୁ ହିଁ କେବଳ ଅନୁମତି ଦିଅନ୍ତୁ। \n\nଯଦି ଆପଣ ସମସ୍ତ ଡିଭାଇସ ଲଗକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ, ତେବେ ଏହା ନିଜର ଡିଭାଇସ ଲଗଗୁଡ଼ିକୁ ଏବେ ବି ଆକ୍ସେସ କରିପାରିବ। ଆପଣଙ୍କ ଡିଭାଇସର ନିର୍ମାତା ଏବେ ବି ଆପଣଙ୍କର ଡିଭାଇସରେ କିଛି ଲଗ କିମ୍ବା ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ସକ୍ଷମ ହୋଇପାରନ୍ତି।"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>ରେ ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ଆପ ସେଟ ଅପ କରାଯାଇଥିବା"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletରେ ଅତିକମରେ ଗୋଟିଏ କାର୍ଡ ଯୋଗ କରାଯାଇଥିବା"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ଆପଣଙ୍କ ୱାର୍କ ନୀତି ଆପଣଙ୍କୁ କେବଳ ୱାର୍କ ପ୍ରୋଫାଇଲରୁ ଫୋନ କଲ କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ୱାର୍କ ପ୍ରୋଫାଇଲକୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ବନ୍ଦ କରନ୍ତୁ"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ଲକ ସ୍କ୍ରିନ ସେଟିଂସ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index be4e149..fb4c759 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ਹੇਠਾਂ ਦੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ਖੱਬੇ ਪਾਸੇ ਵਾਲੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ਸੱਜੇ ਪਾਸੇ ਵਾਲੀ ਸੀਮਾ <xliff:g id="PERCENT">%1$d</xliff:g> ਫ਼ੀਸਦ"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ਕਾਰਜ ਸਕ੍ਰੀਨਸ਼ਾਟਾਂ ਨੂੰ <xliff:g id="APP">%1$s</xliff:g> ਐਪ ਵਿੱਚ ਰੱਖਿਅਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ <xliff:g id="APP">%1$s</xliff:g> ਵਿੱਚ ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ਫ਼ਾਈਲਾਂ"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ਅਤੇ ਹੋਰ ਖੁੱਲ੍ਹੀਆਂ ਐਪਾਂ ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ਨੋਟ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਖੋਲ੍ਹਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ਖੱਬੇ ਲਿਜਾਓ"</item>
-    <item msgid="5558598599408514296">"ਹੇਠਾਂ ਲਿਜਾਓ"</item>
-    <item msgid="4844142668312841831">"ਸੱਜੇ ਲਿਜਾਓ"</item>
-    <item msgid="5640521437931460125">"ਉੱਪਰ ਲਿਜਾਓ"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਐਪ ਚੁਣੋ"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}one{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}other{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ਹਟਾਇਆ ਗਿਆ"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"ਕੀ <xliff:g id="APPNAME">%s</xliff:g> ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"ਜਦੋਂ ਤੁਸੀਂ <xliff:g id="APPNAME">%s</xliff:g> ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਇਹ ਇਸ ਪੈਨਲ ਵਿੱਚ ਕੰਟਰੋਲਾਂ ਅਤੇ ਸਮੱਗਰੀ ਨੂੰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੀ ਹੈ। ਕੁਝ ਐਪਾਂ ਲਈ, ਤੁਸੀਂ ਇਹ ਚੁਣ ਸਕਦੇ ਹੋ ਕਿ ਇੱਥੇ ਕਿਹੜੇ ਕੰਟਰੋਲ ਦਿਸਣ।"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ, ਸਥਾਨ <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ਮਨਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਇਆ ਗਿਆ"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ਤੋਂ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚਲਾਓ"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ਤੁਹਾਡੇ ਲਈ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> \'ਤੇ ਚਲਾਉਣ ਲਈ ਨੇੜੇ ਲਿਜਾਓ"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ਇੱਥੇ ਚਲਾਉਣ ਲਈ, <xliff:g id="DEVICENAME">%1$s</xliff:g> ਦੇ ਨੇੜੇ ਲਿਆਓ"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ਲੋਡ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ਟੈਬਲੈੱਟ"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"ਅਕਿਰਿਆਸ਼ੀਲ, ਐਪ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ਨਹੀਂ ਮਿਲਿਆ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ਕੰਟਰੋਲ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"ਗੜਬੜ, ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"ਕੰਟਰੋਲਾਂ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ਐਪ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ਆਊਟਪੁੱਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"ਗਰੁੱਪ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ਡੀਵਾਈਸ ਨੂੰ ਚੁਣਿਆ ਗਿਆ"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ਸਪੀਕਰ ਅਤੇ ਡਿਸਪਲੇਆਂ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ਸੁਝਾਏ ਗਏ ਡੀਵਾਈਸ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ਪ੍ਰੀਮੀਅਮ ਖਾਤੇ ਦੀ ਲੋੜ ਹੈ"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ਪ੍ਰਸਾਰਨ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"ਬਿਲਡ ਨੰਬਰ"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"ਬਿਲਡ ਨੰਬਰ ਨੂੰ ਕਲਿੱਪਬੋਰਡ \'ਤੇ ਕਾਪੀ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="basic_status" msgid="2315371112182658176">"ਗੱਲਬਾਤ ਖੋਲ੍ਹੋ"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"ਕੈਮਰਾ ਬੰਦ ਹੈ"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ਮਾਈਕ ਬੰਦ ਹੈ"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ ਬੰਦ ਹਨ"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant ਸੁਣ ਰਹੀ ਹੈ"</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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ਇੱਕ-ਵਾਰ ਲਈ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ਆਗਿਆ ਨਾ ਦਿਓ"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"ਡੀਵਾਈਸ ਲੌਗਾਂ ਵਿੱਚ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀਆਂ ਕਾਰਵਾਈਆਂ ਰਿਕਾਰਡ ਹੁੰਦੀਆਂ ਹਨ। ਐਪਾਂ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਲੱਭਣ ਅਤੇ ਉਨ੍ਹਾਂ ਦਾ ਹੱਲ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਲੌਗਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੀਆਂ ਹਨ।\n\nਕੁਝ ਲੌਗਾਂ ਵਿੱਚ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ, ਇਸ ਲਈ ਸਿਰਫ਼ ਆਪਣੀਆਂ ਭਰੋਸੇਯੋਗ ਐਪਾਂ ਨੂੰ ਹੀ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ। \n\nਜੇ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਾਰੇ ਡੀਵਾਈਸ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਦਿੰਦੇ ਹੋ, ਤਾਂ ਇਹ ਹਾਲੇ ਵੀ ਆਪਣੇ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ। ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਨਿਰਮਾਤਾ ਹਾਲੇ ਵੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਕੁਝ ਲੌਗਾਂ ਜਾਂ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ਹੋਰ ਜਾਣੋ"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> \'ਤੇ ਹੋਰ ਜਾਣੋ"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ਐਪ ਦਾ ਸੈੱਟਅੱਪ ਹੋ ਗਿਆ ਹੈ"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਕਾਰਡ ਨੂੰ Wallet ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ਤੁਹਾਡੀ ਕਾਰਜ ਨੀਤੀ ਤੁਹਾਨੂੰ ਸਿਰਫ਼ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਤੋਂ ਹੀ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ \'ਤੇ ਜਾਓ"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ਬੰਦ ਕਰੋ"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"ਲਾਕ ਸਕ੍ਰੀਨ ਸੈਟਿੰਗਾਂ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index b9c3fa6..da2e56e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Przycięcie dolnej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Przycięcie lewej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Przycięcie prawej krawędzi o <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Służbowe zrzuty ekranu są zapisywane w aplikacji <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Zapisano w aplikacji <xliff:g id="APP">%1$s</xliff:g> w profilu służbowym"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Pliki"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> wykryła ten zrzut ekranu."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> i inne aplikacje wykryły ten zrzut ekranu."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj do notatek"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Twarz rozpoznana. Aby otworzyć, kliknij ikonę odblokowywania."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Odblokowano skanem twarzy"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Twarz rozpoznana"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Przenieś w lewo"</item>
-    <item msgid="5558598599408514296">"Przenieś w dół"</item>
-    <item msgid="4844142668312841831">"Przenieś w prawo"</item>
-    <item msgid="5640521437931460125">"Przenieś w górę"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć komunikacji NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Wybierz aplikację, do której chcesz dodać elementy sterujące"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodano # element sterujący.}few{Dodano # elementy sterujące.}many{Dodano # elementów sterujących.}other{Dodano # elementu sterującego.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodać aplikację <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Gdy dodasz aplikację <xliff:g id="APPNAME">%s</xliff:g>, będzie ona mogła dodawać elementy sterujące i treści do tego panelu. W niektórych aplikacjach można wybrać elementy sterujące, które się tu pojawią."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano do ulubionych, pozycja <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Usunięto z ulubionych"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otwórz aplikację <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Odtwórz utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) w aplikacji <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Odtwórz utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> w aplikacji <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Dla Ciebie"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Cofnij"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Przysuń się bliżej, aby odtwarzać na urządzeniu <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Aby zagrać tutaj, przysuń bliżej urządzenie <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Coś poszło nie tak. Spróbuj ponownie."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Wczytuję"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Nieaktywny, sprawdź aplikację"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nie znaleziono"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Element jest niedostępny"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Błąd, spróbuj ponownie"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Dodaj elementy sterujące"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Edytuj elementy sterujące"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodaj aplikację"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodaj urządzenia wyjściowe"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupa"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Wybrano 1 urządzenie"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Wymagane konto premium"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nie można przesyłać"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nie można zapisać. Spróbuj ponownie."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nie można zapisać."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numer kompilacji"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numer kompilacji został skopiowany do schowka."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otwarta rozmowa"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera jest wyłączona"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon jest wyłączony"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Aparat i mikrofon są wyłączone"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asystent słucha"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# powiadomienie}few{# powiadomienia}many{# powiadomień}other{# powiadomienia}}"</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">"Notatki"</string>
@@ -1046,6 +1049,8 @@
     <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_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>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacja została skonfigurowana."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Do Portfela została dodana co najmniej 1 karta."</string>
@@ -1058,7 +1063,7 @@
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Rozłóż telefon, aby uzyskać lepszej jakości selfie"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Przełączyć na przedni wyświetlacz?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Użyj tylnego aparatu, aby zrobić szersze zdjęcie o większej rozdzielczości."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Ekran się wyłączy"</b></string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"* Ten ekran się wyłączy"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Składane urządzenie jest rozkładane"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Składane urządzenie jest obracane"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Pozostało <xliff:g id="PERCENTAGE">%s</xliff:g> baterii"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Przełącz na profil służbowy"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zamknij"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Ustawienia ekranu blokady"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 8bb3e7d..e7edaae 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Borda inferior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Borda esquerda em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Borda direita em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturas de tela do trabalho são salvas no app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salva no app <xliff:g id="APP">%1$s</xliff:g> no perfil de trabalho"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adicionar às notas"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rosto reconhecido. Pressione o ícone de desbloq. para abrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Desbloqueado pelo rosto"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Rosto reconhecido"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mais para a esquerda"</item>
-    <item msgid="5558598599408514296">"Mais para baixo"</item>
-    <item msgid="4844142668312841831">"Mais para a direita"</item>
-    <item msgid="5640521437931460125">"Mais para cima"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
@@ -500,7 +497,7 @@
     <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Chamadas e notificações farão o smartphone tocar (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizador System UI"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barra de status"</string>
-    <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da IU do sistema"</string>
+    <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da interface do sistema"</string>
     <string name="enable_demo_mode" msgid="3180345364745966431">"Ativar modo de demonstração"</string>
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Quando você adiciona o app <xliff:g id="APPNAME">%s</xliff:g>, ele pode incluir controles e conteúdo neste painel. Em alguns casos, é possível escolher quais controles aparecem aqui."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Tocar <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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> no app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para você"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfazer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para abrir aqui, aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Carregando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Transmitindo sua mídia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Transmitindo o app <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controles"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Adicionar app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicionar saídas"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"A câmera está desativada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"O microfone está desativado"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Google Assistente está ouvindo"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}many{# notificações}other{# notificações}}"</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">"Anotações"</string>
@@ -1046,13 +1047,15 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saiba mais em <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Pelo menos um cartão foi adicionado à Carteira"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Um app de câmera está instalado"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantenha o atalho pressionado"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque e pressione o atalho"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Configurações de tela de bloqueio"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 19e9194..4ec3080 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Limite inferior de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Limite esquerdo de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Limite direito de <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"As capturas de ecrã do trabalho são guardadas na app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Guardada na app <xliff:g id="APP">%1$s</xliff:g> no perfil de trabalho"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Ficheiros"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"A app <xliff:g id="APPNAME">%1$s</xliff:g> detetou esta captura de ecrã."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A app <xliff:g id="APPNAME">%1$s</xliff:g> e outras apps abertas detetaram esta captura de ecrã."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adicionar a uma nota"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de ecrã"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rosto reconhecido. Prima o ícone de desbloqueio para abrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Desbloqueado com o rosto"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Rosto reconhecido"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mover para a esquerda"</item>
-    <item msgid="5558598599408514296">"Mover para baixo"</item>
-    <item msgid="4844142668312841831">"Mover para a direita"</item>
-    <item msgid="5640521437931460125">"Mover para cima"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha uma app para adicionar controlos"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controlo adicionado.}many{# controlos adicionados.}other{# controlos adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Quando adicionar a app <xliff:g id="APPNAME">%s</xliff:g>, esta pode adicionar controlos e conteúdos a este painel. Em algumas apps, pode escolher que controlos são apresentados aqui."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Reproduzir <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Reproduzir <xliff:g id="SONG_NAME">%1$s</xliff:g> a partir da app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para si"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Anular"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime-se para reproduzir no dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para reproduzir aqui, aproxime-se do <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Algo correu mal. Tente novamente."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"A carregar"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"A transmitir o conteúdo multimédia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"A transmitir a app <xliff:g id="APP_LABEL">%1$s</xliff:g>…"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O controlo está indisponível"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controlos"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editar controlos"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Adicionar app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicione saídas"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altifalantes e ecrãs"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não é possível transmitir"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Não é possível guardar. Tente novamente."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Não é possível guardar."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da compilação"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da compilação copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Abrir conversa"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"A câmara está desativada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"O microfone está desativado"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmara e o microfone estão desativados"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Assistente está a ouvir"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}many{# notificações}other{# notificações}}"</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">"Tomar notas"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir acesso único"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registos do dispositivo documentam o que ocorre no seu dispositivo. As apps podem usar esses registos para detetar e corrigir problemas.\n\nAlguns registos podem conter informações confidenciais e, por isso, o acesso a todos os registos do dispositivo só deve ser permitido às apps nas quais confia. \n\nSe não permitir o acesso desta app a todos os registos do dispositivo, esta pode ainda assim aceder aos próprios registos. O fabricante do dispositivo pode continuar a aceder a alguns registos ou informações no seu dispositivo."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saiba mais em <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• A app está configurada"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Foi adicionado, pelo menos, um cartão à Carteira"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Definições do ecrã de bloqueio"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8bb3e7d..e7edaae 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Borda inferior em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Borda esquerda em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Borda direita em <xliff:g id="PERCENT">%1$d</xliff:g> por cento"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturas de tela do trabalho são salvas no app <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salva no app <xliff:g id="APP">%1$s</xliff:g> no perfil de trabalho"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adicionar às notas"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Rosto reconhecido. Pressione o ícone de desbloq. para abrir."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Desbloqueado pelo rosto"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Rosto reconhecido"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mais para a esquerda"</item>
-    <item msgid="5558598599408514296">"Mais para baixo"</item>
-    <item msgid="4844142668312841831">"Mais para a direita"</item>
-    <item msgid="5640521437931460125">"Mais para cima"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
@@ -500,7 +497,7 @@
     <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Chamadas e notificações farão o smartphone tocar (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizador System UI"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barra de status"</string>
-    <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da IU do sistema"</string>
+    <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da interface do sistema"</string>
     <string name="enable_demo_mode" msgid="3180345364745966431">"Ativar modo de demonstração"</string>
     <string name="show_demo_mode" msgid="3677956462273059726">"Mostrar modo de demonstração"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Quando você adiciona o app <xliff:g id="APPNAME">%s</xliff:g>, ele pode incluir controles e conteúdo neste painel. Em alguns casos, é possível escolher quais controles aparecem aqui."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Abrir <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Tocar <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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Tocar <xliff:g id="SONG_NAME">%1$s</xliff:g> no app <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para você"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Desfazer"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Aproxime os dispositivos para tocar a mídia neste: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para abrir aqui, aproxime-se do dispositivo <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Algo deu errado. Tente novamente."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Carregando"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Transmitindo sua mídia"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Transmitindo o app <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"O controle está indisponível"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Erro. Tente novamente"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Adicionar controles"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editar controles"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Adicionar app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adicionar saídas"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupo"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 dispositivo selecionado"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Alto-falantes e telas"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispositivos sugeridos"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Requer uma conta premium"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Não foi possível fazer a transmissão"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Falha ao salvar. Tente de novo."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Falha ao salvar."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Número da versão"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Número da versão copiado para a área de transferência."</string>
     <string name="basic_status" msgid="2315371112182658176">"Conversa aberta"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"A câmera está desativada"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"O microfone está desativado"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"A câmera e o microfone estão desativados"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"O Google Assistente está ouvindo"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificação}one{# notificação}many{# notificações}other{# notificações}}"</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">"Anotações"</string>
@@ -1046,13 +1047,15 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saiba mais em <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Pelo menos um cartão foi adicionado à Carteira"</string>
     <string name="keyguard_affordance_enablement_dialog_qr_scanner_instruction" msgid="5355839079232119791">"• Um app de câmera está instalado"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_1" msgid="8438311171750568633">"• O app está disponível"</string>
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Pelo menos um dispositivo está disponível"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantenha o atalho pressionado"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Toque e pressione o atalho"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Virar agora"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Abra o smartphone para tirar uma selfie melhor"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Alternar para o perfil de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Fechar"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Configurações de tela de bloqueio"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2473153..7526cba 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Marginea de jos la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Marginea stângă la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Marginea dreaptă la <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Capturile de ecran pentru serviciu sunt salvate în aplicația <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Salvată în <xliff:g id="APP">%1$s</xliff:g> în profilul de serviciu"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fișiere"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a detectat această captură de ecran."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> și alte aplicații deschise au detectat această captură de ecran."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adaugă în notă"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder pentru ecran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Chip recunoscut. Apasă pictograma Deblocare ca să deschizi."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"S-a deblocat folosind fața"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Chipul a fost recunoscut"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Mută la stânga"</item>
-    <item msgid="5558598599408514296">"Mută în jos"</item>
-    <item msgid="4844142668312841831">"Mută la dreapta"</item>
-    <item msgid="5640521437931460125">"Mută în sus"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Glisează pentru a încerca din nou"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Deblochează pentru a folosi NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației tale"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Alege aplicația pentru a adăuga comenzi"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S-a adăugat # comandă.}few{S-au adăugat # comenzi.}other{S-au adăugat # de comenzi.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Eliminată"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Adaugi <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Când adaugi <xliff:g id="APPNAME">%s</xliff:g>, aplicația poate să adauge comenzi și conținut pe acest panou. În anumite aplicații, poți să alegi comenzile care se afișează aici."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Marcată ca preferată"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Marcată ca preferată, poziția <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"S-a anulat marcarea ca preferată"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Deschide <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Redă <xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Redă <xliff:g id="SONG_NAME">%1$s</xliff:g> în <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pentru tine"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Anulează"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Apropie-te pentru a reda pe <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Pentru a reda conținutul aici, apropie-te de <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"A apărut o eroare. Încearcă din nou."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Se încarcă"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tabletă"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verifică aplicația"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Comanda este indisponibilă"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Eroare, încearcă din nou"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Adaugă comenzi"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Editează comenzile"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Adaugă o aplicație"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Adaugă ieșiri"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"S-a selectat un dispozitiv"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Difuzoare și afișaje"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Dispozitive sugerate"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Necesită un cont premium"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cum funcționează transmisia"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmite"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Persoanele din apropiere cu dispozitive Bluetooth compatibile pot asculta conținutul pe care îl transmiți"</string>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nu se poate transmite"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nu se poate salva. Încearcă din nou."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nu se poate salva."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numărul versiunii"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numărul versiunii s-a copiat în clipboard."</string>
     <string name="basic_status" msgid="2315371112182658176">"Deschide conversația"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera foto este dezactivată"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Microfonul este dezactivat"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Camera și microfonul sunt dezactivate"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistentul ascultă"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notificare}few{# notificări}other{# de notificări}}"</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">"Notetaking"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Permite accesul o dată"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nu permite"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Jurnalele dispozitivului înregistrează activitatea de pe dispozitivul tău. Aplicațiile pot folosi aceste jurnale pentru a identifica și a remedia probleme.\n\nUnele jurnale pot să conțină informații sensibile, prin urmare permite accesul la toate jurnalele dispozitivului doar aplicațiilor în care ai încredere. \n\nDacă nu permiți accesul aplicației la toate jurnalele dispozitivului, aceasta poate în continuare să acceseze propriile jurnale. Este posibil ca producătorul dispozitivului să acceseze în continuare unele jurnale sau informații de pe dispozitiv."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Află mai multe"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Află mai multe la <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Deschide <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplicația este configurată"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Cel puțin un card a fost adăugat în Portofel"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Comută la profilul de serviciu"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Închide"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Setările ecranului de blocare"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 830b0c1..57aef61 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Граница снизу: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Граница слева: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Граница справа: <xliff:g id="PERCENT">%1$d</xliff:g> %%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Скриншоты сохраняются в приложении \"<xliff:g id="APP">%1$s</xliff:g>\" в рабочем профиле"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Скриншот сохранен в рабочем профиле в приложении <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файлы"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" обнаружило создание скриншота."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" и другие запущенные продукты обнаружили создание скриншота."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавить в заметку"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запись видео с экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лицо распознано. Нажмите на значок разблокировки."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Разблокировано сканированием лица"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Лицо распознано"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Переместите палец влево"</item>
-    <item msgid="5558598599408514296">"Переместите палец вниз"</item>
-    <item msgid="4844142668312841831">"Переместите палец вправо"</item>
-    <item msgid="5640521437931460125">"Переместите палец вверх"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Чтобы повторить попытку, проведите вверх"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Чтобы использовать NFC, разблокируйте устройство."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Это устройство принадлежит вашей организации"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Чтобы добавить виджеты управления, выберите приложение"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавлен # элемент управления.}one{Добавлен # элемент управления.}few{Добавлено # элемента управления.}many{Добавлено # элементов управления.}other{Добавлено # элемента управления.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Удалено"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Добавить приложение \"<xliff:g id="APPNAME">%s</xliff:g>\"?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Приложение \"<xliff:g id="APPNAME">%s</xliff:g>\" может добавить на эту панель элементы управления и контент. Некоторые приложения позволяют выбирать, какие элементы будут здесь показаны."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Добавлено в избранное"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Добавлено в избранное на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не добавлено в избранное"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Открыть приложение \"<xliff:g id="APP_LABEL">%1$s</xliff:g>\""</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Воспроизвести медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\""</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Воспроизвести медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" из приложения \"<xliff:g id="APP_LABEL">%2$s</xliff:g>\""</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Для вас"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Отменить"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Чтобы начать трансляцию на устройстве \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\", подойдите к нему ближе."</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Чтобы начать воспроизведение здесь, подойдите ближе к устройству (<xliff:g id="DEVICENAME">%1$s</xliff:g>)."</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Произошла ошибка. Повторите попытку."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Загрузка…"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Трансляция медиаконтента"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Трансляция: <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Нет ответа. Проверьте приложение."</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не найдено."</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Управление недоступно"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Ошибка. Повторите попытку."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Добавить виджеты"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Изменить виджеты"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Добавить приложение"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Добавление устройств вывода"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Группа"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Выбрано 1 устройство"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки и дисплеи"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Рекомендуемые устройства"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Требуется премиум-аккаунт"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Не удалось запустить трансляцию"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не удалось сохранить. Повторите попытку."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не удалось сохранить."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер сборки"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер сборки скопирован в буфер обмена."</string>
     <string name="basic_status" msgid="2315371112182658176">"Открытый чат"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера отключена"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон отключен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон отключены"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Ассистент вас слушает"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# уведомление}one{# уведомление}few{# уведомления}many{# уведомлений}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Разрешить разовый доступ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Запретить"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"В журналы записывается информация о том, что происходит на устройстве. Приложения могут использовать их, чтобы находить и устранять неполадки.\n\nТак как некоторые журналы могут содержать конфиденциальную информацию, доступ ко всем журналам следует предоставлять только тем приложениям, которым вы доверяете. \n\nЕсли вы не предоставите такой доступ этому приложению, оно по-прежнему сможет просматривать свои журналы. Не исключено, что некоторые журналы или сведения на вашем устройстве будут по-прежнему доступны его производителю."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Подробнее"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Подробнее: <xliff:g id="URL">%s</xliff:g>."</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Открыть \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Приложение установлено."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• В Кошельке есть хотя бы одна карта."</string>
@@ -1056,7 +1059,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отмена"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Перевернуть сейчас"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Разложите телефон, чтобы селфи получилось лучше"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перевернули телефон передним экраном к себе?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Перейти на передний экран?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Используйте основную камеру с широкоугольным объективом и высоким разрешением."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Этот экран отключится"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Складное устройство в разложенном виде"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Согласно правилам вашей организации вы можете совершать телефонные звонки только из рабочего профиля."</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в рабочий профиль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрыть"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Настройки блокировки экрана"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index bee211a..8ca011d 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"පහළ සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"වම් සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"දකුණු සීමාව සියයට <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"වැඩ තිර රූ <xliff:g id="APP">%1$s</xliff:g> යෙදුම තුළ සුරැකෙයි"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"කාර්යාල පැතිකඩේ <xliff:g id="APP">%1$s</xliff:g> තුළ සුරකින ලදි"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ගොනු"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> සහ අනෙකුත් විවෘත යෙදුම් මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"සටහනට එක් කරන්න"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"තිර රෙකෝඩරය"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"මුහුණ හඳුනා ගන්නා ලදි. විවෘත කිරීමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"මුහුණ මගින් අගුලු හරින ලදි"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"මුහුණ හඳුනා ගන්නා ලදි"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"වමට ගෙන යන්න"</item>
-    <item msgid="5558598599408514296">"පහළට ගෙන යන්න"</item>
-    <item msgid="4844142668312841831">"දකුණට ගෙන යන්න"</item>
-    <item msgid="5640521437931460125">"ඉහළට ගෙන යන්න"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC භාවිත කිරීමට අගුලු හරින්න"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"පාලන එක් කිරීමට යෙදුම තෝරා ගන්න"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# පාලනයක් එක් කර ඇත.}one{පාලන #ක් එක් කර ඇත.}other{පාලන #ක් එක් කර ඇත.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ඉවත් කළා"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> එක් කරන්න ද?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"ඔබ <xliff:g id="APPNAME">%s</xliff:g> එක් කළ විට, එයට මෙම පැනලයට පාලන සහ අන්තර්ගතය එක් කළ හැක. සමහර යෙදුම්වල, ඔබට මෙහි පෙන්වන්නේ කුමන පාලන ද යන්න තෝරා ගැනීමට හැක."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ප්‍රියතම කළා"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ප්‍රියතම කළා, තත්ත්ව <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ප්‍රියතම වෙතින් ඉවත් කළා"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> විවෘත කරන්න"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%2$s</xliff:g> වෙතින් වාදනය කරන්න"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"ඔබට"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"පසුගමනය කරන්න"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> හි වාදනය කිරීමට වඩාත් ළං වන්න"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"මෙහි වාදනය කිරීම සඳහා, <xliff:g id="DEVICENAME">%1$s</xliff:g> වෙත සමීප වන්න"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"යම් දෙයක් වැරදිණි. නැවත උත්සාහ කරන්න."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"පූරණය වේ"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ටැබ්ලටය"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"අක්‍රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"පාලනය ලබා ගත නොහැකිය"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"දෝෂයකි, නැවත උත්සාහ කරන්න"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"පාලන එක් කරන්න"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"පාලන සංස්කරණය කරන්න"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"යෙදුම එක් කරන්න"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"ප්‍රතිදාන එක් කරන්න"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"සමූහය"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"උපාංග 1ක් තෝරන ලදී"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ස්පීකර් සහ සංදර්ශක"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"යෝජිත උපාංග"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"පාරිතෝෂික ගිණුමක් අවශ්‍යයි"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"විකාශනය කළ නොහැකිය"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"සුරැකිය නොහැකිය. නැවත උත්සාහ කරන්න."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"සුරැකිය නොහැකිය."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"නිමැවුම් අංකය"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"නිමැවුම් අංකය පසුරු පුවරුවට පිටපත් කරන ලදි."</string>
     <string name="basic_status" msgid="2315371112182658176">"සංවාදය විවෘත කරන්න"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"කැමරාව ක්‍රියා විරහිතයි"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"මයිකය ක්‍රියා විරහිතයි"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"කැමරාව සහ මයික් ක්‍රියාවිරහිතයි"</string>
+    <string name="dream_overlay_status_bar_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_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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"එක් වරක් ප්‍රවේශය ඉඩ දෙන්න"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ඉඩ නොදෙන්න"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"උපාංග ලොග ඔබේ උපාංගයෙහි සිදු වන දේ වාර්තා කරයි. ගැටලු සොයා ගැනීමට සහ නිරාකරණයට යෙදුම්වලට මෙම ලොග භාවිතා කළ හැක.\n\nසමහර ලොගවල සංවේදී තතු අඩංගු විය හැකි බැවින්, ඔබ විශ්වාස කරන යෙදුම්වලට පමණක් සියලු උපාංග ලොග වෙත ප්‍රවේශ වීමට ඉඩ දෙන්න. \n\nඔබ මෙම යෙදුමට සියලු උපාංග ලොග වෙත ප්‍රවේශ වීමට ඉඩ නොදෙන්නේ නම්, එයට තවමත් එහිම ලොග වෙත ප්‍රවේශ විය හැක. ඔබේ උපාංග නිෂ්පාදකයාට තවමත් ඔබේ උපාංගයෙහි සමහර ලොග හෝ තතු වෙත ප්‍රවේශ විය හැක."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"තව දැන ගන්න"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> තුළින් තව දැන ගන්න"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> විවෘත කරන්න"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• යෙදුම සකසා ඇත"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Wallet වෙත අවම වශයෙන් එක කාඩ්පතක් එක් කර ඇත"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"ඔබේ වැඩ ප්‍රතිපත්තිය ඔබට කාර්යාල පැතිකඩෙන් පමණක් දුරකථන ඇමතුම් ලබා ගැනීමට ඉඩ සලසයි"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"කාර්යාල පැතිකඩ වෙත මාරු වන්න"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"වසන්න"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"අගුළු තිර සැකසීම්"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index beb0ee07..fd67778 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> %% dolnej hranice"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> %% ľavej hranice"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> %% pravej hranice"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Pracovné snímky obrazovky sú uložené v aplikácii <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Uložená v aplikácii <xliff:g id="APP">%1$s</xliff:g> v pracovnom profile"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikácia <xliff:g id="APPNAME">%1$s</xliff:g> zaznamenala túto snímku obrazovky."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ďalšie otvorené aplikácie zaznamenali túto snímku obrazovky."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridať do poznámky"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Tvár bola rozpoznaná. Otvorte stlačením ikony odomknutia."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Odomknuté tvárou"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Tvár bola rozpoznaná"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Posunúť doľava"</item>
-    <item msgid="5558598599408514296">"Posunúť nadol"</item>
-    <item msgid="4844142668312841831">"Posunúť doprava"</item>
-    <item msgid="5640521437931460125">"Posunúť nahor"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Potiahnutím nahor to skúste znova"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ak chcete použiť NFC, odomknite"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zariadenie patrí vašej organizácii"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Vyberte aplikáciu, ktorej ovládače si chcete pridať"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Bol pridaný # ovládací prvok.}few{Boli pridané # ovládacie prvky.}many{# controls added.}other{Bolo pridaných # ovládacích prvkov.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Odstránené"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Chcete pridať aplikáciu <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Keď pridáte aplikáciu <xliff:g id="APPNAME">%s</xliff:g>, bude môcť pridať ovládanie a obsah na tento panel. V prípade niektorých aplikácií môžete vybrať, ktoré ovládacie prvky sa tu majú zobraziť."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pridané medzi obľúbené"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pridané medzi obľúbené, pozícia <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstránené z obľúbených"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Otvoriť <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Prehrať skladbu <xliff:g id="SONG_NAME">%1$s</xliff:g> z aplikácie <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Pre vás"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Späť"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Ak chcete prehrávať v zariadení <xliff:g id="DEVICENAME">%1$s</xliff:g>, priblížte sa k nemu"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ak tu chcete prehrávať obsah, priblížte zariadenie k zariadeniu <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Niečo sa pokazilo. Skúste to znova."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Načítava sa"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Prenášajú sa médiá"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Prenáša sa <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ovládač nie je k dispozícii"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Chyba, skúste to znova"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Pridať ovládače"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Upraviť ovládače"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Pridať aplikáciu"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Pridanie výstupov"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 vybrané zariadenie"</string>
@@ -919,7 +916,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Vyžaduje prémiový účet"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nedá sa vysielať"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nedá sa uložiť. Skúste to znova."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nedá sa uložiť."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Číslo zostavy"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Číslo zostavy bolo skopírované do schránky."</string>
     <string name="basic_status" msgid="2315371112182658176">"Otvorená konverzácia"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera je vypnutá"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofón je vypnutý"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera a mikrofón sú vypnuté"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistent počúva"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# upozornenie}few{# upozornenia}many{# notifications}other{# upozornení}}"</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">"Zapisovanie poznámok"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Povoliť jednorazový prístup"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Nepovoliť"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Denníky zariadenia zaznamenávajú, čo sa deje vo vašom zariadení. Aplikácie môžu pomocou týchto denníkov vyhľadávať a riešiť problémy.\n\nNiektoré denníky môžu obsahovať citlivé údaje, preto povoľte prístup k všetkým denníkom zariadenia iba dôveryhodným aplikáciám. \n\nAk tejto aplikácii nepovolíte prístup k všetkým denníkom zariadenia, stále bude mať prístup k vlastným denníkom. Výrobca vášho zariadenia bude mať naďalej prístup k niektorým denníkom alebo informáciám vo vašom zariadení."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Ďalšie informácie"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Viac sa dozviete na <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvoriť <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikácia je nastavená"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Do Peňaženky bola pridaná minimálne jedna karta"</string>
@@ -1054,9 +1057,9 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• K dispozícii je minimálne jedno zariadenie"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržte skratku"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Prevráťte"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Otočiť"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Ak chcete lepšie selfie, rozložte telefón"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Prevrátiť na pred. obrazovku pre lepšie selfie?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Otočiť na prednú obrazovku pre lepšie selfie?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Pomocou zadného fotoaparátu vytvorte širšiu fotku s vyšším rozlíšením."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Táto obrazovka sa vypne"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Rozloženie skladacieho zariadenia"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Prepnúť na pracovný profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zavrieť"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavenia uzamknutej obrazovky"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 72eddd3..6122f38 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Meja spodaj <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Meja levo <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Meja desno <xliff:g id="PERCENT">%1$d</xliff:g> odstotkov"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Posnetki zaslona v delovnem profilu so shranjeni v aplikaciji <xliff:g id="APP">%1$s</xliff:g>."</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Shranjeno v aplikaciji <xliff:g id="APP">%1$s</xliff:g> v delovnem profilu"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Datoteke"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je zaznala ta posnetek zaslona."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> in druge odprte aplikacije so zaznale ta posnetek zaslona."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj v zapisek"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snemalnik zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Obraz je prepoznan. Za odpiranje pritisnite ikono za odklepanje."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Odklenjeno z obrazom"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Obraz je prepoznan"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Premik levo"</item>
-    <item msgid="5558598599408514296">"Premik navzdol"</item>
-    <item msgid="4844142668312841831">"Premik desno"</item>
-    <item msgid="5640521437931460125">"Premik navzgor"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati NFC."</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Izberite aplikacijo za dodajanje kontrolnikov"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrolnik je dodan.}one{# kontrolnik je dodan.}two{# kontrolnika sta dodana.}few{# kontrolniki so dodani.}other{# kontrolnikov je dodanih.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite dodati aplikacijo <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Ko dodate aplikacijo <xliff:g id="APPNAME">%s</xliff:g>, lahko ta doda kontrolnike in vsebino v to podokno. V nekaterih aplikacijah lahko izberete, kateri kontrolniki so prikazani tukaj."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano med priljubljene, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstranjeno iz priljubljenih"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Odpri aplikacijo <xliff:g id="APP_LABEL">%1$s</xliff:g>."</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Predvajaj skladbo <xliff:g id="SONG_NAME">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_LABEL">%2$s</xliff:g>."</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Za vas"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Razveljavi"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Za predvajanje v napravi <xliff:g id="DEVICENAME">%1$s</xliff:g> bolj približajte telefon"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Če želite predvajati tukaj, se približajte napravi <xliff:g id="DEVICENAME">%1$s</xliff:g>."</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Prišlo je do napake. Poskusite znova."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Nalaganje"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablični računalnik"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, poglejte aplikacijo"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ni mogoče najti"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolnik ni na voljo"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Napaka, poskusite znova"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Dodajte kontrolnike"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Uredite kontrolnike"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Dodaj aplikacijo"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Dodajanje izhodov"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Skupina"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Izbrana je ena naprava"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Zvočniki in zasloni"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Predlagane naprave"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Obvezen je plačljivi račun"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Oddajanje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osebe v bližini z združljivo napravo Bluetooth lahko poslušajo predstavnost, ki jo oddajate."</string>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Oddajanje ni mogoče"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ni mogoče shraniti. Poskusite znova."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ni mogoče shraniti."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Delovna različica"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Delovna različica je bila kopirana v odložišče."</string>
     <string name="basic_status" msgid="2315371112182658176">"Odprt pogovor"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Fotoaparat je izklopljen"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon je izklopljen"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Fotoaparat in mikrofon sta izklopljena."</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Pomočnik posluša."</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# obvestilo}one{# obvestilo}two{# obvestili}few{# obvestila}other{# obvestil}}"</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">"Ustvarjanje zapiskov"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Dovoli enkratni dostop"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne dovoli"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"V dnevnikih naprave se beleži dogajanje v napravi. Aplikacije lahko te dnevnike uporabijo za iskanje in odpravljanje težav.\n\nNekateri dnevniki morda vsebujejo občutljive podatke, zato dostop do vseh dnevnikov naprave omogočite le aplikacijam, ki jim zaupate. \n\nČe tej aplikaciji ne dovolite dostopa do vseh dnevnikov naprave, bo aplikacija kljub temu lahko dostopala do svojih dnevnikov. Proizvajalec naprave bo morda lahko kljub temu dostopal do nekaterih dnevnikov ali podatkov v napravi."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Več o tem"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Več informacij je na voljo na strani <xliff:g id="URL">%s</xliff:g>."</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Odpri aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacija mora biti nastavljena."</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Vsaj ena kartica mora biti dodana v Denarnico."</string>
@@ -1054,7 +1059,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Na voljo mora biti vsaj ena naprava."</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržite bližnjico"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Prekliči"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrnite"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Obrni"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Razprite telefon za boljši selfi"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Obrnite telefon na sprednji zaslon za boljši selfi"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Uporabite hrbtni fotoaparat, da posnamete širšo sliko višje ločljivosti."</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Preklopi na delovni profil"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Zapri"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Nastavitve zaklepanja zaslona"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 0cbd9cd..dd75f30 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Kufiri i poshtëm <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Kufiri i majtë <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Kufiri i djathtë <xliff:g id="PERCENT">%1$d</xliff:g> për qind"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Pamjet e ekranit të punës janë ruajtur në aplikacionin \"<xliff:g id="APP">%1$s</xliff:g>\""</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Ruajtur në <xliff:g id="APP">%1$s</xliff:g> në profilin e punës"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Skedarë"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> zbuloi këtë pamje ekrani."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dhe aplikacionet e tjera të hapura zbuluan këtë pamje ekrani."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Shto te shënimi"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Fytyra u njoh. Shtyp ikonën e shkyçjes për ta hapur."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"U shkyç me fytyrë"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Fytyra u njoh"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Lëvize majtas"</item>
-    <item msgid="5558598599408514296">"Lëvize poshtë"</item>
-    <item msgid="4844142668312841831">"Lëvize djathtas"</item>
-    <item msgid="5640521437931460125">"Lëvize lart"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Rrëshqit lart për të provuar përsëri"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Shkyçe për të përdorur NFC-në"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Zgjidh aplikacionin për të shtuar kontrollet"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{U shtua # kontroll.}other{U shtuan # kontrolle.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"E hequr"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Të shtohet <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Kur shton <xliff:g id="APPNAME">%s</xliff:g>, ai mund t\'i shtojë kontrolle dhe përmbajtje këtij paneli. Në disa aplikacione, mund të zgjedhësh se cilat kontrolle shfaqen këtu."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"E shtuar te të preferuarat"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"E shtuar te të preferuarat, pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"E hequr nga të preferuarat"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Hap <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Luaj <xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Luaj <xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Për ty"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Zhbëj"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Afrohu për të luajtur në <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Për ta luajtur këtu, afrohu më shumë te <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Ndodhi një gabim. Provo përsëri."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Po ngarkohet"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Po transmeton median tënde"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Po transmeton <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrolli është i padisponueshëm"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Gabim, provo sërish"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Shto kontrollet"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Modifiko kontrollet"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Shto një aplikacion"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Shto daljet"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupi"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 pajisje e zgjedhur"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Altoparlantët dhe ekranet"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Pajisjet e sugjeruara"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Kërkon llogari premium"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Si funksionon transmetimi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmetimi"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personat në afërsi me ty me pajisje të përputhshme me Bluetooth mund të dëgjojnë median që ti po transmeton"</string>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Nuk mund të transmetohet"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Nuk mund të ruhet. Provo përsëri."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Nuk mund të ruhet."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numri i ndërtimit"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Numri i ndërtimit u kopjua te kujtesa e fragmenteve"</string>
     <string name="basic_status" msgid="2315371112182658176">"Hap bisedën"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera është joaktive"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofoni është joaktiv"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera dhe mikrofoni janë joaktivë"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"\"Asistenti\" po dëgjon"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# njoftim}other{# njoftime}}"</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">"Mbajtja e shënimeve"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Lejo qasjen vetëm për një herë"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Mos lejo"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Evidencat e pajisjes regjistrojnë çfarë ndodh në pajisjen tënde. Aplikacionet mund t\'i përdorin këto evidenca për të gjetur dhe rregulluar problemet.\n\nDisa evidenca mund të përmbajnë informacione delikate, ndaj lejo vetëm aplikacionet që u beson të kenë qasje te të gjitha evidencat e pajisjes. \n\nNëse nuk e lejon këtë aplikacion që të ketë qasje te të gjitha evidencat e pajisjes, ai mund të vazhdojë të ketë qasje tek evidencat e tij. Prodhuesi i pajisjes sate mund të jetë ende në gjendje që të ketë qasje te disa evidenca ose informacione në pajisjen tënde."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Mëso më shumë"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Mëso më shumë në <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Hap \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Aplikacioni është konfiguruar"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Të paktën një kartë të jetë shtuar në \"Portofol\""</string>
@@ -1054,7 +1057,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Ofrohet të paktën një pajisje"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prek dhe mbaj shtypur shkurtoren"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"U kthye tani"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Ktheje tani"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Shpalos telefonin për një selfi më të mirë"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Të kthehet tek ekrani para për selfi më të mirë?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Përdor lenten e kamerës së pasme për një fotografi më të gjerë me rezolucion më të lartë."</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Kalo te profili i punës"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Mbyll"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Cilësimet e ekranit të kyçjes"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4c685a9..1cdf858 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Доња ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Лева ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Десна ивица <xliff:g id="PERCENT">%1$d</xliff:g> посто"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Снимци екрана за посао се чувају у апликацији <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Сачувано је у апликацији <xliff:g id="APP">%1$s</xliff:g> на пословном профилу"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Фајлови"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Апликација <xliff:g id="APPNAME">%1$s</xliff:g> је открила овај снимак екрана."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и друге отворене апликације су откриле овај снимак екрана."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај у белешку"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Лице препознато. Притисните икону откључавања да бисте отворили."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Откључано је лицем"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Лице је препознато"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Померите налево"</item>
-    <item msgid="5558598599408514296">"Померите надоле"</item>
-    <item msgid="4844142668312841831">"Померите надесно"</item>
-    <item msgid="5640521437931460125">"Померите нагоре"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Одаберите апликацију за додавање контрола"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Желите ли да додате <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Када додате апликацију <xliff:g id="APPNAME">%s</xliff:g>, она може да додаје контроле и садржај у ово окно. У неким апликацијама можете да изаберете које ће се контроле овде приказивати."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Уклоњено је из омиљених"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Отворите <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Пустите <xliff:g id="SONG_NAME">%1$s</xliff:g> из апликације <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"За вас"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Опозови"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Приближите да бисте пуштали музику на: <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Да бисте пуштали садржај овде, приближите уређају <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Дошло је до грешке. Пробајте поново."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Учитава се"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"таблет"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Контрола није доступна"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Грешка. Пробајте поново"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Додај контроле"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Измени контроле"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Додај апликацију"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додајте излазе"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Изабран је 1 уређај"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Звучници и екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Предложени уређаји"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Захтева премијум налог"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Емитовање није успело"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Чување није успело. Пробајте поново."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Чување није успело."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Број верзије"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Број верзије је копиран у привремену меморију."</string>
     <string name="basic_status" msgid="2315371112182658176">"Отворите конверзацију"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камера је искључена"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Микрофон је искључен"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камера и микрофон су искључени"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Помоћник слуша"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# обавештење}one{# обавештење}few{# обавештења}other{# обавештења}}"</string>
     <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string>
     <string name="note_task_button_label" msgid="8718616095800343136">"Прављење бележака"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Дозволи једнократан приступ"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не дозволи"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Евиденције уређаја региструју шта се дешава на уређају. Апликације могу да користе те евиденције да би пронашле и решиле проблеме.\n\nНеке евиденције могу да садрже осетљиве информације, па приступ свим евиденцијама уређаја треба да дозвољавате само апликацијама у које имате поверења. \n\nАко не дозволите овој апликацији да приступа свим евиденцијама уређаја, она и даље може да приступа сопственим евиденцијама. Произвођач уређаја ће можда и даље моћи да приступа неким евиденцијама или информацијама на уређају."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Сазнајте више"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Сазнајте више на <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• да је апликација подешена"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• да је у Новчаник додата барем једна картица"</string>
@@ -1054,7 +1059,7 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• да је доступан барем један уређај"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Додирните и задржите пречицу"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрните"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Обрни"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Отворите телефон за бољи селфи"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Желите да обрнете на предњи екран за бољи селфи?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Користите задњу камеру да бисте снимили ширу слику са вишом резолуцијом."</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Смернице за посао вам омогућавају да телефонирате само са пословног профила"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Пређи на пословни профил"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Затвори"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Подешавања закључаног екрана"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 94cd420..92e0ad4 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Vänster gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Höger gräns: <xliff:g id="PERCENT">%1$d</xliff:g> procent"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Jobbskärmbilder sparas i <xliff:g id="APP">%1$s</xliff:g>-appen"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Sparad i <xliff:g id="APP">%1$s</xliff:g> i jobbprofilen"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> identifierade skärmbilden."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> och andra öppna appar identifierade skärmbilden."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lägg till i anteckning"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Upplåst med ansiktslås"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Ansiktet har identifierats"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Flytta åt vänster"</item>
-    <item msgid="5558598599408514296">"Flytta nedåt"</item>
-    <item msgid="4844142668312841831">"Flytta åt höger"</item>
-    <item msgid="5640521437931460125">"Flytta uppåt"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Svep uppåt om du vill försöka igen"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås upp om du vill använda NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Den här enheten tillhör organisationen"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Välj en app om du vill lägga till snabbkontroller"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll har lagts till.}other{# kontroller har lagts till.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Vill du lägga till <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"När du lägger till <xliff:g id="APPNAME">%s</xliff:g> kan den lägga till kontroller och innehåll i den här panelen. I vissa appar kan du styra vilka kontroller som visas här."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Har lagts till som favorit, plats <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Har tagits bort från favoriter"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Öppna <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Spela upp <xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Spela upp <xliff:g id="SONG_NAME">%1$s</xliff:g> från <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"För dig"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Ångra"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Flytta närmare för att spela upp på <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Kom närmare <xliff:g id="DEVICENAME">%1$s</xliff:g> om du vill spela upp här"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Något gick fel. Försök igen."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Läser in"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"surfplatta"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Styrning är inte tillgänglig"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Fel, försök igen"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Lägg till snabbkontroller"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Redigera snabbkontroller"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Lägg till app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Lägg till utgångar"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grupp"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 enhet har valts"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Högtalare och skärmar"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Förslag på enheter"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premiumkonto krävs"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Det gick inte att sända ut"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Det gick inte att spara. Försök igen."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Det gick inte att spara."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Versionsnummer"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Versionsnumret har kopierats till urklipp."</string>
     <string name="basic_status" msgid="2315371112182658176">"Öppen konversation"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kameran är av"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofonen är av"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kameran och mikrofonen är avstängda"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistenten lyssnar"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# avisering}other{# aviseringar}}"</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">"Anteckningar"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Tillåt engångsåtkomst"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Tillåt inte"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"I enhetsloggar registreras vad som händer på enheten. Appar kan använda dessa loggar för att hitta och åtgärda problem.\n\nVissa loggar kan innehålla känsliga uppgifter, så du ska bara bevilja appar du litar på åtkomst till alla enhetsloggar. \n\nEn app har åtkomst till sina egna loggar även om du inte ger den åtkomst till alla enhetsloggar. Enhetens tillverkare kan fortfarande ha åtkomst till vissa loggar eller viss information på enheten."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Läs mer"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Läs mer på <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Öppna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• appen har konfigurerats"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• minst ett kort har lagts till i Wallet"</string>
@@ -1056,7 +1061,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Vänd nu"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Vik upp telefonen för att ta en bättre selfie"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vill du ta en bättre selfie med främre skärmen?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Vill du ta en bättre selfie med främre kameran?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Använd den bakre kameran för att ta ett mer vidsträckt foto med högre upplösning."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Den här skärmen inaktiveras"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En vikbar enhet viks upp"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Byt till jobbprofilen"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Stäng"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Inställningar för låsskärm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9fbaf92..fec66b2 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Mpaka wa sehemu ya chini wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Mpaka wa sehemu ya kushoto wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Mpaka wa sehemu ya kulia wa asilimia <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Picha ya skrini ya kazi huhifadhiwa kwenye programu ya <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Imehifadhiwa kwenye <xliff:g id="APP">%1$s</xliff:g> katika wasifu wa kazini"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Faili"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> imetambua picha hii ya skrini."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> na zingine zinazotumika zimetambua picha hii ya skrini."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ongeza kwenye dokezo"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Kinasa Skrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili ufungue."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Imefunguliwa kwa kutumia uso"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Uso umetambuliwa"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Sogeza kushoto"</item>
-    <item msgid="5558598599408514296">"Sogeza chini"</item>
-    <item msgid="4844142668312841831">"Sogeza kulia"</item>
-    <item msgid="5640521437931460125">"Sogeza juu"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Telezesha kidole juu ili ujaribu tena"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Fungua ili utumie NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Chagua programu ili uweke vidhibiti"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Umeweka kidhibiti #.}other{Umeweka vidhibiti #.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ungependa kuweka <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Unapoweka <xliff:g id="APPNAME">%s</xliff:g>, inaweza kuweka vidhibiti na maudhui kwenye kidirisha hiki. Katika baadhi ya programu, unaweza kuchagua ni vidhibiti vipi vionekane hapa."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kimewekwa kwenye vipendwa, nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Kimeondolewa kwenye vipendwa"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Fungua <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Cheza <xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Cheza <xliff:g id="SONG_NAME">%1$s</xliff:g> katika <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Kwa Ajili Yako"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Tendua"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sogeza karibu ili ucheze kwenye <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ili ucheze maudhui kwenye kifaa hiki, sogeza karibu na <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Hitilafu fulani imetokea. Jaribu tena."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Inapakia"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"kompyuta kibao"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kidhibiti hakipatikani"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Hitilafu, jaribu tena"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Weka vidhibiti"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Badilisha vidhibiti"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Weka programu"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Weka vifaa vya kutoa sauti"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Kikundi"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Umechagua kifaa 1"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Spika na Skrini"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Vifaa Vilivyopendekezwa"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Inahitaji akaunti ya kulipia"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jinsi utangazaji unavyofanya kazi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Tangaza"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Watu walio karibu nawe wenye vifaa oanifu vya Bluetooth wanaweza kusikiliza maudhui unayoyatangaza"</string>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Imeshindwa kutuma arifa"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Imeshindwa kuhifadhi. Jaribu tena."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Imeshindwa kuhifadhi."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nambari ya muundo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nambari ya muundo imewekwa kwenye ubao wa kunakili."</string>
     <string name="basic_status" msgid="2315371112182658176">"Fungua mazungumzo"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera imezimwa"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Maikrofoni imezimwa"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera na maikrofoni zimezimwa"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Programu ya Mratibu inasikiliza"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Arifa #}other{Arifa #}}"</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">"Kuandika vidokezo"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Ruhusu ufikiaji wa mara moja"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Usiruhusu"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Kumbukumbu za kifaa hurekodi kinachofanyika kwenye kifaa chako. Programu zinaweza kutumia kumbukumbu hizi ili kutambua na kurekebisha hitilafu.\n\nHuenda baadhi ya kumbukumbu zikawa na taarifa nyeti, hivyo ruhusu tu programu unazoziamini kufikia kumbukumbu zote za kifaa. \n\nIwapo hutaruhusu programu hii ifikie kumbukumbu zote za kifaa, bado inaweza kufikia kumbukumbu zake yenyewe. Huenda mtengenezaji wa kifaa chako bado akaweza kufikia baadhi ya kumbukumbu au taarifa zilizopo kwenye kifaa chako."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Pata maelezo zaidi"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Pata maelezo zaidi katika <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Fungua <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Programu hii imewekewa mipangilio"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Angalau kadi moja imewekwa kwenye Pochi"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Tumia wasifu wa kazini"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Funga"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Mipangilio ya skrini iliyofungwa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 5d78e4e..2a27b47 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -45,8 +45,6 @@
     <item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">0.45</item>
     <dimen name="controls_task_view_right_margin">8dp</dimen>
 
-    <dimen name="status_bar_header_height_keyguard">42dp</dimen>
-
     <dimen name="lockscreen_shade_max_over_scroll_amount">32dp</dimen>
 
     <dimen name="status_view_margin_horizontal">8dp</dimen>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index db7fb48..45b137a 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -16,8 +16,9 @@
 */
 -->
 <resources>
-    <!-- Height of the status bar header bar when on Keyguard -->
-    <dimen name="status_bar_header_height_keyguard">60dp</dimen>
+    <!-- Height of the status bar header bar when on Keyguard.
+         On large screens should be the same as the regular status bar. -->
+    <dimen name="status_bar_header_height_keyguard">@dimen/status_bar_height</dimen>
 
     <!-- Size of user icon + frame in the qs user picker (incl. frame) -->
     <dimen name="qs_framed_avatar_size">60dp</dimen>
@@ -51,9 +52,6 @@
     <!-- Text size for user name in user switcher -->
     <dimen name="kg_user_switcher_text_size">18sp</dimen>
 
-    <dimen name="controls_header_bottom_margin">12dp</dimen>
-    <dimen name="controls_top_margin">24dp</dimen>
-
     <dimen name="global_actions_grid_item_layout_height">80dp</dimen>
 
     <dimen name="qs_brightness_margin_bottom">16dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index 122806a..9ed9360 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -17,14 +17,11 @@
 */
 -->
 <resources>
-    <dimen name="controls_padding_horizontal">205dp</dimen>
     <dimen name="split_shade_notifications_scrim_margin_bottom">24dp</dimen>
     <dimen name="notification_panel_margin_bottom">64dp</dimen>
 
     <dimen name="keyguard_split_shade_top_margin">72dp</dimen>
 
-    <dimen name="status_bar_header_height_keyguard">56dp</dimen>
-
     <dimen name="status_view_margin_horizontal">24dp</dimen>
 
     <dimen name="qs_media_session_height_expanded">184dp</dimen>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 927059a..8f59df6 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -19,7 +19,7 @@
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">1dp</dimen>
 
-    <dimen name="controls_padding_horizontal">75dp</dimen>
+    <dimen name="controls_padding_horizontal">40dp</dimen>
 
     <dimen name="large_screen_shade_header_height">56dp</dimen>
 
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index dd99594..20889ba 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"கீழ் எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"இடது எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"வலது எல்லை <xliff:g id="PERCENT">%1$d</xliff:g> சதவீதம்"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"பணிக் கணக்கு ஸ்கிரீன்ஷாட்டுகள் <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸில் சேமிக்கப்படும்"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"பணிக் கணக்கில் உள்ள <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸில் சேமிக்கப்பட்டது"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> கண்டறிந்துள்ளது."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> மற்றும் திறந்திருக்கும் பிற ஆப்ஸ் கண்டறிந்துள்ளன."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"குறிப்பில் சேர்"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"முகம் அங்கீகரிக்கப்பட்டது. திறக்க அன்லாக் ஐகானை அழுத்தவும்."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"முகத்தால் அன்லாக் செய்யப்பட்டது"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"முகம் அங்கீகரிக்கப்பட்டது"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"இடதுபுறம் நகர்த்துங்கள்"</item>
-    <item msgid="5558598599408514296">"கீழே நகர்த்துங்கள்"</item>
-    <item msgid="4844142668312841831">"வலதுபுறம் நகர்த்துங்கள்"</item>
-    <item msgid="5640521437931460125">"மேலே நகர்த்துங்கள்"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"கட்டுப்பாடுகளைச் சேர்க்க வேண்டிய ஆப்ஸைத் தேர்ந்தெடுங்கள்"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# கட்டுப்பாடு சேர்க்கப்பட்டது.}other{# கட்டுப்பாடுகள் சேர்க்கப்பட்டன.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"அகற்றப்பட்டது"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ஆப்ஸைச் சேர்க்கவா?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"இந்தப் பேனலில் <xliff:g id="APPNAME">%s</xliff:g> ஆப்ஸைச் சேர்க்கும்போது கட்டுப்பாடுகளையும் உள்ளடக்கத்தையும் அது சேர்க்கலாம். இருப்பினும், சில ஆப்ஸில் எந்தெந்தக் கட்டுப்பாடுகள் இங்கே காட்டப்பட வேண்டும் என்பதை நீங்களே தேர்வுசெய்யலாம்."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"பிடித்தவற்றில் சேர்க்கப்பட்டது"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"பிடித்தவற்றில் சேர்க்கப்பட்டது, நிலை <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"பிடித்தவற்றிலிருந்து நீக்கப்பட்டது"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ஆப்ஸைத் திறங்கள்"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="SONG_NAME">%1$s</xliff:g> பாடலை <xliff:g id="APP_LABEL">%2$s</xliff:g> ஆப்ஸில் பிளேசெய்"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"உங்களுக்கானவை"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"செயல்தவிர்"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> சாதனத்தில் இயக்க உங்கள் சாதனத்தை அருகில் எடுத்துச் செல்லுங்கள்"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"இங்கு பிளே செய்ய உங்கள் சாதனத்தை <xliff:g id="DEVICENAME">%1$s</xliff:g>அருகில் நகர்த்துங்கள்"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ஏதோ தவறாகிவிட்டது. மீண்டும் முயலவும்."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"ஏற்றுகிறது"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"டேப்லெட்"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"கட்டுப்பாடு இல்லை"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"பிழை, மீண்டும் முயலவும்"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"கட்டுப்பாடுகளைச் சேர்த்தல்"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"கட்டுப்பாடுகளை மாற்றுதல்"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ஆப்ஸைச் சேர்"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"அவுட்புட்களைச் சேர்த்தல்"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"குழு"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 சாதனம் தேர்ந்தெடுக்கப்பட்டுள்ளது"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ஸ்பீக்கர்கள் &amp; டிஸ்ப்ளேக்கள்"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"பரிந்துரைக்கப்படும் சாதனங்கள்"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"பிரீமியம் கணக்கு தேவை"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ஒளிபரப்ப முடியவில்லை"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"சேமிக்க முடியவில்லை. மீண்டும் முயலவும்."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"சேமிக்க முடியவில்லை."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"பதிப்பு எண்"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"பதிப்பு எண் கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது."</string>
     <string name="basic_status" msgid="2315371112182658176">"திறந்தநிலை உரையாடல்"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"கேமரா முடக்கப்பட்டுள்ளது"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"மைக் முடக்கப்பட்டுள்ளது"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"கேமராவும் மைக்கும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant கேட்டுக்கொண்டிருக்கிறது"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# அறிவிப்பு}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"ஒருமுறை அணுகலை அனுமதி"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"அனுமதிக்க வேண்டாம்"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"உங்கள் சாதனத்தில் நடப்பவற்றைச் சாதனப் பதிவுகள் ரெக்கார்டு செய்யும். சிக்கல்களைக் கண்டறிந்து சரிசெய்ய ஆப்ஸ் இந்தப் பதிவுகளைப் பயன்படுத்தலாம்.\n\nபாதுகாக்க வேண்டிய தகவல்கள் சில பதிவுகளில் இருக்கக்கூடும் என்பதால் சாதனப் பதிவுகள் அனைத்தையும் அணுக நீங்கள் நம்பும் ஆப்ஸை மட்டுமே அனுமதிக்கவும். \n\nசாதனப் பதிவுகள் அனைத்தையும் அணுக இந்த ஆப்ஸை நீங்கள் அனுமதிக்கவில்லை என்றாலும் அதற்குச் சொந்தமான பதிவுகளை அதனால் அணுக முடியும். உங்கள் சாதனத்திலுள்ள சில பதிவுகளையோ தகவல்களையோ சாதன உற்பத்தியாளரால் தொடர்ந்து அணுக முடியும்."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"மேலும் அறிக"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"மேலும் அறிக: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸைத் திற"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• இந்த ஆப்ஸ் அமைக்கப்பட்டிருக்க வேண்டும்"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletடில் குறைந்தபட்சம் ஒரு கார்டாவது சேர்க்கப்பட்டிருக்க வேண்டும்"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"உங்கள் பணிக் கொள்கையின்படி நீங்கள் பணிக் கணக்கில் இருந்து மட்டுமே ஃபோன் அழைப்புகளைச் செய்ய முடியும்"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"பணிக் கணக்கிற்கு மாறு"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"மூடுக"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"பூட்டுத் திரை அமைப்புகள்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 655f2f9..97cdce5 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"దిగువ సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ఎడమ వైపు సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"కుడి వైపు సరిహద్దు <xliff:g id="PERCENT">%1$d</xliff:g> శాతం"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"వర్క్ స్క్రీన్‌షాట్‌లు <xliff:g id="APP">%1$s</xliff:g> యాప్‌లో సేవ్ చేయబడతాయి"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"వర్క్ ప్రొఫైల్‌లోని <xliff:g id="APP">%1$s</xliff:g>‌లో సేవ్ చేయబడింది"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ఫైల్స్"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఈ స్క్రీన్‌షాట్‌ను గుర్తించింది."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఇతర ఓపెన్ యాప్‌లు ఈ స్క్రీన్‌షాట్‌ను గుర్తించాయి."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"గమనికకు జోడించండి"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"స్క్రీన్ రికార్డర్"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"ముఖం గుర్తించబడింది. తెరవడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"ముఖం గుర్తించబడింది"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"ఎడమవైపుగా జరపండి"</item>
-    <item msgid="5558598599408514296">"కిందికి జరపండి"</item>
-    <item msgid="4844142668312841831">"కుడివైపుగా జరపండి"</item>
-    <item msgid="5640521437931460125">"పైకి జరపండి"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్‌లాక్ చేయండి"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"కంట్రోల్స్‌ను యాడ్ చేయడానికి యాప్‌ను ఎంచుకోండి"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# కంట్రోల్ జోడించబడింది.}other{# కంట్రోల్స్ జోడించబడ్డాయి.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>ను జోడించాలా?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"మీరు <xliff:g id="APPNAME">%s</xliff:g>ను జోడించినప్పుడు, ఇది ఈ ప్యానెల్‌కు కంట్రోల్స్‌ని, కంటెంట్‌ను జోడించగలదు. కొన్ని యాప్‌లలో, ఇక్కడ ఏయే కంట్రోల్స్ కనిపించాలో మీరు ఎంచుకోవచ్చు."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ఇష్టమైనదిగా పెట్టిన గుర్తు తీసివేయబడింది"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g>ను తెరవండి"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి <xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g>‌ను ప్లే చేయండి"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> నుండి <xliff:g id="SONG_NAME">%1$s</xliff:g>‌ను ప్లే చేయండి"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"మీ కోసం"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"చర్య రద్దు"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g>‌లో ప్లే చేయడానికి దగ్గరగా వెళ్లండి"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ఇక్కడ ఆడటానికి, <xliff:g id="DEVICENAME">%1$s</xliff:g>‌కు దగ్గరగా వెళ్లండి"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"ఏదో తప్పు జరిగింది. మళ్లీ ట్రై చేయండి."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"లోడ్ అవుతోంది"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"టాబ్లెట్"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"మీ మీడియా ప్రసారం అవుతోంది"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ప్రసారం అవుతోంది"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ఇన్‌యాక్టివ్, యాప్ చెక్ చేయండి"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"కనుగొనబడలేదు"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"కంట్రోల్ అందుబాటులో లేదు"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"ఎర్రర్, మళ్లీ ప్రయత్నించండి"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"కంట్రోల్స్‌ను జోడించండి"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"కంట్రోల్స్‌ను ఎడిట్ చేయండి"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"యాప్‌ను జోడించండి"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"అవుట్‌పుట్‌లను జోడించండి"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"గ్రూప్"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 పరికరం ఎంచుకోబడింది"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"స్పీకర్‌లు &amp; డిస్‌ప్లేలు"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"సూచించబడిన పరికరాలు"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ప్రీమియం ఖాతా అవసరం"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ప్రసారం చేయడం సాధ్యపడలేదు"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"సేవ్ చేయడం సాధ్యపడదు. మళ్లీ ట్రై చేయండి."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"సేవ్ చేయడం సాధ్యపడదు."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"బిల్డ్ నంబర్"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"బిల్డ్ నంబర్, క్లిప్‌బోర్డ్‌కు కాపీ చేయబడింది."</string>
     <string name="basic_status" msgid="2315371112182658176">"సంభాషణను తెరవండి"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"కెమెరా ఆఫ్‌లో ఉంది"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"మైక్ ఆఫ్‌లో ఉంది"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"కెమెరా, మైక్ ఆఫ్‌లో ఉన్నాయి"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant వింటోంది"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# నోటిఫికేషన్}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"వన్-టైమ్ యాక్సెస్‌ను అనుమతించండి"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"అనుమతించవద్దు"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"మీ పరికరంలో జరిగే దాన్ని పరికర లాగ్‌లు రికార్డ్ చేస్తాయి. సమస్యలను కనుగొని, పరిష్కరించడానికి యాప్‌లు ఈ లాగ్‌లను ఉపయోగిస్తాయి.\n\nకొన్ని లాగ్‌లలో గోప్యమైన సమాచారం ఉండవచ్చు, కాబట్టి మీరు విశ్వసించే యాప్‌లను మాత్రమే అన్ని పరికర లాగ్‌లను యాక్సెస్ చేయడానికి అనుమతించండి. \n\nఅన్ని పరికర లాగ్‌లను యాక్సెస్ చేయడానికి మీరు ఈ యాప్‌ను అనుమతించకపోతే, అది తన స్వంత లాగ్‌లను ఇప్పటికి యాక్సెస్ చేయగలదు. మీ పరికర తయారీదారు ఇప్పటికీ మీ పరికరంలో కొన్ని లాగ్‌లు లేదా సమాచారాన్ని యాక్సెస్ చేయగలరు."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"మరింత తెలుసుకోండి"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>‌లో మరింత తెలుసుకోండి"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>‌ను తెరవండి"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• యాప్ సెటప్ చేయబడి ఉందని"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Walletకు కనీసం ఒక కార్డ్ అయినా జోడించబడి ఉందని"</string>
@@ -1057,7 +1060,7 @@
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"ఇప్పుడే తిప్పండి"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"మెరుగైన సెల్ఫీ కోసం ఫోన్‌ను అన్‌ఫోల్డ్ చేయండి"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"మంచి సెల్ఫీ కోసం ముందు వైపు డిస్‌ప్లేకు తిప్పాలా?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"అధిక రిజల్యూషన్‌తో పెద్ద ఫోటో కోసం వెనుక వైపున ఉన్న కెమెరాను ఉపయోగించండి."</string>
+    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"వెనుక వైపున ఉన్న కెమెరాను ఉపయోగించి అధిక రిజల్యూషన్ గల, మరింత వెడల్పైన ఫోటోను పొందండి."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ ఈ స్క్రీన్ ఆఫ్ అవుతుంది"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"మడవగల పరికరం విప్పబడుతోంది"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"మడవగల పరికరం చుట్టూ తిప్పబడుతోంది"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"మీ వర్క్ పాలసీ, మిమ్మల్ని వర్క్ ప్రొఫైల్ నుండి మాత్రమే ఫోన్ కాల్స్ చేయడానికి అనుమతిస్తుంది"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"వర్క్ ప్రొఫైల్‌కు మారండి"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"మూసివేయండి"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"లాక్ స్క్రీన్ సెట్టింగ్‌లు"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 1d62202..05f643d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"ขอบเขตด้านล่าง <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"ขอบเขตด้านซ้าย <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"ขอบเขตด้านขวา <xliff:g id="PERCENT">%1$d</xliff:g> เปอร์เซ็นต์"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"ภาพหน้าจองานจะบันทึกอยู่ในแอป <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"บันทึกไว้ที่ <xliff:g id="APP">%1$s</xliff:g> ในโปรไฟล์งาน"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"ไฟล์"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ตรวจพบภาพหน้าจอนี้"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> และแอปอื่นๆ ที่เปิดอยู่ตรวจพบภาพหน้าจอนี้"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"เพิ่มลงในโน้ต"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"โปรแกรมบันทึกหน้าจอ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อเปิด"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"ปลดล็อกด้วยใบหน้าแล้ว"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"จดจำใบหน้าได้"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"เลื่อนนิ้วไปทางซ้าย"</item>
-    <item msgid="5558598599408514296">"เลื่อนนิ้วลง"</item>
-    <item msgid="4844142668312841831">"เลื่อนนิ้วไปทางขวา"</item>
-    <item msgid="5640521437931460125">"เลื่อนนิ้วขึ้น"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ปลดล็อกเพื่อใช้ NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"เปิด <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"เปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"เปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> จาก <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"สำหรับคุณ"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"เลิกทำ"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"ขยับไปใกล้มากขึ้นเพื่อเล่นใน <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"ขยับไปใกล้ <xliff:g id="DEVICENAME">%1$s</xliff:g> มากขึ้นเพื่อเล่นที่นี่"</string>
@@ -891,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"เกิดข้อผิดพลาด โปรดลองอีกครั้ง"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"กำลังโหลด"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"แท็บเล็ต"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"กำลังแคสต์สื่อ"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"กำลังแคสต์ <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"ใช้การควบคุมไม่ได้"</string>
@@ -916,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ลำโพงและจอแสดงผล"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"อุปกรณ์ที่แนะนำ"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"ต้องใช้บัญชี Premium"</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>
@@ -928,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"ออกอากาศไม่ได้"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"บันทึกไม่ได้ โปรดลองอีกครั้ง"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"บันทึกไม่ได้"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"หมายเลขบิลด์"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"คัดลอกหมายเลขบิลด์ไปยังคลิปบอร์ดแล้ว"</string>
     <string name="basic_status" msgid="2315371112182658176">"เปิดการสนทนา"</string>
@@ -1028,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"กล้องปิดอยู่"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"ไมค์ปิดอยู่"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"กล้องและไมค์ปิดอยู่"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistant กำลังฟังอยู่"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{การแจ้งเตือน # รายการ}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>
@@ -1043,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"อนุญาตสิทธิ์เข้าถึงแบบครั้งเดียว"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"ไม่อนุญาต"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"บันทึกของอุปกรณ์เก็บข้อมูลสิ่งที่เกิดขึ้นในอุปกรณ์ แอปสามารถใช้บันทึกเหล่านี้เพื่อค้นหาและแก้ไขปัญหา\n\nบันทึกบางรายการอาจมีข้อมูลที่ละเอียดอ่อน คุณจึงควรอนุญาตเฉพาะแอปที่เชื่อถือได้ให้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ \n\nหากคุณไม่อนุญาตให้แอปนี้เข้าถึงบันทึกทั้งหมดของอุปกรณ์ แอปจะยังเข้าถึงบันทึกของตัวเองได้อยู่ ผู้ผลิตอุปกรณ์อาจยังเข้าถึงบันทึกหรือข้อมูลบางรายการในอุปกรณ์ของคุณได้"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ดูข้อมูลเพิ่มเติม"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"ดูข้อมูลเพิ่มเติมที่ <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"เปิด <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• แอปได้รับการตั้งค่าแล้ว"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• มีการเพิ่มบัตรลงใน Wallet อย่างน้อย 1 รายการ"</string>
@@ -1066,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"นโยบายการทำงานอนุญาตให้คุณโทรออกได้จากโปรไฟล์งานเท่านั้น"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"สลับไปใช้โปรไฟล์งาน"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"ปิด"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"การตั้งค่าหน้าจอล็อก"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e29fc9e..8206db1 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa ibaba"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa kaliwa"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"<xliff:g id="PERCENT">%1$d</xliff:g> (na) porsyento sa hangganan sa kanan"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Naka-save ang mga screenshot sa trabaho sa <xliff:g id="APP">%1$s</xliff:g> app"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Na-save sa <xliff:g id="APP">%1$s</xliff:g> sa profile sa trabaho"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Mga File"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> ang screenshot. na ito"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> at ng iba pang bukas na app ang screenshot na ito."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Idagdag sa tala"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder ng Screen"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Nakilala ang mukha. Pindutin ang icon ng unlock para buksan."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Na-unlock gamit ang mukha"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Nakilala ang mukha"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Ilipat pakaliwa"</item>
-    <item msgid="5558598599408514296">"Ibaba"</item>
-    <item msgid="4844142668312841831">"Ilipat pakanan"</item>
-    <item msgid="5640521437931460125">"Itaas"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Mag-swipe pataas para subukan ulit"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"I-unlock para magamit ang NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
@@ -884,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Buksan ang <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"I-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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"I-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Para sa Iyo"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"I-undo"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Lumapit pa para mag-play sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Para mag-play dito, lumapit sa <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -891,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Nagkaproblema. Subukan ulit."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Naglo-load"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Hindi available ang kontrol"</string>
@@ -916,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Mga Speaker at Display"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Mga Iminumungkahing Device"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Nangangailangan ng premium account"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Paano gumagana ang pag-broadcast"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Makakapakinig ang mga taong malapit sa iyo na may mga compatible na Bluetooth device sa media na bino-broadcast mo"</string>
@@ -928,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Hindi makapag-broadcast"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Hindi ma-save. Subukan ulit."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Hindi ma-save."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Numero ng build"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nakopya sa clipboard ang numero ng build."</string>
     <string name="basic_status" msgid="2315371112182658176">"Buksan ang pag-uusap"</string>
@@ -1028,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Naka-off ang camera"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Naka-off ang mikropono"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Naka-off ang camera at mikropono"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Nakikinig ang Assistant"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# notification}one{# notification}other{# na notification}}"</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">"Pagtatala"</string>
@@ -1043,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Payagan ang isang beses na pag-access"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Huwag payagan"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Nire-record ng mga log ng device kung ano ang nangyayari sa iyong device. Magagamit ng mga app ang mga log na ito para maghanap at mag-ayos ng mga isyu.\n\nPosibleng maglaman ang ilang log ng sensitibong impormasyon, kaya ang mga app lang na pinagkakatiwalaan mo ang payagang maka-access sa lahat ng log ng device. \n\nKung hindi mo papayagan ang app na ito na i-access ang lahat ng log ng device, maa-access pa rin nito ang mga sarili nitong log. Posible pa ring ma-access ng manufacturer ng iyong device ang ilang log o impormasyon sa device mo."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Matuto pa"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Matuto pa sa <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buksan ang <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Na-set up ang app"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• May kahit isang card na idinagdag sa Wallet"</string>
@@ -1066,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Lumipat sa profile sa trabaho"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Isara"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Mga setting ng lock screen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d421610..be2f84a 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Alt sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Sol sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Sağ sınır yüzde <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"İş profilindeki ekran görüntüleri <xliff:g id="APP">%1$s</xliff:g> uygulamasına kaydedilir"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"İş profilinde <xliff:g id="APP">%1$s</xliff:g> uygulamasına kaydedildi"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Dosyalar"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu ekran görüntüsünü algıladı."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ve diğer açık uygulamalar bu ekran görüntüsünü algıladı."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Nota ekle"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Kaydedicisi"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Cihazın kilidini yüzünüzle açtınız"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Yüzünüz tanındı"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Sola taşı"</item>
-    <item msgid="5558598599408514296">"Aşağı taşı"</item>
-    <item msgid="4844142668312841831">"Sağa taşı"</item>
-    <item msgid="5640521437931460125">"Yukarı taşı"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Denetim eklemek için uygulama seçin"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol eklendi.}other{# kontrol eklendi.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Kaldırıldı"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> eklensin mi?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> uygulamasını eklerseniz bu panele kontrol ve içerik ekleyebilir. Bazı uygulamalarda, burada hangi kontrollerin görüneceğini seçebilirsiniz."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoriler listesine eklendi"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorilere eklendi, konum: <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Favorilerden kaldırıldı"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> uygulamasını aç"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısını çal"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> uygulamasından <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısını çal"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Sizin İçin"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Geri al"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> cihazında oynatmak için yaklaşın"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Burada oynatmak için <xliff:g id="DEVICENAME">%1$s</xliff:g> cihazına yaklaşın"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Bir hata oluştu. Tekrar deneyin."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Yükleme"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"tablet"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrol kullanılamıyor"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Hata, yeniden deneyin"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Denetim ekle"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Denetimleri düzenle"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Uygulama ekle"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Çıkışlar ekleyin"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 cihaz seçildi"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hesap gerekiyor"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Yayınlanamıyor"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Kaydedilemiyor. Tekrar deneyin."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Kaydedilemiyor."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Derleme numarası"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Derleme numarası panoya kopyalandı."</string>
     <string name="basic_status" msgid="2315371112182658176">"Görüşmeyi aç"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera kapalı"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon kapalı"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera ve mikrofon kapalı"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Asistan dinliyor"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# bildirim}other{# bildirim}}"</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">"Not alma"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Tek seferlik erişim izni ver"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"İzin verme"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Cihaz günlükleri, cihazınızda olanları kaydeder. Uygulamalar, sorunları bulup düzeltmek için bu günlükleri kullanabilir.\n\nBazı günlükler hassas bilgiler içerebileceği için yalnızca güvendiğiniz uygulamaların tüm cihaz günlüklerine erişmesine izin verin. \n\nBu uygulamanın tüm cihaz günlüklerine erişmesine izin vermeseniz de kendi günlüklerine erişmeye devam edebilir. Ayrıca, cihaz üreticiniz de cihazınızdaki bazı günlüklere veya bilgilere erişmeye devam edebilir."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Daha fazla bilgi"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Daha fazla bilgiyi <xliff:g id="URL">%s</xliff:g> sayfasında bulabilirsiniz"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını aç"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Uygulama kurulmuş olmalıdır"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Cüzdan\'a en az bir kart eklenmelidir"</string>
@@ -1058,7 +1063,7 @@
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Daha iyi selfie çekmek için telefonu açın"</string>
     <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Daha iyi bir selfie için ön ekrana geçilsin mi?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Daha yüksek çözünürlüğe sahip daha büyük bir fotoğraf için arka yüz kamerasını kullanın."</string>
-    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ * Bu ekran kapatılacak"</b></string>
+    <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran kapatılacak"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Katlanabilir cihaz açılıyor"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Katlanabilir cihaz döndürülüyor"</string>
     <string name="stylus_battery_low_percentage" msgid="1620068112350141558">"<xliff:g id="PERCENTAGE">%s</xliff:g> pil kaldı"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"İş profiline geç"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Kapat"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Kilit ekranı ayarları"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 43c212d..824e64a 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Знизу на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Зліва на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Справа на <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Робочі знімки екрана зберігаються в додатку <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Збережено в додатку <xliff:g id="APP">%1$s</xliff:g> у робочому профілі"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Файли"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Додаток <xliff:g id="APPNAME">%1$s</xliff:g> виявив цей знімок екрана."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> та інші відкриті додатки виявили цей знімок екрана."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додати до примітки"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запис відео з екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Обличчя розпізнано. Натисніть значок розблокування."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Розблоковано (фейсконтроль)"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Обличчя розпізнано"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Перемістіть палець ліворуч"</item>
-    <item msgid="5558598599408514296">"Перемістіть палець униз"</item>
-    <item msgid="4844142668312841831">"Перемістіть палець праворуч"</item>
-    <item msgid="5640521437931460125">"Перемістіть палець угору"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Виберіть, для якого додатка налаштувати елементи керування"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додано # елемент керування.}one{Додано # елемент керування.}few{Додано # елементи керування.}many{Додано # елементів керування.}other{Додано # елемента керування.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Вилучено"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Долучити додаток <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Якщо ви долучите додаток <xliff:g id="APPNAME">%s</xliff:g>, він зможе розміщувати елементи керування й контент на цій панелі. У деяких додатках можна вибрати, які елементи керування тут відображатимуться."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Додано у вибране"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Додано у вибране, позиція <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Видалено з вибраного"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Відкрити додаток <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Увімкнути пісню \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, у додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Увімкнути пісню \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" у додатку <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Для вас"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Відмінити"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Щоб відтворити контент на пристрої <xliff:g id="DEVICENAME">%1$s</xliff:g>, наблизьтеся до нього"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Щоб відтворити на цьому пристрої, перемістіть його ближче до пристрою \"<xliff:g id="DEVICENAME">%1$s</xliff:g>\""</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Сталася помилка. Повторіть спробу."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Завантаження"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"планшет"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, перейдіть у додаток"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Не знайдено"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Елемент керування недоступний"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Помилка. Спробуйте знову"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Додати елементи керування"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Змінити елементи керування"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Долучити додаток"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Додати пристрої виводу"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Група"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Вибрано 1 пристрій"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Колонки й екрани"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Пропоновані пристрої"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Потрібен платний обліковий запис"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Неможливо транслювати"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Не вдалося зберегти. Повторіть спробу."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Не вдалося зберегти."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Номер складання"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Номер складання скопійовано в буфер обміну."</string>
     <string name="basic_status" msgid="2315371112182658176">"Відкрита розмова"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Камеру вимкнено"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Мікрофон вимкнено"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Камеру й мікрофон вимкнено"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Асистент слухає"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# сповіщення}one{# сповіщення}few{# сповіщення}many{# сповіщень}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Надати доступ лише цього разу"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Не надавати"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"У журналах пристрою реєструється все, що відбувається на ньому. За допомогою цих журналів додатки можуть виявляти й усувати проблеми.\n\nДеякі журнали можуть містити конфіденційні дані, тому надавати доступ до всіх журналів пристрою слід лише надійним додаткам. \n\nЯкщо додаток не має доступу до всіх журналів пристрою, він усе одно може використовувати власні журнали. Виробник вашого пристрою все одно може використовувати деякі журнали чи інформацію на ньому."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Докладніше"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Докладніше: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Відкрити <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Додаток налаштовано"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Принаймні одну картку додано в Гаманець"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"Відповідно до правил організації ви можете телефонувати лише з робочого профілю"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Перейти в робочий профіль"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Закрити"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Параметри заблокованого екрана"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index c9e1ee4..a72bbc2 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"نیچے کا احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"بایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"دایاں احاطہ <xliff:g id="PERCENT">%1$d</xliff:g> فیصد"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"دفتری اسکرین شاٹس کو <xliff:g id="APP">%1$s</xliff:g> ایپ میں محفوظ کیا جاتا ہے"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"دفتری پروفائل میں <xliff:g id="APP">%1$s</xliff:g> میں محفوظ کی گئی"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"فائلز"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> اور دیگر کھلی ایپس نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"نوٹ میں شامل کریں"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"اسکرین ریکارڈر"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"چہرے کی شناخت ہو گئی۔ کھولنے کیلئے انلاک آئیکن دبائیں۔"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"چہرے سے غیر مقفل کیا گیا"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"چہرے کی شناخت ہو گئی"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"دائیں منتقل کریں"</item>
-    <item msgid="5558598599408514296">"نیچے منتقل کریں"</item>
-    <item msgid="4844142668312841831">"بائیں منتقل کریں"</item>
-    <item msgid="5640521437931460125">"اوپر منتقل کریں"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏NFC استعمال کرنے کیلئے غیر مقفل کریں"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"یہ آلہ آپ کی تنظیم کا ہے"</string>
@@ -818,7 +815,7 @@
     <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"ایکسیسبیلٹی خصوصیات کھولنے کے لیے تھپتھپائیں۔ ترتیبات میں اس بٹن کو حسب ضرورت بنائیں یا تبدیل کریں۔\n\n"<annotation id="link">"ترتیبات ملاحظہ کریں"</annotation></string>
     <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"عارضی طور پر بٹن کو چھپانے کے لئے اسے کنارے پر لے جائیں"</string>
     <string name="accessibility_floating_button_undo" msgid="511112888715708241">"کالعدم کریں"</string>
-    <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"<xliff:g id="FEATURE_NAME">%s</xliff:g> شارٹ کٹ ہٹا دیا گیا"</string>
+    <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"‫<xliff:g id="FEATURE_NAME">%s</xliff:g> شارٹ کٹ ہٹا دیا گیا"</string>
     <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{# شارٹ کٹ ہٹا دیا گیا}other{# شارٹ کٹس ہٹا دیے گئے}}"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"اوپر بائیں جانب لے جائیں"</string>
     <string name="accessibility_floating_button_action_move_top_right" msgid="6106225581993479711">"اوپر دائیں جانب لے جائيں"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"کنٹرولز شامل کرنے کے لیے ایپ منتخب کریں"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنٹرول کو شامل کیا گیا۔}other{# کنٹرولز کو شامل کیا گیا۔}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"ہٹا دیا گیا"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> کو شامل کریں؟"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"جب آپ <xliff:g id="APPNAME">%s</xliff:g> کو شامل کرتے ہیں، تو یہ اس پینل میں کنٹرولز اور مواد کو شامل کر سکتا ہے۔ کچھ ایپس میں، آپ یہ منتخب کر سکتے ہیں کہ کون سے کنٹرولز یہاں ظاہر ہوں۔"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"پسند کردہ"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"پسند کردہ، پوزیشن <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ناپسند کردہ"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> کھولیں"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> سے <xliff:g id="SONG_NAME">%1$s</xliff:g> چلائیں"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"آپ کیلئے"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"کالعدم کریں"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"‫<xliff:g id="DEVICENAME">%1$s</xliff:g> پر چلانے کے لیے قریب کریں"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"یہاں چلانے کے لیے، <xliff:g id="DEVICENAME">%1$s</xliff:g> کے زیادہ جائیں"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"کچھ غلط ہوگیا۔ پھر کوشش کریں۔"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"لوڈ ہو رہا ہے"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ٹیبلیٹ"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"غیر فعال، ایپ چیک کریں"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"نہیں ملا"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"کنٹرول دستیاب نہیں ہے"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"خرابی، دوبارہ کوشش کریں"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"کنٹرولز شامل کریں"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"کنٹرولز میں ترمیم کریں"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"ایپ شامل کریں"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"آؤٹ پٹس شامل کریں"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"گروپ"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 آلہ منتخب کیا گیا"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"اسپیکرز اور ڈسپلیز"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"تجویز کردہ آلات"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"پریمئیم اکاؤنٹ درکار ہے"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"براڈکاسٹ نہیں کیا جا سکتا"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"محفوظ نہیں کیا جا سکا۔ پھر کوشش کریں۔"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"محفوظ نہیں کیا جا سکا۔"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"بلڈ نمبر"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"بلڈ نمبر کلپ بورڈ میں کاپی ہو گیا۔"</string>
     <string name="basic_status" msgid="2315371112182658176">"گفتگو کھولیں"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"کیمرا آف ہے"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"مائیک آف ہے"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"کیمرا اور مائیک آف ہیں"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"اسسٹنٹ سن رہی ہے"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# اطلاع}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"یک وقتی رسائی کی اجازت دیں"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"اجازت نہ دیں"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"آپ کے آلے پر جو ہوتا ہے آلے کے لاگز اسے ریکارڈ کر لیتے ہیں۔ ایپس ان لاگز کا استعمال مسائل کو تلاش کرنے اور ان کو حل کرنے کے لیے کر سکتی ہیں۔\n\nکچھ لاگز میں حساس معلومات شامل ہو سکتی ہیں، اس لیے صرف اپنی بھروسے مند ایپس کو ہی آلے کے تمام لاگز تک رسائی کی اجازت دیں۔ \n\nاگر آپ اس ایپ کو آلے کے تمام لاگز تک رسائی کی اجازت نہیں دیتے ہیں تب بھی یہ اپنے لاگز تک رسائی حاصل کر سکتی ہے۔ آپ کے آلے کا مینوفیکچرر اب بھی آپ کے آلے پر کچھ لاگز یا معلومات تک رسائی حاصل کر سکتا ہے۔"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"مزید جانیں"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> پر مزید جانیں"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> کھولیں"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• ایپ سیٹ اپ ہو گئی ہے"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• والٹ میں کم از کم ایک کارڈ شامل کیا گیا ہے"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"آپ کے کام سے متعلق پالیسی آپ کو صرف دفتری پروفائل سے فون کالز کرنے کی اجازت دیتی ہے"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"دفتری پروفائل پر سوئچ کریں"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"بند کریں"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"مقفل اسکرین کی ترتیبات"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index d31f3f8..31dd7c12 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Quyi chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Chap chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Oʻng chegara <xliff:g id="PERCENT">%1$d</xliff:g> foiz"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ish skrinshotlari <xliff:g id="APP">%1$s</xliff:g> ilovasida saqlanadi"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Ish profilidagi <xliff:g id="APP">%1$s</xliff:g> ilovasiga saqlandi"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fayllar"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"Bu skrinshotda <xliff:g id="APPNAME">%1$s</xliff:g> aniqlandi."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Bu skrinshotda <xliff:g id="APPNAME">%1$s</xliff:g> va boshqa ochiq ilovalar aniqlandi"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qaydga qoʻshish"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Yuz aniqlandi. Ochish uchun ochish belgisini bosing."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Yuz bilan ochildi"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Yuz aniqlandi"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Chapga siljitish"</item>
-    <item msgid="5558598599408514296">"Pastga siljitish"</item>
-    <item msgid="4844142668312841831">"Oʻngga siljitish"</item>
-    <item msgid="5640521437931460125">"Tepaga siljitish"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Boshqaruv elementlarini kiritish uchun ilovani tanlang"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ta boshqaruv elementi kiritildi.}other{# ta boshqaruv elementi kiritildi.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> qoʻshilsinmi?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"<xliff:g id="APPNAME">%s</xliff:g> bu panelga boshqaruv elementlari va kontent qoʻshishi mumkin. Ayrim ilovalarda bu yerda qaysi elementlar chiqishini tanlashingiz mumkin."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Saralanganlarga kiritilgan, <xliff:g id="NUMBER">%d</xliff:g>-joy"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Saralanganlardan olib tashlangan"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> ilovasini ochish"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etish: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"<xliff:g id="APP_LABEL">%2$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Siz uchun"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Qaytarish"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"<xliff:g id="DEVICENAME">%1$s</xliff:g> qurilmasida ijro qilish uchun unga yaqinlashing"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Shu yerda ijro qilish uchun <xliff:g id="DEVICENAME">%1$s</xliff:g>ga yaqinroq suring"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Xatolik yuz berdi. Qayta urining."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Yuklanmoqda"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"planshet"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Mediani translatsiya qilish"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Translatsiya qilinmoqda: <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Boshqarish imkonsiz"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Xato, qayta urining"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Element kiritish"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Elementlarni tahrirlash"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ilova kiritish"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Chiquvchi qurilmani kiritish"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Guruh"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 ta qurilma tanlandi"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Karnaylar va displeylar"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Taklif qilingan qurilmalar"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Premium hisob talab etiladi"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Uzatilmadi"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Saqlanmadi. Qayta urining."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Saqlanmadi."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Nashr raqami"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Nashr raqami vaqtinchalik xotiraga nusxalandi."</string>
     <string name="basic_status" msgid="2315371112182658176">"Suhbatni ochish"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Kamera yoqilmagan"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Mikrofon yoqilmagan"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Kamera va mikrofon yoqilmagan"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Assistent tinglamoqda"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# ta bildirishnoma}other{# ta bildirishnoma}}"</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">"Eslatma yozish"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Bir matalik foydalanishga ruxsat berish"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Rad etish"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Qurilma jurnaliga qurilma bilan yuz bergan hodisalar qaydlari yoziladi. Ilovalar bu jurnal qaydlari yordamida muammolarni topishi va bartaraf qilishi mumkin.\n\nAyrim jurnal qaydlarida maxfiy axborotlar yozilishi mumkin, shu sababli qurilmadagi barcha jurnal qaydlariga ruxsatni faqat ishonchli ilovalarga bering. \n\nBu ilovaga qurilmadagi barcha jurnal qaydlariga ruxsat berilmasa ham, u oʻzining jurnalini ocha oladi. Qurilma ishlab chiqaruvchisi ham ayrim jurnallar yoki qurilma haqidagi axborotlarni ocha oladi."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Batafsil"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Batafsil: <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ochish: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Ilova sozlangan"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Kamida bitta kartochka Wallet xizmatiga qoʻshilgan"</string>
@@ -1054,10 +1057,10 @@
     <string name="keyguard_affordance_enablement_dialog_home_instruction_2" msgid="8308525385889021652">"• Kamida bitta qurilma mavjud"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Bosib turish yorligʻi"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Bekor qilish"</string>
-    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Hozir aylantirish"</string>
+    <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"Almashtirish"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"Yaxshiroq selfi olish uchun telefonni yoying"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Old ekran sizga qaragan holda aylantirdingizmi?"</string>
-    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Keng va yuqori tiniqlikdagi suratga olish uchun orqa kameradan foydalaning."</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"Yaxshiroq selfi uchun old ekranga almashilsinmi?"</string>
+    <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"Keng burchakli va yuqori aniqlikda suratga olish uchun orqa kameradan foydalaning."</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ Bu ekran oʻchiriladi"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Buklanadigan qurilma ochilmoqda"</string>
     <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Buklanadigan qurilma aylantirilmoqda"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Ish profiliga almashish"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Yopish"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Qulflangan ekran sozlamalari"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 2a4989a..558cfdb0 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Cạnh dưới cùng <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Cạnh trái <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Cạnh phải <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Ảnh chụp màn hình công việc được lưu trong ứng dụng <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Đã lưu vào <xliff:g id="APP">%1$s</xliff:g> trong hồ sơ công việc"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Files"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> đã phát hiện thấy ảnh chụp màn hình này."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> và các ứng dụng đang mở khác đã phát hiện thấy ảnh chụp màn hình này."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Thêm vào ghi chú"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Trình ghi màn hình"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để mở."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Đã mở khoá bằng khuôn mặt."</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Đã nhận diện khuôn mặt."</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Di chuyển sang trái"</item>
-    <item msgid="5558598599408514296">"Di chuyển xuống"</item>
-    <item msgid="4844142668312841831">"Di chuyển sang phải"</item>
-    <item msgid="5640521437931460125">"Di chuyển lên"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Chọn ứng dụng để thêm các tùy chọn điều khiển"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Đã thêm # chế độ điều khiển.}other{Đã thêm # chế độ điều khiển.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Thêm <xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Khi bạn thêm <xliff:g id="APPNAME">%s</xliff:g>, ứng dụng có thể bổ sung các chế độ điều khiển và nội dung vào bảng điều khiển này. Trong một số ứng dụng, bạn có thể chọn chế độ điều khiển nào sẽ hiển thị tại đây."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Được yêu thích, vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Không được yêu thích"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Mở <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"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_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Phát <xliff:g id="SONG_NAME">%1$s</xliff:g> trên <xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Dành cho bạn"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Hủy"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Đưa thiết bị đến gần hơn để phát trên <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Để phát ở đây, vui lòng lại gần <xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Đã xảy ra lỗi. Hãy thử lại."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Đang tải"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"máy tính bảng"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Không có chức năng điều khiển"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Lỗi, hãy thử lại"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Thêm các tùy chọn điều khiển"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Chỉnh sửa tùy chọn điều khiển"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Thêm ứng dụng"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Thêm thiết bị đầu ra"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Nhóm"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Đã chọn 1 thiết bị"</string>
@@ -919,7 +918,6 @@
     <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>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Yêu cầu tài khoản trả phí"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Không thể truyền"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Không lưu được. Hãy thử lại."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Không lưu được."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Số bản dựng"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Đã sao chép số bản dựng vào bảng nhớ tạm."</string>
     <string name="basic_status" msgid="2315371112182658176">"Mở cuộc trò chuyện"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Camera đang tắt"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Micrô đã bị tắt"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Máy ảnh và micrô đang tắt"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Trợ lý đang nghe bạn nói"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# thông báo}other{# thông báo}}"</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">"Ghi chú"</string>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Cho phép truy cập một lần"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Không cho phép"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Nhật ký thiết bị ghi lại những hoạt động diễn ra trên thiết bị của bạn. Các ứng dụng có thể dùng nhật ký này để tìm và khắc phục vấn đề.\n\nMột số nhật ký có thể chứa thông tin nhạy cảm, vì vậy, bạn chỉ nên cấp quyền truy cập vào mọi nhật ký thiết bị cho những ứng dụng mà mình tin tưởng. \n\nNếu bạn không cho phép ứng dụng này truy cập vào mọi nhật ký thiết bị, thì ứng dụng này vẫn có thể truy cập vào nhật ký của chính nó. Nhà sản xuất thiết bị vẫn có thể truy cập vào một số nhật ký hoặc thông tin trên thiết bị của bạn."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Tìm hiểu thêm"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Tìm hiểu thêm tại <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Mở <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• Ứng dụng được thiết lập"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Thêm ít nhất một thẻ vào Wallet"</string>
@@ -1069,6 +1074,5 @@
     <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_action" msgid="2937701298133010724">"Chuyển sang hồ sơ công việc"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Đóng"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Cài đặt màn hình khoá"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 431146b..6ac74ad 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"底部边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左侧边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右侧边界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作屏幕截图保存在“<xliff:g id="APP">%1$s</xliff:g>”应用中"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"已保存到工作资料名下的 <xliff:g id="APP">%1$s</xliff:g>中"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"文件"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 检测到此屏幕截图。"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 及其他打开的应用检测到此屏幕截图。"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"添加到备注中"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"屏幕录制器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"识别出面孔。按下解锁图标即可打开。"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"已用面孔解锁"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"已识别出面孔"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"左移"</item>
-    <item msgid="5558598599408514296">"下移"</item>
-    <item msgid="4844142668312841831">"右移"</item>
-    <item msgid="5640521437931460125">"上移"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"向上滑动即可重试"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"需要解锁才能使用 NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"此设备归贵单位所有"</string>
@@ -661,7 +658,7 @@
     <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_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>
@@ -679,15 +676,15 @@
   </string-array>
     <string name="tuner_low_priority" msgid="8412666814123009820">"显示低优先级的通知图标"</string>
     <string name="other" msgid="429768510980739978">"其他"</string>
-    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"移除图块"</string>
-    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"将图块添加到末尾"</string>
-    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"移动图块"</string>
-    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"添加图块"</string>
+    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"移除功能块"</string>
+    <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"将功能块添加到末尾"</string>
+    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"移动功能块"</string>
+    <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"添加功能块"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"移至 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"添加到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已添加卡片"</string>
-    <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除卡片"</string>
+    <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已添加功能块"</string>
+    <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除功能块"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string>
     <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"打开设置。"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"选择要添加控制器的应用"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已添加 # 个控件。}other{已添加 # 个控件。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"添加“<xliff:g id="APPNAME">%s</xliff:g>”?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"当您添加“<xliff:g id="APPNAME">%s</xliff:g>”后,它可以将控件和内容添加到此面板。在某些应用中,您可以选择在此处显示哪些控件。"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已收藏,位置:<xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"打开<xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"通过<xliff:g id="APP_LABEL">%2$s</xliff:g>播放《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"为您推荐"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"撤消"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"若要在“<xliff:g id="DEVICENAME">%1$s</xliff:g>”上播放,请靠近这台设备"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"若要在此设备上播放,请再靠近<xliff:g id="DEVICENAME">%1$s</xliff:g>一点"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"出了点问题,请重试。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"正在加载"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板电脑"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"投放您的媒体"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"投放 <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"无效,请检查应用"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"未找到"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"控件不可用"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"出现错误,请重试"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"添加控制器"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"修改控制器"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"添加应用"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"添加输出设备"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"群组"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已选择 1 个设备"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"音箱和显示屏"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建议的设备"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"需要使用付费帐号"</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>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"无法广播"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"无法保存,请重试。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"无法保存。"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本号"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已将版本号复制到剪贴板。"</string>
     <string name="basic_status" msgid="2315371112182658176">"开放式对话"</string>
@@ -997,9 +997,9 @@
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"如要切换网络,请断开以太网连接"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"为了提升设备的使用体验,即使 WLAN 已关闭,应用和服务仍可以随时扫描 WLAN 网络。您可以在 WLAN 扫描设置中更改此设置。"<annotation id="link">"更改"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"关闭飞行模式"</string>
-    <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"“<xliff:g id="APPNAME">%1$s</xliff:g>”希望将以下图块添加到“快捷设置”"</string>
-    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"添加图块"</string>
-    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"不添加图块"</string>
+    <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"“<xliff:g id="APPNAME">%1$s</xliff:g>”希望将以下功能块添加到“快捷设置”"</string>
+    <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"添加功能块"</string>
+    <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"不添加功能块"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"选择用户"</string>
     <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# 个应用处于活动状态}other{# 个应用处于活动状态}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"新信息"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"摄像头已关闭"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"麦克风已关闭"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"摄像头和麦克风已关闭"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google 助理正在聆听"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 条通知}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>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"允许访问一次"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允许"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"设备日志会记录设备上发生的活动。应用可以使用这些日志查找和修复问题。\n\n部分日志可能包含敏感信息,因此请仅允许您信任的应用访问所有设备日志。\n\n如果您不授予此应用访问所有设备日志的权限,它仍然可以访问自己的日志。您的设备制造商可能仍然能够访问设备上的部分日志或信息。"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"了解详情"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"如需了解详情,请前往 <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"打开<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 应用已设置完毕"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 至少已将一张银行卡添加到钱包"</string>
@@ -1056,7 +1059,7 @@
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="4383356544661421206">"立即翻转"</string>
     <string name="rear_display_fold_bottom_sheet_title" msgid="6081542277622721548">"展开手机可拍出更好的自拍照"</string>
-    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"要翻转到外屏以拍出更好的自拍照吗?"</string>
+    <string name="rear_display_unfold_bottom_sheet_title" msgid="2137403802960396357">"翻转到外屏后自拍效果更好,要试试吗?"</string>
     <string name="rear_display_bottom_sheet_description" msgid="1852662982816810352">"您可以使用后置摄像头拍摄视角更广、分辨率更高的照片。"</string>
     <string name="rear_display_bottom_sheet_warning" msgid="800995919558238930"><b>"✱ 此屏幕将会关闭"</b></string>
     <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"正在展开可折叠设备"</string>
@@ -1069,6 +1072,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"根据您的工作政策,您只能通过工作资料拨打电话"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"关闭"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"锁屏设置"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index ac27be2..e0b042b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右方邊界 <xliff:g id="PERCENT">%1$d</xliff:g>%%"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作的螢幕截圖會儲存在「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"已儲存在工作設定檔的「<xliff:g id="APP">%1$s</xliff:g>」中"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"檔案"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 偵測到此螢幕截圖。"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 和其他開啟的應用程式偵測到此螢幕截圖。"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至筆記"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕畫面錄影工具"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"已識別面孔。按解鎖圖示即可開啟。"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"已使用面孔解鎖"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"已識別面孔"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"向左移"</item>
-    <item msgid="5558598599408514296">"向下移"</item>
-    <item msgid="4844142668312841831">"向右移"</item>
-    <item msgid="5640521437931460125">"向上移"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"選擇要新增控制項的應用程式"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"要新增「<xliff:g id="APPNAME">%s</xliff:g>」嗎?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"如果您新增「<xliff:g id="APPNAME">%s</xliff:g>」,應用程式可將控制項和內容新增至此面板。部份應用程式可讓您選擇要在這裡顯示的控制項。"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入至收藏位置 <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"開啟 <xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"在 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"在 <xliff:g id="APP_LABEL">%2$s</xliff:g> 播放《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"為您推薦"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"復原"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"如要在這部裝置播放,請靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」一點"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"正在載入"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制功能"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請重試"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"新增控制項"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"編輯控制項"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"新增應用程式"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"新增輸出裝置"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"群組"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已選取 1 部裝置"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"需要付費帳戶"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"版本號碼已複製到剪貼簿。"</string>
     <string name="basic_status" msgid="2315371112182658176">"開啟對話"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"相機已關閉"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"麥克風已關閉"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"相機和麥克風已關閉"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"「Google 助理」正在聆聽"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"允許存取一次"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允許"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"裝置記錄會記下裝置的活動。應用程式可透過這些記錄找出並修正問題。\n\n部分記錄可能包含敏感資料,因此請只允許信任的應用程式存取所有裝置記錄。\n\n如果不允許此應用程式存取所有裝置記錄,此應用程式仍能存取自己的記錄,且裝置製造商可能仍可存取裝置上的部分記錄或資料。"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"瞭解詳情"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"詳情請瀏覽 <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 應用程式已完成設定"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 已新增至少一張卡至「錢包」"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"您的公司政策只允許透過工作設定檔撥打電話"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作設定檔"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"上鎖畫面設定"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 56fc01d..dff6169 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"下方邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"左側邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"右側邊界百分之 <xliff:g id="PERCENT">%1$d</xliff:g>"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"工作的螢幕截圖會儲存在「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"已儲存在工作資料夾的「<xliff:g id="APP">%1$s</xliff:g>」中"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"檔案"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"「<xliff:g id="APPNAME">%1$s</xliff:g>」偵測到這張螢幕截圖。"</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"「<xliff:g id="APPNAME">%1$s</xliff:g>」和其他開啟的應用程式偵測到這張螢幕截圖。"</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至記事"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕錄影器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"臉孔辨識完成,按下「解鎖」圖示即可開啟。"</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"裝置已透過你的臉解鎖"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"臉孔辨識完成"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"向左移"</item>
-    <item msgid="5558598599408514296">"向下移"</item>
-    <item msgid="4844142668312841831">"向右移"</item>
-    <item msgid="5640521437931460125">"向上移"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"向上滑動即可重試"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"如要使用 NFC,請先解鎖"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"這部裝置的擁有者為貴機構"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"選擇應用程式以新增控制項"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"要新增「<xliff:g id="APPNAME">%s</xliff:g>」嗎?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"當你新增「<xliff:g id="APPNAME">%s</xliff:g>」時,應用程式也可將控制選項及內容新增到這個面板。某些應用程式可讓你選擇要顯示在這裡的控制選項。"</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入收藏,位置 <xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"從收藏中移除"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"開啟「<xliff:g id="APP_LABEL">%1$s</xliff:g>」"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"透過「<xliff:g id="APP_LABEL">%2$s</xliff:g>」播放〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"為你推薦"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"復原"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"如要在「<xliff:g id="DEVICENAME">%1$s</xliff:g>」上播放,請靠近一點"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"如要在這部裝置播放,請移到更靠近「<xliff:g id="DEVICENAME">%1$s</xliff:g>」的位置"</string>
@@ -893,6 +889,10 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"發生錯誤,請再試一次。"</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"載入中"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"平板電腦"</string>
+    <!-- no translation found for media_transfer_receiver_content_description_unknown_app (7381771464846263667) -->
+    <skip />
+    <!-- no translation found for media_transfer_receiver_content_description_with_app_name (8555975056850659389) -->
+    <skip />
     <string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"無法使用控制項"</string>
@@ -902,8 +902,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"發生錯誤,請再試一次"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"新增控制項"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"編輯控制項"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"新增應用程式"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"新增輸出裝置"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"群組"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"已選取 1 部裝置"</string>
@@ -919,7 +918,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"喇叭和螢幕"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"建議的裝置"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"必須有付費帳戶"</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>
@@ -931,6 +929,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"無法廣播"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"無法儲存,請再試一次。"</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"無法儲存。"</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"版本號碼"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"已將版本號碼複製到剪貼簿。"</string>
     <string name="basic_status" msgid="2315371112182658176">"開放式對話"</string>
@@ -1031,6 +1033,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"相機已關閉"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"麥克風已關閉"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"已關閉相機和麥克風"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"Google 助理正在聆聽"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{# 則通知}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>
@@ -1046,6 +1049,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"允許一次性存取"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"不允許"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"系統會透過裝置記錄記下裝置上的活動。應用程式可以根據這些記錄找出問題並修正。\n\n某些記錄可能含有機密資訊,因此請勿讓不信任的應用程式存取所有裝置記錄。\n\n即使你不允許這個應用程式存取所有裝置記錄,這個應用程式仍能存取自己的記錄,而且裝置製造商或許仍可存取裝置的某些記錄或資訊。"</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"瞭解詳情"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"如要瞭解詳情,請前往 <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• 完成應用程式設定"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• 錢包中至少要有一張卡片"</string>
@@ -1069,6 +1074,5 @@
     <string name="call_from_work_profile_text" msgid="3458704745640229638">"貴公司政策僅允許透過工作資料夾撥打電話"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切換至工作資料夾"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"關閉"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"螢幕鎖定設定"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index eda7571..3e8a5f9 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -91,8 +91,11 @@
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ophansi"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ongakwesobunxele"</string>
     <string name="screenshot_right_boundary_pct" msgid="1201150713021779321">"Iphesenti elingu-<xliff:g id="PERCENT">%1$d</xliff:g> lomngcele ongakwesokudla"</string>
-    <string name="screenshot_work_profile_notification" msgid="2812417845875653929">"Izithombe-skrini zomsebenzi zigcinwa ku-app ye-<xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Kulondolozwe ku-<xliff:g id="APP">%1$s</xliff:g> kuphrofayela yomsebenzi"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Amafayela"</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"I-<xliff:g id="APPNAME">%1$s</xliff:g> ithole lesi sithombe-skrini."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"I-<xliff:g id="APPNAME">%1$s</xliff:g> namanye ama-app avuliwe athole lesi sithombe-skrini."</string>
+    <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engeza kunothi"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Irekhoda yesikrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
@@ -339,12 +342,6 @@
     <string name="keyguard_face_successful_unlock_press_alt_3" msgid="7219030481255573962">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uvule."</string>
     <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Vula ngobuso"</string>
     <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Ubuso buyaziwa"</string>
-  <string-array name="udfps_accessibility_touch_hints">
-    <item msgid="1901953991150295169">"Yisa kwesokunxele"</item>
-    <item msgid="5558598599408514296">"Yehlisa"</item>
-    <item msgid="4844142668312841831">"Yisa kwesokudla"</item>
-    <item msgid="5640521437931460125">"Khuphula"</item>
-  </string-array>
     <string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string>
     <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string>
     <string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string>
@@ -832,10 +829,8 @@
     <string name="controls_providers_title" msgid="6879775889857085056">"Khetha uhlelo lokusebenza ukwengeza izilawuli"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ulawulo olu-# olwengeziwe.}one{ukulawulwa okungu-# okwengeziwe.}other{ukulawulwa okungu-# okwengeziwe.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Isusiwe"</string>
-    <!-- no translation found for controls_panel_authorization_title (267429338785864842) -->
-    <skip />
-    <!-- no translation found for controls_panel_authorization (4540047176861801815) -->
-    <skip />
+    <string name="controls_panel_authorization_title" msgid="267429338785864842">"Engeza i-<xliff:g id="APPNAME">%s</xliff:g>?"</string>
+    <string name="controls_panel_authorization" msgid="4540047176861801815">"Uma wengeza i-<xliff:g id="APPNAME">%s</xliff:g>, ingangeza izilawuli nokuqukethwe kuleli phaneli. Kwamanye ama-app, ungakhetha ukuthi yiziphi izilawuli eziboniswa lapha."</string>
     <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kwenziwe intandokazi"</string>
     <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kwenziwe intandokazi, isimo esiyi-<xliff:g id="NUMBER">%d</xliff:g>"</string>
     <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Akwenziwanga intandokazi"</string>
@@ -886,6 +881,7 @@
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"Vula i-<xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"Dlala i-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_smartspace_rec_item_no_artist_description" msgid="8703614798636591077">"Dlala i-<xliff:g id="SONG_NAME">%1$s</xliff:g> kusuka ku-<xliff:g id="APP_LABEL">%2$s</xliff:g>"</string>
+    <string name="controls_media_smartspace_rec_header" msgid="5053461390357112834">"Okwenzelwe wena"</string>
     <string name="media_transfer_undo" msgid="1895606387620728736">"Hlehlisa"</string>
     <string name="media_move_closer_to_start_cast" msgid="2673104707465013176">"Sondeza eduze ukudlala ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
     <string name="media_move_closer_to_end_cast" msgid="7302555909119374738">"Ukuze udlale lapha, sondela ku-<xliff:g id="DEVICENAME">%1$s</xliff:g>"</string>
@@ -893,6 +889,8 @@
     <string name="media_transfer_failed" msgid="7955354964610603723">"Kukhona okungahambanga kahle. Zama futhi."</string>
     <string name="media_transfer_loading" msgid="5544017127027152422">"Iyalayisha"</string>
     <string name="media_ttt_default_device_type" msgid="4457646436153370169">"ithebulethi"</string>
+    <string name="media_transfer_receiver_content_description_unknown_app" msgid="7381771464846263667">"Isakaza imidiya yakho"</string>
+    <string name="media_transfer_receiver_content_description_with_app_name" msgid="8555975056850659389">"Isakaza i-<xliff:g id="APP_LABEL">%1$s</xliff:g>"</string>
     <string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Ukulawula akutholakali"</string>
@@ -902,8 +900,7 @@
     <string name="controls_error_failed" msgid="960228639198558525">"Iphutha, zama futhi"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Engeza Izilawuli"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Hlela izilawuli"</string>
-    <!-- no translation found for controls_menu_add_another_app (8661172304650786705) -->
-    <skip />
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Engeza i-app"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Engeza okukhiphayo"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Iqembu"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"idivayisi ekhethiwe e-1"</string>
@@ -919,7 +916,6 @@
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
     <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"Izipikha Neziboniso"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"Amadivayisi Aphakanyisiwe"</string>
-    <string name="media_output_status_require_premium" msgid="5691200962588753380">"Idinga i-akhawunti ye-premium"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Indlela ukusakaza okusebenza ngayo"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Sakaza"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Abantu abaseduze nawe abanamadivayisi e-Bluetooth ahambisanayo bangalalela imidiya oyisakazayo"</string>
@@ -931,6 +927,10 @@
     <string name="media_output_broadcast_start_failed" msgid="3670835946856129775">"Ayikwazi ukusakaza"</string>
     <string name="media_output_broadcast_update_error" msgid="1420868236079122521">"Ayikwazi ukulondoloza. Zama futhi."</string>
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"Ayikwazi ukulondoloza."</string>
+    <!-- no translation found for media_output_broadcast_code_hint_no_less_than_min (4663836092607696185) -->
+    <skip />
+    <!-- no translation found for media_output_broadcast_code_hint_no_more_than_max (9181869364856175638) -->
+    <skip />
     <string name="build_number_clip_data_label" msgid="3623176728412560914">"Yakha inombolo"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"Yakha inombolo ekopishelwe kubhodi yokunamathisela."</string>
     <string name="basic_status" msgid="2315371112182658176">"Vula ingxoxo"</string>
@@ -1031,6 +1031,7 @@
     <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"Ikhamera ivaliwe"</string>
     <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"Imakrofoni ivaliwe"</string>
     <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"Ikhamera nemakrofoni kuvaliwe"</string>
+    <string name="dream_overlay_status_bar_assistant_attention_indicator" msgid="4712565923771372690">"I-Assistant ilalele"</string>
     <string name="dream_overlay_status_bar_notification_indicator" msgid="8091389255691081711">"{count,plural, =1{Isaziso esingu-#}one{Izaziso ezingu-#}other{Izaziso ezingu-#}}"</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">"Ukuthatha amanothi"</string>
@@ -1046,6 +1047,8 @@
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Vumela ukufinyelela kwesikhathi esisodwa"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ungavumeli"</string>
     <string name="log_access_confirmation_body" msgid="6883031912003112634">"Amalogu edivayisi arekhoda okwenzekayo kudivayisi yakho. Ama-app angasebenzisa lawa malogu ukuze athole futhi alungise izinkinga.\n\nAmanye amalogu angase aqukathe ulwazi olubucayi, ngakho vumela ama-app owathembayo kuphela ukuthi afinyelele wonke amalogu edivayisi. \n\nUma ungayivumeli le app ukuthi ifinyelele wonke amalogu wedivayisi, isengakwazi ukufinyelela amalogu wayo. Umkhiqizi wedivayisi yakho usengakwazi ukufinyelela amanye amalogu noma ulwazi kudivayisi yakho."</string>
+    <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Funda kabanzi"</string>
+    <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Funda kabanzi ku-<xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Vula i-<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_1" msgid="8439655049139819278">"• I-app isethiwe"</string>
     <string name="keyguard_affordance_enablement_dialog_wallet_instruction_2" msgid="4321089250629477835">"• Okungenani ikhadi elilodwa lengeziwe ku-Wallet"</string>
@@ -1069,6 +1072,5 @@
     <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_action" msgid="2937701298133010724">"Shintshela kuphrofayela yomsebenzi"</string>
     <string name="call_from_work_profile_close" msgid="7927067108901068098">"Vala"</string>
-    <!-- no translation found for lock_screen_settings (9197175446592718435) -->
-    <skip />
+    <string name="lock_screen_settings" msgid="9197175446592718435">"Amasethingi okukhiya isikrini"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index b3256ef..8d8fdf0 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -210,16 +210,6 @@
         <attr name="permissionGrantButtonBottomStyle" format="reference"/>
     </declare-styleable>
 
-    <declare-styleable name="BiometricsEnrollView">
-        <attr name="biometricsEnrollStyle" format="reference" />
-        <attr name="biometricsEnrollIcon" format="reference|color" />
-        <attr name="biometricsMovingTargetFill" format="reference|color" />
-        <attr name="biometricsMovingTargetFillError" format="reference|color" />
-        <attr name="biometricsEnrollProgress" format="reference|color" />
-        <attr name="biometricsEnrollProgressHelp" format="reference|color" />
-        <attr name="biometricsEnrollProgressHelpWithTalkback" format="reference|color" />
-    </declare-styleable>
-
     <declare-styleable name="SeekBarWithIconButtonsView_Layout">
         <attr name="max" format="integer" />
         <attr name="progress" format="integer" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 7360c79..e2fdf16 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -136,15 +136,6 @@
     <!-- SFPS colors -->
     <color name="sfps_chevron_fill">@color/material_dynamic_primary90</color>
 
-    <!-- UDFPS colors -->
-    <color name="udfps_enroll_icon">#699FF3</color>
-    <color name="udfps_moving_target_fill">#C2D7F7</color>
-    <!-- 50% of udfps_moving_target_fill-->
-    <color name="udfps_moving_target_fill_error">#80C2D7F7</color>
-    <color name="udfps_enroll_progress">#699FF3</color>
-    <color name="udfps_enroll_progress_help">#70699FF3</color>
-    <color name="udfps_enroll_progress_help_with_talkback">#FFEE675C</color>
-
     <!-- Floating overlay actions -->
     <color name="overlay_button_ripple">#1f000000</color>
     <color name="overlay_background_protection_start">#40000000</color> <!-- 25% black -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 034f145..d9e9c5db 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -445,6 +445,13 @@
          screenshot has been saved to work profile. If blank, a default icon will be shown. -->
     <string name="config_sceenshotWorkProfileFilesApp" translatable="false"></string>
 
+    <!-- The component name of the screenshot editing activity that provides the App Clips flow.
+         The App Clips flow includes taking a screenshot, showing user screenshot cropping activity
+         and finally letting user send the screenshot to the calling notes app. This activity
+         should not send the screenshot to the calling activity without user consent. -->
+    <string name="config_screenshotAppClipsActivityComponent" translatable="false"
+            >com.android.systemui/com.android.systemui.screenshot.AppClipsActivity</string>
+
     <!-- Remote copy default activity.  Must handle REMOTE_COPY_ACTION intents.
      This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_remoteCopyPackage" translatable="false"></string>
@@ -586,11 +593,6 @@
         58.0001 29.2229,56.9551 26.8945,55.195
     </string>
 
-    <!-- The radius of the enrollment progress bar, in dp -->
-    <integer name="config_udfpsEnrollProgressBar" translatable="false">
-        280
-    </integer>
-
     <!-- The time (in ms) needed to trigger the lock icon view's long-press affordance -->
     <integer name="config_lockIconLongPress" translatable="false">200</integer>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ebf232f..36172ca 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -43,12 +43,18 @@
     <dimen name="navigation_edge_panel_height">268dp</dimen>
     <!-- The threshold to drag to trigger the edge action -->
     <dimen name="navigation_edge_action_drag_threshold">16dp</dimen>
+    <!-- The drag distance to consider evaluating gesture -->
+    <dimen name="navigation_edge_action_min_distance_to_start_animation">24dp</dimen>
     <!-- The threshold to progress back animation for edge swipe -->
     <dimen name="navigation_edge_action_progress_threshold">412dp</dimen>
     <!-- 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-->
     <dimen name="navigation_edge_finger_offset">64dp</dimen>
+    <!-- The threshold to dynamically activate the edge action -->
+    <dimen name="navigation_edge_action_reactivation_drag_threshold">32dp</dimen>
+    <!-- The threshold to dynamically deactivate the edge action -->
+    <dimen name="navigation_edge_action_deactivation_drag_threshold">32dp</dimen>
 
     <!-- The thickness of the arrow -->
     <dimen name="navigation_edge_arrow_thickness">4dp</dimen>
@@ -56,37 +62,61 @@
     <dimen name="navigation_edge_minimum_x_delta_for_switch">32dp</dimen>
 
     <!-- entry state -->
+    <item name="navigation_edge_entry_scale" format="float" type="dimen">0.98</item>
     <dimen name="navigation_edge_entry_margin">4dp</dimen>
-    <dimen name="navigation_edge_entry_background_width">8dp</dimen>
-    <dimen name="navigation_edge_entry_background_height">60dp</dimen>
-    <dimen name="navigation_edge_entry_edge_corners">30dp</dimen>
-    <dimen name="navigation_edge_entry_far_corners">30dp</dimen>
-    <dimen name="navigation_edge_entry_arrow_length">10dp</dimen>
-    <dimen name="navigation_edge_entry_arrow_height">7dp</dimen>
+    <item name="navigation_edge_entry_background_alpha" format="float" type="dimen">1.0</item>
+    <dimen name="navigation_edge_entry_background_width">0dp</dimen>
+    <dimen name="navigation_edge_entry_background_height">48dp</dimen>
+    <dimen name="navigation_edge_entry_edge_corners">6dp</dimen>
+    <dimen name="navigation_edge_entry_far_corners">6dp</dimen>
+    <item name="navigation_edge_entry_arrow_alpha" format="float" type="dimen">0.0</item>
+    <dimen name="navigation_edge_entry_arrow_length">8.6dp</dimen>
+    <dimen name="navigation_edge_entry_arrow_height">5dp</dimen>
 
     <!-- pre-threshold -->
     <dimen name="navigation_edge_pre_threshold_margin">4dp</dimen>
-    <dimen name="navigation_edge_pre_threshold_background_width">64dp</dimen>
-    <dimen name="navigation_edge_pre_threshold_background_height">60dp</dimen>
-    <dimen name="navigation_edge_pre_threshold_edge_corners">22dp</dimen>
-    <dimen name="navigation_edge_pre_threshold_far_corners">26dp</dimen>
+    <item name="navigation_edge_pre_threshold_background_alpha" format="float" type="dimen">1.0
+    </item>
+    <item name="navigation_edge_pre_threshold_scale" format="float" type="dimen">0.98</item>
+    <dimen name="navigation_edge_pre_threshold_background_width">51dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_background_height">46dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_edge_corners">16dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_far_corners">20dp</dimen>
+    <item name="navigation_edge_pre_threshold_arrow_alpha" format="float" type="dimen">1.0</item>
+    <dimen name="navigation_edge_pre_threshold_arrow_length">8dp</dimen>
+    <dimen name="navigation_edge_pre_threshold_arrow_height">5.6dp</dimen>
 
-    <!-- post-threshold / active -->
+    <!-- active (post-threshold) -->
+    <item name="navigation_edge_active_scale" format="float" type="dimen">1.0</item>
     <dimen name="navigation_edge_active_margin">14dp</dimen>
-    <dimen name="navigation_edge_active_background_width">60dp</dimen>
-    <dimen name="navigation_edge_active_background_height">60dp</dimen>
-    <dimen name="navigation_edge_active_edge_corners">30dp</dimen>
-    <dimen name="navigation_edge_active_far_corners">30dp</dimen>
-    <dimen name="navigation_edge_active_arrow_length">8dp</dimen>
-    <dimen name="navigation_edge_active_arrow_height">9dp</dimen>
+    <item name="navigation_edge_active_background_alpha" format="float" type="dimen">1.0</item>
+    <dimen name="navigation_edge_active_background_width">48dp</dimen>
+    <dimen name="navigation_edge_active_background_height">48dp</dimen>
+    <dimen name="navigation_edge_active_edge_corners">24dp</dimen>
+    <dimen name="navigation_edge_active_far_corners">24dp</dimen>
+    <item name="navigation_edge_active_arrow_alpha" format="float" type="dimen">1.0</item>
+    <dimen name="navigation_edge_active_arrow_length">6.4dp</dimen>
+    <dimen name="navigation_edge_active_arrow_height">7.2dp</dimen>
 
+    <!-- committed -->
+    <item name="navigation_edge_committed_scale" format="float" type="dimen">0.85</item>
+    <item name="navigation_edge_committed_alpha" format="float" type="dimen">0</item>
+
+    <!-- cancelled -->
+    <dimen name="navigation_edge_cancelled_background_width">0dp</dimen>
+
+    <item name="navigation_edge_stretch_scale" format="float" type="dimen">1.0</item>
     <dimen name="navigation_edge_stretch_margin">18dp</dimen>
-    <dimen name="navigation_edge_stretch_background_width">74dp</dimen>
-    <dimen name="navigation_edge_stretch_background_height">60dp</dimen>
-    <dimen name="navigation_edge_stretch_edge_corners">30dp</dimen>
-    <dimen name="navigation_edge_stretch_far_corners">30dp</dimen>
-    <dimen name="navigation_edge_stretched_arrow_length">7dp</dimen>
-    <dimen name="navigation_edge_stretched_arrow_height">10dp</dimen>
+    <dimen name="navigation_edge_stretch_background_width">60dp</dimen>
+    <item name="navigation_edge_stretch_background_alpha" format="float" type="dimen">
+        @dimen/navigation_edge_entry_background_alpha
+    </item>
+    <dimen name="navigation_edge_stretch_background_height">48dp</dimen>
+    <dimen name="navigation_edge_stretch_edge_corners">24dp</dimen>
+    <dimen name="navigation_edge_stretch_far_corners">24dp</dimen>
+    <item name="navigation_edge_strech_arrow_alpha" format="float" type="dimen">1.0</item>
+    <dimen name="navigation_edge_stretched_arrow_length">5.6dp</dimen>
+    <dimen name="navigation_edge_stretched_arrow_height">8dp</dimen>
 
     <dimen name="navigation_edge_cancelled_arrow_length">12dp</dimen>
     <dimen name="navigation_edge_cancelled_arrow_height">0dp</dimen>
@@ -154,6 +184,15 @@
     <!-- Height of a small notification in the status bar-->
     <dimen name="notification_min_height">@*android:dimen/notification_min_height</dimen>
 
+    <!-- Minimum allowed height of notifications -->
+    <dimen name="notification_validation_minimum_allowed_height">10dp</dimen>
+
+    <!-- Minimum height for displaying notification content. -->
+    <dimen name="notification_content_min_height">48dp</dimen>
+
+    <!-- Reference width used when validating notification layouts -->
+    <dimen name="notification_validation_reference_width">320dp</dimen>
+
     <!-- Increased height of a small notification in the status bar -->
     <dimen name="notification_min_height_increased">146dp</dimen>
 
@@ -1156,7 +1195,7 @@
 
     <!-- Home Controls -->
     <dimen name="controls_header_menu_size">48dp</dimen>
-    <dimen name="controls_header_bottom_margin">24dp</dimen>
+    <dimen name="controls_header_bottom_margin">16dp</dimen>
     <dimen name="controls_header_app_icon_size">24dp</dimen>
     <dimen name="controls_top_margin">48dp</dimen>
     <dimen name="controls_padding_horizontal">0dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 943844f..bf894d7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -247,6 +247,8 @@
     <string name="screenshot_detected_template"><xliff:g id="appName" example="Google Chrome">%1$s</xliff:g> detected this screenshot.</string>
     <!-- A notice shown to the user to indicate that multiple apps have detected the screenshot that the user has just taken. [CHAR LIMIT=75] -->
     <string name="screenshot_detected_multiple_template"><xliff:g id="appName" example="Google Chrome">%1$s</xliff:g> and other open apps detected this screenshot.</string>
+    <!-- Add to note button used in App Clips flow to return the saved screenshot image to notes app. [CHAR LIMIT=NONE] -->
+    <string name="app_clips_save_add_to_note">Add to note</string>
 
     <!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
     <string name="screenrecord_name">Screen Recorder</string>
@@ -908,14 +910,6 @@
     <!-- Message shown when non-bypass face authentication succeeds. [CHAR LIMIT=60] -->
     <string name="keyguard_face_successful_unlock_alt1">Face recognized</string>
 
-    <!-- Messages shown when users press outside of udfps region during -->
-    <string-array name="udfps_accessibility_touch_hints">
-        <item>Move left</item>
-        <item>Move down</item>
-        <item>Move right</item>
-        <item>Move up</item>
-    </string-array>
-
     <!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] -->
     <string name="keyguard_retry">Swipe up to try again</string>
 
@@ -2486,6 +2480,10 @@
     <string name="media_transfer_loading">Loading</string>
     <!-- Default name of the device. [CHAR LIMIT=30] -->
     <string name="media_ttt_default_device_type">tablet</string>
+    <!-- Description of media transfer icon of unknown app appears in receiver devices. [CHAR LIMIT=NONE]-->
+    <string name="media_transfer_receiver_content_description_unknown_app">Casting your media</string>
+    <!-- Description of media transfer icon appears in receiver devices. [CHAR LIMIT=NONE]-->
+    <string name="media_transfer_receiver_content_description_with_app_name">Casting <xliff:g id="app_label" example="Spotify">%1$s</xliff:g></string>
 
     <!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
     <string name="controls_error_timeout">Inactive, check app</string>
@@ -2538,8 +2536,7 @@
     <string name="media_output_group_title_speakers_and_displays">Speakers &amp; Displays</string>
     <!-- Title for Suggested Devices group. [CHAR LIMIT=NONE] -->
     <string name="media_output_group_title_suggested_device">Suggested Devices</string>
-    <!-- Sub status indicates device need premium account. [CHAR LIMIT=NONE] -->
-    <string name="media_output_status_require_premium">Requires premium account</string>
+
 
     <!-- Media Output Broadcast Dialog -->
     <!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
@@ -2564,7 +2561,10 @@
     <string name="media_output_broadcast_update_error">Can\u2019t save. Try again.</string>
     <!-- The error message when Broadcast name/code update failed and can't change again[CHAR LIMIT=60] -->
     <string name="media_output_broadcast_last_update_error">Can\u2019t save.</string>
-
+    <!-- The hint message when Broadcast code is less than 4 characters [CHAR LIMIT=60] -->
+    <string name="media_output_broadcast_code_hint_no_less_than_min">Use at least 4 characters</string>
+    <!-- The hint message when Broadcast code is more than 16 characters [CHAR LIMIT=60] -->
+    <string name="media_output_broadcast_code_hint_no_more_than_max">Use fewer than 16 characters</string>
 
     <!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
     <string name="build_number_clip_data_label">Build number</string>
@@ -2846,7 +2846,7 @@
     </string>
 
     <!-- Learn more URL for the log access confirmation dialog. [DO NOT TRANSLATE]-->
-    <string name="log_access_confirmation_learn_more_url" translatable="false">https://support.google.com/android?p=system_logs#topic=7313011</string>
+    <string name="log_access_confirmation_learn_more_url" translatable="false">https://support.google.com/android/answer/12986432</string>
     <string name="log_access_confirmation_learn_more">Learn more</string>
     <string name="log_access_confirmation_learn_more_at">Learn more at <xliff:g id="url" example="g.co/android/devicelogs">%s</xliff:g></string>
 
@@ -2899,15 +2899,15 @@
     <!-- Text for education page of cancel button to hide the page. [CHAR_LIMIT=NONE] -->
     <string name="rear_display_bottom_sheet_cancel">Cancel</string>
     <!-- Text for the user to confirm they flipped the device around. [CHAR_LIMIT=NONE] -->
-    <string name="rear_display_bottom_sheet_confirm">Flip now</string>
+    <string name="rear_display_bottom_sheet_confirm">Switch screens now</string>
     <!-- Text for education page title to guide user to unfold phone. [CHAR_LIMIT=50] -->
-    <string name="rear_display_fold_bottom_sheet_title">Unfold phone for a better selfie</string>
-    <!-- Text for education page title to guide user to flip to the front display. [CHAR_LIMIT=50] -->
-    <string name="rear_display_unfold_bottom_sheet_title">Flip to front display for a better selfie?</string>
+    <string name="rear_display_folded_bottom_sheet_title">Unfold phone</string>
+    <!-- Text for education page title to guide user to switch to the front display. [CHAR_LIMIT=50] -->
+    <string name="rear_display_unfolded_bottom_sheet_title">Switch screens?</string>
     <!-- Text for education page description to suggest user to use rear selfie capture. [CHAR_LIMIT=NONE] -->
-    <string name="rear_display_bottom_sheet_description">Use the rear-facing camera for a wider photo with higher resolution.</string>
-    <!-- Text for education page description to warn user that the display will turn off if the button is clicked. [CHAR_LIMIT=NONE] -->
-    <string name="rear_display_bottom_sheet_warning"><b>&#x2731; This screen will turn off</b></string>
+    <string name="rear_display_folded_bottom_sheet_description">For higher resolution, use the rear camera</string>
+    <!-- Text for unfolded education page description to suggest user to use rear selfie capture. [CHAR_LIMIT=NONE] -->
+    <string name="rear_display_unfolded_bottom_sheet_description">For higher resolution, flip the phone</string>
     <!-- Text for education page content description for folded animation. [CHAR_LIMIT=NONE] -->
     <string name="rear_display_accessibility_folded_animation">Foldable device being unfolded</string>
     <!-- Text for education page content description for unfolded animation. [CHAR_LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index dd87e91..9398c89 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -315,10 +315,6 @@
 
         <!-- Needed for MediaRoute chooser dialog -->
         <item name="*android:isLightTheme">false</item>
-
-        <!-- Biometrics enroll color style -->
-        <item name="biometricsEnrollStyle">@style/BiometricsEnrollStyle</item>
-
     </style>
 
     <style name="Theme.SystemUI.LightWallpaper">
@@ -758,6 +754,18 @@
     </style>
 
     <!-- Screenshots -->
+    <style name="AppClipsTrampolineActivity">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:backgroundDimEnabled">true</item>
+    </style>
+
+    <style name="AppClipsActivity" parent="LongScreenshotActivity">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+
     <style name="LongScreenshotActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowLightStatusBar">true</item>
@@ -1343,15 +1351,6 @@
         <item name="android:background">@drawable/grant_permissions_buttons_bottom</item>
     </style>
 
-    <style name="BiometricsEnrollStyle">
-        <item name="biometricsEnrollIcon">@color/udfps_enroll_icon</item>
-        <item name="biometricsMovingTargetFill">@color/udfps_moving_target_fill</item>
-        <item name="biometricsMovingTargetFillError">@color/udfps_moving_target_fill_error</item>
-        <item name="biometricsEnrollProgress">@color/udfps_enroll_progress</item>
-        <item name="biometricsEnrollProgressHelp">@color/udfps_enroll_progress_help</item>
-        <item name="biometricsEnrollProgressHelpWithTalkback">@color/udfps_enroll_progress_help_with_talkback</item>
-    </style>
-
     <!-- Magnification styles -->
     <style name="TextAppearance.MagnificationSetting" />
 
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index d9c81af..5129fc0 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -73,11 +73,12 @@
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/qs_media_info_spacing"
         android:layout_marginBottom="@dimen/qs_media_padding"
-        android:layout_marginTop="0dp"
+        android:layout_marginTop="@dimen/qs_media_icon_offset"
         app:layout_constraintStart_toStartOf="@id/header_title"
         app:layout_constraintEnd_toStartOf="@id/header_artist"
         app:layout_constraintTop_toTopOf="@id/header_artist"
-        app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
+        app:layout_constraintBottom_toBottomOf="@id/header_artist"
+        app:layout_constraintVertical_bias="0"
         app:layout_constraintHorizontal_bias="0"
         app:layout_constraintHorizontal_chainStyle="packed" />
 
diff --git a/packages/SystemUI/res/xml/qqs_header.xml b/packages/SystemUI/res/xml/qqs_header.xml
index e56e5d5..00a0444 100644
--- a/packages/SystemUI/res/xml/qqs_header.xml
+++ b/packages/SystemUI/res/xml/qqs_header.xml
@@ -48,8 +48,7 @@
             app:layout_constrainedWidth="true"
             app:layout_constraintStart_toEndOf="@id/clock"
             app:layout_constraintEnd_toStartOf="@id/barrier"
-            app:layout_constraintTop_toTopOf="parent"
-            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintBaseline_toBaselineOf="@id/clock"
             app:layout_constraintHorizontal_bias="0"
         />
     </Constraint>
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 95675ce..209d5e8 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
@@ -38,13 +38,19 @@
 public class Monitor {
     private final String mTag = getClass().getSimpleName();
     private final Executor mExecutor;
+    private final Set<Condition> mPreconditions;
 
     private final HashMap<Condition, ArraySet<Subscription.Token>> mConditions = new HashMap<>();
     private final HashMap<Subscription.Token, SubscriptionState> mSubscriptions = new HashMap<>();
 
     private static class SubscriptionState {
         private final Subscription mSubscription;
+
+        // A subscription must maintain a reference to any active nested subscription so that it may
+        // be later removed when the current subscription becomes invalid.
+        private Subscription.Token mNestedSubscriptionToken;
         private Boolean mAllConditionsMet;
+        private boolean mActive;
 
         SubscriptionState(Subscription subscription) {
             mSubscription = subscription;
@@ -54,7 +60,27 @@
             return mSubscription.mConditions;
         }
 
-        public void update() {
+        /**
+         * Signals that the {@link Subscription} is now being monitored and will receive updates
+         * based on its conditions.
+         */
+        private void setActive(boolean active) {
+            if (mActive == active) {
+                return;
+            }
+
+            mActive = active;
+
+            final Callback callback = mSubscription.getCallback();
+
+            if (callback == null) {
+                return;
+            }
+
+            callback.onActiveChanged(active);
+        }
+
+        public void update(Monitor monitor) {
             final Boolean result = Evaluator.INSTANCE.evaluate(mSubscription.mConditions,
                     Evaluator.OP_AND);
             // Consider unknown (null) as true
@@ -65,7 +91,50 @@
             }
 
             mAllConditionsMet = newAllConditionsMet;
-            mSubscription.mCallback.onConditionsChanged(mAllConditionsMet);
+
+            final Subscription nestedSubscription = mSubscription.getNestedSubscription();
+
+            if (nestedSubscription != null) {
+                if (mAllConditionsMet && mNestedSubscriptionToken == null) {
+                    // When all conditions are met for a subscription with a nested subscription
+                    // that is not currently being monitored, add the nested subscription for
+                    // monitor.
+                    mNestedSubscriptionToken =
+                            monitor.addSubscription(nestedSubscription, null);
+                } else if (!mAllConditionsMet && mNestedSubscriptionToken != null) {
+                    // When conditions are not met and there is an active nested condition, remove
+                    // the nested condition from monitoring.
+                    removeNestedSubscription(monitor);
+                }
+                return;
+            }
+
+            mSubscription.getCallback().onConditionsChanged(mAllConditionsMet);
+        }
+
+        /**
+         * Invoked when the {@link Subscription} has been added to the {@link Monitor}.
+         */
+        public void onAdded() {
+            setActive(true);
+        }
+
+        /**
+         * Invoked when the {@link Subscription} has been removed from the {@link Monitor},
+         * allowing cleanup code to run.
+         */
+        public void onRemoved(Monitor monitor) {
+            setActive(false);
+            removeNestedSubscription(monitor);
+        }
+
+        private void removeNestedSubscription(Monitor monitor) {
+            if (mNestedSubscriptionToken == null) {
+                return;
+            }
+
+            monitor.removeSubscription(mNestedSubscriptionToken);
+            mNestedSubscriptionToken = null;
         }
     }
 
@@ -77,9 +146,20 @@
         }
     };
 
+    /**
+     * Constructor for injected use-cases. By default, no preconditions are present.
+     */
     @Inject
     public Monitor(@Main Executor executor) {
+        this(executor, Collections.emptySet());
+    }
+
+    /**
+     * Main constructor, allowing specifying preconditions.
+     */
+    public Monitor(Executor executor, Set<Condition> preconditions) {
         mExecutor = executor;
+        mPreconditions = preconditions;
     }
 
     private void updateConditionMetState(Condition condition) {
@@ -91,7 +171,7 @@
             return;
         }
 
-        subscriptions.stream().forEach(token -> mSubscriptions.get(token).update());
+        subscriptions.stream().forEach(token -> mSubscriptions.get(token).update(this));
     }
 
     /**
@@ -101,15 +181,25 @@
      * @return A {@link Subscription.Token} that can be used to remove the subscription.
      */
     public Subscription.Token addSubscription(@NonNull Subscription subscription) {
+        return addSubscription(subscription, mPreconditions);
+    }
+
+    private Subscription.Token addSubscription(@NonNull Subscription subscription,
+            Set<Condition> preconditions) {
+        // If preconditions are set on the monitor, set up as a nested condition.
+        final Subscription normalizedCondition = preconditions != null
+                ? new Subscription.Builder(subscription).addConditions(preconditions).build()
+                : subscription;
+
         final Subscription.Token token = new Subscription.Token();
-        final SubscriptionState state = new SubscriptionState(subscription);
+        final SubscriptionState state = new SubscriptionState(normalizedCondition);
 
         mExecutor.execute(() -> {
             if (shouldLog()) Log.d(mTag, "adding subscription");
             mSubscriptions.put(token, state);
 
             // Add and associate conditions.
-            subscription.getConditions().stream().forEach(condition -> {
+            normalizedCondition.getConditions().stream().forEach(condition -> {
                 if (!mConditions.containsKey(condition)) {
                     mConditions.put(condition, new ArraySet<>());
                     condition.addCallback(mConditionCallback);
@@ -118,8 +208,10 @@
                 mConditions.get(condition).add(token);
             });
 
+            state.onAdded();
+
             // Update subscription state.
-            state.update();
+            state.update(this);
 
         });
         return token;
@@ -139,7 +231,9 @@
                 return;
             }
 
-            mSubscriptions.remove(token).getConditions().forEach(condition -> {
+            final SubscriptionState removedSubscription = mSubscriptions.remove(token);
+
+            removedSubscription.getConditions().forEach(condition -> {
                 if (!mConditions.containsKey(condition)) {
                     Log.e(mTag, "condition not present:" + condition);
                     return;
@@ -153,6 +247,8 @@
                     mConditions.remove(condition);
                 }
             });
+
+            removedSubscription.onRemoved(this);
         });
     }
 
@@ -168,12 +264,19 @@
         private final Set<Condition> mConditions;
         private final Callback mCallback;
 
-        /**
-         *
-         */
-        public Subscription(Set<Condition> conditions, Callback callback) {
+        // A nested {@link Subscription} is a special callback where the specified condition's
+        // active state is dependent on the conditions of the parent {@link Subscription} being met.
+        // Once active, the nested subscription's conditions are registered as normal with the
+        // monitor and its callback (which could also be a nested condition) is triggered based on
+        // those conditions. The nested condition will be removed from monitor if the outer
+        // subscription's conditions ever become invalid.
+        private final Subscription mNestedSubscription;
+
+        private Subscription(Set<Condition> conditions, Callback callback,
+                Subscription nestedSubscription) {
             this.mConditions = Collections.unmodifiableSet(conditions);
             this.mCallback = callback;
+            this.mNestedSubscription = nestedSubscription;
         }
 
         public Set<Condition> getConditions() {
@@ -184,6 +287,10 @@
             return mCallback;
         }
 
+        public Subscription getNestedSubscription() {
+            return mNestedSubscription;
+        }
+
         /**
          * A {@link Token} is an identifier that is associated with a {@link Subscription} which is
          * registered with a {@link Monitor}.
@@ -196,14 +303,26 @@
          */
         public static class Builder {
             private final Callback mCallback;
+            private final Subscription mNestedSubscription;
             private final ArraySet<Condition> mConditions;
+            private final ArraySet<Condition> mPreconditions;
 
             /**
              * Default constructor specifying the {@link Callback} for the {@link Subscription}.
              */
             public Builder(Callback callback) {
+                this(null, callback);
+            }
+
+            public Builder(Subscription nestedSubscription) {
+                this(nestedSubscription, null);
+            }
+
+            private Builder(Subscription nestedSubscription, Callback callback) {
+                mNestedSubscription = nestedSubscription;
                 mCallback = callback;
-                mConditions = new ArraySet<>();
+                mConditions = new ArraySet();
+                mPreconditions = new ArraySet();
             }
 
             /**
@@ -217,11 +336,38 @@
             }
 
             /**
+             * Adds a set of {@link Condition} to be a precondition for {@link Subscription}.
+             *
+             * @return The updated {@link Builder}.
+             */
+            public Builder addPreconditions(Set<Condition> condition) {
+                if (condition == null) {
+                    return this;
+                }
+                mPreconditions.addAll(condition);
+                return this;
+            }
+
+            /**
+             * Adds a {@link Condition} to be a precondition for {@link Subscription}.
+             *
+             * @return The updated {@link Builder}.
+             */
+            public Builder addPrecondition(Condition condition) {
+                mPreconditions.add(condition);
+                return this;
+            }
+
+            /**
              * Adds a set of {@link Condition} to be associated with the {@link Subscription}.
              *
              * @return The updated {@link Builder}.
              */
             public Builder addConditions(Set<Condition> condition) {
+                if (condition == null) {
+                    return this;
+                }
+
                 mConditions.addAll(condition);
                 return this;
             }
@@ -232,7 +378,11 @@
              * @return The resulting {@link Subscription}.
              */
             public Subscription build() {
-                return new Subscription(mConditions, mCallback);
+                final Subscription subscription =
+                        new Subscription(mConditions, mCallback, mNestedSubscription);
+                return !mPreconditions.isEmpty()
+                        ? new Subscription(mPreconditions, null, subscription)
+                        : subscription;
             }
         }
     }
@@ -255,5 +405,13 @@
          *                         only partial conditions have been fulfilled.
          */
         void onConditionsChanged(boolean allConditionsMet);
+
+        /**
+         * Called when the active state of the {@link Subscription} changes.
+         * @param active {@code true} when changes to the conditions will affect the
+         *               {@link Subscription}, {@code false} otherwise.
+         */
+        default void onActiveChanged(boolean active) {
+        }
     }
 }
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 ef2247f..9a581aa 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
@@ -114,7 +114,27 @@
 
     /** Dump region sampler */
     fun dump(pw: PrintWriter) {
-        regionSampler?.dump(pw)
+        pw.println("[RegionSampler]")
+        pw.println("regionSamplingEnabled: $regionSamplingEnabled")
+        pw.println("regionDarkness: $regionDarkness")
+        pw.println("lightForegroundColor: ${Integer.toHexString(lightForegroundColor)}")
+        pw.println("darkForegroundColor: ${Integer.toHexString(darkForegroundColor)}")
+        pw.println("passed-in sampledView: $sampledView")
+        pw.println("calculated samplingBounds: $samplingBounds")
+        pw.println(
+            "sampledView width: ${sampledView?.width}, sampledView height: ${sampledView?.height}"
+        )
+        pw.println("screen width: ${displaySize.x}, screen height: ${displaySize.y}")
+        pw.println(
+            "sampledRegionWithOffset: ${convertBounds(calculateSampledRegion(sampledView!!))}"
+        )
+        // 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)}"
+        )
     }
 
     fun calculateSampledRegion(sampledView: View): RectF {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
index 9b73cc3..bd20777 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/shadow/DoubleShadowTextView.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.shared.shadow.DoubleShadowTextHelper.applyShadows
 
 /** Extension of [TextView] which draws two shadows on the text (ambient and key shadows} */
-class DoubleShadowTextView
+open class DoubleShadowTextView
 @JvmOverloads
 constructor(
     context: Context,
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 0d35aa3..7d39c4a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -43,6 +43,7 @@
     public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy";
     public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius";
     public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners";
+    public static final String KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER = "extra_unfold_animation";
     // See ISysuiUnlockAnimationController.aidl
     public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation";
 
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 b7e2494..44c0e16 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
@@ -88,6 +88,7 @@
                 final ArrayList<WindowContainerToken> pausingTasks = new ArrayList<>();
                 WindowContainerToken pipTask = null;
                 WindowContainerToken recentsTask = null;
+                int recentsTaskId = -1;
                 for (int i = apps.length - 1; i >= 0; --i) {
                     final ActivityManager.RunningTaskInfo taskInfo = apps[i].taskInfo;
                     if (apps[i].mode == MODE_CLOSING) {
@@ -106,8 +107,10 @@
                         // This task is for recents, keep it on top.
                         t.setLayer(apps[i].leash, info.getChanges().size() * 3 - i);
                         recentsTask = taskInfo.token;
+                        recentsTaskId = taskInfo.taskId;
                     } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
                         recentsTask = taskInfo.token;
+                        recentsTaskId = taskInfo.taskId;
                     }
                 }
                 // Also make all the wallpapers opaque since we want the visible from the start
@@ -116,7 +119,7 @@
                 }
                 t.apply();
                 mRecentsSession.setup(controller, info, finishedCallback, pausingTasks, pipTask,
-                        recentsTask, leashMap, mToken,
+                        recentsTask, recentsTaskId, leashMap, mToken,
                         (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0);
                 recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0),
                         new Rect());
@@ -154,6 +157,7 @@
         private ArrayList<WindowContainerToken> mPausingTasks = null;
         private WindowContainerToken mPipTask = null;
         private WindowContainerToken mRecentsTask = null;
+        private int mRecentsTaskId = 0;
         private TransitionInfo mInfo = null;
         private ArrayList<SurfaceControl> mOpeningLeashes = null;
         private boolean mOpeningHome = false;
@@ -167,8 +171,8 @@
         void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info,
                 IRemoteTransitionFinishedCallback finishCB,
                 ArrayList<WindowContainerToken> pausingTasks, WindowContainerToken pipTask,
-                WindowContainerToken recentsTask, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
-                IBinder transition, boolean keyguardLocked) {
+                WindowContainerToken recentsTask, int recentsTaskId, ArrayMap<SurfaceControl,
+                SurfaceControl> leashMap, IBinder transition, boolean keyguardLocked) {
             if (mInfo != null) {
                 throw new IllegalStateException("Trying to run a new recents animation while"
                         + " recents is already active.");
@@ -179,6 +183,7 @@
             mPausingTasks = pausingTasks;
             mPipTask = pipTask;
             mRecentsTask = recentsTask;
+            mRecentsTaskId = recentsTaskId;
             mLeashMap = leashMap;
             mTransition = transition;
             mKeyguardLocked = keyguardLocked;
@@ -296,6 +301,15 @@
         }
 
         @Override public void setInputConsumerEnabled(boolean enabled) {
+            if (enabled) {
+                // transient launches don't receive focus automatically. Since we are taking over
+                // the gesture now, take focus explicitly.
+                try {
+                    ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to set focused task", e);
+                }
+            }
             if (mWrapped != null) mWrapped.setInputConsumerEnabled(enabled);
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
index 38fa354..54ae84f9 100644
--- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
@@ -16,18 +16,20 @@
 
 package com.android.keyguard
 
-import android.annotation.IntDef
 import android.content.ContentResolver
 import android.database.ContentObserver
 import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
 import android.net.Uri
 import android.os.Handler
+import android.os.PowerManager
+import android.os.PowerManager.WAKE_REASON_UNFOLD_DEVICE
 import android.os.UserHandle
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
 import android.util.Log
 import com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser
@@ -52,23 +54,26 @@
 
     companion object {
         const val TAG = "ActiveUnlockConfig"
-
-        const val BIOMETRIC_TYPE_NONE = 0
-        const val BIOMETRIC_TYPE_ANY_FACE = 1
-        const val BIOMETRIC_TYPE_ANY_FINGERPRINT = 2
-        const val BIOMETRIC_TYPE_UNDER_DISPLAY_FINGERPRINT = 3
     }
 
-    @Retention(AnnotationRetention.SOURCE)
-    @IntDef(BIOMETRIC_TYPE_NONE, BIOMETRIC_TYPE_ANY_FACE, BIOMETRIC_TYPE_ANY_FINGERPRINT,
-            BIOMETRIC_TYPE_UNDER_DISPLAY_FINGERPRINT)
-    annotation class BiometricType
-
     /**
      * Indicates the origin for an active unlock request.
      */
-    enum class ACTIVE_UNLOCK_REQUEST_ORIGIN {
-        WAKE, UNLOCK_INTENT, BIOMETRIC_FAIL, ASSISTANT
+    enum class ActiveUnlockRequestOrigin {
+        WAKE,
+        UNLOCK_INTENT,
+        BIOMETRIC_FAIL,
+        ASSISTANT,
+    }
+
+    /**
+     * Biometric type options.
+     */
+    enum class BiometricType(val intValue: Int) {
+        NONE(0),
+        ANY_FACE(1),
+        ANY_FINGERPRINT(2),
+        UNDER_DISPLAY_FINGERPRINT(3),
     }
 
     var keyguardUpdateMonitor: KeyguardUpdateMonitor? = null
@@ -76,9 +81,10 @@
     private var requestActiveUnlockOnUnlockIntent = false
     private var requestActiveUnlockOnBioFail = false
 
-    private var faceErrorsToTriggerBiometricFailOn = mutableSetOf(FACE_ERROR_TIMEOUT)
+    private var faceErrorsToTriggerBiometricFailOn = mutableSetOf<Int>()
     private var faceAcquireInfoToTriggerBiometricFailOn = mutableSetOf<Int>()
-    private var onUnlockIntentWhenBiometricEnrolled = mutableSetOf<Int>(BIOMETRIC_TYPE_NONE)
+    private var onUnlockIntentWhenBiometricEnrolled = mutableSetOf<Int>()
+    private var wakeupsConsideredUnlockIntents = mutableSetOf<Int>()
 
     private val settingsObserver = object : ContentObserver(handler) {
         private val wakeUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
@@ -89,16 +95,19 @@
                 secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO)
         private val unlockIntentWhenBiometricEnrolledUri =
                 secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
+        private val wakeupsConsideredUnlockIntentsUri =
+            secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS)
 
         fun register() {
             registerUri(
                     listOf(
-                            wakeUri,
-                            unlockIntentUri,
-                            bioFailUri,
-                            faceErrorsUri,
-                            faceAcquireInfoUri,
-                            unlockIntentWhenBiometricEnrolledUri
+                        wakeUri,
+                        unlockIntentUri,
+                        bioFailUri,
+                        faceErrorsUri,
+                        faceAcquireInfoUri,
+                        unlockIntentWhenBiometricEnrolledUri,
+                        wakeupsConsideredUnlockIntentsUri,
                     )
             )
 
@@ -153,7 +162,7 @@
                         secureSettings.getStringForUser(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
                                 getCurrentUser()),
                         faceAcquireInfoToTriggerBiometricFailOn,
-                        setOf<Int>())
+                        emptySet())
             }
 
             if (selfChange || uris.contains(unlockIntentWhenBiometricEnrolledUri)) {
@@ -162,7 +171,16 @@
                                 ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
                                 getCurrentUser()),
                         onUnlockIntentWhenBiometricEnrolled,
-                        setOf(BIOMETRIC_TYPE_NONE))
+                        setOf(BiometricType.NONE.intValue))
+            }
+
+            if (selfChange || uris.contains(wakeupsConsideredUnlockIntentsUri)) {
+                processStringArray(
+                    secureSettings.getStringForUser(
+                        ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
+                        getCurrentUser()),
+                    wakeupsConsideredUnlockIntents,
+                    setOf(WAKE_REASON_UNFOLD_DEVICE))
             }
         }
 
@@ -181,10 +199,12 @@
             out.clear()
             stringSetting?.let {
                 for (code: String in stringSetting.split("|")) {
-                    try {
-                        out.add(code.toInt())
-                    } catch (e: NumberFormatException) {
-                        Log.e(TAG, "Passed an invalid setting=$code")
+                    if (code.isNotEmpty()) {
+                        try {
+                            out.add(code.toInt())
+                        } catch (e: NumberFormatException) {
+                            Log.e(TAG, "Passed an invalid setting=$code")
+                        }
                     }
                 }
             } ?: out.addAll(default)
@@ -221,22 +241,30 @@
     }
 
     /**
+     * Whether the PowerManager wake reason is considered an unlock intent and should use origin
+     * [ActiveUnlockRequestOrigin.UNLOCK_INTENT] instead of [ActiveUnlockRequestOrigin.WAKE].
+     */
+    fun isWakeupConsideredUnlockIntent(pmWakeReason: Int): Boolean {
+        return wakeupsConsideredUnlockIntents.contains(pmWakeReason)
+    }
+
+    /**
      * Whether to trigger active unlock based on where the request is coming from and
      * the current settings.
      */
-    fun shouldAllowActiveUnlockFromOrigin(requestOrigin: ACTIVE_UNLOCK_REQUEST_ORIGIN): Boolean {
+    fun shouldAllowActiveUnlockFromOrigin(requestOrigin: ActiveUnlockRequestOrigin): Boolean {
         return when (requestOrigin) {
-            ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE -> requestActiveUnlockOnWakeup
+            ActiveUnlockRequestOrigin.WAKE -> requestActiveUnlockOnWakeup
 
-            ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT ->
+            ActiveUnlockRequestOrigin.UNLOCK_INTENT ->
                 requestActiveUnlockOnUnlockIntent || requestActiveUnlockOnWakeup ||
                         (shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment())
 
-            ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL ->
+            ActiveUnlockRequestOrigin.BIOMETRIC_FAIL ->
                 requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntent ||
                         requestActiveUnlockOnWakeup
 
-            ACTIVE_UNLOCK_REQUEST_ORIGIN.ASSISTANT -> isActiveUnlockEnabled()
+            ActiveUnlockRequestOrigin.ASSISTANT -> isActiveUnlockEnabled()
         }
     }
 
@@ -252,18 +280,18 @@
             val udfpsEnrolled = it.isUdfpsEnrolled
 
             if (!anyFaceEnrolled && !anyFingerprintEnrolled) {
-                return onUnlockIntentWhenBiometricEnrolled.contains(BIOMETRIC_TYPE_NONE)
+                return onUnlockIntentWhenBiometricEnrolled.contains(BiometricType.NONE.intValue)
             }
 
             if (!anyFaceEnrolled && anyFingerprintEnrolled) {
                 return onUnlockIntentWhenBiometricEnrolled.contains(
-                        BIOMETRIC_TYPE_ANY_FINGERPRINT) ||
+                        BiometricType.ANY_FINGERPRINT.intValue) ||
                         (udfpsEnrolled && onUnlockIntentWhenBiometricEnrolled.contains(
-                                BIOMETRIC_TYPE_UNDER_DISPLAY_FINGERPRINT))
+                                BiometricType.UNDER_DISPLAY_FINGERPRINT.intValue))
             }
 
             if (!anyFingerprintEnrolled && anyFaceEnrolled) {
-                return onUnlockIntentWhenBiometricEnrolled.contains(BIOMETRIC_TYPE_ANY_FACE)
+                return onUnlockIntentWhenBiometricEnrolled.contains(BiometricType.ANY_FACE.intValue)
             }
         }
 
@@ -275,11 +303,15 @@
         pw.println("   requestActiveUnlockOnWakeup=$requestActiveUnlockOnWakeup")
         pw.println("   requestActiveUnlockOnUnlockIntent=$requestActiveUnlockOnUnlockIntent")
         pw.println("   requestActiveUnlockOnBioFail=$requestActiveUnlockOnBioFail")
-        pw.println("   requestActiveUnlockOnUnlockIntentWhenBiometricEnrolled=" +
-                "$onUnlockIntentWhenBiometricEnrolled")
+        pw.println("   requestActiveUnlockOnUnlockIntentWhenBiometricEnrolled=${
+            onUnlockIntentWhenBiometricEnrolled.map { BiometricType.values()[it] }
+        }")
         pw.println("   requestActiveUnlockOnFaceError=$faceErrorsToTriggerBiometricFailOn")
         pw.println("   requestActiveUnlockOnFaceAcquireInfo=" +
                 "$faceAcquireInfoToTriggerBiometricFailOn")
+        pw.println("   activeUnlockWakeupsConsideredUnlockIntents=${
+            wakeupsConsideredUnlockIntents.map { PowerManager.wakeReasonToString(it) }
+        }")
 
         pw.println("Current state:")
         keyguardUpdateMonitor?.let {
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 7f95ca6..1254e1e 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -24,8 +24,8 @@
 import android.text.format.DateFormat
 import android.util.TypedValue
 import android.view.View
-import android.widget.FrameLayout
 import android.view.ViewTreeObserver
+import android.widget.FrameLayout
 import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
@@ -40,34 +40,37 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.log.dagger.KeyguardSmallClockLog
 import com.android.systemui.log.dagger.KeyguardLargeClockLog
+import com.android.systemui.log.dagger.KeyguardSmallClockLog
 import com.android.systemui.plugins.ClockController
 import com.android.systemui.plugins.ClockFaceController
 import com.android.systemui.plugins.ClockTickRate
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel.DEBUG
 import com.android.systemui.shared.regionsampling.RegionSampler
+import com.android.systemui.plugins.Weather
 import com.android.systemui.statusbar.policy.BatteryController
 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
  * [KeyguardClockSwitchController]. Functionality is forked from [AnimatableClockController].
  */
-open class ClockEventController @Inject constructor(
+open class ClockEventController
+@Inject
+constructor(
     private val keyguardInteractor: KeyguardInteractor,
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val broadcastDispatcher: BroadcastDispatcher,
@@ -114,52 +117,59 @@
     private var disposableHandle: DisposableHandle? = null
     private val regionSamplingEnabled = featureFlags.isEnabled(REGION_SAMPLING)
 
-    private val mLayoutChangedListener = object : View.OnLayoutChangeListener {
-        private var currentSmallClockView: View? = null
-        private var currentLargeClockView: View? = null
-        private var currentSmallClockLocation = IntArray(2)
-        private var currentLargeClockLocation = IntArray(2)
+    private val mLayoutChangedListener =
+        object : View.OnLayoutChangeListener {
+            private var currentSmallClockView: View? = null
+            private var currentLargeClockView: View? = null
+            private var currentSmallClockLocation = IntArray(2)
+            private var currentLargeClockLocation = IntArray(2)
 
-        override fun onLayoutChange(
-            view: View?,
-            left: Int,
-            top: Int,
-            right: Int,
-            bottom: Int,
-            oldLeft: Int,
-            oldTop: Int,
-            oldRight: Int,
-            oldBottom: Int
-        ) {
-        val parent = (view?.parent) as FrameLayout
+            override fun onLayoutChange(
+                view: View?,
+                left: Int,
+                top: Int,
+                right: Int,
+                bottom: Int,
+                oldLeft: Int,
+                oldTop: Int,
+                oldRight: Int,
+                oldBottom: Int
+            ) {
+                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
-        }
+                // don't pass in negative bounds when clocks are in transition state
+                if (view.locationOnScreen[0] < 0 || view.locationOnScreen[1] < 0) {
+                    return
+                }
 
-        // SMALL CLOCK
-        if (parent.id == R.id.lockscreen_clock_view) {
-            // view bounds have changed due to clock size changing (i.e. different character widths)
-            // AND/OR the view has been translated when transitioning between small and large clock
-            if (view != currentSmallClockView ||
-                !view.locationOnScreen.contentEquals(currentSmallClockLocation)) {
-                currentSmallClockView = view
-                currentSmallClockLocation = view.locationOnScreen
-                updateRegionSampler(view)
+                // SMALL CLOCK
+                if (parent.id == R.id.lockscreen_clock_view) {
+                    // view bounds have changed due to clock size changing (i.e. different character
+                    // widths)
+                    // AND/OR the view has been translated when transitioning between small and
+                    // large clock
+                    if (
+                        view != currentSmallClockView ||
+                            !view.locationOnScreen.contentEquals(currentSmallClockLocation)
+                    ) {
+                        currentSmallClockView = view
+                        currentSmallClockLocation = view.locationOnScreen
+                        updateRegionSampler(view)
+                    }
+                }
+                // LARGE CLOCK
+                else if (parent.id == R.id.lockscreen_clock_view_large) {
+                    if (
+                        view != currentLargeClockView ||
+                            !view.locationOnScreen.contentEquals(currentLargeClockLocation)
+                    ) {
+                        currentLargeClockView = view
+                        currentLargeClockLocation = view.locationOnScreen
+                        updateRegionSampler(view)
+                    }
+                }
             }
         }
-        // LARGE CLOCK
-        else if (parent.id == R.id.lockscreen_clock_view_large) {
-            if (view != currentLargeClockView ||
-                !view.locationOnScreen.contentEquals(currentLargeClockLocation)) {
-                currentLargeClockView = view
-                currentLargeClockLocation = view.locationOnScreen
-                updateRegionSampler(view)
-            }
-        }
-        }
-    }
 
     private fun updateColors() {
         val wallpaperManager = WallpaperManager.getInstance(context)
@@ -188,30 +198,33 @@
 
     private fun updateRegionSampler(sampledRegion: View) {
         regionSampler?.stopRegionSampler()
-        regionSampler = createRegionSampler(
-            sampledRegion,
-            mainExecutor,
-            bgExecutor,
-            regionSamplingEnabled,
-            ::updateColors
-        )?.apply { startRegionSampler() }
+        regionSampler =
+            createRegionSampler(
+                    sampledRegion,
+                    mainExecutor,
+                    bgExecutor,
+                    regionSamplingEnabled,
+                    ::updateColors
+                )
+                ?.apply { startRegionSampler() }
 
         updateColors()
     }
 
     protected open fun createRegionSampler(
-            sampledView: View?,
-            mainExecutor: Executor?,
-            bgExecutor: Executor?,
-            regionSamplingEnabled: Boolean,
-            updateColors: () -> Unit
+        sampledView: View?,
+        mainExecutor: Executor?,
+        bgExecutor: Executor?,
+        regionSamplingEnabled: Boolean,
+        updateColors: () -> Unit
     ): RegionSampler? {
         return RegionSampler(
             sampledView,
             mainExecutor,
             bgExecutor,
             regionSamplingEnabled,
-            updateColors)
+            updateColors
+        )
     }
 
     var regionSampler: RegionSampler? = null
@@ -223,58 +236,68 @@
     private var smallClockIsDark = true
     private var largeClockIsDark = true
 
-    private val configListener = object : ConfigurationController.ConfigurationListener {
-        override fun onThemeChanged() {
-            clock?.events?.onColorPaletteChanged(resources)
-            updateColors()
-        }
-
-        override fun onDensityOrFontScaleChanged() {
-            updateFontSizes()
-        }
-    }
-
-    private val batteryCallback = object : BatteryStateChangeCallback {
-        override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
-            if (isKeyguardVisible && !isCharging && charging) {
-                clock?.animations?.charge()
+    private val configListener =
+        object : ConfigurationController.ConfigurationListener {
+            override fun onThemeChanged() {
+                clock?.events?.onColorPaletteChanged(resources)
+                updateColors()
             }
-            isCharging = charging
-        }
-    }
 
-    private val localeBroadcastReceiver = object : BroadcastReceiver() {
-        override fun onReceive(context: Context, intent: Intent) {
-            clock?.events?.onLocaleChanged(Locale.getDefault())
+            override fun onDensityOrFontScaleChanged() {
+                updateFontSizes()
+            }
         }
-    }
 
-    private val keyguardUpdateMonitorCallback = object : KeyguardUpdateMonitorCallback() {
-        override fun onKeyguardVisibilityChanged(visible: Boolean) {
-            isKeyguardVisible = visible
-            if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) {
-                if (!isKeyguardVisible) {
-                    clock?.animations?.doze(if (isDozing) 1f else 0f)
+    private val batteryCallback =
+        object : BatteryStateChangeCallback {
+            override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
+                if (isKeyguardVisible && !isCharging && charging) {
+                    clock?.animations?.charge()
+                }
+                isCharging = charging
+            }
+        }
+
+    private val localeBroadcastReceiver =
+        object : BroadcastReceiver() {
+            override fun onReceive(context: Context, intent: Intent) {
+                clock?.events?.onLocaleChanged(Locale.getDefault())
+            }
+        }
+
+    private val keyguardUpdateMonitorCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onKeyguardVisibilityChanged(visible: Boolean) {
+                isKeyguardVisible = visible
+                if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) {
+                    if (!isKeyguardVisible) {
+                        clock?.animations?.doze(if (isDozing) 1f else 0f)
+                    }
+                }
+
+                smallTimeListener?.update(shouldTimeListenerRun)
+                largeTimeListener?.update(shouldTimeListenerRun)
+            }
+
+            override fun onTimeFormatChanged(timeFormat: String) {
+                clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
+            }
+
+            override fun onTimeZoneChanged(timeZone: TimeZone) {
+                clock?.events?.onTimeZoneChanged(timeZone)
+            }
+
+            override fun onUserSwitchComplete(userId: Int) {
+                clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
+            }
+
+            override fun onWeatherDataChanged(data: Weather?) {
+                if (data != null) {
+                    clock?.events?.onWeatherDataChanged(data)
                 }
             }
-
-            smallTimeListener?.update(shouldTimeListenerRun)
-            largeTimeListener?.update(shouldTimeListenerRun)
         }
 
-        override fun onTimeFormatChanged(timeFormat: String) {
-            clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
-        }
-
-        override fun onTimeZoneChanged(timeZone: TimeZone) {
-            clock?.events?.onTimeZoneChanged(timeZone)
-        }
-
-        override fun onUserSwitchComplete(userId: Int) {
-            clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
-        }
-    }
-
     fun registerListeners(parent: View) {
         if (isRegistered) {
             return
@@ -288,17 +311,18 @@
         configurationController.addCallback(configListener)
         batteryController.addCallback(batteryCallback)
         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
-        disposableHandle = parent.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.STARTED) {
-                listenForDozing(this)
-                if (featureFlags.isEnabled(DOZING_MIGRATION_1)) {
-                    listenForDozeAmountTransition(this)
-                    listenForAnyStateToAodTransition(this)
-                } else {
-                    listenForDozeAmount(this)
+        disposableHandle =
+            parent.repeatWhenAttached {
+                repeatOnLifecycle(Lifecycle.State.STARTED) {
+                    listenForDozing(this)
+                    if (featureFlags.isEnabled(DOZING_MIGRATION_1)) {
+                        listenForDozeAmountTransition(this)
+                        listenForAnyStateToAodTransition(this)
+                    } else {
+                        listenForDozeAmount(this)
+                    }
                 }
             }
-        }
         smallTimeListener?.update(shouldTimeListenerRun)
         largeTimeListener?.update(shouldTimeListenerRun)
     }
@@ -337,10 +361,18 @@
     }
 
     private fun updateFontSizes() {
-        clock?.smallClock?.events?.onFontSettingChanged(
-            resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat())
-        clock?.largeClock?.events?.onFontSettingChanged(
-            resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat())
+        clock
+            ?.smallClock
+            ?.events
+            ?.onFontSettingChanged(
+                resources.getDimensionPixelSize(R.dimen.small_clock_text_size).toFloat()
+            )
+        clock
+            ?.largeClock
+            ?.events
+            ?.onFontSettingChanged(
+                resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
+            )
     }
 
     private fun handleDoze(doze: Float) {
@@ -352,68 +384,59 @@
 
     @VisibleForTesting
     internal fun listenForDozeAmount(scope: CoroutineScope): Job {
-        return scope.launch {
-            keyguardInteractor.dozeAmount.collect {
-                handleDoze(it)
-            }
-        }
+        return scope.launch { keyguardInteractor.dozeAmount.collect { handleDoze(it) } }
     }
 
     @VisibleForTesting
     internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job {
         return scope.launch {
-            keyguardTransitionInteractor.dozeAmountTransition.collect {
-                handleDoze(it.value)
-            }
+            keyguardTransitionInteractor.dozeAmountTransition.collect { handleDoze(it.value) }
         }
     }
 
     /**
-     * When keyguard is displayed again after being gone, the clock must be reset to full
-     * dozing.
+     * When keyguard is displayed again after being gone, the clock must be reset to full dozing.
      */
     @VisibleForTesting
     internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job {
         return scope.launch {
-            keyguardTransitionInteractor.anyStateToAodTransition.filter {
-                it.transitionState == TransitionState.FINISHED
-            }.collect {
-                handleDoze(1f)
-            }
+            keyguardTransitionInteractor.anyStateToAodTransition
+                .filter { it.transitionState == TransitionState.FINISHED }
+                .collect { handleDoze(1f) }
         }
     }
 
     @VisibleForTesting
     internal fun listenForDozing(scope: CoroutineScope): Job {
         return scope.launch {
-            combine (
-                keyguardInteractor.dozeAmount,
-                keyguardInteractor.isDozing,
-            ) { localDozeAmount, localIsDozing ->
-                localDozeAmount > dozeAmount || localIsDozing
-            }
-            .collect { localIsDozing ->
-                isDozing = localIsDozing
-            }
+            combine(
+                    keyguardInteractor.dozeAmount,
+                    keyguardInteractor.isDozing,
+                ) { localDozeAmount, localIsDozing ->
+                    localDozeAmount > dozeAmount || localIsDozing
+                }
+                .collect { localIsDozing -> isDozing = localIsDozing }
         }
     }
 
     class TimeListener(val clockFace: ClockFaceController, val executor: DelayableExecutor) {
-        val predrawListener = ViewTreeObserver.OnPreDrawListener {
-            clockFace.events.onTimeTick()
-            true
-        }
-
-        val secondsRunnable = object : Runnable {
-            override fun run() {
-                if (!isRunning) {
-                    return
-                }
-
-                executor.executeDelayed(this, 990)
+        val predrawListener =
+            ViewTreeObserver.OnPreDrawListener {
                 clockFace.events.onTimeTick()
+                true
             }
-        }
+
+        val secondsRunnable =
+            object : Runnable {
+                override fun run() {
+                    if (!isRunning) {
+                        return
+                    }
+
+                    executor.executeDelayed(this, 990)
+                    clockFace.events.onTimeTick()
+                }
+            }
 
         var isRunning: Boolean = false
             private set
@@ -425,7 +448,9 @@
 
             isRunning = true
             when (clockFace.events.tickRate) {
-                ClockTickRate.PER_MINUTE -> {/* Handled by KeyguardClockSwitchController */}
+                ClockTickRate.PER_MINUTE -> {
+                    /* Handled by KeyguardClockSwitchController */
+                }
                 ClockTickRate.PER_SECOND -> executor.execute(secondsRunnable)
                 ClockTickRate.PER_FRAME -> {
                     clockFace.view.viewTreeObserver.addOnPreDrawListener(predrawListener)
@@ -435,7 +460,9 @@
         }
 
         fun stop() {
-            if (!isRunning) { return }
+            if (!isRunning) {
+                return
+            }
 
             isRunning = false
             clockFace.view.viewTreeObserver.removeOnPreDrawListener(predrawListener)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 4acbb0a..0326b6d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -209,7 +209,6 @@
 
         if (!animate) {
             out.setAlpha(0f);
-            out.setVisibility(INVISIBLE);
             in.setAlpha(1f);
             in.setVisibility(VISIBLE);
             mStatusArea.setTranslationY(statusAreaYTranslation);
@@ -225,10 +224,7 @@
                         direction * -mClockSwitchYAmount));
         mClockOutAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                if (mClockOutAnim == animation) {
-                    out.setVisibility(INVISIBLE);
-                    mClockOutAnim = null;
-                }
+                mClockOutAnim = null;
             }
         });
 
@@ -242,9 +238,7 @@
         mClockInAnim.setStartDelay(CLOCK_OUT_MILLIS / 2);
         mClockInAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                if (mClockInAnim == animation) {
-                    mClockInAnim = null;
-                }
+                mClockInAnim = null;
             }
         });
 
@@ -257,9 +251,7 @@
         mStatusAreaAnim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         mStatusAreaAnim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
-                if (mStatusAreaAnim == animation) {
-                    mStatusAreaAnim = null;
-                }
+                mStatusAreaAnim = null;
             }
         });
         mStatusAreaAnim.start();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 3eec565..f1b90e3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -106,6 +106,12 @@
             updateDoubleLineClock();
         }
     };
+    private final ContentObserver mShowWeatherObserver = new ContentObserver(null) {
+        @Override
+        public void onChange(boolean change) {
+            setWeatherVisibility();
+        }
+    };
 
     private final KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener
             mKeyguardUnlockAnimationListener =
@@ -216,7 +222,15 @@
                 UserHandle.USER_ALL
         );
 
+        mSecureSettings.registerContentObserverForUser(
+                Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED,
+                false, /* notifyForDescendants */
+                mShowWeatherObserver,
+                UserHandle.USER_ALL
+        );
+
         updateDoubleLineClock();
+        setWeatherVisibility();
 
         mKeyguardUnlockAnimationController.addKeyguardUnlockAnimationListener(
                 mKeyguardUnlockAnimationListener);
@@ -390,6 +404,10 @@
             int clockHeight = clock.getLargeClock().getView().getHeight();
             return frameHeight / 2 + clockHeight / 2 + mKeyguardLargeClockTopMargin / -2;
         } else {
+            // This is only called if we've never shown the large clock as the frame is inflated
+            // with 'gone', but then the visibility is never set when it is animated away by
+            // KeyguardClockSwitch, instead it is removed from the view hierarchy.
+            // TODO(b/261755021): Cleanup Large Frame Visibility
             int clockHeight = clock.getSmallClock().getView().getHeight();
             return clockHeight + statusBarHeaderHeight + mKeyguardSmallClockTopMargin;
         }
@@ -407,11 +425,15 @@
         if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
             return clock.getLargeClock().getView().getHeight();
         } else {
+            // Is not called except in certain edge cases, see comment in getClockBottom
+            // TODO(b/261755021): Cleanup Large Frame Visibility
             return clock.getSmallClock().getView().getHeight();
         }
     }
 
     boolean isClockTopAligned() {
+        // Returns false except certain edge cases, see comment in getClockBottom
+        // TODO(b/261755021): Cleanup Large Frame Visibility
         return mLargeClockFrame.getVisibility() != View.VISIBLE;
     }
 
@@ -449,6 +471,14 @@
         }
     }
 
+    private void setWeatherVisibility() {
+        if (mWeatherView != null) {
+            mUiExecutor.execute(
+                    () -> mWeatherView.setVisibility(
+                        mSmartspaceController.isWeatherEnabled() ? View.VISIBLE : View.GONE));
+        }
+    }
+
     /**
      * Sets the clipChildren property on relevant views, to allow the smartspace to draw out of
      * bounds during the unlock transition.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
index 1a06b5f..fe8b8c9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFaceListenModel.kt
@@ -27,6 +27,7 @@
     override var userId: Int = 0,
     override var listening: Boolean = false,
     // keep sorted
+    var alternateBouncerShowing: Boolean = false,
     var authInterruptActive: Boolean = false,
     var biometricSettingEnabledForUser: Boolean = false,
     var bouncerFullyShown: Boolean = false,
@@ -44,7 +45,6 @@
     var secureCameraLaunched: Boolean = false,
     var supportsDetect: Boolean = false,
     var switchingUser: Boolean = false,
-    var udfpsBouncerShowing: Boolean = false,
     var udfpsFingerDown: Boolean = false,
     var userNotTrustedOrDetectionIsNeeded: Boolean = false,
 ) : KeyguardListenModel() {
@@ -73,7 +73,7 @@
             secureCameraLaunched.toString(),
             supportsDetect.toString(),
             switchingUser.toString(),
-            udfpsBouncerShowing.toString(),
+            alternateBouncerShowing.toString(),
             udfpsFingerDown.toString(),
             userNotTrustedOrDetectionIsNeeded.toString(),
         )
@@ -95,6 +95,7 @@
                 userId = model.userId
                 listening = model.listening
                 // keep sorted
+                alternateBouncerShowing = model.alternateBouncerShowing
                 biometricSettingEnabledForUser = model.biometricSettingEnabledForUser
                 bouncerFullyShown = model.bouncerFullyShown
                 faceAndFpNotAuthenticated = model.faceAndFpNotAuthenticated
@@ -111,7 +112,6 @@
                 secureCameraLaunched = model.secureCameraLaunched
                 supportsDetect = model.supportsDetect
                 switchingUser = model.switchingUser
-                udfpsBouncerShowing = model.udfpsBouncerShowing
                 switchingUser = model.switchingUser
                 udfpsFingerDown = model.udfpsFingerDown
                 userNotTrustedOrDetectionIsNeeded = model.userNotTrustedOrDetectionIsNeeded
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 6139403..1051de3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -202,8 +202,11 @@
         mKeyguardSecurityContainerController.onPause();
     }
 
-    public void resetSecurityContainer() {
-        mKeyguardSecurityContainerController.reset();
+    /**
+     * Reinflate the view flipper child view.
+     */
+    public void reinflateViewFlipper() {
+        mKeyguardSecurityContainerController.reinflateViewFlipper();
     }
 
     /**
@@ -232,23 +235,19 @@
     /**
      * Starts the animation when the Keyguard gets shown.
      */
-    public void appear(int statusBarHeight) {
+    public void appear() {
         // We might still be collapsed and the view didn't have time to layout yet or still
         // be small, let's wait on the predraw to do the animation in that case.
-        if (mView.getHeight() != 0 && mView.getHeight() != statusBarHeight) {
-            mKeyguardSecurityContainerController.startAppearAnimation();
-        } else {
-            mView.getViewTreeObserver().addOnPreDrawListener(
-                    new ViewTreeObserver.OnPreDrawListener() {
-                        @Override
-                        public boolean onPreDraw() {
-                            mView.getViewTreeObserver().removeOnPreDrawListener(this);
-                            mKeyguardSecurityContainerController.startAppearAnimation();
-                            return true;
-                        }
-                    });
-            mView.requestLayout();
-        }
+        mView.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                    @Override
+                    public boolean onPreDraw() {
+                        mView.getViewTreeObserver().removeOnPreDrawListener(this);
+                        mKeyguardSecurityContainerController.startAppearAnimation();
+                        return true;
+                    }
+                });
+        mView.requestLayout();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index b143c5b..48844db 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -30,6 +30,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.statusbar.policy.DevicePostureController;
 import com.android.systemui.util.ViewController;
 import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -184,6 +185,7 @@
         private final FalsingCollector mFalsingCollector;
         private final DevicePostureController mDevicePostureController;
         private final KeyguardViewController mKeyguardViewController;
+        private final FeatureFlags mFeatureFlags;
 
         @Inject
         public Factory(KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -195,7 +197,8 @@
                 TelephonyManager telephonyManager, FalsingCollector falsingCollector,
                 EmergencyButtonController.Factory emergencyButtonControllerFactory,
                 DevicePostureController devicePostureController,
-                KeyguardViewController keyguardViewController) {
+                KeyguardViewController keyguardViewController,
+                FeatureFlags featureFlags) {
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
             mLockPatternUtils = lockPatternUtils;
             mLatencyTracker = latencyTracker;
@@ -209,6 +212,7 @@
             mFalsingCollector = falsingCollector;
             mDevicePostureController = devicePostureController;
             mKeyguardViewController = keyguardViewController;
+            mFeatureFlags = featureFlags;
         }
 
         /** Create a new {@link KeyguardInputViewController}. */
@@ -236,7 +240,7 @@
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
                         keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
                         mLiftToActivateListener, emergencyButtonController, mFalsingCollector,
-                        mDevicePostureController);
+                        mDevicePostureController, mFeatureFlags);
             } else if (keyguardInputView instanceof KeyguardSimPinView) {
                 return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
                         mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index 8011efd..92e3641 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -131,6 +131,7 @@
 
     @Override
     void resetState() {
+        mMessageAreaController.setMessage(getInitialMessageResId());
         mView.setPasswordEntryEnabled(true);
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 35b2db2..fd47e39 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -16,6 +16,8 @@
 
 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;
@@ -23,6 +25,8 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.statusbar.policy.DevicePostureController;
 
 public class KeyguardPinViewController
@@ -31,6 +35,14 @@
     private final DevicePostureController mPostureController;
     private final DevicePostureController.Callback mPostureCallback = posture ->
             mView.onDevicePostureChanged(posture);
+    private LockPatternUtils mLockPatternUtils;
+    private final FeatureFlags mFeatureFlags;
+    private static final int DEFAULT_PIN_LENGTH = 6;
+    private NumPadButton mBackspaceKey;
+    private View mOkButton = mView.findViewById(R.id.key_enter);
+
+    private int mUserId;
+    private long mPinLength;
 
     protected KeyguardPinViewController(KeyguardPINView view,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -40,12 +52,16 @@
             LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
             EmergencyButtonController emergencyButtonController,
             FalsingCollector falsingCollector,
-            DevicePostureController postureController) {
+            DevicePostureController postureController,
+            FeatureFlags featureFlags) {
         super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
                 messageAreaControllerFactory, latencyTracker, liftToActivateListener,
                 emergencyButtonController, falsingCollector);
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mPostureController = postureController;
+        mLockPatternUtils = lockPatternUtils;
+        mFeatureFlags = featureFlags;
+        mBackspaceKey = view.findViewById(R.id.delete_button);
     }
 
     @Override
@@ -59,10 +75,20 @@
                 getKeyguardSecurityCallback().onCancelClicked();
             });
         }
-
+        mPasswordEntry.setUserActivityListener(this::onUserInput);
         mPostureController.addCallback(mPostureCallback);
     }
 
+    protected void onUserInput() {
+        super.onUserInput();
+        if (isAutoConfirmation()) {
+            updateBackSpaceVisibility();
+            if (mPasswordEntry.getText().length() == mPinLength) {
+                verifyPasswordAndUnlock();
+            }
+        }
+    }
+
     @Override
     protected void onViewDetached() {
         super.onViewDetached();
@@ -70,8 +96,55 @@
     }
 
     @Override
+    public void startAppearAnimation() {
+        if (mFeatureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)) {
+            mUserId = KeyguardUpdateMonitor.getCurrentUser();
+            mPinLength = mLockPatternUtils.getPinLength(mUserId);
+            mBackspaceKey.setTransparentMode(/* isTransparentMode= */ isAutoConfirmation());
+            mOkButton.setVisibility(isAutoConfirmation() ? View.INVISIBLE : View.VISIBLE);
+            updateBackSpaceVisibility();
+            mPasswordEntry.setUsePinShapes(true);
+            mPasswordEntry.setIsPinHinting(isAutoConfirmation() && isPinHinting());
+        }
+        super.startAppearAnimation();
+    }
+
+    @Override
     public boolean startDisappearAnimation(Runnable finishRunnable) {
         return mView.startDisappearAnimation(
                 mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
     }
+
+    //
+
+    /**
+     *  Updates the visibility and the enabled state of the backspace.
+     * Visibility changes are only for auto confirmation configuration.
+     */
+    private void updateBackSpaceVisibility() {
+        if (!isAutoConfirmation()) {
+            return;
+        }
+
+        if (mPasswordEntry.getText().length() > 0) {
+            mBackspaceKey.setVisibility(View.VISIBLE);
+        } else {
+            mBackspaceKey.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    /**
+     *   Responsible for identifying if PIN hinting is to be enabled or not
+     */
+    private boolean isPinHinting() {
+        return mLockPatternUtils.getPinLength(mUserId) == DEFAULT_PIN_LENGTH;
+    }
+
+    /**
+     *   Responsible for identifying if auto confirm is enabled or not in Settings
+     */
+    private boolean isAutoConfirmation() {
+        //Checks if user has enabled the auto confirm in Settings
+        return mLockPatternUtils.isAutoPinConfirmEnabled(mUserId);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 57bfe54..8281c8b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -237,7 +237,7 @@
             }
             if (mUpdateMonitor.isFaceEnrolled()) {
                 mUpdateMonitor.requestActiveUnlock(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
                         "swipeUpOnBouncer");
             }
         }
@@ -247,6 +247,7 @@
                 @Override
                 public void onThemeChanged() {
                     reloadColors();
+                    reset();
                 }
 
                 @Override
@@ -743,17 +744,20 @@
     }
 
     private void reloadColors() {
-        resetViewFlipper();
+        reinflateViewFlipper();
         mView.reloadColors();
     }
 
     /** Handles density or font scale changes. */
     private void onDensityOrFontScaleChanged() {
-        resetViewFlipper();
+        reinflateViewFlipper();
         mView.onDensityOrFontScaleChanged();
     }
 
-    private void resetViewFlipper() {
+    /**
+     * Reinflate the view flipper child view.
+     */
+    public void reinflateViewFlipper() {
         mSecurityViewFlipperController.clearViews();
         mSecurityViewFlipperController.getSecurityView(mCurrentSecurityMode,
                 mKeyguardSecurityCallback);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index afa9ef6..9f1c382 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -95,6 +95,7 @@
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
+import android.hardware.biometrics.SensorProperties;
 import android.hardware.face.FaceManager;
 import android.hardware.face.FaceSensorPropertiesInternal;
 import android.hardware.fingerprint.FingerprintManager;
@@ -109,7 +110,6 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -149,6 +149,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.dump.DumpsysTableLogger;
 import com.android.systemui.log.SessionTracker;
+import com.android.systemui.plugins.Weather;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -261,6 +262,7 @@
     @VisibleForTesting
     public static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
     public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
+    public static final int BIOMETRIC_HELP_FACE_NOT_AVAILABLE = -3;
 
     /**
      * If no cancel signal has been received after this amount of time, set the biometric running
@@ -311,7 +313,7 @@
     private boolean mGoingToSleep;
     private boolean mPrimaryBouncerFullyShown;
     private boolean mPrimaryBouncerIsOrWillBeShowing;
-    private boolean mUdfpsBouncerShowing;
+    private boolean mAlternateBouncerShowing;
     private boolean mAuthInterruptActive;
     private boolean mNeedsSlowUnlockTransition;
     private boolean mAssistantVisible;
@@ -536,7 +538,8 @@
      * It's assumed that the trust was granted for the current user.
      */
     private boolean shouldDismissKeyguardOnTrustGrantedWithCurrentUser(TrustGrantFlags flags) {
-        final boolean isBouncerShowing = mPrimaryBouncerIsOrWillBeShowing || mUdfpsBouncerShowing;
+        final boolean isBouncerShowing =
+                mPrimaryBouncerIsOrWillBeShowing || mAlternateBouncerShowing;
         return (flags.isInitiatedByUser() || flags.dismissKeyguardRequested())
                 && (mDeviceInteractive || flags.temporaryAndRenewable())
                 && (isBouncerShowing || flags.dismissKeyguardRequested());
@@ -1312,7 +1315,8 @@
     }
 
     public boolean getUserHasTrust(int userId) {
-        return !isTrustDisabled() && mUserHasTrust.get(userId);
+        return !isTrustDisabled() && mUserHasTrust.get(userId)
+                && isUnlockingWithTrustAgentAllowed();
     }
 
     /**
@@ -1320,12 +1324,19 @@
      */
     public boolean getUserUnlockedWithBiometric(int userId) {
         BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
-        BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);
         boolean fingerprintAllowed = fingerprint != null && fingerprint.mAuthenticated
                 && isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric);
-        boolean faceAllowed = face != null && face.mAuthenticated
+        return fingerprintAllowed || getUserUnlockedWithFace(userId);
+    }
+
+
+    /**
+     * Returns whether the user is unlocked with face.
+     */
+    public boolean getUserUnlockedWithFace(int userId) {
+        BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);
+        return face != null && face.mAuthenticated
                 && isUnlockingWithBiometricAllowed(face.mIsStrongBiometric);
-        return fingerprintAllowed || faceAllowed;
     }
 
     /**
@@ -1400,6 +1411,10 @@
         return mUserTrustIsUsuallyManaged.get(userId);
     }
 
+    private boolean isUnlockingWithTrustAgentAllowed() {
+        return isUnlockingWithBiometricAllowed(true);
+    }
+
     public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
         // StrongAuthTracker#isUnlockingWithBiometricAllowed includes
         // STRONG_AUTH_REQUIRED_AFTER_LOCKOUT which is the same as mFingerprintLockedOutPermanent;
@@ -1535,7 +1550,7 @@
                 FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED);
         if (mAssistantVisible) {
             requestActiveUnlock(
-                    ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.ASSISTANT,
+                    ActiveUnlockConfig.ActiveUnlockRequestOrigin.ASSISTANT,
                     "assistant",
                     false);
         }
@@ -1665,7 +1680,7 @@
                 @Override
                 public void onAuthenticationFailed() {
                     requestActiveUnlockDismissKeyguard(
-                            ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
+                            ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL,
                             "fingerprintFailure");
                     handleFingerprintAuthFailed();
                 }
@@ -1730,11 +1745,11 @@
                 public void onAuthenticationFailed() {
                         String reason =
                                 mKeyguardBypassController.canBypass() ? "bypass"
-                                        : mUdfpsBouncerShowing ? "udfpsBouncer"
+                                        : mAlternateBouncerShowing ? "alternateBouncer"
                                                 : mPrimaryBouncerFullyShown ? "bouncer"
                                                         : "udfpsFpDown";
                         requestActiveUnlock(
-                                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
+                                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL,
                                 "faceFailure-" + reason);
 
                     handleFaceAuthFailed();
@@ -1761,7 +1776,7 @@
 
                     if (mActiveUnlockConfig.shouldRequestActiveUnlockOnFaceError(errMsgId)) {
                         requestActiveUnlock(
-                                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
+                                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL,
                                 "faceError-" + errMsgId);
                     }
                 }
@@ -1773,7 +1788,7 @@
                     if (mActiveUnlockConfig.shouldRequestActiveUnlockOnFaceAcquireInfo(
                             acquireInfo)) {
                         requestActiveUnlock(
-                                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL,
+                                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL,
                                 "faceAcquireInfo-" + acquireInfo);
                     }
                 }
@@ -1913,8 +1928,11 @@
             FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
             updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
                     FACE_AUTH_UPDATED_STARTED_WAKING_UP);
-            requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp - "
-                    + PowerManager.wakeReasonToString(pmWakeReason));
+            requestActiveUnlock(
+                    mActiveUnlockConfig.isWakeupConsideredUnlockIntent(pmWakeReason)
+                            ? ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
+                            : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE,
+                    "wakingUp - " + PowerManager.wakeReasonToString(pmWakeReason));
         } else {
             mLogger.logSkipUpdateFaceListeningOnWakeup(pmWakeReason);
         }
@@ -2478,7 +2496,7 @@
         mAuthInterruptActive = active;
         updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
                 FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD);
-        requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "onReach");
+        requestActiveUnlock(ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE, "onReach");
     }
 
     /**
@@ -2548,7 +2566,7 @@
      * Attempts to trigger active unlock from trust agent.
      */
     private void requestActiveUnlock(
-            @NonNull ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN requestOrigin,
+            @NonNull ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin,
             String reason,
             boolean dismissKeyguard
     ) {
@@ -2559,7 +2577,7 @@
 
         final boolean allowRequest =
                 mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(requestOrigin);
-        if (requestOrigin == ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE
+        if (requestOrigin == ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
                 && !allowRequest && mActiveUnlockConfig.isActiveUnlockEnabled()) {
             // instead of requesting the active unlock, initiate the unlock
             initiateActiveUnlock(reason);
@@ -2578,7 +2596,7 @@
      * Only dismisses the keyguard under certain conditions.
      */
     public void requestActiveUnlock(
-            @NonNull ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN requestOrigin,
+            @NonNull ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin,
             String extraReason
     ) {
         final boolean canFaceBypass = isFaceEnrolled() && mKeyguardBypassController != null
@@ -2586,7 +2604,7 @@
         requestActiveUnlock(
                 requestOrigin,
                 extraReason, canFaceBypass
-                        || mUdfpsBouncerShowing
+                        || mAlternateBouncerShowing
                         || mPrimaryBouncerFullyShown
                         || mAuthController.isUdfpsFingerDown());
     }
@@ -2595,7 +2613,7 @@
      * Attempts to trigger active unlock from trust agent with a request to dismiss the keyguard.
      */
     public void requestActiveUnlockDismissKeyguard(
-            @NonNull ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN requestOrigin,
+            @NonNull ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin,
             String extraReason
     ) {
         requestActiveUnlock(
@@ -2604,23 +2622,23 @@
     }
 
     /**
-     * Whether the UDFPS bouncer is showing.
+     * Whether the alternate bouncer is showing.
      */
-    public void setUdfpsBouncerShowing(boolean showing) {
-        mUdfpsBouncerShowing = showing;
-        if (mUdfpsBouncerShowing) {
+    public void setAlternateBouncerShowing(boolean showing) {
+        mAlternateBouncerShowing = showing;
+        if (mAlternateBouncerShowing) {
             updateFaceListeningState(BIOMETRIC_ACTION_START,
                     FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN);
             requestActiveUnlock(
-                    ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
-                    "udfpsBouncer");
+                    ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
+                    "alternateBouncer");
         }
     }
 
     private boolean shouldTriggerActiveUnlock() {
         // Triggers:
         final boolean triggerActiveUnlockForAssistant = shouldTriggerActiveUnlockForAssistant();
-        final boolean awakeKeyguard = mPrimaryBouncerFullyShown || mUdfpsBouncerShowing
+        final boolean awakeKeyguard = mPrimaryBouncerFullyShown || mAlternateBouncerShowing
                 || (isKeyguardVisible() && !mGoingToSleep
                 && mStatusBarState != StatusBarState.SHADE_LOCKED);
 
@@ -2804,7 +2822,6 @@
         final boolean isPostureAllowedForFaceAuth =
                 mConfigFaceAuthSupportedPosture == 0 /* DEVICE_POSTURE_UNKNOWN */ ? true
                         : (mPostureState == mConfigFaceAuthSupportedPosture);
-
         // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
         final boolean shouldListen =
@@ -2814,11 +2831,11 @@
                         || awakeKeyguard
                         || shouldListenForFaceAssistant
                         || isUdfpsFingerDown
-                        || mUdfpsBouncerShowing)
+                        || mAlternateBouncerShowing)
                 && !mSwitchingUser && !faceDisabledForUser && userNotTrustedOrDetectionIsNeeded
                 && !mKeyguardGoingAway && biometricEnabledForUser
                 && faceAuthAllowedOrDetectionIsNeeded && mIsPrimaryUser
-                && (!mSecureCameraLaunched || mOccludingAppRequestingFace)
+                && (!mSecureCameraLaunched || mAlternateBouncerShowing)
                 && faceAndFpNotAuthenticated
                 && !mGoingToSleep
                 && isPostureAllowedForFaceAuth;
@@ -2829,6 +2846,7 @@
                     System.currentTimeMillis(),
                     user,
                     shouldListen,
+                    mAlternateBouncerShowing,
                     mAuthInterruptActive,
                     biometricEnabledForUser,
                     mPrimaryBouncerFullyShown,
@@ -2846,7 +2864,6 @@
                     mSecureCameraLaunched,
                     supportsDetect,
                     mSwitchingUser,
-                    mUdfpsBouncerShowing,
                     isUdfpsFingerDown,
                     userNotTrustedOrDetectionIsNeeded));
 
@@ -2934,9 +2951,26 @@
             // This would need to be updated for multi-sensor devices
             final boolean supportsFaceDetection = !mFaceSensorProperties.isEmpty()
                     && mFaceSensorProperties.get(0).supportsFaceDetection;
-            if (!isUnlockingWithBiometricAllowed(FACE) && supportsFaceDetection) {
-                mLogger.v("startListeningForFace - detect");
-                mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
+            if (!isUnlockingWithBiometricAllowed(FACE)) {
+                final boolean udfpsFingerprintAuthRunning = isUdfpsSupported()
+                        && isFingerprintDetectionRunning();
+                if (supportsFaceDetection && !udfpsFingerprintAuthRunning) {
+                    // Run face detection. (If a face is detected, show the bouncer.)
+                    mLogger.v("startListeningForFace - detect");
+                    mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
+                } else {
+                    // Don't run face detection. Instead, inform the user
+                    // face auth is unavailable and how to proceed.
+                    // (ie: "Use fingerprint instead" or "Swipe up to open")
+                    mLogger.v("Ignoring \"startListeningForFace - detect\". "
+                            + "Informing user face isn't available.");
+                    mFaceAuthenticationCallback.onAuthenticationHelp(
+                            BIOMETRIC_HELP_FACE_NOT_AVAILABLE,
+                            mContext.getResources().getString(
+                                    R.string.keyguard_face_unlock_unavailable)
+                    );
+                    return;
+                }
             } else {
                 mLogger.v("startListeningForFace - authenticate");
                 final boolean isBypassEnabled = mKeyguardBypassController != null
@@ -2967,6 +3001,23 @@
         return isUnlockWithFacePossible(userId) || isUnlockWithFingerprintPossible(userId);
     }
 
+    /**
+     * If non-strong (i.e. weak or convenience) biometrics hardware is available, not disabled, and
+     * user has enrolled templates. This does NOT check if the device is encrypted or in lockdown.
+     *
+     * @param userId User that's trying to unlock.
+     * @return {@code true} if possible.
+     */
+    public boolean isUnlockingWithNonStrongBiometricsPossible(int userId) {
+        // This assumes that there is at most one face and at most one fingerprint sensor
+        return (mFaceManager != null && !mFaceSensorProperties.isEmpty()
+                && (mFaceSensorProperties.get(0).sensorStrength != SensorProperties.STRENGTH_STRONG)
+                && isUnlockWithFacePossible(userId))
+                || (mFpm != null && !mFingerprintSensorProperties.isEmpty()
+                && (mFingerprintSensorProperties.get(0).sensorStrength
+                != SensorProperties.STRENGTH_STRONG) && isUnlockWithFingerprintPossible(userId));
+    }
+
     @SuppressLint("MissingPermission")
     @VisibleForTesting
     boolean isUnlockWithFingerprintPossible(int userId) {
@@ -3219,6 +3270,24 @@
     }
 
     /**
+     * @param data the weather data (temp, conditions, unit) for weather clock to use
+     */
+    public void sendWeatherData(Weather data) {
+        mHandler.post(()-> {
+            handleWeatherDataUpdate(data); });
+    }
+
+    private void handleWeatherDataUpdate(Weather data) {
+        Assert.isMainThread();
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onWeatherDataChanged(data);
+            }
+        }
+    }
+
+    /**
      * Handle {@link #MSG_BATTERY_UPDATE}
      */
     private void handleBatteryUpdate(BatteryStatus status) {
@@ -3400,7 +3469,7 @@
         if (wasPrimaryBouncerFullyShown != mPrimaryBouncerFullyShown) {
             if (mPrimaryBouncerFullyShown) {
                 requestActiveUnlock(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
                         "bouncerFullyShown");
             }
             for (int i = 0; i < mCallbacks.size(); i++) {
@@ -3923,7 +3992,7 @@
                 pw.println("        mPrimaryBouncerIsOrWillBeShowing="
                         + mPrimaryBouncerIsOrWillBeShowing);
                 pw.println("        mStatusBarState=" + StatusBarState.toString(mStatusBarState));
-                pw.println("        mUdfpsBouncerShowing=" + mUdfpsBouncerShowing);
+                pw.println("        mAlternateBouncerShowing=" + mAlternateBouncerShowing);
             } else if (isSfpsSupported()) {
                 pw.println("        sfpsEnrolled=" + isSfpsEnrolled());
                 pw.println("        shouldListenForSfps=" + shouldListenForFingerprint(false));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index e6b9ac8..0da799e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -23,6 +23,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.settingslib.fuelgauge.BatteryStatus;
+import com.android.systemui.plugins.Weather;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 
 import java.util.TimeZone;
@@ -58,6 +59,11 @@
     public void onTimeFormatChanged(String timeFormat) { }
 
     /**
+     * Called when receive new weather data.
+     */
+    public void onWeatherDataChanged(Weather data) { }
+
+    /**
      * Called when the carrier PLMN or SPN changes.
      */
     public void onRefreshCarrierInfo() { }
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index 41111e3..5135eed 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -95,7 +95,6 @@
         mHeight = height;
         mStartRadius = height / 2f;
         mEndRadius = height / 4f;
-        mBackground.setCornerRadius(mStartRadius);
         mExpandAnimator.setFloatValues(mStartRadius, mEndRadius);
         mContractAnimator.setFloatValues(mEndRadius, mStartRadius);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 37060987c..11c329e 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -27,6 +27,8 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.systemui.R;
+
 /**
  * Similar to the {@link NumPadKey}, but displays an image.
  */
@@ -35,18 +37,13 @@
     @Nullable
     private NumPadAnimator mAnimator;
     private int mOrientation;
+    private int mStyleAttr;
+    private boolean mIsTransparentMode;
 
     public NumPadButton(Context context, AttributeSet attrs) {
         super(context, attrs);
-
-        Drawable background = getBackground();
-        if (background instanceof GradientDrawable) {
-            mAnimator = new NumPadAnimator(context, background.mutate(),
-                    attrs.getStyleAttribute(), getDrawable());
-        } else {
-            mAnimator = null;
-        }
-
+        mStyleAttr = attrs.getStyleAttribute();
+        setupAnimator();
     }
 
     @Override
@@ -98,7 +95,9 @@
     public void reloadColors() {
         if (mAnimator != null) mAnimator.reloadColors(getContext());
 
-        int[] customAttrs = {android.R.attr.textColorPrimaryInverse};
+        int textColorResId = mIsTransparentMode ? android.R.attr.textColorPrimary
+                : android.R.attr.textColorPrimaryInverse;
+        int[] customAttrs = {textColorResId};
         TypedArray a = getContext().obtainStyledAttributes(customAttrs);
         int imageColor = a.getColor(0, 0);
         a.recycle();
@@ -111,4 +110,34 @@
             mAnimator.setProgress(progress);
         }
     }
+
+    /**
+     * Set whether button is transparent mode.
+     *
+     * @param isTransparentMode
+     */
+    public void setTransparentMode(boolean isTransparentMode) {
+        mIsTransparentMode = isTransparentMode;
+        if (isTransparentMode) {
+            setBackgroundColor(android.R.color.transparent);
+        } else {
+            setBackground(getContext().getDrawable(R.drawable.num_pad_key_background));
+        }
+        setupAnimator();
+        reloadColors();
+        requestLayout();
+    }
+
+    /**
+     * Set up the animator for the NumPadButton.
+     */
+    private void setupAnimator() {
+        Drawable background = getBackground();
+        if (background instanceof GradientDrawable) {
+            mAnimator = new NumPadAnimator(getContext(), background.mutate(),
+                    mStyleAttr, getDrawable());
+        } else {
+            mAnimator = null;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index 35cae09..8554e11 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -35,13 +35,14 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.Gravity;
-import android.view.View;
+import android.view.LayoutInflater;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.EditText;
+import android.widget.FrameLayout;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
@@ -52,12 +53,12 @@
  * A View similar to a textView which contains password text and can animate when the text is
  * changed
  */
-public class PasswordTextView extends View {
+public class PasswordTextView extends FrameLayout {
 
     private static final float DOT_OVERSHOOT_FACTOR = 1.5f;
     private static final long DOT_APPEAR_DURATION_OVERSHOOT = 320;
-    private static final long APPEAR_DURATION = 160;
-    private static final long DISAPPEAR_DURATION = 160;
+    public static final long APPEAR_DURATION = 160;
+    public static final long DISAPPEAR_DURATION = 160;
     private static final long RESET_DELAY_PER_ELEMENT = 40;
     private static final long RESET_MAX_DELAY = 200;
 
@@ -95,11 +96,14 @@
     private PowerManager mPM;
     private int mCharPadding;
     private final Paint mDrawPaint = new Paint();
+    private int mDrawColor;
     private Interpolator mAppearInterpolator;
     private Interpolator mDisappearInterpolator;
     private Interpolator mFastOutSlowInInterpolator;
     private boolean mShowPassword;
     private UserActivityListener mUserActivityListener;
+    private PinShapeInput mPinShapeInput;
+    private boolean mUsePinShapes = false;
 
     public interface UserActivityListener {
         void onUserActivity();
@@ -141,8 +145,10 @@
             mCharPadding = a.getDimensionPixelSize(R.styleable.PasswordTextView_charPadding,
                     getContext().getResources().getDimensionPixelSize(
                             R.dimen.password_char_padding));
-            mDrawPaint.setColor(a.getColor(R.styleable.PasswordTextView_android_textColor,
-                    Color.WHITE));
+            mDrawColor = a.getColor(R.styleable.PasswordTextView_android_textColor,
+                    Color.WHITE);
+            mDrawPaint.setColor(mDrawColor);
+
         } finally {
             a.recycle();
         }
@@ -161,6 +167,7 @@
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(mContext,
                 android.R.interpolator.fast_out_slow_in);
         mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        setWillNotDraw(false);
     }
 
     @Override
@@ -171,6 +178,12 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
+        // Do not use legacy draw animations for pin shapes.
+        if (mUsePinShapes) {
+            super.onDraw(canvas);
+            return;
+        }
+
         float totalDrawingWidth = getDrawingWidth();
         float currentDrawPosition;
         if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
@@ -205,9 +218,12 @@
      * Reload colors from resources.
      **/
     public void reloadColors() {
-        int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
-                .getDefaultColor();
-        mDrawPaint.setColor(textColor);
+        mDrawColor = Utils.getColorAttr(getContext(),
+                android.R.attr.textColorPrimary).getDefaultColor();
+        mDrawPaint.setColor(mDrawColor);
+        if (mPinShapeInput != null) {
+            mPinShapeInput.setDrawColor(mDrawColor);
+        }
     }
 
     @Override
@@ -252,6 +268,9 @@
             charState = mTextChars.get(newLength - 1);
             charState.whichChar = c;
         }
+        if (mPinShapeInput != null) {
+            mPinShapeInput.append();
+        }
         charState.startAppearAnimation();
 
         // ensure that the previous element is being swapped
@@ -265,8 +284,8 @@
         sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length(), 0, 1);
     }
 
-    public void setUserActivityListener(UserActivityListener userActivitiListener) {
-        mUserActivityListener = userActivitiListener;
+    public void setUserActivityListener(UserActivityListener userActivityListener) {
+        mUserActivityListener = userActivityListener;
     }
 
     private void userActivity() {
@@ -284,6 +303,9 @@
             CharState charState = mTextChars.get(length - 1);
             charState.startRemoveAnimation(0, 0);
             sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
+            if (mPinShapeInput != null) {
+                mPinShapeInput.delete();
+            }
         }
         userActivity();
     }
@@ -339,6 +361,11 @@
         }
         if (!animated) {
             mTextChars.clear();
+        } else {
+            userActivity();
+        }
+        if (mPinShapeInput != null) {
+            mPinShapeInput.reset();
         }
         if (announce) {
             sendAccessibilityEventTypeViewTextChanged(textbefore, 0, textbefore.length(), 0);
@@ -385,6 +412,35 @@
         info.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD);
     }
 
+    /**
+     * Sets whether to use pin shapes.
+     */
+    public void setUsePinShapes(boolean usePinShapes) {
+        mUsePinShapes = usePinShapes;
+    }
+
+    /**
+     * Determines whether AutoConfirmation feature is on.
+     *
+     * @param usePinShapes
+     * @param isPinHinting
+     */
+    public void setIsPinHinting(boolean isPinHinting) {
+        if (mPinShapeInput != null) {
+            removeView(mPinShapeInput.getView());
+            mPinShapeInput = null;
+        }
+
+        if (isPinHinting) {
+            mPinShapeInput = (PinShapeInput) LayoutInflater.from(mContext).inflate(
+                    R.layout.keyguard_pin_shape_hinting_view, null);
+        } else {
+            mPinShapeInput = (PinShapeInput) LayoutInflater.from(mContext).inflate(
+                    R.layout.keyguard_pin_shape_non_hinting_view, null);
+        }
+        addView(mPinShapeInput.getView());
+    }
+
     private class CharState {
         char whichChar;
         ValueAnimator textAnimator;
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt b/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.kt
new file mode 100644
index 0000000..4496dc31
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeAdapter.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.keyguard
+
+import android.content.Context
+import com.android.systemui.R
+import kotlin.random.Random
+
+class PinShapeAdapter {
+    var shapes: MutableList<Int> = ArrayList()
+    val random = Random(System.currentTimeMillis())
+
+    constructor(context: Context) {
+        val availableShapes = context.resources.obtainTypedArray(R.array.bouncer_pin_shapes)
+
+        for (i in 0 until availableShapes.length()) {
+            val shape = availableShapes.getResourceId(i, 0)
+            shapes.add(shape)
+        }
+
+        shapes.shuffle()
+        availableShapes.recycle()
+    }
+
+    fun getShape(pos: Int): Int {
+        return shapes[pos.mod(shapes.size)]
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
new file mode 100644
index 0000000..cf9d053
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard;
+
+import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import androidx.core.graphics.drawable.DrawableCompat;
+
+import com.android.settingslib.Utils;
+import com.android.systemui.R;
+
+/**
+ * This class contains implementation for methods that will be used when user has set a
+ * six digit pin on their device
+ */
+public class PinShapeHintingView extends LinearLayout implements PinShapeInput {
+
+    private int mPinLength;
+    private int mDotDiameter;
+    private int mDotSpacing;
+    private int mColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
+            .getDefaultColor();
+    private int mPosition = 0;
+    private static final int DEFAULT_PIN_LENGTH = 6;
+    private PinShapeAdapter mPinShapeAdapter;
+
+    public PinShapeHintingView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mPinShapeAdapter = new PinShapeAdapter(context);
+        mPinLength = DEFAULT_PIN_LENGTH;
+        mDotDiameter = context.getResources().getDimensionPixelSize(R.dimen.default_dot_diameter);
+        mDotSpacing = context.getResources().getDimensionPixelSize(R.dimen.default_dot_spacing);
+
+        for (int i = 0; i < mPinLength; i++) {
+            ImageView pinDot = new ImageView(context, attrs);
+            LayoutParams layoutParams = new LayoutParams(mDotDiameter, mDotDiameter);
+            pinDot.setLayoutParams(layoutParams);
+            pinDot.setImageResource(R.drawable.pin_dot_avd);
+            if (pinDot.getDrawable() != null) {
+                Drawable drawable = DrawableCompat.wrap(pinDot.getDrawable());
+                DrawableCompat.setTint(drawable, mColor);
+            }
+            addView(pinDot);
+        }
+    }
+
+    @Override
+    public void append() {
+        if (mPosition == DEFAULT_PIN_LENGTH) {
+            return;
+        }
+        setAnimatedDrawable(mPosition, mPinShapeAdapter.getShape(mPosition));
+        mPosition++;
+    }
+
+    @Override
+    public void delete() {
+        if (mPosition == 0) {
+            return;
+        }
+        mPosition--;
+        setAnimatedDrawable(mPosition, R.drawable.pin_dot_delete_avd);
+    }
+
+    @Override
+    public void setDrawColor(int color) {
+        this.mColor = color;
+    }
+
+    @Override
+    public void reset() {
+        int size = mPosition;
+        for (int i = 0; i < size; i++) {
+            delete();
+        }
+        mPosition = 0;
+    }
+
+    @Override
+    public View getView() {
+        return this;
+    }
+
+    private void setAnimatedDrawable(int position, int drawableResId) {
+        ImageView pinDot = (ImageView) getChildAt(position);
+        pinDot.setImageResource(drawableResId);
+        if (pinDot.getDrawable() != null) {
+            Drawable drawable = DrawableCompat.wrap(pinDot.getDrawable());
+            DrawableCompat.setTint(drawable, mColor);
+        }
+        if (pinDot.getDrawable() instanceof AnimatedVectorDrawable) {
+            ((AnimatedVectorDrawable) pinDot.getDrawable()).start();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeInput.java b/packages/SystemUI/src/com/android/keyguard/PinShapeInput.java
new file mode 100644
index 0000000..52ae6ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeInput.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard;
+
+import android.view.View;
+
+/**
+ * A common interface for classes that provide functionality for the PIN type view
+ */
+public interface PinShapeInput {
+
+    /**
+     * This is the method that is triggered when user types in a character
+     */
+    void append();
+
+    /**
+     * This is the method that is triggered when user deletes a character
+     */
+    void delete();
+
+    /**
+     * This is the method that is triggered for setting the color of the view
+     */
+    void setDrawColor(int color);
+
+    /**
+     * This is the method that is triggered for resetting the view
+     */
+    void reset();
+
+    /**
+     * This is the method that is triggered for getting the view
+     */
+    View getView();
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
new file mode 100644
index 0000000..6a6e81e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.transition.TransitionValues;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import androidx.core.graphics.drawable.DrawableCompat;
+
+import com.android.settingslib.Utils;
+import com.android.systemui.R;
+import com.android.systemui.animation.Interpolators;
+
+/**
+ * This class contains implementation for methods that will be used when user has set a
+ * non six digit pin on their device
+ */
+public class PinShapeNonHintingView extends LinearLayout implements PinShapeInput {
+
+    private int mColor = Utils.getColorAttr(getContext(),
+            android.R.attr.textColorPrimary).getDefaultColor();
+    private int mPosition = 0;
+    private final PinShapeAdapter mPinShapeAdapter;
+    private Animation mCurrentPlayingAnimation;
+    public PinShapeNonHintingView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mPinShapeAdapter = new PinShapeAdapter(context);
+    }
+
+    @Override
+    public void append() {
+        int size = getResources().getDimensionPixelSize(R.dimen.password_shape_size);
+        ImageView pinDot = new ImageView(getContext());
+        pinDot.setLayoutParams(new LayoutParams(size, size));
+        pinDot.setImageResource(mPinShapeAdapter.getShape(mPosition));
+        if (pinDot.getDrawable() != null) {
+            Drawable wrappedDrawable = DrawableCompat.wrap(pinDot.getDrawable());
+            DrawableCompat.setTint(wrappedDrawable, mColor);
+        }
+        if (pinDot.getDrawable() instanceof AnimatedVectorDrawable) {
+            ((AnimatedVectorDrawable) pinDot.getDrawable()).start();
+        }
+        TransitionManager.beginDelayedTransition(this, new PinShapeViewTransition());
+        addView(pinDot);
+        mPosition++;
+    }
+
+    @Override
+    public void delete() {
+        if (mPosition == 0) {
+            Log.e(getClass().getName(), "Trying to delete a non-existent char");
+            return;
+        }
+        mPosition--;
+        ImageView pinDot = (ImageView) getChildAt(mPosition);
+        ValueAnimator animator = ValueAnimator.ofFloat(1f, 0f);
+        animator.addUpdateListener(valueAnimator -> {
+            float value = (float) valueAnimator.getAnimatedValue();
+            pinDot.setScaleX(value);
+            pinDot.setScaleY(value);
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                TransitionManager.beginDelayedTransition(
+                        PinShapeNonHintingView.this,
+                        new PinShapeViewTransition());
+                removeView(pinDot);
+                mCurrentPlayingAnimation = null;
+            }
+        });
+        animator.setDuration(PasswordTextView.DISAPPEAR_DURATION);
+        animator.start();
+    }
+
+    @Override
+    public void setDrawColor(int color) {
+        this.mColor = color;
+    }
+
+    @Override
+    public void reset() {
+        final int position = mPosition;
+        for (int i = 0; i < position; i++) {
+            delete();
+        }
+    }
+
+    @Override
+    public View getView() {
+        return this;
+    }
+
+    class PinShapeViewTransition extends Transition {
+        private static final String PROP_BOUNDS = "PinShapeViewTransition:bounds";
+
+        @Override
+        public void captureEndValues(TransitionValues transitionValues) {
+            if (transitionValues != null) {
+                captureValues(transitionValues);
+            }
+        }
+
+        @Override
+        public void captureStartValues(TransitionValues transitionValues) {
+            if (transitionValues != null) {
+                captureValues(transitionValues);
+            }
+        }
+
+        private void captureValues(TransitionValues values) {
+            Rect boundsRect = new Rect();
+            boundsRect.left = values.view.getLeft();
+            boundsRect.top = values.view.getTop();
+            boundsRect.right = values.view.getRight();
+            boundsRect.bottom = values.view.getBottom();
+            values.values.put(PROP_BOUNDS, boundsRect);
+        }
+
+        @Override
+        public String[] getTransitionProperties() {
+            return new String[] { PROP_BOUNDS };
+        }
+
+        @Override
+        public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+                TransitionValues endValues) {
+            if (sceneRoot == null || startValues == null || endValues == null) {
+                return null;
+            }
+
+            Rect startRect = (Rect) startValues.values.get(PROP_BOUNDS);
+            Rect endRect = (Rect) endValues.values.get(PROP_BOUNDS);
+            View v = startValues.view;
+            ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+            animator.setDuration(PasswordTextView.APPEAR_DURATION);
+            animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+            animator.addUpdateListener(valueAnimator -> {
+                float value = (float) valueAnimator.getAnimatedValue();
+                int diff = startRect.left - endRect.left;
+                int currentTranslation = (int) ((diff) * value);
+                v.setLeftTopRightBottom(
+                        startRect.left - currentTranslation,
+                        startRect.top,
+                        startRect.right - currentTranslation,
+                        startRect.bottom
+                );
+            });
+            animator.start();
+            return animator;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index 676979c..b1a83fb 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -18,13 +18,12 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.os.Handler;
-import android.os.UserHandle;
 import android.view.LayoutInflater;
 
 import com.android.systemui.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.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
@@ -34,6 +33,8 @@
 
 import dagger.Module;
 import dagger.Provides;
+import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.CoroutineScope;
 
 /** Dagger Module for clocks. */
 @Module
@@ -44,17 +45,23 @@
     public static ClockRegistry getClockRegistry(
             @Application Context context,
             PluginManager pluginManager,
-            @Main Handler handler,
+            @Application CoroutineScope scope,
+            @Main CoroutineDispatcher mainDispatcher,
+            @Background CoroutineDispatcher bgDispatcher,
             FeatureFlags featureFlags,
             @Main Resources resources,
             LayoutInflater layoutInflater) {
-        return new ClockRegistry(
+        ClockRegistry registry = new ClockRegistry(
                 context,
                 pluginManager,
-                handler,
+                scope,
+                mainDispatcher,
+                bgDispatcher,
                 featureFlags.isEnabled(Flags.LOCKSCREEN_CUSTOM_CLOCKS),
-                UserHandle.USER_ALL,
+                /* handleAllUsers= */ true,
                 new DefaultClockProvider(context, layoutInflater, resources),
                 context.getString(R.string.lockscreen_clock_id_fallback));
+        registry.registerListeners();
+        return registry;
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
index 2c7eceb..379c78a 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt
@@ -16,9 +16,11 @@
 
 package com.android.keyguard.logging
 
+import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController
 import com.android.systemui.log.dagger.KeyguardLog
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.statusbar.KeyguardIndicationController
 import com.google.errorprone.annotations.CompileTimeConstant
 import javax.inject.Inject
 
@@ -76,4 +78,46 @@
             { "$str1 msgId: $str2 msg: $str3" }
         )
     }
+
+    fun logUpdateDeviceEntryIndication(
+        animate: Boolean,
+        visible: Boolean,
+        dozing: Boolean,
+    ) {
+        buffer.log(
+            KeyguardIndicationController.TAG,
+            LogLevel.DEBUG,
+            {
+                bool1 = animate
+                bool2 = visible
+                bool3 = dozing
+            },
+            { "updateDeviceEntryIndication animate:$bool1 visible:$bool2 dozing $bool3" }
+        )
+    }
+
+    fun logKeyguardSwitchIndication(
+        type: Int,
+        message: String?,
+    ) {
+        buffer.log(
+            KeyguardIndicationController.TAG,
+            LogLevel.DEBUG,
+            {
+                int1 = type
+                str1 = message
+            },
+            { "keyguardSwitchIndication ${getKeyguardSwitchIndicationNonSensitiveLog(int1, str1)}" }
+        )
+    }
+
+    fun getKeyguardSwitchIndicationNonSensitiveLog(type: Int, message: String?): String {
+        // only show the battery string. other strings may contain sensitive info
+        return if (type == KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY) {
+            "type=${KeyguardIndicationRotateTextViewController.indicationTypeToString(type)}" +
+                " message=$message"
+        } else {
+            "type=${KeyguardIndicationRotateTextViewController.indicationTypeToString(type)}"
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 201a1d9..c414c08 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -372,7 +372,7 @@
     }
 
     fun logUserRequestedUnlock(
-        requestOrigin: ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN,
+        requestOrigin: ActiveUnlockConfig.ActiveUnlockRequestOrigin,
         reason: String?,
         dismissKeyguard: Boolean
     ) {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index c1c7f2d..fb65588 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -124,16 +124,7 @@
     };
     private final ScreenDecorationsLogger mLogger;
 
-    private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
-        @Override
-        public void onFaceSensorLocationChanged() {
-            mLogger.onSensorLocationChanged();
-            if (mExecutor != null) {
-                mExecutor.execute(
-                        () -> updateOverlayProviderViews(new Integer[]{mFaceScanningViewId}));
-            }
-        }
-    };
+    private final AuthController mAuthController;
 
     private DisplayTracker mDisplayTracker;
     @VisibleForTesting
@@ -340,9 +331,22 @@
         mFaceScanningFactory = faceScanningFactory;
         mFaceScanningViewId = com.android.systemui.R.id.face_scanning_anim;
         mLogger = logger;
-        authController.addCallback(mAuthControllerCallback);
+        mAuthController = authController;
     }
 
+
+    private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
+        @Override
+        public void onFaceSensorLocationChanged() {
+            mLogger.onSensorLocationChanged();
+            if (mExecutor != null) {
+                mExecutor.execute(
+                        () -> updateOverlayProviderViews(
+                                new Integer[]{mFaceScanningViewId}));
+            }
+        }
+    };
+
     @Override
     public void start() {
         if (DEBUG_DISABLE_SCREEN_DECORATIONS) {
@@ -353,6 +357,7 @@
         mExecutor = mThreadFactory.buildDelayableExecutorOnHandler(mHandler);
         mExecutor.execute(this::startOnScreenDecorationsThread);
         mDotViewController.setUiExecutor(mExecutor);
+        mAuthController.addCallback(mAuthControllerCallback);
     }
 
     private boolean isPrivacyDotEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 4c1a9fa..15264e64 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -50,6 +50,7 @@
 import android.widget.SeekBar;
 import android.widget.Switch;
 
+import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.systemui.R;
@@ -139,8 +140,10 @@
         @Override
         public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
             float scale = progress * A11Y_CHANGE_SCALE_DIFFERENCE + A11Y_SCALE_MIN_VALUE;
-            // update persisted scale only when scale >= 2.0
-            if (scale >= 2.0f) {
+            // Update persisted scale only when scale >= PERSISTED_SCALE_MIN_VALUE const.
+            // We assume if the scale is lower than the PERSISTED_SCALE_MIN_VALUE, there will be
+            // no obvious magnification effect.
+            if (scale >= MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) {
                 Settings.Secure.putFloatForUser(mContext.getContentResolver(),
                         Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale,
                         UserHandle.USER_CURRENT);
@@ -395,13 +398,12 @@
         mChangeModeButton = mSettingView.findViewById(R.id.magnifier_full_button);
 
         mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
-
-        mZoomSeekbar.setOnSeekBarChangeListener(new ZoomSeekbarChangeListener());
-
         float scale = mSecureSettings.getFloatForUser(
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0,
                 UserHandle.USER_CURRENT);
         setSeekbarProgress(scale);
+        mZoomSeekbar.setOnSeekBarChangeListener(new ZoomSeekbarChangeListener());
+
         mAllowDiagonalScrollingSwitch =
                 (Switch) mSettingView.findViewById(R.id.magnifier_horizontal_lock_switch);
         mAllowDiagonalScrollingSwitch.setChecked(mAllowDiagonalScrolling);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index d0c426d..3f41a76 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -17,6 +17,7 @@
 package com.android.systemui.accessibility.floatingmenu;
 
 import static android.view.WindowInsets.Type.ime;
+import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 
 import static androidx.core.view.WindowInsetsCompat.Type;
 
@@ -32,6 +33,7 @@
 import android.annotation.StringDef;
 import android.annotation.SuppressLint;
 import android.content.ComponentCallbacks;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -132,16 +134,30 @@
                     Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "",
                     UserHandle.USER_CURRENT);
 
+            final List<ComponentName> hardwareKeyShortcutComponents =
+                    mAccessibilityManager.getAccessibilityShortcutTargets(
+                                    ACCESSIBILITY_SHORTCUT_KEY)
+                            .stream()
+                            .map(ComponentName::unflattenFromString)
+                            .toList();
+
             // Should disable the corresponding service when the fragment type is
             // INVISIBLE_TOGGLE, which will enable service when the shortcut is on.
             final List<AccessibilityServiceInfo> serviceInfoList =
                     mAccessibilityManager.getEnabledAccessibilityServiceList(
                             AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
             serviceInfoList.forEach(info -> {
-                if (getAccessibilityServiceFragmentType(info) == INVISIBLE_TOGGLE) {
-                    setAccessibilityServiceState(getContext(),
-                            info.getComponentName(), /* enabled= */ false);
+                if (getAccessibilityServiceFragmentType(info) != INVISIBLE_TOGGLE) {
+                    return;
                 }
+
+                final ComponentName serviceComponentName = info.getComponentName();
+                if (hardwareKeyShortcutComponents.contains(serviceComponentName)) {
+                    return;
+                }
+
+                setAccessibilityServiceState(getContext(), serviceComponentName, /* enabled= */
+                        false);
             });
 
             mFloatingMenu.hide();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index 1f6f6d9..3ea3cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -18,6 +18,7 @@
 
 import android.annotation.RawRes
 import android.content.Context
+import android.content.Context.FINGERPRINT_SERVICE
 import android.content.res.Configuration
 import android.hardware.fingerprint.FingerprintManager
 import android.view.DisplayInfo
@@ -66,16 +67,11 @@
                 R.dimen.biometric_dialog_fingerprint_icon_width),
                 context.resources.getDimensionPixelSize(
                         R.dimen.biometric_dialog_fingerprint_icon_height))
-        var sideFps = false
-        (context.getSystemService(Context.FINGERPRINT_SERVICE)
-                as FingerprintManager?)?.let { fpm ->
-            for (prop in fpm.sensorPropertiesInternal) {
-                if (prop.isAnySidefpsType) {
-                    sideFps = true
-                }
-            }
-        }
-        isSideFps = sideFps
+        isSideFps =
+            (context.getSystemService(FINGERPRINT_SERVICE) as FingerprintManager?)?.let { fpm ->
+                fpm.sensorPropertiesInternal.any { it.isAnySidefpsType }
+            } ?: false
+        preloadAssets(context)
         val displayInfo = DisplayInfo()
         context.display?.getDisplayInfo(displayInfo)
         if (isSideFps && getRotationFromDefault(displayInfo.rotation) == Surface.ROTATION_180) {
@@ -329,6 +325,40 @@
         else -> null
     }
 
+    private fun preloadAssets(context: Context) {
+        if (isSideFps) {
+            cacheLottieAssetsInContext(
+                context,
+                R.raw.biometricprompt_fingerprint_to_error_landscape,
+                R.raw.biometricprompt_folded_base_bottomright,
+                R.raw.biometricprompt_folded_base_default,
+                R.raw.biometricprompt_folded_base_topleft,
+                R.raw.biometricprompt_landscape_base,
+                R.raw.biometricprompt_portrait_base_bottomright,
+                R.raw.biometricprompt_portrait_base_topleft,
+                R.raw.biometricprompt_symbol_error_to_fingerprint_landscape,
+                R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_bottomright,
+                R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_topleft,
+                R.raw.biometricprompt_symbol_error_to_success_landscape,
+                R.raw.biometricprompt_symbol_error_to_success_portrait_bottomright,
+                R.raw.biometricprompt_symbol_error_to_success_portrait_topleft,
+                R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright,
+                R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft,
+                R.raw.biometricprompt_symbol_fingerprint_to_success_landscape,
+                R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_bottomright,
+                R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft
+            )
+        } else {
+            cacheLottieAssetsInContext(
+                context,
+                R.raw.fingerprint_dialogue_error_to_fingerprint_lottie,
+                R.raw.fingerprint_dialogue_error_to_success_lottie,
+                R.raw.fingerprint_dialogue_fingerprint_to_error_lottie,
+                R.raw.fingerprint_dialogue_fingerprint_to_success_lottie
+            )
+        }
+    }
+
     override fun onFoldUpdated(isFolded: Boolean) {
         isDeviceFolded = isFolded
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index dad6ebe..c8cf5d7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -55,7 +55,6 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserManager;
-import android.util.DisplayUtils;
 import android.util.Log;
 import android.util.RotationUtils;
 import android.util.SparseBooleanArray;
@@ -69,6 +68,8 @@
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.widget.LockPatternUtils;
+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;
@@ -169,6 +170,7 @@
     @NonNull private final UserManager mUserManager;
     @NonNull private final LockPatternUtils mLockPatternUtils;
     @NonNull private final InteractionJankMonitor mInteractionJankMonitor;
+    @NonNull private final UdfpsUtils mUdfpsUtils;
     private final @Background DelayableExecutor mBackgroundExecutor;
     private final DisplayInfo mCachedDisplayInfo = new DisplayInfo();
 
@@ -578,17 +580,7 @@
      */
     private void updateSensorLocations() {
         mDisplay.getDisplayInfo(mCachedDisplayInfo);
-        final Display.Mode maxDisplayMode =
-                DisplayUtils.getMaximumResolutionDisplayMode(mCachedDisplayInfo.supportedModes);
-        final float scaleFactor = android.util.DisplayUtils.getPhysicalPixelDisplaySizeRatio(
-                maxDisplayMode.getPhysicalWidth(), maxDisplayMode.getPhysicalHeight(),
-                mCachedDisplayInfo.getNaturalWidth(), mCachedDisplayInfo.getNaturalHeight());
-        if (scaleFactor == Float.POSITIVE_INFINITY) {
-            mScaleFactor = 1f;
-        } else {
-            mScaleFactor = scaleFactor;
-        }
-
+        mScaleFactor = mUdfpsUtils.getScaleFactor(mCachedDisplayInfo);
         updateUdfpsLocation();
         updateFingerprintLocation();
         updateFaceLocation();
@@ -732,7 +724,8 @@
             @NonNull InteractionJankMonitor jankMonitor,
             @Main Handler handler,
             @Background DelayableExecutor bgExecutor,
-            @NonNull VibratorHelper vibrator) {
+            @NonNull VibratorHelper vibrator,
+            @NonNull UdfpsUtils udfpsUtils) {
         mContext = context;
         mExecution = execution;
         mUserManager = userManager;
@@ -753,6 +746,7 @@
         mSfpsEnrolledForUser = new SparseBooleanArray();
         mFaceEnrolledForUser = new SparseBooleanArray();
         mVibratorHelper = vibrator;
+        mUdfpsUtils = udfpsUtils;
 
         mLogContextInteractor = logContextInteractor;
         mBiometricPromptInteractor = biometricPromptInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
index b3b6fa2..d6ad4da 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
@@ -24,14 +24,15 @@
 import android.graphics.drawable.Drawable
 import android.util.Log
 import com.airbnb.lottie.LottieAnimationView
+import com.airbnb.lottie.LottieCompositionFactory
 import com.android.systemui.biometrics.AuthBiometricView.BiometricState
 
 private const val TAG = "AuthIconController"
 
 /** Controller for animating the BiometricPrompt icon/affordance. */
 abstract class AuthIconController(
-        protected val context: Context,
-        protected val iconView: LottieAnimationView
+    protected val context: Context,
+    protected val iconView: LottieAnimationView
 ) : Animatable2.AnimationCallback() {
 
     /** If this controller should ignore events and pause. */
@@ -94,4 +95,12 @@
     open fun handleAnimationEnd(drawable: Drawable) {}
 
     open fun onConfigurationChanged(newConfig: Configuration) {}
+
+    // TODO(b/251476085): Migrate this to an extension at the appropriate level?
+    /** Load the given [rawResources] immediately so they are cached for use in the [context]. */
+    protected fun cacheLottieAssetsInContext(context: Context, vararg rawResources: Int) {
+        for (res in rawResources) {
+            LottieCompositionFactory.fromRawRes(context, res)
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index 53ab6d6..58b230f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -88,6 +88,7 @@
         rippleShader.color = 0xffffffff.toInt() // default color
         rippleShader.rawProgress = 0f
         rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
+        setupRippleFadeParams()
         ripplePaint.shader = rippleShader
 
         dwellShader.color = 0xffffffff.toInt() // default color
@@ -294,7 +295,6 @@
             )
             addListener(object : AnimatorListenerAdapter() {
                 override fun onAnimationStart(animation: Animator?) {
-                    rippleShader.rippleFill = false
                     drawRipple = true
                     visibility = VISIBLE
                 }
@@ -339,6 +339,18 @@
         )
     }
 
+    private fun setupRippleFadeParams() {
+        with(rippleShader) {
+            baseRingFadeParams.fadeOutStart = RippleShader.DEFAULT_BASE_RING_FADE_OUT_START
+            baseRingFadeParams.fadeOutEnd = RippleShader.DEFAULT_FADE_OUT_END
+
+            centerFillFadeParams.fadeInStart = RippleShader.DEFAULT_FADE_IN_START
+            centerFillFadeParams.fadeInEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_IN_END
+            centerFillFadeParams.fadeOutStart = RippleShader.DEFAULT_CENTER_FILL_FADE_OUT_START
+            centerFillFadeParams.fadeOutEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_OUT_END
+        }
+    }
+
     override fun onDraw(canvas: Canvas?) {
         // To reduce overdraw, we mask the effect to a circle whose radius is big enough to cover
         // the active effect area. Values here should be kept in sync with the
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 64d5518..9e83264 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -50,10 +50,8 @@
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.util.Log;
-import android.util.RotationUtils;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
-import android.view.Surface;
 import android.view.VelocityTracker;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -66,6 +64,8 @@
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.FaceAuthApiRequestReason;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
+import com.android.settingslib.udfps.UdfpsUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.biometrics.dagger.BiometricsBackground;
@@ -168,6 +168,7 @@
     @NonNull private final SessionTracker mSessionTracker;
     @NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor;
     @NonNull private final SecureSettings mSecureSettings;
+    @NonNull private final UdfpsUtils mUdfpsUtils;
 
     // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
     // sensors, this, in addition to a lot of the code here, will be updated.
@@ -266,7 +267,7 @@
                             mUdfpsDisplayMode, mSecureSettings, requestId, reason, callback,
                             (view, event, fromUdfpsView) -> onTouch(requestId, event,
                                     fromUdfpsView), mActivityLaunchAnimator, mFeatureFlags,
-                            mPrimaryBouncerInteractor, mAlternateBouncerInteractor)));
+                            mPrimaryBouncerInteractor, mAlternateBouncerInteractor, mUdfpsUtils)));
         }
 
         @Override
@@ -306,34 +307,15 @@
                         unconfigureDisplay(view);
                     }
                     tryAodSendFingerUp();
-                    if (acquiredGood) {
-                        mOverlay.onAcquiredGood();
-                    }
                 });
             }
         }
 
         @Override
-        public void onEnrollmentProgress(int sensorId, int remaining) {
-            mFgExecutor.execute(() -> {
-                if (mOverlay == null) {
-                    Log.e(TAG, "onEnrollProgress received but serverRequest is null");
-                    return;
-                }
-                mOverlay.onEnrollmentProgress(remaining);
-            });
-        }
+        public void onEnrollmentProgress(int sensorId, int remaining) { }
 
         @Override
-        public void onEnrollmentHelp(int sensorId) {
-            mFgExecutor.execute(() -> {
-                if (mOverlay == null) {
-                    Log.e(TAG, "onEnrollmentHelp received but serverRequest is null");
-                    return;
-                }
-                mOverlay.onEnrollmentHelp();
-            });
-        }
+        public void onEnrollmentHelp(int sensorId) { }
 
         @Override
         public void setDebugMessage(int sensorId, String message) {
@@ -475,27 +457,6 @@
                 && mOverlayParams.getSensorBounds().contains((int) x, (int) y);
     }
 
-    private Point getTouchInNativeCoordinates(@NonNull MotionEvent event, int idx) {
-        Point portraitTouch = new Point(
-                (int) event.getRawX(idx),
-                (int) event.getRawY(idx)
-        );
-        final int rot = mOverlayParams.getRotation();
-        if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
-            RotationUtils.rotatePoint(portraitTouch,
-                    RotationUtils.deltaRotation(rot, Surface.ROTATION_0),
-                    mOverlayParams.getLogicalDisplayWidth(),
-                    mOverlayParams.getLogicalDisplayHeight()
-            );
-        }
-
-        // Scale the coordinates to native resolution.
-        final float scale = mOverlayParams.getScaleFactor();
-        portraitTouch.x = (int) (portraitTouch.x / scale);
-        portraitTouch.y = (int) (portraitTouch.y / scale);
-        return portraitTouch;
-    }
-
     private void tryDismissingKeyguard() {
         if (!mOnFingerDown) {
             playStartHaptic();
@@ -713,7 +674,8 @@
                         break;
                     }
                     // Map the touch to portrait mode if the device is in landscape mode.
-                    final Point scaledTouch = getTouchInNativeCoordinates(event, idx);
+                    final Point scaledTouch = mUdfpsUtils.getTouchInNativeCoordinates(
+                            idx, event, mOverlayParams);
                     if (actionMoveWithinSensorArea) {
                         if (mVelocityTracker == null) {
                             // touches could be injected, so the velocity tracker may not have
@@ -757,16 +719,7 @@
                                         + "but serverRequest is null");
                                 return;
                             }
-                            // Scale the coordinates to native resolution.
-                            final float scale = mOverlayParams.getScaleFactor();
-                            final float scaledSensorX =
-                                    mOverlayParams.getSensorBounds().centerX() / scale;
-                            final float scaledSensorY =
-                                    mOverlayParams.getSensorBounds().centerY() / scale;
-
-                            mOverlay.onTouchOutsideOfSensorArea(
-                                    scaledTouch.x, scaledTouch.y, scaledSensorX, scaledSensorY,
-                                    mOverlayParams.getRotation());
+                            mOverlay.onTouchOutsideOfSensorArea(scaledTouch);
                         });
                     }
                 }
@@ -838,7 +791,8 @@
             @NonNull SinglePointerTouchProcessor singlePointerTouchProcessor,
             @NonNull SessionTracker sessionTracker,
             @NonNull AlternateBouncerInteractor alternateBouncerInteractor,
-            @NonNull SecureSettings secureSettings) {
+            @NonNull SecureSettings secureSettings,
+            @NonNull UdfpsUtils udfpsUtils) {
         mContext = context;
         mExecution = execution;
         mVibrator = vibrator;
@@ -880,6 +834,7 @@
         mPrimaryBouncerInteractor = primaryBouncerInteractor;
         mAlternateBouncerInteractor = alternateBouncerInteractor;
         mSecureSettings = secureSettings;
+        mUdfpsUtils = udfpsUtils;
 
         mTouchProcessor = mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
                 ? singlePointerTouchProcessor : null;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 45ca24d..414c2ec 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -20,6 +20,7 @@
 import android.annotation.UiThread
 import android.content.Context
 import android.graphics.PixelFormat
+import android.graphics.Point
 import android.graphics.Rect
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_BP
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
@@ -33,7 +34,6 @@
 import android.os.Build
 import android.os.RemoteException
 import android.provider.Settings
-import android.util.FeatureFlagUtils
 import android.util.Log
 import android.util.RotationUtils
 import android.view.LayoutInflater
@@ -46,6 +46,8 @@
 import androidx.annotation.LayoutRes
 import androidx.annotation.VisibleForTesting
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.settingslib.udfps.UdfpsUtils
+import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.R
 import com.android.systemui.animation.ActivityLaunchAnimator
 import com.android.systemui.dump.DumpManager
@@ -101,6 +103,7 @@
         private val primaryBouncerInteractor: PrimaryBouncerInteractor,
         private val alternateBouncerInteractor: AlternateBouncerInteractor,
         private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
+        private val udfpsUtils: UdfpsUtils
 ) {
     /** The view, when [isShowing], or null. */
     var overlayView: UdfpsView? = null
@@ -131,14 +134,6 @@
         }
     }
 
-    /** A helper if the [requestReason] was due to enrollment. */
-    val enrollHelper: UdfpsEnrollHelper? =
-        if (requestReason.isEnrollmentReason() && !shouldRemoveEnrollmentUi()) {
-            UdfpsEnrollHelper(context, fingerprintManager, secureSettings, requestReason)
-        } else {
-            null
-        }
-
     /** If the overlay is currently showing. */
     val isShowing: Boolean
         get() = overlayView != null
@@ -235,30 +230,16 @@
         return when (filteredRequestReason) {
             REASON_ENROLL_FIND_SENSOR,
             REASON_ENROLL_ENROLLING -> {
-                if (FeatureFlagUtils.isEnabled(context,
-                                FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
-                    // Enroll udfps UI is handled by settings, so use empty view here
-                    UdfpsFpmEmptyViewController(
-                            view.addUdfpsView(R.layout.udfps_fpm_empty_view),
-                            statusBarStateController,
-                            shadeExpansionStateManager,
-                            dialogManager,
-                            dumpManager
-                    )
-                } else {
-                    UdfpsEnrollViewController(
-                            view.addUdfpsView(R.layout.udfps_enroll_view) {
-                                updateSensorLocation(sensorBounds)
-                            },
-                            enrollHelper ?: throw IllegalStateException("no enrollment helper"),
-                            statusBarStateController,
-                            shadeExpansionStateManager,
-                            dialogManager,
-                            dumpManager,
-                            featureFlags,
-                            overlayParams.scaleFactor
-                    )
-                }
+                // Enroll udfps UI is handled by settings, so use empty view here
+                UdfpsFpmEmptyViewController(
+                    view.addUdfpsView(R.layout.udfps_fpm_empty_view){
+                        updateAccessibilityViewLocation(sensorBounds)
+                    },
+                    statusBarStateController,
+                    shadeExpansionStateManager,
+                    dialogManager,
+                    dumpManager
+                )
             }
             REASON_AUTH_KEYGUARD -> {
                 UdfpsKeyguardViewController(
@@ -331,98 +312,23 @@
         return wasShowing
     }
 
-    fun onEnrollmentProgress(remaining: Int) {
-        enrollHelper?.onEnrollmentProgress(remaining)
-    }
-
-    fun onAcquiredGood() {
-        enrollHelper?.animateIfLastStep()
-    }
-
-    fun onEnrollmentHelp() {
-        enrollHelper?.onEnrollmentHelp()
-    }
-
     /**
      * This function computes the angle of touch relative to the sensor and maps
      * the angle to a list of help messages which are announced if accessibility is enabled.
      *
      */
-    fun onTouchOutsideOfSensorArea(
-        touchX: Float,
-        touchY: Float,
-        sensorX: Float,
-        sensorY: Float,
-        rotation: Int
-    ) {
-
-        if (!touchExplorationEnabled) {
-            return
+    fun onTouchOutsideOfSensorArea(scaledTouch: Point) {
+        val theStr =
+            udfpsUtils.onTouchOutsideOfSensorArea(
+                touchExplorationEnabled,
+                context,
+                scaledTouch.x,
+                scaledTouch.y,
+                overlayParams
+            )
+        if (theStr != null) {
+            animationViewController?.doAnnounceForAccessibility(theStr)
         }
-        val touchHints =
-            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
-        if (touchHints.size != 4) {
-            Log.e(TAG, "expected exactly 4 touch hints, got $touchHints.size?")
-            return
-        }
-        val theStr = onTouchOutsideOfSensorAreaImpl(touchX, touchY, sensorX, sensorY, rotation)
-        Log.v(TAG, "Announcing touch outside : " + theStr)
-        animationViewController?.doAnnounceForAccessibility(theStr)
-    }
-
-    /**
-     * This function computes the angle of touch relative to the sensor and maps
-     * the angle to a list of help messages which are announced if accessibility is enabled.
-     *
-     * There are 4 quadrants of the circle (90 degree arcs)
-     *
-     * [315, 360] && [0, 45) -> touchHints[0] = "Move Fingerprint to the left"
-     * [45,  135)            -> touchHints[1] = "Move Fingerprint down"
-     * And so on.
-     */
-    fun onTouchOutsideOfSensorAreaImpl(
-        touchX: Float,
-        touchY: Float,
-        sensorX: Float,
-        sensorY: Float,
-        rotation: Int
-    ): String {
-        val touchHints =
-            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
-
-        val xRelativeToSensor = touchX - sensorX
-        // Touch coordinates are with respect to the upper left corner, so reverse
-        // this calculation
-        val yRelativeToSensor = sensorY - touchY
-
-        var angleInRad =
-            Math.atan2(yRelativeToSensor.toDouble(), xRelativeToSensor.toDouble())
-        // If the radians are negative, that means we are counting clockwise.
-        // So we need to add 360 degrees
-        if (angleInRad < 0.0) {
-            angleInRad += 2.0 * Math.PI
-        }
-        // rad to deg conversion
-        val degrees = Math.toDegrees(angleInRad)
-
-        val degreesPerBucket = 360.0 / touchHints.size
-        val halfBucketDegrees = degreesPerBucket / 2.0
-        // The mapping should be as follows
-        // [315, 360] && [0, 45] -> 0
-        // [45, 135]             -> 1
-        var index = (((degrees + halfBucketDegrees) % 360) / degreesPerBucket).toInt()
-        index %= touchHints.size
-
-        // A rotation of 90 degrees corresponds to increasing the index by 1.
-        if (rotation == Surface.ROTATION_90) {
-            index = (index + 1) % touchHints.size
-        }
-
-        if (rotation == Surface.ROTATION_270) {
-            index = (index + 3) % touchHints.size
-        }
-
-        return touchHints[index]
     }
 
     /** Cancel this request. */
@@ -514,10 +420,6 @@
 }
 
 @ShowReason
-private fun Int.isEnrollmentReason() =
-    this == REASON_ENROLL_FIND_SENSOR || this == REASON_ENROLL_ENROLLING
-
-@ShowReason
 private fun Int.isImportantForAccessibility() =
     this == REASON_ENROLL_FIND_SENSOR ||
             this == REASON_ENROLL_ENROLLING ||
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
deleted file mode 100644
index 3e1c4e5..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollDrawable.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.AttributeSet;
-import android.view.animation.AccelerateDecelerateInterpolator;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.R;
-
-/**
- * UDFPS fingerprint drawable that is shown when enrolling
- */
-public class UdfpsEnrollDrawable extends UdfpsDrawable {
-    private static final String TAG = "UdfpsAnimationEnroll";
-
-    private static final long TARGET_ANIM_DURATION_LONG = 800L;
-    private static final long TARGET_ANIM_DURATION_SHORT = 600L;
-    // 1 + SCALE_MAX is the maximum that the moving target will animate to
-    private static final float SCALE_MAX = 0.25f;
-
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-
-    @NonNull private final Drawable mMovingTargetFpIcon;
-    @NonNull private final Paint mSensorOutlinePaint;
-    @NonNull private final Paint mBlueFill;
-
-    @Nullable private RectF mSensorRect;
-    @Nullable private UdfpsEnrollHelper mEnrollHelper;
-
-    // Moving target animator set
-    @Nullable AnimatorSet mTargetAnimatorSet;
-    // Moving target location
-    float mCurrentX;
-    float mCurrentY;
-    // Moving target size
-    float mCurrentScale = 1.f;
-
-    @NonNull private final Animator.AnimatorListener mTargetAnimListener;
-
-    private boolean mShouldShowTipHint = false;
-    private boolean mShouldShowEdgeHint = false;
-
-    private int mEnrollIcon;
-    private int mMovingTargetFill;
-
-    UdfpsEnrollDrawable(@NonNull Context context, @Nullable AttributeSet attrs) {
-        super(context);
-
-        loadResources(context, attrs);
-        mSensorOutlinePaint = new Paint(0 /* flags */);
-        mSensorOutlinePaint.setAntiAlias(true);
-        mSensorOutlinePaint.setColor(mMovingTargetFill);
-        mSensorOutlinePaint.setStyle(Paint.Style.FILL);
-
-        mBlueFill = new Paint(0 /* flags */);
-        mBlueFill.setAntiAlias(true);
-        mBlueFill.setColor(mMovingTargetFill);
-        mBlueFill.setStyle(Paint.Style.FILL);
-
-        mMovingTargetFpIcon = context.getResources()
-                .getDrawable(R.drawable.ic_kg_fingerprint, null);
-        mMovingTargetFpIcon.setTint(mEnrollIcon);
-        mMovingTargetFpIcon.mutate();
-
-        getFingerprintDrawable().setTint(mEnrollIcon);
-
-        mTargetAnimListener = new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animation) {}
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                updateTipHintVisibility();
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {}
-
-            @Override
-            public void onAnimationRepeat(Animator animation) {}
-        };
-    }
-
-    void loadResources(Context context, @Nullable AttributeSet attrs) {
-        final TypedArray ta = context.obtainStyledAttributes(attrs,
-                R.styleable.BiometricsEnrollView, R.attr.biometricsEnrollStyle,
-                R.style.BiometricsEnrollStyle);
-        mEnrollIcon = ta.getColor(R.styleable.BiometricsEnrollView_biometricsEnrollIcon, 0);
-        mMovingTargetFill = ta.getColor(
-                R.styleable.BiometricsEnrollView_biometricsMovingTargetFill, 0);
-        ta.recycle();
-    }
-
-    void setEnrollHelper(@NonNull UdfpsEnrollHelper helper) {
-        mEnrollHelper = helper;
-    }
-
-    @Override
-    public void onSensorRectUpdated(@NonNull RectF sensorRect) {
-        super.onSensorRectUpdated(sensorRect);
-        mSensorRect = sensorRect;
-    }
-
-    @Override
-    protected void updateFingerprintIconBounds(@NonNull Rect bounds) {
-        super.updateFingerprintIconBounds(bounds);
-        mMovingTargetFpIcon.setBounds(bounds);
-        invalidateSelf();
-    }
-
-    void onEnrollmentProgress(int remaining, int totalSteps) {
-        if (mEnrollHelper == null) {
-            return;
-        }
-
-        if (!mEnrollHelper.isCenterEnrollmentStage()) {
-            if (mTargetAnimatorSet != null && mTargetAnimatorSet.isRunning()) {
-                mTargetAnimatorSet.end();
-            }
-
-            final PointF point = mEnrollHelper.getNextGuidedEnrollmentPoint();
-            if (mCurrentX != point.x || mCurrentY != point.y) {
-                final ValueAnimator x = ValueAnimator.ofFloat(mCurrentX, point.x);
-                x.addUpdateListener(animation -> {
-                    mCurrentX = (float) animation.getAnimatedValue();
-                    invalidateSelf();
-                });
-
-                final ValueAnimator y = ValueAnimator.ofFloat(mCurrentY, point.y);
-                y.addUpdateListener(animation -> {
-                    mCurrentY = (float) animation.getAnimatedValue();
-                    invalidateSelf();
-                });
-
-                final boolean isMovingToCenter = point.x == 0f && point.y == 0f;
-                final long duration = isMovingToCenter
-                        ? TARGET_ANIM_DURATION_SHORT
-                        : TARGET_ANIM_DURATION_LONG;
-
-                final ValueAnimator scale = ValueAnimator.ofFloat(0, (float) Math.PI);
-                scale.setDuration(duration);
-                scale.addUpdateListener(animation -> {
-                    // Grow then shrink
-                    mCurrentScale = 1
-                            + SCALE_MAX * (float) Math.sin((float) animation.getAnimatedValue());
-                    invalidateSelf();
-                });
-
-                mTargetAnimatorSet = new AnimatorSet();
-
-                mTargetAnimatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
-                mTargetAnimatorSet.setDuration(duration);
-                mTargetAnimatorSet.addListener(mTargetAnimListener);
-                mTargetAnimatorSet.playTogether(x, y, scale);
-                mTargetAnimatorSet.start();
-            } else {
-                updateTipHintVisibility();
-            }
-        } else {
-            updateTipHintVisibility();
-        }
-
-        updateEdgeHintVisibility();
-    }
-
-    private void updateTipHintVisibility() {
-        final boolean shouldShow = mEnrollHelper != null && mEnrollHelper.isTipEnrollmentStage();
-        // With the new update, we will git rid of most of this code, and instead
-        // we will change the fingerprint icon.
-        if (mShouldShowTipHint == shouldShow) {
-            return;
-        }
-        mShouldShowTipHint = shouldShow;
-    }
-
-    private void updateEdgeHintVisibility() {
-        final boolean shouldShow = mEnrollHelper != null && mEnrollHelper.isEdgeEnrollmentStage();
-        if (mShouldShowEdgeHint == shouldShow) {
-            return;
-        }
-        mShouldShowEdgeHint = shouldShow;
-    }
-
-    @Override
-    public void draw(@NonNull Canvas canvas) {
-        if (isDisplayConfigured()) {
-            return;
-        }
-
-        // Draw moving target
-        if (mEnrollHelper != null && !mEnrollHelper.isCenterEnrollmentStage()) {
-            canvas.save();
-            canvas.translate(mCurrentX, mCurrentY);
-
-            if (mSensorRect != null) {
-                canvas.scale(mCurrentScale, mCurrentScale,
-                        mSensorRect.centerX(), mSensorRect.centerY());
-                canvas.drawOval(mSensorRect, mBlueFill);
-            }
-
-            mMovingTargetFpIcon.draw(canvas);
-            canvas.restore();
-        } else {
-            if (mSensorRect != null) {
-                canvas.drawOval(mSensorRect, mSensorOutlinePaint);
-            }
-            getFingerprintDrawable().draw(canvas);
-            getFingerprintDrawable().setAlpha(getAlpha());
-            mSensorOutlinePaint.setAlpha(getAlpha());
-        }
-
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        super.setAlpha(alpha);
-        mSensorOutlinePaint.setAlpha(alpha);
-        mBlueFill.setAlpha(alpha);
-        mMovingTargetFpIcon.setAlpha(alpha);
-        invalidateSelf();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
deleted file mode 100644
index cfa8ec5..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.PointF;
-import android.hardware.biometrics.BiometricOverlayConstants;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Build;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.systemui.util.settings.SecureSettings;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Helps keep track of enrollment state and animates the progress bar accordingly.
- */
-public class UdfpsEnrollHelper {
-    private static final String TAG = "UdfpsEnrollHelper";
-
-    private static final String SCALE_OVERRIDE =
-            "com.android.systemui.biometrics.UdfpsEnrollHelper.scale";
-    private static final float SCALE = 0.5f;
-
-    private static final String NEW_COORDS_OVERRIDE =
-            "com.android.systemui.biometrics.UdfpsNewCoords";
-
-    interface Listener {
-        void onEnrollmentProgress(int remaining, int totalSteps);
-        void onEnrollmentHelp(int remaining, int totalSteps);
-        void onLastStepAcquired();
-    }
-
-    @NonNull private final FingerprintManager mFingerprintManager;
-    @NonNull private final SecureSettings mSecureSettings;
-    // IUdfpsOverlayController reason
-    private final int mEnrollReason;
-    private final boolean mAccessibilityEnabled;
-    @NonNull private final List<PointF> mGuidedEnrollmentPoints;
-
-    private int mTotalSteps = -1;
-    private int mRemainingSteps = -1;
-
-    // Note that this is actually not equal to "mTotalSteps - mRemainingSteps", because the
-    // interface makes no promises about monotonically increasing by one each time.
-    private int mLocationsEnrolled = 0;
-
-    private int mCenterTouchCount = 0;
-
-    @Nullable Listener mListener;
-
-    public UdfpsEnrollHelper(@NonNull Context context,
-            @NonNull FingerprintManager fingerprintManager, SecureSettings secureSettings,
-            int reason) {
-
-        mFingerprintManager = fingerprintManager;
-        mSecureSettings = secureSettings;
-        mEnrollReason = reason;
-
-        final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
-        mAccessibilityEnabled = am.isEnabled();
-
-        mGuidedEnrollmentPoints = new ArrayList<>();
-
-        // Number of pixels per mm
-        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1,
-                context.getResources().getDisplayMetrics());
-        boolean useNewCoords = mSecureSettings.getIntForUser(NEW_COORDS_OVERRIDE, 0,
-                UserHandle.USER_CURRENT) != 0;
-        if (useNewCoords && (Build.IS_ENG || Build.IS_USERDEBUG)) {
-            Log.v(TAG, "Using new coordinates");
-            mGuidedEnrollmentPoints.add(new PointF(-0.15f * px, -1.02f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-0.15f * px,  1.02f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 0.29f * px,  0.00f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 2.17f * px, -2.35f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 1.07f * px, -3.96f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-0.37f * px, -4.31f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-1.69f * px, -3.29f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-2.48f * px, -1.23f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-2.48f * px,  1.23f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-1.69f * px,  3.29f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-0.37f * px,  4.31f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 1.07f * px,  3.96f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 2.17f * px,  2.35f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 2.58f * px,  0.00f * px));
-        } else {
-            Log.v(TAG, "Using old coordinates");
-            mGuidedEnrollmentPoints.add(new PointF( 2.00f * px,  0.00f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 0.87f * px, -2.70f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-1.80f * px, -1.31f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-1.80f * px,  1.31f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 0.88f * px,  2.70f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 3.94f * px, -1.06f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 2.90f * px, -4.14f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-0.52f * px, -5.95f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-3.33f * px, -3.33f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-3.99f * px, -0.35f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-3.62f * px,  2.54f * px));
-            mGuidedEnrollmentPoints.add(new PointF(-1.49f * px,  5.57f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 2.29f * px,  4.92f * px));
-            mGuidedEnrollmentPoints.add(new PointF( 3.82f * px,  1.78f * px));
-        }
-    }
-
-    int getStageCount() {
-        return mFingerprintManager.getEnrollStageCount();
-    }
-
-    int getStageThresholdSteps(int totalSteps, int stageIndex) {
-        return Math.round(totalSteps * mFingerprintManager.getEnrollStageThreshold(stageIndex));
-    }
-
-    boolean shouldShowProgressBar() {
-        return mEnrollReason == BiometricOverlayConstants.REASON_ENROLL_ENROLLING;
-    }
-
-    void onEnrollmentProgress(int remaining) {
-        if (mTotalSteps == -1) {
-            mTotalSteps = remaining;
-        }
-
-        if (remaining != mRemainingSteps) {
-            mLocationsEnrolled++;
-            if (isCenterEnrollmentStage()) {
-                mCenterTouchCount++;
-            }
-        }
-
-        mRemainingSteps = remaining;
-
-        if (mListener != null) {
-            mListener.onEnrollmentProgress(remaining, mTotalSteps);
-        }
-    }
-
-    void onEnrollmentHelp() {
-        if (mListener != null) {
-            mListener.onEnrollmentHelp(mRemainingSteps, mTotalSteps);
-        }
-    }
-
-    void setListener(Listener listener) {
-        mListener = listener;
-
-        // Only notify during setListener if enrollment is already in progress, so the progress
-        // bar can be updated. If enrollment has not started yet, the progress bar will be empty
-        // anyway.
-        if (mListener != null && mTotalSteps != -1) {
-            mListener.onEnrollmentProgress(mRemainingSteps, mTotalSteps);
-        }
-    }
-
-    boolean isCenterEnrollmentStage() {
-        if (mTotalSteps == -1 || mRemainingSteps == -1) {
-            return true;
-        }
-        return mTotalSteps - mRemainingSteps < getStageThresholdSteps(mTotalSteps, 0);
-    }
-
-    boolean isGuidedEnrollmentStage() {
-        if (mAccessibilityEnabled || mTotalSteps == -1 || mRemainingSteps == -1) {
-            return false;
-        }
-        final int progressSteps = mTotalSteps - mRemainingSteps;
-        return progressSteps >= getStageThresholdSteps(mTotalSteps, 0)
-                && progressSteps < getStageThresholdSteps(mTotalSteps, 1);
-    }
-
-    boolean isTipEnrollmentStage() {
-        if (mTotalSteps == -1 || mRemainingSteps == -1) {
-            return false;
-        }
-        final int progressSteps = mTotalSteps - mRemainingSteps;
-        return progressSteps >= getStageThresholdSteps(mTotalSteps, 1)
-                && progressSteps < getStageThresholdSteps(mTotalSteps, 2);
-    }
-
-    boolean isEdgeEnrollmentStage() {
-        if (mTotalSteps == -1 || mRemainingSteps == -1) {
-            return false;
-        }
-        return mTotalSteps - mRemainingSteps >= getStageThresholdSteps(mTotalSteps, 2);
-    }
-
-    @NonNull
-    PointF getNextGuidedEnrollmentPoint() {
-        if (mAccessibilityEnabled || !isGuidedEnrollmentStage()) {
-            return new PointF(0f, 0f);
-        }
-
-        float scale = SCALE;
-        if (Build.IS_ENG || Build.IS_USERDEBUG) {
-            scale = mSecureSettings.getFloatForUser(SCALE_OVERRIDE, SCALE,
-                    UserHandle.USER_CURRENT);
-        }
-        final int index = mLocationsEnrolled - mCenterTouchCount;
-        final PointF originalPoint = mGuidedEnrollmentPoints
-                .get(index % mGuidedEnrollmentPoints.size());
-        return new PointF(originalPoint.x * scale, originalPoint.y * scale);
-    }
-
-    void animateIfLastStep() {
-        if (mListener == null) {
-            Log.e(TAG, "animateIfLastStep, null listener");
-            return;
-        }
-
-        if (mRemainingSteps <= 2 && mRemainingSteps >= 0) {
-            mListener.onLastStepAcquired();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
deleted file mode 100644
index 66a8424..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollProgressBarDrawable.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-import android.os.Process;
-import android.os.VibrationAttributes;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
-import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.OvershootInterpolator;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.R;
-
-/**
- * UDFPS enrollment progress bar.
- */
-public class UdfpsEnrollProgressBarDrawable extends Drawable {
-    private static final String TAG = "UdfpsProgressBar";
-
-    private static final long CHECKMARK_ANIMATION_DELAY_MS = 200L;
-    private static final long CHECKMARK_ANIMATION_DURATION_MS = 300L;
-    private static final long FILL_COLOR_ANIMATION_DURATION_MS = 350L;
-    private static final long PROGRESS_ANIMATION_DURATION_MS = 400L;
-    private static final float STROKE_WIDTH_DP = 12f;
-    private static final Interpolator DEACCEL = new DecelerateInterpolator();
-
-    private static final VibrationEffect VIBRATE_EFFECT_ERROR =
-            VibrationEffect.createWaveform(new long[] {0, 5, 55, 60}, -1);
-    private static final VibrationAttributes FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES =
-            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ACCESSIBILITY);
-
-    private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
-            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
-
-    private static final VibrationEffect SUCCESS_VIBRATION_EFFECT =
-            VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-
-    private final float mStrokeWidthPx;
-    @ColorInt private final int mProgressColor;
-    @ColorInt private final int mHelpColor;
-    @ColorInt private final int mOnFirstBucketFailedColor;
-    @NonNull private final Drawable mCheckmarkDrawable;
-    @NonNull private final Interpolator mCheckmarkInterpolator;
-    @NonNull private final Paint mBackgroundPaint;
-    @NonNull private final Paint mFillPaint;
-    @NonNull private final Vibrator mVibrator;
-    @NonNull private final boolean mIsAccessibilityEnabled;
-    @NonNull private final Context mContext;
-
-    private boolean mAfterFirstTouch;
-
-    private int mRemainingSteps = 0;
-    private int mTotalSteps = 0;
-    private float mProgress = 0f;
-    @Nullable private ValueAnimator mProgressAnimator;
-    @NonNull private final ValueAnimator.AnimatorUpdateListener mProgressUpdateListener;
-
-    private boolean mShowingHelp = false;
-    @Nullable private ValueAnimator mFillColorAnimator;
-    @NonNull private final ValueAnimator.AnimatorUpdateListener mFillColorUpdateListener;
-
-    @Nullable private ValueAnimator mBackgroundColorAnimator;
-    @NonNull private final ValueAnimator.AnimatorUpdateListener mBackgroundColorUpdateListener;
-
-    private boolean mComplete = false;
-    private float mCheckmarkScale = 0f;
-    @Nullable private ValueAnimator mCheckmarkAnimator;
-    @NonNull private final ValueAnimator.AnimatorUpdateListener mCheckmarkUpdateListener;
-
-    private int mMovingTargetFill;
-    private int mMovingTargetFillError;
-    private int mEnrollProgress;
-    private int mEnrollProgressHelp;
-    private int mEnrollProgressHelpWithTalkback;
-
-    public UdfpsEnrollProgressBarDrawable(@NonNull Context context, @Nullable AttributeSet attrs) {
-        mContext = context;
-
-        loadResources(context, attrs);
-        mStrokeWidthPx = Utils.dpToPixels(context, STROKE_WIDTH_DP);
-        mProgressColor = mEnrollProgress;
-        final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
-        mIsAccessibilityEnabled = am.isTouchExplorationEnabled();
-        mOnFirstBucketFailedColor = mMovingTargetFillError;
-        if (!mIsAccessibilityEnabled) {
-            mHelpColor = mEnrollProgressHelp;
-        } else {
-            mHelpColor = mEnrollProgressHelpWithTalkback;
-        }
-        mCheckmarkDrawable = context.getDrawable(R.drawable.udfps_enroll_checkmark);
-        mCheckmarkDrawable.mutate();
-        mCheckmarkInterpolator = new OvershootInterpolator();
-
-        mBackgroundPaint = new Paint();
-        mBackgroundPaint.setStrokeWidth(mStrokeWidthPx);
-        mBackgroundPaint.setColor(mMovingTargetFill);
-        mBackgroundPaint.setAntiAlias(true);
-        mBackgroundPaint.setStyle(Paint.Style.STROKE);
-        mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND);
-
-        // Progress fill should *not* use the extracted system color.
-        mFillPaint = new Paint();
-        mFillPaint.setStrokeWidth(mStrokeWidthPx);
-        mFillPaint.setColor(mProgressColor);
-        mFillPaint.setAntiAlias(true);
-        mFillPaint.setStyle(Paint.Style.STROKE);
-        mFillPaint.setStrokeCap(Paint.Cap.ROUND);
-
-        mVibrator = mContext.getSystemService(Vibrator.class);
-
-        mProgressUpdateListener = animation -> {
-            mProgress = (float) animation.getAnimatedValue();
-            invalidateSelf();
-        };
-
-        mFillColorUpdateListener = animation -> {
-            mFillPaint.setColor((int) animation.getAnimatedValue());
-            invalidateSelf();
-        };
-
-        mCheckmarkUpdateListener = animation -> {
-            mCheckmarkScale = (float) animation.getAnimatedValue();
-            invalidateSelf();
-        };
-
-        mBackgroundColorUpdateListener = animation -> {
-            mBackgroundPaint.setColor((int) animation.getAnimatedValue());
-            invalidateSelf();
-        };
-    }
-
-    void loadResources(Context context, @Nullable AttributeSet attrs) {
-        final TypedArray ta = context.obtainStyledAttributes(attrs,
-                R.styleable.BiometricsEnrollView, R.attr.biometricsEnrollStyle,
-                R.style.BiometricsEnrollStyle);
-        mMovingTargetFill = ta.getColor(
-                R.styleable.BiometricsEnrollView_biometricsMovingTargetFill, 0);
-        mMovingTargetFillError = ta.getColor(
-                R.styleable.BiometricsEnrollView_biometricsMovingTargetFillError, 0);
-        mEnrollProgress = ta.getColor(
-                R.styleable.BiometricsEnrollView_biometricsEnrollProgress, 0);
-        mEnrollProgressHelp = ta.getColor(
-                R.styleable.BiometricsEnrollView_biometricsEnrollProgressHelp, 0);
-        mEnrollProgressHelpWithTalkback = ta.getColor(
-                R.styleable.BiometricsEnrollView_biometricsEnrollProgressHelpWithTalkback, 0);
-        ta.recycle();
-    }
-
-    void onEnrollmentProgress(int remaining, int totalSteps) {
-        mAfterFirstTouch = true;
-        updateState(remaining, totalSteps, false /* showingHelp */);
-    }
-
-    void onEnrollmentHelp(int remaining, int totalSteps) {
-        updateState(remaining, totalSteps, true /* showingHelp */);
-    }
-
-    void onLastStepAcquired() {
-        updateState(0, mTotalSteps, false /* showingHelp */);
-    }
-
-    private void updateState(int remainingSteps, int totalSteps, boolean showingHelp) {
-        updateProgress(remainingSteps, totalSteps, showingHelp);
-        updateFillColor(showingHelp);
-    }
-
-    private void updateProgress(int remainingSteps, int totalSteps, boolean showingHelp) {
-        if (mRemainingSteps == remainingSteps && mTotalSteps == totalSteps) {
-            return;
-        }
-
-        if (mShowingHelp) {
-            if (mVibrator != null && mIsAccessibilityEnabled) {
-                mVibrator.vibrate(Process.myUid(), mContext.getOpPackageName(),
-                        VIBRATE_EFFECT_ERROR, getClass().getSimpleName() + "::onEnrollmentHelp",
-                        FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES);
-            }
-        } else {
-            // If the first touch is an error, remainingSteps will be -1 and the callback
-            // doesn't come from onEnrollmentHelp. If we are in the accessibility flow,
-            // we still would like to vibrate.
-            if (mVibrator != null) {
-                if (remainingSteps == -1 && mIsAccessibilityEnabled) {
-                    mVibrator.vibrate(Process.myUid(), mContext.getOpPackageName(),
-                            VIBRATE_EFFECT_ERROR,
-                            getClass().getSimpleName() + "::onFirstTouchError",
-                            FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES);
-                } else if (remainingSteps != -1 && !mIsAccessibilityEnabled) {
-                    mVibrator.vibrate(Process.myUid(),
-                            mContext.getOpPackageName(),
-                            SUCCESS_VIBRATION_EFFECT,
-                            getClass().getSimpleName() + "::OnEnrollmentProgress",
-                            HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
-                }
-            }
-        }
-
-        mShowingHelp = showingHelp;
-        mRemainingSteps = remainingSteps;
-        mTotalSteps = totalSteps;
-
-        final int progressSteps = Math.max(0, totalSteps - remainingSteps);
-
-        // If needed, add 1 to progress and total steps to account for initial touch.
-        final int adjustedSteps = mAfterFirstTouch ? progressSteps + 1 : progressSteps;
-        final int adjustedTotal = mAfterFirstTouch ? mTotalSteps + 1 : mTotalSteps;
-
-        final float targetProgress = Math.min(1f, (float) adjustedSteps / (float) adjustedTotal);
-
-        if (mProgressAnimator != null && mProgressAnimator.isRunning()) {
-            mProgressAnimator.cancel();
-        }
-
-        mProgressAnimator = ValueAnimator.ofFloat(mProgress, targetProgress);
-        mProgressAnimator.setDuration(PROGRESS_ANIMATION_DURATION_MS);
-        mProgressAnimator.addUpdateListener(mProgressUpdateListener);
-        mProgressAnimator.start();
-
-        if (remainingSteps == 0) {
-            startCompletionAnimation();
-        } else if (remainingSteps > 0) {
-            rollBackCompletionAnimation();
-        }
-    }
-
-    private void animateBackgroundColor() {
-        if (mBackgroundColorAnimator != null && mBackgroundColorAnimator.isRunning()) {
-            mBackgroundColorAnimator.end();
-        }
-        mBackgroundColorAnimator = ValueAnimator.ofArgb(mBackgroundPaint.getColor(),
-                mOnFirstBucketFailedColor);
-        mBackgroundColorAnimator.setDuration(FILL_COLOR_ANIMATION_DURATION_MS);
-        mBackgroundColorAnimator.setRepeatCount(1);
-        mBackgroundColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
-        mBackgroundColorAnimator.setInterpolator(DEACCEL);
-        mBackgroundColorAnimator.addUpdateListener(mBackgroundColorUpdateListener);
-        mBackgroundColorAnimator.start();
-    }
-
-    private void updateFillColor(boolean showingHelp) {
-        if (!mAfterFirstTouch && showingHelp) {
-            // If we are on the first touch, animate the background color
-            // instead of the progress color.
-            animateBackgroundColor();
-            return;
-        }
-
-        if (mFillColorAnimator != null && mFillColorAnimator.isRunning()) {
-            mFillColorAnimator.end();
-        }
-
-        @ColorInt final int targetColor = showingHelp ? mHelpColor : mProgressColor;
-        mFillColorAnimator = ValueAnimator.ofArgb(mFillPaint.getColor(), targetColor);
-        mFillColorAnimator.setDuration(FILL_COLOR_ANIMATION_DURATION_MS);
-        mFillColorAnimator.setRepeatCount(1);
-        mFillColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
-        mFillColorAnimator.setInterpolator(DEACCEL);
-        mFillColorAnimator.addUpdateListener(mFillColorUpdateListener);
-        mFillColorAnimator.start();
-    }
-
-    private void startCompletionAnimation() {
-        if (mComplete) {
-            return;
-        }
-        mComplete = true;
-
-        if (mCheckmarkAnimator != null && mCheckmarkAnimator.isRunning()) {
-            mCheckmarkAnimator.cancel();
-        }
-
-        mCheckmarkAnimator = ValueAnimator.ofFloat(mCheckmarkScale, 1f);
-        mCheckmarkAnimator.setStartDelay(CHECKMARK_ANIMATION_DELAY_MS);
-        mCheckmarkAnimator.setDuration(CHECKMARK_ANIMATION_DURATION_MS);
-        mCheckmarkAnimator.setInterpolator(mCheckmarkInterpolator);
-        mCheckmarkAnimator.addUpdateListener(mCheckmarkUpdateListener);
-        mCheckmarkAnimator.start();
-    }
-
-    private void rollBackCompletionAnimation() {
-        if (!mComplete) {
-            return;
-        }
-        mComplete = false;
-
-        // Adjust duration based on how much of the completion animation has played.
-        final float animatedFraction = mCheckmarkAnimator != null
-                ? mCheckmarkAnimator.getAnimatedFraction()
-                : 0f;
-        final long durationMs = Math.round(CHECKMARK_ANIMATION_DELAY_MS * animatedFraction);
-
-        if (mCheckmarkAnimator != null && mCheckmarkAnimator.isRunning()) {
-            mCheckmarkAnimator.cancel();
-        }
-
-        mCheckmarkAnimator = ValueAnimator.ofFloat(mCheckmarkScale, 0f);
-        mCheckmarkAnimator.setDuration(durationMs);
-        mCheckmarkAnimator.addUpdateListener(mCheckmarkUpdateListener);
-        mCheckmarkAnimator.start();
-    }
-
-    @Override
-    public void draw(@NonNull Canvas canvas) {
-        canvas.save();
-
-        // Progress starts from the top, instead of the right
-        canvas.rotate(-90f, getBounds().centerX(), getBounds().centerY());
-
-        final float halfPaddingPx = mStrokeWidthPx / 2f;
-
-        if (mProgress < 1f) {
-            // Draw the background color of the progress circle.
-            canvas.drawArc(
-                    halfPaddingPx,
-                    halfPaddingPx,
-                    getBounds().right - halfPaddingPx,
-                    getBounds().bottom - halfPaddingPx,
-                    0f /* startAngle */,
-                    360f /* sweepAngle */,
-                    false /* useCenter */,
-                    mBackgroundPaint);
-        }
-
-        if (mProgress > 0f) {
-            // Draw the filled portion of the progress circle.
-            canvas.drawArc(
-                    halfPaddingPx,
-                    halfPaddingPx,
-                    getBounds().right - halfPaddingPx,
-                    getBounds().bottom - halfPaddingPx,
-                    0f /* startAngle */,
-                    360f * mProgress /* sweepAngle */,
-                    false /* useCenter */,
-                    mFillPaint);
-        }
-
-        canvas.restore();
-
-        if (mCheckmarkScale > 0f) {
-            final float offsetScale = (float) Math.sqrt(2) / 2f;
-            final float centerXOffset = (getBounds().width() - mStrokeWidthPx) / 2f * offsetScale;
-            final float centerYOffset = (getBounds().height() - mStrokeWidthPx) / 2f * offsetScale;
-            final float centerX = getBounds().centerX() + centerXOffset;
-            final float centerY = getBounds().centerY() + centerYOffset;
-
-            final float boundsXOffset =
-                    mCheckmarkDrawable.getIntrinsicWidth() / 2f * mCheckmarkScale;
-            final float boundsYOffset =
-                    mCheckmarkDrawable.getIntrinsicHeight() / 2f * mCheckmarkScale;
-
-            final int left = Math.round(centerX - boundsXOffset);
-            final int top = Math.round(centerY - boundsYOffset);
-            final int right = Math.round(centerX + boundsXOffset);
-            final int bottom = Math.round(centerY + boundsYOffset);
-            mCheckmarkDrawable.setBounds(left, top, right, bottom);
-            mCheckmarkDrawable.draw(canvas);
-        }
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-    }
-
-    @Override
-    public void setColorFilter(@Nullable ColorFilter colorFilter) {
-    }
-
-    @Override
-    public int getOpacity() {
-        return 0;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
deleted file mode 100644
index 1cc4141..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollView.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.systemui.R;
-
-/**
- * View corresponding with udfps_enroll_view.xml
- */
-public class UdfpsEnrollView extends UdfpsAnimationView {
-    @NonNull private final UdfpsEnrollDrawable mFingerprintDrawable;
-    @NonNull private final UdfpsEnrollProgressBarDrawable mFingerprintProgressDrawable;
-    @NonNull private final Handler mHandler;
-
-    @NonNull private ImageView mFingerprintView;
-    @NonNull private ImageView mFingerprintProgressView;
-
-    private LayoutParams mProgressParams;
-    private float mProgressBarRadius;
-
-    public UdfpsEnrollView(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        mFingerprintDrawable = new UdfpsEnrollDrawable(mContext, attrs);
-        mFingerprintProgressDrawable = new UdfpsEnrollProgressBarDrawable(context, attrs);
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        mFingerprintView = findViewById(R.id.udfps_enroll_animation_fp_view);
-        mFingerprintProgressView = findViewById(R.id.udfps_enroll_animation_fp_progress_view);
-        mFingerprintView.setImageDrawable(mFingerprintDrawable);
-        mFingerprintProgressView.setImageDrawable(mFingerprintProgressDrawable);
-    }
-
-    @Override
-    void onSensorRectUpdated(RectF bounds) {
-        if (mUseExpandedOverlay) {
-            RectF converted = getBoundsRelativeToView(bounds);
-
-            mProgressParams = new LayoutParams(
-                    (int) (converted.width() + mProgressBarRadius * 2),
-                    (int) (converted.height() + mProgressBarRadius * 2));
-            mProgressParams.setMargins(
-                    (int) (converted.left - mProgressBarRadius),
-                    (int) (converted.top - mProgressBarRadius),
-                    (int) (converted.right + mProgressBarRadius),
-                    (int) (converted.bottom + mProgressBarRadius)
-            );
-
-            mFingerprintProgressView.setLayoutParams(mProgressParams);
-            super.onSensorRectUpdated(converted);
-        } else {
-            super.onSensorRectUpdated(bounds);
-        }
-    }
-
-    void setProgressBarRadius(float radius) {
-        mProgressBarRadius = radius;
-    }
-
-    @Override
-    public UdfpsDrawable getDrawable() {
-        return mFingerprintDrawable;
-    }
-
-    void updateSensorLocation(@NonNull Rect sensorBounds) {
-        View fingerprintAccessibilityView = findViewById(R.id.udfps_enroll_accessibility_view);
-        ViewGroup.LayoutParams params = fingerprintAccessibilityView.getLayoutParams();
-        params.width = sensorBounds.width();
-        params.height = sensorBounds.height();
-        fingerprintAccessibilityView.setLayoutParams(params);
-        fingerprintAccessibilityView.requestLayout();
-    }
-
-    void setEnrollHelper(UdfpsEnrollHelper enrollHelper) {
-        mFingerprintDrawable.setEnrollHelper(enrollHelper);
-    }
-
-    void onEnrollmentProgress(int remaining, int totalSteps) {
-        mHandler.post(() -> {
-            mFingerprintProgressDrawable.onEnrollmentProgress(remaining, totalSteps);
-            mFingerprintDrawable.onEnrollmentProgress(remaining, totalSteps);
-        });
-    }
-
-    void onEnrollmentHelp(int remaining, int totalSteps) {
-        mHandler.post(() -> mFingerprintProgressDrawable.onEnrollmentHelp(remaining, totalSteps));
-    }
-
-    void onLastStepAcquired() {
-        mHandler.post(mFingerprintProgressDrawable::onLastStepAcquired);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java
deleted file mode 100644
index c82e6e1..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollViewController.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.annotation.NonNull;
-import android.graphics.PointF;
-
-import com.android.systemui.R;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shade.ShadeExpansionStateManager;
-import com.android.systemui.statusbar.phone.SystemUIDialogManager;
-
-/**
- * Class that coordinates non-HBM animations during enrollment.
- */
-public class UdfpsEnrollViewController extends UdfpsAnimationViewController<UdfpsEnrollView> {
-
-    private final int mEnrollProgressBarRadius;
-    @NonNull private final UdfpsEnrollHelper mEnrollHelper;
-    @NonNull private final UdfpsEnrollHelper.Listener mEnrollHelperListener =
-            new UdfpsEnrollHelper.Listener() {
-                @Override
-                public void onEnrollmentProgress(int remaining, int totalSteps) {
-                    mView.onEnrollmentProgress(remaining, totalSteps);
-                }
-
-                @Override
-                public void onEnrollmentHelp(int remaining, int totalSteps) {
-                    mView.onEnrollmentHelp(remaining, totalSteps);
-                }
-
-                @Override
-                public void onLastStepAcquired() {
-                    mView.onLastStepAcquired();
-                }
-            };
-
-    protected UdfpsEnrollViewController(
-            @NonNull UdfpsEnrollView view,
-            @NonNull UdfpsEnrollHelper enrollHelper,
-            @NonNull StatusBarStateController statusBarStateController,
-            @NonNull ShadeExpansionStateManager shadeExpansionStateManager,
-            @NonNull SystemUIDialogManager systemUIDialogManager,
-            @NonNull DumpManager dumpManager,
-            @NonNull FeatureFlags featureFlags,
-            float scaleFactor) {
-        super(view, statusBarStateController, shadeExpansionStateManager, systemUIDialogManager,
-                dumpManager);
-        mEnrollProgressBarRadius = (int) (scaleFactor * getContext().getResources().getInteger(
-                R.integer.config_udfpsEnrollProgressBar));
-        mEnrollHelper = enrollHelper;
-        mView.setEnrollHelper(mEnrollHelper);
-        mView.setProgressBarRadius(mEnrollProgressBarRadius);
-        mView.mUseExpandedOverlay = featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION);
-    }
-
-    @Override
-    @NonNull protected String getTag() {
-        return "UdfpsEnrollViewController";
-    }
-
-    @Override
-    protected void onViewAttached() {
-        super.onViewAttached();
-        if (mEnrollHelper.shouldShowProgressBar()) {
-            // Only need enrollment updates if the progress bar is showing :)
-            mEnrollHelper.setListener(mEnrollHelperListener);
-        }
-    }
-
-    @NonNull
-    @Override
-    public PointF getTouchTranslation() {
-        if (!mEnrollHelper.isGuidedEnrollmentStage()) {
-            return new PointF(0, 0);
-        } else {
-            return mEnrollHelper.getNextGuidedEnrollmentPoint();
-        }
-    }
-
-    @Override
-    public int getPaddingX() {
-        return mEnrollProgressBarRadius;
-    }
-
-    @Override
-    public int getPaddingY() {
-        return mEnrollProgressBarRadius;
-    }
-
-    @Override
-    public void doAnnounceForAccessibility(String str) {
-        mView.announceForAccessibility(str);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
index e8f041e..8352d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmEmptyView.kt
@@ -16,7 +16,11 @@
 package com.android.systemui.biometrics
 
 import android.content.Context
+import android.graphics.Rect
 import android.util.AttributeSet
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.R
 
 /**
  * View corresponding with udfps_fpm_empty_view.xml
@@ -32,4 +36,13 @@
     private val fingerprintDrawable: UdfpsFpDrawable = UdfpsFpDrawable(context)
 
     override fun getDrawable(): UdfpsDrawable = fingerprintDrawable
+
+    fun updateAccessibilityViewLocation(sensorBounds: Rect) {
+        val fingerprintAccessibilityView: View = findViewById(R.id.udfps_enroll_accessibility_view)
+        val params: ViewGroup.LayoutParams = fingerprintAccessibilityView.layoutParams
+        params.width = sensorBounds.width()
+        params.height = sensorBounds.height()
+        fingerprintAccessibilityView.layoutParams = params
+        fingerprintAccessibilityView.requestLayout()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
index 802b9b6..079c0b3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlay.kt
@@ -32,6 +32,7 @@
 import android.view.WindowManager
 import android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
index 4e6a06b..28ca41d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayView.kt
@@ -25,6 +25,7 @@
 import android.util.AttributeSet
 import android.view.MotionEvent
 import android.widget.FrameLayout
+import com.android.settingslib.udfps.UdfpsOverlayParams
 
 private const val TAG = "UdfpsOverlayView"
 private const val POINT_SIZE = 10f
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index e61c614..06dee7a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -26,6 +26,7 @@
 import android.util.Log
 import android.view.MotionEvent
 import android.widget.FrameLayout
+import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.R
 import com.android.systemui.doze.DozeReceiver
 
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 6f8efba..67d2f30 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.biometrics.dagger
 
+import com.android.settingslib.udfps.UdfpsUtils
 import com.android.systemui.biometrics.data.repository.PromptRepository
 import com.android.systemui.biometrics.data.repository.PromptRepositoryImpl
 import com.android.systemui.biometrics.domain.interactor.CredentialInteractor
@@ -54,6 +55,9 @@
         @BiometricsBackground
         fun providesPluginExecutor(threadFactory: ThreadFactory): Executor =
             threadFactory.buildExecutorOnNewThread("biometrics")
+
+        @Provides
+        fun providesUdfpsUtils(): UdfpsUtils = UdfpsUtils()
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
index 39ea936..6c9390d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessor.kt
@@ -21,7 +21,7 @@
 import android.view.MotionEvent
 import android.view.MotionEvent.INVALID_POINTER_ID
 import android.view.Surface
-import com.android.systemui.biometrics.UdfpsOverlayParams
+import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.biometrics.udfps.TouchProcessorResult.Failure
 import com.android.systemui.biometrics.udfps.TouchProcessorResult.ProcessedTouch
 import com.android.systemui.dagger.SysUISingleton
@@ -92,9 +92,14 @@
         val data = touch.data.find { it.pointerId == pointerOnSensorId } ?: NormalizedTouchData()
         ProcessedTouch(InteractionEvent.DOWN, data.pointerId, data)
     } else if (hadPointerOnSensor && !hasPointerOnSensor) {
-        ProcessedTouch(InteractionEvent.UP, INVALID_POINTER_ID, NormalizedTouchData())
+        val data =
+            touch.data.find { it.pointerId == touch.previousPointerOnSensorId }
+                ?: NormalizedTouchData()
+        ProcessedTouch(InteractionEvent.UP, INVALID_POINTER_ID, data)
     } else {
-        val data = touch.data.find { it.pointerId == pointerOnSensorId } ?: NormalizedTouchData()
+        val data =
+            touch.data.find { it.pointerId == pointerOnSensorId }
+                ?: touch.data.firstOrNull() ?: NormalizedTouchData()
         ProcessedTouch(InteractionEvent.UNCHANGED, pointerOnSensorId, data)
     }
 }
@@ -102,16 +107,15 @@
 private fun processActionUp(touch: PreprocessedTouch, actionId: Int): TouchProcessorResult {
     // Finger lifted and it was the only finger on the sensor
     return if (touch.pointersOnSensor.size == 1 && touch.pointersOnSensor.contains(actionId)) {
-        ProcessedTouch(
-            InteractionEvent.UP,
-            pointerOnSensorId = INVALID_POINTER_ID,
-            NormalizedTouchData()
-        )
+        val data = touch.data.find { it.pointerId == actionId } ?: NormalizedTouchData()
+        ProcessedTouch(InteractionEvent.UP, pointerOnSensorId = INVALID_POINTER_ID, data)
     } else {
         // Pick new pointerOnSensor that's not the finger that was lifted
         val pointerOnSensorId = touch.pointersOnSensor.find { it != actionId } ?: INVALID_POINTER_ID
-        val data = touch.data.find { it.pointerId == pointerOnSensorId } ?: NormalizedTouchData()
-        ProcessedTouch(InteractionEvent.UNCHANGED, data.pointerId, data)
+        val data =
+            touch.data.find { it.pointerId == pointerOnSensorId }
+                ?: touch.data.firstOrNull() ?: NormalizedTouchData()
+        ProcessedTouch(InteractionEvent.UNCHANGED, pointerOnSensorId, data)
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt
index ffcebf9..4bf0ef6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/udfps/TouchProcessor.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.biometrics.udfps
 
 import android.view.MotionEvent
-import com.android.systemui.biometrics.UdfpsOverlayParams
+import com.android.settingslib.udfps.UdfpsOverlayParams
 
 /**
  * Determines whether a finger entered or left the area of the under-display fingerprint sensor
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
index fb0c0a6..5ca36ab 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
@@ -72,7 +72,7 @@
         height = WindowManager.LayoutParams.MATCH_PARENT
         layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
         format = PixelFormat.TRANSLUCENT
-        type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
+        type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
         fitInsetsTypes = 0 // Ignore insets from all system bars
         title = "Wired Charging Animation"
         flags = (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
diff --git a/packages/SystemUI/src/com/android/systemui/common/coroutine/CoroutineResult.kt b/packages/SystemUI/src/com/android/systemui/common/coroutine/CoroutineResult.kt
new file mode 100644
index 0000000..b973667
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/coroutine/CoroutineResult.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.common.coroutine
+
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.currentCoroutineContext
+import kotlinx.coroutines.ensureActive
+import kotlinx.coroutines.withTimeout
+
+/**
+ * Calls the specified function [block] and returns its encapsulated result if invocation was
+ * successful, catching any [Throwable] exception that was thrown from the block function execution
+ * and encapsulating it as a failure.
+ *
+ * Unlike [runCatching], [suspendRunCatching] does not break structured concurrency by rethrowing
+ * any [CancellationException].
+ *
+ * **Heads-up:** [TimeoutCancellationException] extends [CancellationException] but catching it does
+ * not breaks structured concurrency and therefore, will not be rethrown. Therefore, you can use
+ * [suspendRunCatching] with [withTimeout], and handle any timeout gracefully.
+ *
+ * @see <a href="https://github.com/Kotlin/kotlinx.coroutines/issues/1814">link</a>
+ */
+suspend inline fun <T> suspendRunCatching(crossinline block: suspend () -> T): Result<T> =
+    try {
+        Result.success(block())
+    } catch (e: Throwable) {
+        // Ensures the try-catch block will not break structured concurrency.
+        currentCoroutineContext().ensureActive()
+        Result.failure(e)
+    }
+
+/**
+ * Calls the specified function [block] and returns its encapsulated result if invocation was
+ * successful, catching any [Throwable] exception that was thrown from the block function execution
+ * and encapsulating it as a failure.
+ *
+ * Unlike [runCatching], [suspendRunCatching] does not break structured concurrency by rethrowing
+ * any [CancellationException].
+ *
+ * **Heads-up:** [TimeoutCancellationException] extends [CancellationException] but catching it does
+ * not breaks structured concurrency and therefore, will not be rethrown. Therefore, you can use
+ * [suspendRunCatching] with [withTimeout], and handle any timeout gracefully.
+ *
+ * @see <a href="https://github.com/Kotlin/kotlinx.coroutines/issues/1814">link</a>
+ */
+suspend inline fun <T, R> T.suspendRunCatching(crossinline block: suspend T.() -> R): Result<R> =
+    // Overload with a `this` receiver, matches with `kotlin.runCatching` functions.
+    // Qualified name needs to be used to avoid a recursive call.
+    com.android.systemui.common.coroutine.suspendRunCatching { block(this) }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
index 27466d4..7509a8a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
@@ -19,11 +19,11 @@
 import android.content.Context
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
-import com.android.systemui.controls.settings.ControlsSettingsRepository
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.controls.controller.ControlsTileResourceConfiguration
 import com.android.systemui.controls.controller.ControlsTileResourceConfigurationImpl
 import com.android.systemui.controls.management.ControlsListingController
+import com.android.systemui.controls.settings.ControlsSettingsRepository
 import com.android.systemui.controls.ui.ControlsUiController
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.settings.UserTracker
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
index 4eb444e..a5beb4e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java
@@ -23,6 +23,8 @@
 import com.android.systemui.keyguard.WorkLockActivity;
 import com.android.systemui.people.PeopleSpaceActivity;
 import com.android.systemui.people.widget.LaunchConversationActivity;
+import com.android.systemui.screenshot.AppClipsActivity;
+import com.android.systemui.screenshot.AppClipsTrampolineActivity;
 import com.android.systemui.screenshot.LongScreenshotActivity;
 import com.android.systemui.sensorprivacy.SensorUseStartedActivity;
 import com.android.systemui.sensorprivacy.television.TvSensorPrivacyChangedActivity;
@@ -119,6 +121,18 @@
     @ClassKey(LongScreenshotActivity.class)
     public abstract Activity bindLongScreenshotActivity(LongScreenshotActivity activity);
 
+    /** Inject into AppClipsTrampolineActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(AppClipsTrampolineActivity.class)
+    public abstract Activity bindAppClipsTrampolineActivity(AppClipsTrampolineActivity activity);
+
+    /** Inject into AppClipsActivity. */
+    @Binds
+    @IntoMap
+    @ClassKey(AppClipsActivity.class)
+    public abstract Activity bindAppClipsActivity(AppClipsActivity activity);
+
     /** Inject into LaunchConversationActivity. */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index 96bfa43..b054c7e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -32,6 +32,7 @@
 import android.app.UiModeManager;
 import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
+import android.app.ambientcontext.AmbientContextManager;
 import android.app.job.JobScheduler;
 import android.app.role.RoleManager;
 import android.app.smartspace.SmartspaceManager;
@@ -80,6 +81,7 @@
 import android.safetycenter.SafetyCenterManager;
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
+import android.service.vr.IVrManager;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
@@ -147,6 +149,13 @@
         return Optional.ofNullable(context.getSystemService(SystemUpdateManager.class));
     }
 
+    @Provides
+    @Nullable
+    @Singleton
+    static AmbientContextManager provideAmbientContextManager(Context context) {
+        return context.getSystemService(AmbientContextManager.class);
+    }
+
     /** */
     @Provides
     public AmbientDisplayConfiguration provideAmbientDisplayConfiguration(Context context) {
@@ -268,6 +277,13 @@
     @Provides
     @Singleton
     @Nullable
+    static IVrManager provideIVrManager() {
+        return IVrManager.Stub.asInterface(ServiceManager.getService(Context.VR_SERVICE));
+    }
+
+    @Provides
+    @Singleton
+    @Nullable
     static FaceManager provideFaceManager(Context context) {
         if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
             return context.getSystemService(FaceManager.class);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 68f4dbe..625a028 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -35,6 +35,8 @@
 import com.android.systemui.unfold.FoldStateLoggingProvider;
 import com.android.systemui.unfold.SysUIUnfoldComponent;
 import com.android.systemui.unfold.UnfoldLatencyTracker;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
 import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
 import com.android.wm.shell.TaskViewFactory;
 import com.android.wm.shell.back.BackAnimation;
@@ -137,6 +139,10 @@
         getUnfoldLatencyTracker().init();
         getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init);
         getFoldStateLogger().ifPresent(FoldStateLogger::init);
+        getUnfoldTransitionProgressProvider().ifPresent((progressProvider) ->
+                getUnfoldTransitionProgressForwarder().ifPresent((forwarder) ->
+                        progressProvider.addCallback(forwarder)
+                ));
     }
 
     /**
@@ -164,6 +170,18 @@
     UnfoldLatencyTracker getUnfoldLatencyTracker();
 
     /**
+     * Creates a UnfoldTransitionProgressProvider.
+     */
+    @SysUISingleton
+    Optional<UnfoldTransitionProgressProvider> getUnfoldTransitionProgressProvider();
+
+    /**
+     * Creates a UnfoldTransitionProgressForwarder.
+     */
+    @SysUISingleton
+    Optional<UnfoldTransitionProgressForwarder> getUnfoldTransitionProgressForwarder();
+
+    /**
      * Creates a FoldStateLoggingProvider.
      */
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemPropertiesFlagsModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemPropertiesFlagsModule.kt
new file mode 100644
index 0000000..c6f833b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemPropertiesFlagsModule.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.dagger
+
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags
+import dagger.Module
+import dagger.Provides
+
+/** A module which provides access to the default [SystemUiSystemPropertiesFlags.FlagResolver] */
+@Module
+object SystemPropertiesFlagsModule {
+    /** provide the default FlagResolver. */
+    @Provides
+    fun provideFlagResolver(): SystemUiSystemPropertiesFlags.FlagResolver =
+        SystemUiSystemPropertiesFlags.getResolver()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 45872f4..cbeff2b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -139,6 +139,7 @@
             DemoModeModule.class,
             FalsingModule.class,
             FlagsModule.class,
+            SystemPropertiesFlagsModule.class,
             FooterActionsModule.class,
             LogModule.class,
             MediaProjectionModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
index 102f208..055cd52 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
@@ -16,19 +16,23 @@
 
 package com.android.systemui.dreams;
 
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
+
 import android.util.Log;
 
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dreams.callbacks.DreamStatusBarStateCallback;
 import com.android.systemui.dreams.conditions.DreamCondition;
 import com.android.systemui.shared.condition.Monitor;
+import com.android.systemui.util.condition.ConditionalCoreStartable;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 /**
  * A {@link CoreStartable} to retain a monitor for tracking dreaming.
  */
-public class DreamMonitor implements CoreStartable {
+public class DreamMonitor extends ConditionalCoreStartable {
     private static final String TAG = "DreamMonitor";
 
     // We retain a reference to the monitor so it is not garbage-collected.
@@ -39,14 +43,17 @@
 
     @Inject
     public DreamMonitor(Monitor monitor, DreamCondition dreamCondition,
+            @Named(DREAM_PRETEXT_MONITOR) Monitor pretextMonitor,
             DreamStatusBarStateCallback callback) {
+        super(pretextMonitor);
         mConditionMonitor = monitor;
         mDreamCondition = dreamCondition;
         mCallback = callback;
 
     }
+
     @Override
-    public void start() {
+    protected void onStart() {
         if (Log.isLoggable(TAG, Log.DEBUG)) {
             Log.d(TAG, "started");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
index 87c5f51..a2dcdf5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayRegistrant.java
@@ -17,6 +17,7 @@
 package com.android.systemui.dreams;
 
 import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT;
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -33,8 +34,9 @@
 import android.service.dreams.IDreamManager;
 import android.util.Log;
 
-import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.shared.condition.Monitor;
+import com.android.systemui.util.condition.ConditionalCoreStartable;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -43,7 +45,7 @@
  * {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
  * the designated dream overlay component.
  */
-public class DreamOverlayRegistrant implements CoreStartable {
+public class DreamOverlayRegistrant extends ConditionalCoreStartable {
     private static final String TAG = "DreamOverlayRegistrant";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private final IDreamManager mDreamManager;
@@ -102,7 +104,9 @@
 
     @Inject
     public DreamOverlayRegistrant(Context context, @Main Resources resources,
-            @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent) {
+            @Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent,
+            @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+        super(monitor);
         mContext = context;
         mResources = resources;
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -111,7 +115,7 @@
     }
 
     @Override
-    public void start() {
+    protected void onStart() {
         final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
         filter.addDataScheme("package");
         filter.addDataSchemeSpecificPart(mOverlayServiceComponent.getPackageName(),
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java
index ee2f1af..244212b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationTypesUpdater.java
@@ -16,27 +16,31 @@
 
 package com.android.systemui.dreams.complication;
 
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
+
 import android.database.ContentObserver;
 import android.os.UserHandle;
 import android.provider.Settings;
 
 import com.android.settingslib.dream.DreamBackend;
-import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.shared.condition.Monitor;
+import com.android.systemui.util.condition.ConditionalCoreStartable;
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 /**
  * {@link ComplicationTypesUpdater} observes the state of available complication types set by the
  * user, and pushes updates to {@link DreamOverlayStateController}.
  */
 @SysUISingleton
-public class ComplicationTypesUpdater implements CoreStartable {
+public class ComplicationTypesUpdater extends ConditionalCoreStartable {
     private final DreamBackend mDreamBackend;
     private final Executor mExecutor;
     private final SecureSettings mSecureSettings;
@@ -48,7 +52,9 @@
             DreamBackend dreamBackend,
             @Main Executor executor,
             SecureSettings secureSettings,
-            DreamOverlayStateController dreamOverlayStateController) {
+            DreamOverlayStateController dreamOverlayStateController,
+            @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+        super(monitor);
         mDreamBackend = dreamBackend;
         mExecutor = executor;
         mSecureSettings = secureSettings;
@@ -56,7 +62,7 @@
     }
 
     @Override
-    public void start() {
+    public void onStart() {
         final ContentObserver settingsObserver = new ContentObserver(null /*handler*/) {
             @Override
             public void onChange(boolean selfChange) {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java
index 77e1fc9..bb1e6e2 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamClockTimeComplication.java
@@ -18,11 +18,14 @@
 
 import static com.android.systemui.dreams.complication.dagger.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_VIEW;
 import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS;
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
 
 import android.view.View;
 
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.shared.condition.Monitor;
+import com.android.systemui.util.condition.ConditionalCoreStartable;
 
 import javax.inject.Inject;
 import javax.inject.Named;
@@ -60,7 +63,7 @@
      * {@link CoreStartable} responsible for registering {@link DreamClockTimeComplication} with
      * SystemUI.
      */
-    public static class Registrant implements CoreStartable {
+    public static class Registrant extends ConditionalCoreStartable {
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final DreamClockTimeComplication mComplication;
 
@@ -70,13 +73,15 @@
         @Inject
         public Registrant(
                 DreamOverlayStateController dreamOverlayStateController,
-                DreamClockTimeComplication dreamClockTimeComplication) {
+                DreamClockTimeComplication dreamClockTimeComplication,
+                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+            super(monitor);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = dreamClockTimeComplication;
         }
 
         @Override
-        public void start() {
+        public void onStart() {
             mDreamOverlayStateController.addComplication(mComplication);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java
index 1065b94..7f395d8 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java
@@ -21,6 +21,7 @@
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE;
 import static com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent.DreamHomeControlsModule.DREAM_HOME_CONTROLS_CHIP_VIEW;
 import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS;
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
 
 import android.content.Context;
 import android.content.Intent;
@@ -42,7 +43,9 @@
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.ViewController;
+import com.android.systemui.util.condition.ConditionalCoreStartable;
 
 import java.util.List;
 
@@ -75,7 +78,7 @@
     /**
      * {@link CoreStartable} for registering the complication with SystemUI on startup.
      */
-    public static class Registrant implements CoreStartable {
+    public static class Registrant extends ConditionalCoreStartable {
         private final DreamHomeControlsComplication mComplication;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final ControlsComponent mControlsComponent;
@@ -105,14 +108,16 @@
         @Inject
         public Registrant(DreamHomeControlsComplication complication,
                 DreamOverlayStateController dreamOverlayStateController,
-                ControlsComponent controlsComponent) {
+                ControlsComponent controlsComponent,
+                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+            super(monitor);
             mComplication = complication;
             mControlsComponent = controlsComponent;
             mDreamOverlayStateController = dreamOverlayStateController;
         }
 
         @Override
-        public void start() {
+        public void onStart() {
             mControlsComponent.getControlsListingController().ifPresent(
                     c -> c.addCallback(mControlsCallback));
             mDreamOverlayStateController.addCallback(mOverlayStateCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
index c3aaf0c..e39073b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
@@ -17,6 +17,7 @@
 package com.android.systemui.dreams.complication;
 
 import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_SMARTSPACE_LAYOUT_PARAMS;
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
 
 import android.content.Context;
 import android.os.Parcelable;
@@ -28,6 +29,8 @@
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
+import com.android.systemui.shared.condition.Monitor;
+import com.android.systemui.util.condition.ConditionalCoreStartable;
 
 import java.util.List;
 
@@ -61,7 +64,7 @@
      * {@link CoreStartable} responsbile for registering {@link SmartSpaceComplication} with
      * SystemUI.
      */
-    public static class Registrant implements CoreStartable {
+    public static class Registrant extends ConditionalCoreStartable {
         private final DreamSmartspaceController mSmartSpaceController;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final SmartSpaceComplication mComplication;
@@ -81,14 +84,16 @@
         public Registrant(
                 DreamOverlayStateController dreamOverlayStateController,
                 SmartSpaceComplication smartSpaceComplication,
-                DreamSmartspaceController smartSpaceController) {
+                DreamSmartspaceController smartSpaceController,
+                @Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
+            super(monitor);
             mDreamOverlayStateController = dreamOverlayStateController;
             mComplication = smartSpaceComplication;
             mSmartSpaceController = smartSpaceController;
         }
 
         @Override
-        public void start() {
+        public void onStart() {
             mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() {
                 @Override
                 public void onStateChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index 7d8389a..3a37c6f 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -30,11 +30,18 @@
 import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
 import com.android.systemui.dreams.dreamcomplication.dagger.ComplicationComponent;
 import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule;
+import com.android.systemui.process.condition.UserProcessCondition;
+import com.android.systemui.shared.condition.Condition;
+import com.android.systemui.shared.condition.Monitor;
 
+import dagger.Binds;
 import dagger.Module;
 import dagger.Provides;
+import dagger.multibindings.IntoSet;
 
 import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Executor;
 
 import javax.inject.Named;
 
@@ -57,6 +64,8 @@
     String DREAM_OVERLAY_ENABLED = "dream_overlay_enabled";
 
     String DREAM_SUPPORTED = "dream_supported";
+    String DREAM_PRETEXT_CONDITIONS = "dream_pretext_conditions";
+    String DREAM_PRETEXT_MONITOR = "dream_prtext_monitor";
 
     /**
      * Provides the dream component
@@ -115,4 +124,19 @@
     static boolean providesDreamSupported(@Main Resources resources) {
         return resources.getBoolean(com.android.internal.R.bool.config_dreamsSupported);
     }
+
+    /** */
+    @Binds
+    @IntoSet
+    @Named(DREAM_PRETEXT_CONDITIONS)
+    Condition bindsUserProcessCondition(UserProcessCondition condition);
+
+    /** */
+    @Provides
+    @Named(DREAM_PRETEXT_MONITOR)
+    static Monitor providesDockerPretextMonitor(
+            @Main Executor executor,
+            @Named(DREAM_PRETEXT_CONDITIONS) Set<Condition> pretextConditions) {
+        return new Monitor(executor, pretextConditions);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index 61e4c32..5c310c3 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -41,7 +41,6 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.util.settings.GlobalSettings;
-import com.android.systemui.util.settings.SecureSettings;
 
 import org.jetbrains.annotations.NotNull;
 
@@ -75,7 +74,6 @@
     private final FlagManager mFlagManager;
     private final Context mContext;
     private final GlobalSettings mGlobalSettings;
-    private final SecureSettings mSecureSettings;
     private final Resources mResources;
     private final SystemPropertiesHelper mSystemProperties;
     private final ServerFlagReader mServerFlagReader;
@@ -88,8 +86,9 @@
     private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
             new ServerFlagReader.ChangeListener() {
                 @Override
-                public void onChange() {
-                    mRestarter.restartSystemUI();
+                public void onChange(Flag<?> flag) {
+                    mRestarter.restartSystemUI(
+                            "Server flag change: " + flag.getNamespace() + "." + flag.getName());
                 }
             };
 
@@ -98,7 +97,6 @@
             FlagManager flagManager,
             Context context,
             GlobalSettings globalSettings,
-            SecureSettings secureSettings,
             SystemPropertiesHelper systemProperties,
             @Main Resources resources,
             ServerFlagReader serverFlagReader,
@@ -107,7 +105,6 @@
         mFlagManager = flagManager;
         mContext = context;
         mGlobalSettings = globalSettings;
-        mSecureSettings = secureSettings;
         mResources = resources;
         mSystemProperties = systemProperties;
         mServerFlagReader = serverFlagReader;
@@ -120,7 +117,8 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(ACTION_SET_FLAG);
         filter.addAction(ACTION_GET_FLAGS);
-        mFlagManager.setOnSettingsChangedAction(this::restartSystemUI);
+        mFlagManager.setOnSettingsChangedAction(
+                suppressRestart -> restartSystemUI(suppressRestart, "Settings changed"));
         mFlagManager.setClearCacheAction(this::removeFromCache);
         mContext.registerReceiver(mReceiver, filter, null, null,
                 Context.RECEIVER_EXPORTED_UNAUDITED);
@@ -234,6 +232,10 @@
         Boolean result = readBooleanFlagOverride(flag.getName());
         if (result == null) {
             result = readBooleanFlagOverride(flag.getId());
+            if (result != null) {
+                // Move overrides from id to name
+                setFlagValueInternal(flag.getName(), result, BooleanFlagSerializer.INSTANCE);
+            }
         }
         boolean hasServerOverride = mServerFlagReader.hasOverride(
                 flag.getNamespace(), flag.getName());
@@ -306,25 +308,38 @@
         requireNonNull(value, "Cannot set a null value");
         T currentValue = readFlagValueInternal(name, serializer);
         if (Objects.equals(currentValue, value)) {
-            Log.i(TAG, "Flag id " + name + " is already " + value);
+            Log.i(TAG, "Flag \"" + name + "\" is already " + value);
             return;
         }
+        setFlagValueInternal(name, value, serializer);
+        Log.i(TAG, "Set flag \"" + name + "\" to " + value);
+        removeFromCache(name);
+        mFlagManager.dispatchListenersAndMaybeRestart(
+                name,
+                suppressRestart -> restartSystemUI(
+                        suppressRestart, "Flag \"" + name + "\" changed to " + value));
+    }
+
+    private <T> void setFlagValueInternal(
+            String name, @NonNull T value, FlagSerializer<T> serializer) {
         final String data = serializer.toSettingsData(value);
         if (data == null) {
-            Log.w(TAG, "Failed to set id " + name + " to " + value);
+            Log.w(TAG, "Failed to set flag " + name + " to " + value);
             return;
         }
         mGlobalSettings.putStringForUser(mFlagManager.nameToSettingsKey(name), data,
                 UserHandle.USER_CURRENT);
-        Log.i(TAG, "Set id " + name + " to " + value);
-        removeFromCache(name);
-        mFlagManager.dispatchListenersAndMaybeRestart(name, this::restartSystemUI);
     }
 
     <T> void eraseFlag(Flag<T> flag) {
         if (flag instanceof SysPropFlag) {
-            mSystemProperties.erase(((SysPropFlag<T>) flag).getName());
-            dispatchListenersAndMaybeRestart(flag.getName(), this::restartAndroid);
+            mSystemProperties.erase(flag.getName());
+            dispatchListenersAndMaybeRestart(
+                    flag.getName(),
+                    suppressRestart -> restartSystemUI(
+                            suppressRestart,
+                            "SysProp Flag \"" + flag.getNamespace() + "."
+                                    + flag.getName() + "\" reset to default."));
         } else {
             eraseFlag(flag.getName());
         }
@@ -334,7 +349,10 @@
     private void eraseFlag(String name) {
         eraseInternal(name);
         removeFromCache(name);
-        dispatchListenersAndMaybeRestart(name, this::restartSystemUI);
+        dispatchListenersAndMaybeRestart(
+                name,
+                suppressRestart -> restartSystemUI(
+                        suppressRestart, "Flag \"" + name + "\" reset to default"));
     }
 
     private void dispatchListenersAndMaybeRestart(String name, Consumer<Boolean> restartAction) {
@@ -368,20 +386,20 @@
         mFlagManager.removeListener(listener);
     }
 
-    private void restartSystemUI(boolean requestSuppress) {
+    private void restartSystemUI(boolean requestSuppress, String reason) {
         if (requestSuppress) {
             Log.i(TAG, "SystemUI Restart Suppressed");
             return;
         }
-        mRestarter.restartSystemUI();
+        mRestarter.restartSystemUI(reason);
     }
 
-    private void restartAndroid(boolean requestSuppress) {
+    private void restartAndroid(boolean requestSuppress, String reason) {
         if (requestSuppress) {
             Log.i(TAG, "Android Restart Suppressed");
             return;
         }
-        mRestarter.restartAndroid();
+        mRestarter.restartAndroid(reason);
     }
 
     void setBooleanFlagInternal(Flag<?> flag, boolean value) {
@@ -392,8 +410,11 @@
         } else if (flag instanceof SysPropBooleanFlag) {
             // Store SysProp flags in SystemProperties where they can read by outside parties.
             mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
-            dispatchListenersAndMaybeRestart(flag.getName(),
-                    FeatureFlagsDebug.this::restartAndroid);
+            dispatchListenersAndMaybeRestart(
+                    flag.getName(),
+                    suppressRestart -> restartSystemUI(
+                            suppressRestart,
+                            "Flag \"" + flag.getName() + "\" changed to " + value));
         } else {
             throw new IllegalArgumentException("Unknown flag type");
         }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt
index 069e612..a6956a4 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt
@@ -29,6 +29,7 @@
 ) : Restarter {
 
     private var androidRestartRequested = false
+    private var pendingReason = ""
 
     val observer =
         object : WakefulnessLifecycle.Observer {
@@ -38,18 +39,20 @@
             }
         }
 
-    override fun restartSystemUI() {
+    override fun restartSystemUI(reason: String) {
         Log.d(FeatureFlagsDebug.TAG, "SystemUI Restart requested. Restarting on next screen off.")
-        scheduleRestart()
+        Log.i(FeatureFlagsDebug.TAG, reason)
+        scheduleRestart(reason)
     }
 
-    override fun restartAndroid() {
+    override fun restartAndroid(reason: String) {
         Log.d(FeatureFlagsDebug.TAG, "Android Restart requested. Restarting on next screen off.")
         androidRestartRequested = true
-        scheduleRestart()
+        scheduleRestart(reason)
     }
 
-    fun scheduleRestart() {
+    fun scheduleRestart(reason: String) {
+        pendingReason = reason
         if (wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP) {
             restartNow()
         } else {
@@ -59,9 +62,9 @@
 
     private fun restartNow() {
         if (androidRestartRequested) {
-            systemExitRestarter.restartAndroid()
+            systemExitRestarter.restartAndroid(pendingReason)
         } else {
-            systemExitRestarter.restartSystemUI()
+            systemExitRestarter.restartSystemUI(pendingReason)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
index 7e14237..9859ff6 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
@@ -57,8 +57,9 @@
     private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
             new ServerFlagReader.ChangeListener() {
                 @Override
-                public void onChange() {
-                    mRestarter.restartSystemUI();
+                public void onChange(Flag<?> flag) {
+                    mRestarter.restartSystemUI(
+                            "Server flag change: " + flag.getNamespace() + "." + flag.getName());
                 }
             };
 
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt
index 7ff3876..c08266c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt
@@ -36,41 +36,43 @@
 ) : Restarter {
     var listenersAdded = false
     var pendingRestart: Runnable? = null
+    private var pendingReason = ""
     var androidRestartRequested = false
 
     val observer =
         object : WakefulnessLifecycle.Observer {
             override fun onFinishedGoingToSleep() {
-                scheduleRestart()
+                scheduleRestart(pendingReason)
             }
         }
 
     val batteryCallback =
         object : BatteryController.BatteryStateChangeCallback {
             override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
-                scheduleRestart()
+                scheduleRestart(pendingReason)
             }
         }
 
-    override fun restartSystemUI() {
+    override fun restartSystemUI(reason: String) {
         Log.d(
             FeatureFlagsDebug.TAG,
             "SystemUI Restart requested. Restarting when plugged in and idle."
         )
-        scheduleRestart()
+        scheduleRestart(reason)
     }
 
-    override fun restartAndroid() {
+    override fun restartAndroid(reason: String) {
         Log.d(
             FeatureFlagsDebug.TAG,
             "Android Restart requested. Restarting when plugged in and idle."
         )
         androidRestartRequested = true
-        scheduleRestart()
+        scheduleRestart(reason)
     }
 
-    private fun scheduleRestart() {
+    private fun scheduleRestart(reason: String) {
         // Don't bother adding listeners twice.
+        pendingReason = reason
         if (!listenersAdded) {
             listenersAdded = true
             wakefulnessLifecycle.addObserver(observer)
@@ -91,9 +93,9 @@
     private fun restartNow() {
         Log.d(FeatureFlagsRelease.TAG, "Restarting due to systemui flag change")
         if (androidRestartRequested) {
-            systemExitRestarter.restartAndroid()
+            systemExitRestarter.restartAndroid(pendingReason)
         } else {
-            systemExitRestarter.restartSystemUI()
+            systemExitRestarter.restartSystemUI(pendingReason)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 94101df..d5634e3 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -68,7 +68,7 @@
     @JvmField val DISABLE_FSI = unreleasedFlag(265804648, "disable_fsi")
 
     // TODO(b/254512538): Tracking Bug
-    val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply", teamfood = true)
+    val INSTANT_VOICE_REPLY = releasedFlag(111, "instant_voice_reply")
 
     // TODO(b/254512425): Tracking Bug
     val NOTIFICATION_MEMORY_MONITOR_ENABLED =
@@ -85,7 +85,7 @@
     // TODO(b/259217907)
     @JvmField
     val NOTIFICATION_GROUP_DISMISSAL_ANIMATION =
-        unreleasedFlag(259217907, "notification_group_dismissal_animation", teamfood = true)
+        releasedFlag(259217907, "notification_group_dismissal_animation")
 
     // TODO(b/257506350): Tracking Bug
     @JvmField val FSI_CHROME = unreleasedFlag(117, "fsi_chrome")
@@ -95,7 +95,7 @@
         unreleasedFlag(259395680, "simplified_appear_fraction", teamfood = true)
 
     // TODO(b/257315550): Tracking Bug
-    val NO_HUN_FOR_OLD_WHEN = unreleasedFlag(118, "no_hun_for_old_when", teamfood = true)
+    val NO_HUN_FOR_OLD_WHEN = releasedFlag(118, "no_hun_for_old_when")
 
     // TODO(b/260335638): Tracking Bug
     @JvmField
@@ -208,9 +208,7 @@
         unreleasedFlag(226, "enable_wallet_contextual_loyalty_cards", teamfood = false)
 
     // TODO(b/242908637): Tracking Bug
-    @JvmField
-    val WALLPAPER_FULLSCREEN_PREVIEW =
-        unreleasedFlag(227, "wallpaper_fullscreen_preview", teamfood = true)
+    @JvmField val WALLPAPER_FULLSCREEN_PREVIEW = releasedFlag(227, "wallpaper_fullscreen_preview")
 
     /** Whether the long-press gesture to open wallpaper picker is enabled. */
     // TODO(b/266242192): Tracking Bug
@@ -339,15 +337,13 @@
     @JvmField val UMO_TURBULENCE_NOISE = releasedFlag(909, "umo_turbulence_noise")
 
     // TODO(b/263272731): Tracking Bug
-    val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE =
-        unreleasedFlag(910, "media_ttt_receiver_success_ripple", teamfood = true)
+    val MEDIA_TTT_RECEIVER_SUCCESS_RIPPLE = releasedFlag(910, "media_ttt_receiver_success_ripple")
 
     // TODO(b/263512203): Tracking Bug
     val MEDIA_EXPLICIT_INDICATOR = releasedFlag(911, "media_explicit_indicator")
 
     // TODO(b/265813373): Tracking Bug
-    val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE =
-        unreleasedFlag(912, "media_ttt_dismiss_gesture", teamfood = true)
+    val MEDIA_TAP_TO_TRANSFER_DISMISS_GESTURE = releasedFlag(912, "media_ttt_dismiss_gesture")
 
     // TODO(b/266157412): Tracking Bug
     val MEDIA_RETAIN_SESSIONS = releasedFlag(913, "media_retain_sessions")
@@ -472,8 +468,7 @@
         sysPropBooleanFlag(1202, "persist.wm.debug.predictive_back_always_enforce", default = false)
 
     // TODO(b/254512728): Tracking Bug
-    @JvmField
-    val NEW_BACK_AFFORDANCE = unreleasedFlag(1203, "new_back_affordance", teamfood = false)
+    @JvmField val NEW_BACK_AFFORDANCE = releasedFlag(1203, "new_back_affordance")
 
     // TODO(b/255854141): Tracking Bug
     @JvmField
@@ -492,7 +487,7 @@
     // TODO(b/238475428): Tracking Bug
     @JvmField
     val WM_SHADE_ALLOW_BACK_GESTURE =
-        unreleasedFlag(1207, "persist.wm.debug.shade_allow_back_gesture", teamfood = false)
+        sysPropBooleanFlag(1207, "persist.wm.debug.shade_allow_back_gesture", default = false)
 
     // TODO(b/238475428): Tracking Bug
     @JvmField
@@ -507,14 +502,21 @@
     // 1300 - screenshots
     // TODO(b/254513155): Tracking Bug
     @JvmField
-    val SCREENSHOT_WORK_PROFILE_POLICY =
-        unreleasedFlag(1301, "screenshot_work_profile_policy", teamfood = true)
+    val SCREENSHOT_WORK_PROFILE_POLICY = releasedFlag(1301, "screenshot_work_profile_policy")
 
     // TODO(b/264916608): Tracking Bug
-    @JvmField val SCREENSHOT_METADATA = unreleasedFlag(1302, "screenshot_metadata")
+    @JvmField val SCREENSHOT_METADATA = unreleasedFlag(1302, "screenshot_metadata", teamfood = true)
 
     // TODO(b/266955521): Tracking bug
-    @JvmField val SCREENSHOT_DETECTION = unreleasedFlag(1303, "screenshot_detection")
+    @JvmField val SCREENSHOT_DETECTION = releasedFlag(1303, "screenshot_detection")
+
+    // TODO(b/251205791): Tracking Bug
+    @JvmField val SCREENSHOT_APP_CLIPS = releasedFlag(1304, "screenshot_app_clips")
+
+    // TODO(b/268484562): Tracking bug
+    @JvmField
+    val SCREENSHOT_METADATA_REFACTOR =
+        unreleasedFlag(1305, "screenshot_metadata_refactor", teamfood = true)
 
     // 1400 - columbus
     // TODO(b/254512756): Tracking Bug
@@ -526,16 +528,20 @@
 
     // 1500 - chooser aka sharesheet
     // TODO(b/254512507): Tracking Bug
-    val CHOOSER_UNBUNDLED = unreleasedFlag(1500, "chooser_unbundled", teamfood = true)
+    val CHOOSER_UNBUNDLED = releasedFlag(1500, "chooser_unbundled")
 
     // TODO(b/266983432) Tracking Bug
-    val SHARESHEET_CUSTOM_ACTIONS = unreleasedFlag(1501, "sharesheet_custom_actions")
+    val SHARESHEET_CUSTOM_ACTIONS = releasedFlag(1501, "sharesheet_custom_actions")
 
     // TODO(b/266982749) Tracking Bug
-    val SHARESHEET_RESELECTION_ACTION = unreleasedFlag(1502, "sharesheet_reselection_action")
+    val SHARESHEET_RESELECTION_ACTION = releasedFlag(1502, "sharesheet_reselection_action")
 
     // TODO(b/266983474) Tracking Bug
-    val SHARESHEET_IMAGE_AND_TEXT_PREVIEW = unreleasedFlag(1503, "sharesheet_image_text_preview")
+    val SHARESHEET_IMAGE_AND_TEXT_PREVIEW = releasedFlag(1503, "sharesheet_image_text_preview")
+
+    // TODO(b/267355521) Tracking Bug
+    val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW =
+        releasedFlag(1504, "sharesheet_scrollable_image_preview")
 
     // 1700 - clipboard
     @JvmField val CLIPBOARD_REMOTE_BEHAVIOR = releasedFlag(1701, "clipboard_remote_behavior")
@@ -549,7 +555,7 @@
     @JvmField val DUAL_SHADE = releasedFlag(1801, "dual_shade")
 
     // 1900
-    @JvmField val NOTE_TASKS = unreleasedFlag(1900, "keycode_flag")
+    @JvmField val NOTE_TASKS = releasedFlag(1900, "keycode_flag")
 
     // 2000 - device controls
     @Keep @JvmField val USE_APP_PANELS = releasedFlag(2000, "use_app_panels", teamfood = true)
@@ -571,10 +577,14 @@
     @JvmField val UDFPS_ELLIPSE_DETECTION = releasedFlag(2201, "udfps_ellipse_detection")
 
     // 2300 - stylus
-    @JvmField val TRACK_STYLUS_EVER_USED = unreleasedFlag(2300, "track_stylus_ever_used")
-    @JvmField val ENABLE_STYLUS_CHARGING_UI = unreleasedFlag(2301, "enable_stylus_charging_ui")
     @JvmField
-    val ENABLE_USI_BATTERY_NOTIFICATIONS = unreleasedFlag(2302, "enable_usi_battery_notifications")
+    val TRACK_STYLUS_EVER_USED = unreleasedFlag(2300, "track_stylus_ever_used", teamfood = true)
+    @JvmField
+    val ENABLE_STYLUS_CHARGING_UI =
+        unreleasedFlag(2301, "enable_stylus_charging_ui", teamfood = true)
+    @JvmField
+    val ENABLE_USI_BATTERY_NOTIFICATIONS =
+        unreleasedFlag(2302, "enable_usi_battery_notifications", teamfood = true)
     @JvmField val ENABLE_STYLUS_EDUCATION = unreleasedFlag(2303, "enable_stylus_education")
 
     // 2400 - performance tools and debugging info
@@ -586,12 +596,11 @@
     // 2500 - output switcher
     // TODO(b/261538825): Tracking Bug
     @JvmField
-    val OUTPUT_SWITCHER_ADVANCED_LAYOUT = unreleasedFlag(2500, "output_switcher_advanced_layout")
+    val OUTPUT_SWITCHER_ADVANCED_LAYOUT = releasedFlag(2500, "output_switcher_advanced_layout")
     @JvmField
-    val OUTPUT_SWITCHER_ROUTES_PROCESSING =
-        unreleasedFlag(2501, "output_switcher_routes_processing")
+    val OUTPUT_SWITCHER_ROUTES_PROCESSING = releasedFlag(2501, "output_switcher_routes_processing")
     @JvmField
-    val OUTPUT_SWITCHER_DEVICE_STATUS = unreleasedFlag(2502, "output_switcher_device_status")
+    val OUTPUT_SWITCHER_DEVICE_STATUS = releasedFlag(2502, "output_switcher_device_status")
 
     // TODO(b/20911786): Tracking Bug
     @JvmField
@@ -608,7 +617,11 @@
     // TODO(b259590361): Tracking bug
     val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release")
 
-    // 2600 - keyboard shortcut
+    // 2600 - keyboard
     // TODO(b/259352579): Tracking Bug
     @JvmField val SHORTCUT_LIST_SEARCH_LAYOUT = unreleasedFlag(2600, "shortcut_list_search_layout")
+
+    // TODO(b/259428678): Tracking Bug
+    @JvmField
+    val KEYBOARD_BACKLIGHT_INDICATOR = unreleasedFlag(2601, "keyboard_backlight_indicator")
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt b/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt
index ce8b821..9c67795 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt
@@ -16,7 +16,7 @@
 package com.android.systemui.flags
 
 interface Restarter {
-    fun restartSystemUI()
+    fun restartSystemUI(reason: String)
 
-    fun restartAndroid()
+    fun restartAndroid(reason: String)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
index a02b795..e225b10 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
@@ -17,8 +17,10 @@
 package com.android.systemui.flags
 
 import android.provider.DeviceConfig
+import android.util.Log
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.TestHarness
 import com.android.systemui.util.DeviceConfigProxy
 import dagger.Module
 import dagger.Provides
@@ -35,21 +37,27 @@
     fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
 
     interface ChangeListener {
-        fun onChange()
+        fun onChange(flag: Flag<*>)
     }
 }
 
 class ServerFlagReaderImpl @Inject constructor(
     private val namespace: String,
     private val deviceConfig: DeviceConfigProxy,
-    @Background private val executor: Executor
+    @Background private val executor: Executor,
+    @TestHarness private val isTestHarness: Boolean
 ) : ServerFlagReader {
 
+    private val TAG = "ServerFlagReader"
+
     private val listeners =
         mutableListOf<Pair<ServerFlagReader.ChangeListener, Collection<Flag<*>>>>()
 
     private val onPropertiesChangedListener = object : DeviceConfig.OnPropertiesChangedListener {
         override fun onPropertiesChanged(properties: DeviceConfig.Properties) {
+            if (isTestHarness) {
+                Log.w(TAG, "Ignore server flag changes in Test Harness mode.")
+            }
             if (properties.namespace != namespace) {
                 return
             }
@@ -59,7 +67,7 @@
                 propLoop@ for (propName in properties.keyset) {
                     for (flag in flags) {
                         if (propName == getServerOverrideName(flag.id) || propName == flag.name) {
-                            listener.onChange()
+                            listener.onChange(flag)
                             break@propLoop
                         }
                     }
@@ -111,10 +119,11 @@
         @SysUISingleton
         fun bindsReader(
             deviceConfig: DeviceConfigProxy,
-            @Background executor: Executor
+            @Background executor: Executor,
+            @TestHarness isTestHarness: Boolean
         ): ServerFlagReader {
             return ServerFlagReaderImpl(
-                SYSUI_NAMESPACE, deviceConfig, executor
+                SYSUI_NAMESPACE, deviceConfig, executor, isTestHarness
             )
         }
     }
@@ -139,7 +148,7 @@
         for ((listener, flags) in listeners) {
             flagLoop@ for (flag in flags) {
                 if (name == flag.name) {
-                    listener.onChange()
+                    listener.onChange(flag)
                     break@flagLoop
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt
index 89daa64..46e28a7 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.flags
 
+import android.util.Log
 import com.android.internal.statusbar.IStatusBarService
 import javax.inject.Inject
 
@@ -24,11 +25,13 @@
 constructor(
     private val barService: IStatusBarService,
 ) : Restarter {
-    override fun restartAndroid() {
+    override fun restartAndroid(reason: String) {
+        Log.d(FeatureFlagsDebug.TAG, "Restarting Android: " + reason)
         barService.restart()
     }
 
-    override fun restartSystemUI() {
+    override fun restartSystemUI(reason: String) {
+        Log.d(FeatureFlagsDebug.TAG, "Restarting SystemUI: " + reason)
         System.exit(0)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index 9b2e6b8..d3fe2c5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -24,6 +24,7 @@
 
 import androidx.annotation.IntDef;
 
+import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -64,6 +65,7 @@
             2000L + KeyguardIndicationTextView.Y_IN_DURATION;
 
     private final StatusBarStateController mStatusBarStateController;
+    private final KeyguardLogger mLogger;
     private final float mMaxAlpha;
     private final ColorStateList mInitialTextColorState;
 
@@ -85,7 +87,8 @@
     public KeyguardIndicationRotateTextViewController(
             KeyguardIndicationTextView view,
             @Main DelayableExecutor executor,
-            StatusBarStateController statusBarStateController
+            StatusBarStateController statusBarStateController,
+            KeyguardLogger logger
     ) {
         super(view);
         mMaxAlpha = view.getAlpha();
@@ -93,6 +96,7 @@
         mInitialTextColorState = mView != null
                 ? mView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
         mStatusBarStateController = statusBarStateController;
+        mLogger = logger;
         init();
     }
 
@@ -259,6 +263,8 @@
         mLastIndicationSwitch = SystemClock.uptimeMillis();
         if (!TextUtils.equals(previousMessage, mCurrMessage)
                 || previousIndicationType != mCurrIndicationType) {
+            mLogger.logKeyguardSwitchIndication(type,
+                    mCurrMessage != null ? mCurrMessage.toString() : null);
             mView.switchIndication(mIndicationMessages.get(type));
         }
 
@@ -352,9 +358,10 @@
     @Override
     public void dump(PrintWriter pw, String[] args) {
         pw.println("KeyguardIndicationRotatingTextViewController:");
-        pw.println("    currentMessage=" + mView.getText());
+        pw.println("    currentTextViewMessage=" + mView.getText());
+        pw.println("    currentStoredMessage=" + mView.getMessage());
         pw.println("    dozing:" + mIsDozing);
-        pw.println("    queue:" + mIndicationQueue.toString());
+        pw.println("    queue:" + mIndicationQueue);
         pw.println("    showNextIndicationRunnable:" + mShowNextIndicationRunnable);
 
         if (hasIndications()) {
@@ -398,4 +405,40 @@
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface IndicationType{}
+
+    /**
+     * Get human-readable string representation of the indication type.
+     */
+    public static String indicationTypeToString(@IndicationType int type) {
+        switch (type) {
+            case INDICATION_TYPE_NONE:
+                return "none";
+            case INDICATION_TYPE_DISCLOSURE:
+                return "disclosure";
+            case INDICATION_TYPE_OWNER_INFO:
+                return "owner_info";
+            case INDICATION_TYPE_LOGOUT:
+                return "logout";
+            case INDICATION_TYPE_BATTERY:
+                return "battery";
+            case INDICATION_TYPE_ALIGNMENT:
+                return "alignment";
+            case INDICATION_TYPE_TRANSIENT:
+                return "transient";
+            case INDICATION_TYPE_TRUST:
+                return "trust";
+            case INDICATION_TYPE_PERSISTENT_UNLOCK_MESSAGE:
+                return "persistent_unlock_message";
+            case INDICATION_TYPE_USER_LOCKED:
+                return "user_locked";
+            case INDICATION_TYPE_REVERSE_CHARGING:
+                return "reverse_charging";
+            case INDICATION_TYPE_BIOMETRIC_MESSAGE:
+                return "biometric_message";
+            case INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP:
+                return "biometric_message_followup";
+            default:
+                return "unknown[" + type + "]";
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 0dbc930..c5ea241 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2442,15 +2442,28 @@
         }
         mKeyguardDisplayManager.show();
 
-        // schedule 4hr idle timeout after which non-strong biometrics (i.e. weak or convenience
-        // biometric) can't be used to unlock device until unlocking with strong biometric or
-        // primary auth (i.e. PIN/pattern/password)
-        mLockPatternUtils.scheduleNonStrongBiometricIdleTimeout(
-                KeyguardUpdateMonitor.getCurrentUser());
+        scheduleNonStrongBiometricIdleTimeout();
 
         Trace.endSection();
     }
 
+    /**
+     * Schedule 4-hour idle timeout for non-strong biometrics when the device is locked
+     */
+    private void scheduleNonStrongBiometricIdleTimeout() {
+        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+        // If unlocking with non-strong (i.e. weak or convenience) biometrics is possible, schedule
+        // 4hr idle timeout after which non-strong biometrics can't be used to unlock device until
+        // unlocking with strong biometric or primary auth (i.e. PIN/pattern/password)
+        if (mUpdateMonitor.isUnlockingWithNonStrongBiometricsPossible(currentUser)) {
+            if (DEBUG) {
+                Log.d(TAG, "scheduleNonStrongBiometricIdleTimeout: schedule an alarm for "
+                        + "currentUser=" + currentUser);
+            }
+            mLockPatternUtils.scheduleNonStrongBiometricIdleTimeout(currentUser);
+        }
+    }
+
     private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
         @Override
         public void run() {
@@ -2934,6 +2947,8 @@
             if (DEBUG) Log.d(TAG, "handleReset");
             mKeyguardViewControllerLazy.get().reset(true /* hideBouncerWhenShowing */);
         }
+
+        scheduleNonStrongBiometricIdleTimeout();
     }
 
     /**
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 0af596a..baadc66 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
@@ -20,9 +20,12 @@
 import android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
 import android.content.Context
 import android.content.IntentFilter
+import android.hardware.biometrics.BiometricManager
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback
 import android.os.Looper
 import android.os.UserHandle
 import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.Dumpable
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -31,7 +34,9 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.user.data.repository.UserRepository
+import java.io.PrintWriter
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -39,10 +44,12 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.transformLatest
 
@@ -57,6 +64,15 @@
     /** Whether any fingerprints are enrolled for the current user. */
     val isFingerprintEnrolled: StateFlow<Boolean>
 
+    /** Whether face authentication is enrolled for the current user. */
+    val isFaceEnrolled: Flow<Boolean>
+
+    /**
+     * Whether face authentication is enabled/disabled based on system settings like device policy,
+     * biometrics setting.
+     */
+    val isFaceAuthenticationEnabled: Flow<Boolean>
+
     /**
      * Whether the current user is allowed to use a strong biometric for device entry based on
      * Android Security policies. If false, the user may be able to use primary authentication for
@@ -80,16 +96,34 @@
     devicePolicyManager: DevicePolicyManager,
     @Application scope: CoroutineScope,
     @Background backgroundDispatcher: CoroutineDispatcher,
+    biometricManager: BiometricManager?,
     @Main looper: Looper,
-) : BiometricSettingsRepository {
+    dumpManager: DumpManager,
+) : BiometricSettingsRepository, Dumpable {
+
+    init {
+        dumpManager.registerDumpable(this)
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<String?>) {
+        pw.println("isFingerprintEnrolled=${isFingerprintEnrolled.value}")
+        pw.println("isStrongBiometricAllowed=${isStrongBiometricAllowed.value}")
+        pw.println("isFingerprintEnabledByDevicePolicy=${isFingerprintEnabledByDevicePolicy.value}")
+    }
 
     /** UserId of the current selected user. */
     private val selectedUserId: Flow<Int> =
         userRepository.selectedUserInfo.map { it.id }.distinctUntilChanged()
 
+    private val devicePolicyChangedForAllUsers =
+        broadcastDispatcher.broadcastFlow(
+            filter = IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+            user = UserHandle.ALL
+        )
+
     override val isFingerprintEnrolled: StateFlow<Boolean> =
         selectedUserId
-            .flatMapLatest {
+            .flatMapLatest { currentUserId ->
                 conflatedCallbackFlow {
                     val callback =
                         object : AuthController.Callback {
@@ -98,7 +132,7 @@
                                 userId: Int,
                                 hasEnrollments: Boolean
                             ) {
-                                if (sensorBiometricType.isFingerprint) {
+                                if (sensorBiometricType.isFingerprint && userId == currentUserId) {
                                     trySendWithFailureLogging(
                                         hasEnrollments,
                                         TAG,
@@ -118,6 +152,77 @@
                     authController.isFingerprintEnrolled(userRepository.getSelectedUserInfo().id)
             )
 
+    override val isFaceEnrolled: Flow<Boolean> =
+        selectedUserId.flatMapLatest { selectedUserId: Int ->
+            conflatedCallbackFlow {
+                val callback =
+                    object : AuthController.Callback {
+                        override fun onEnrollmentsChanged(
+                            sensorBiometricType: BiometricType,
+                            userId: Int,
+                            hasEnrollments: Boolean
+                        ) {
+                            // TODO(b/242022358), use authController.isFaceAuthEnrolled after
+                            //  ag/20176811 is available.
+                            if (
+                                sensorBiometricType == BiometricType.FACE &&
+                                    userId == selectedUserId
+                            ) {
+                                trySendWithFailureLogging(
+                                    hasEnrollments,
+                                    TAG,
+                                    "Face enrollment changed"
+                                )
+                            }
+                        }
+                    }
+                authController.addCallback(callback)
+                trySendWithFailureLogging(
+                    authController.isFaceAuthEnrolled(selectedUserId),
+                    TAG,
+                    "Initial value of face auth enrollment"
+                )
+                awaitClose { authController.removeCallback(callback) }
+            }
+        }
+
+    override val isFaceAuthenticationEnabled: Flow<Boolean>
+        get() =
+            combine(isFaceEnabledByBiometricsManager, isFaceEnabledByDevicePolicy) {
+                biometricsManagerSetting,
+                devicePolicySetting ->
+                biometricsManagerSetting && devicePolicySetting
+            }
+
+    private val isFaceEnabledByDevicePolicy: Flow<Boolean> =
+        combine(selectedUserId, devicePolicyChangedForAllUsers) { userId, _ ->
+                devicePolicyManager.isFaceDisabled(userId)
+            }
+            .onStart {
+                emit(devicePolicyManager.isFaceDisabled(userRepository.getSelectedUserInfo().id))
+            }
+            .flowOn(backgroundDispatcher)
+            .distinctUntilChanged()
+
+    private val isFaceEnabledByBiometricsManager =
+        conflatedCallbackFlow {
+                val callback =
+                    object : IBiometricEnabledOnKeyguardCallback.Stub() {
+                        override fun onChanged(enabled: Boolean, userId: Int) {
+                            trySendWithFailureLogging(
+                                enabled,
+                                TAG,
+                                "biometricsEnabled state changed"
+                            )
+                        }
+                    }
+                biometricManager?.registerEnabledOnKeyguardCallback(callback)
+                awaitClose {}
+            }
+            // This is because the callback is binder-based and we want to avoid multiple callbacks
+            // being registered.
+            .stateIn(scope, SharingStarted.Eagerly, false)
+
     override val isStrongBiometricAllowed: StateFlow<Boolean> =
         selectedUserId
             .flatMapLatest { currUserId ->
@@ -155,17 +260,8 @@
     override val isFingerprintEnabledByDevicePolicy: StateFlow<Boolean> =
         selectedUserId
             .flatMapLatest { userId ->
-                broadcastDispatcher
-                    .broadcastFlow(
-                        filter = IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
-                        user = UserHandle.ALL
-                    )
-                    .transformLatest {
-                        emit(
-                            (devicePolicyManager.getKeyguardDisabledFeatures(null, userId) and
-                                DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) == 0
-                        )
-                    }
+                devicePolicyChangedForAllUsers
+                    .transformLatest { emit(devicePolicyManager.isFingerprintDisabled(userId)) }
                     .flowOn(backgroundDispatcher)
                     .distinctUntilChanged()
             }
@@ -173,13 +269,21 @@
                 scope,
                 started = SharingStarted.Eagerly,
                 initialValue =
-                    devicePolicyManager.getKeyguardDisabledFeatures(
-                        null,
+                    devicePolicyManager.isFingerprintDisabled(
                         userRepository.getSelectedUserInfo().id
-                    ) and DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT == 0
+                    )
             )
 
     companion object {
         private const val TAG = "BiometricsRepositoryImpl"
     }
 }
+
+private fun DevicePolicyManager.isFaceDisabled(userId: Int): Boolean =
+    isNotActive(userId, DevicePolicyManager.KEYGUARD_DISABLE_FACE)
+
+private fun DevicePolicyManager.isFingerprintDisabled(userId: Int): Boolean =
+    isNotActive(userId, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT)
+
+private fun DevicePolicyManager.isNotActive(userId: Int, policy: Int): Boolean =
+    (getKeyguardDisabledFeatures(null, userId) and policy) == 0
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt
index b3a9cf5..7c46684 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepository.kt
@@ -19,10 +19,13 @@
 import android.hardware.biometrics.BiometricSourceType
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.Dumpable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dump.DumpManager
+import java.io.PrintWriter
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.channels.awaitClose
@@ -49,7 +52,16 @@
 constructor(
     val keyguardUpdateMonitor: KeyguardUpdateMonitor,
     @Application scope: CoroutineScope,
-) : DeviceEntryFingerprintAuthRepository {
+    dumpManager: DumpManager,
+) : DeviceEntryFingerprintAuthRepository, Dumpable {
+
+    init {
+        dumpManager.registerDumpable(this)
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<String?>) {
+        pw.println("isLockedOut=${isLockedOut.value}")
+    }
 
     override val isLockedOut: StateFlow<Boolean> =
         conflatedCallbackFlow {
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 7bc6c34..091acad 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
@@ -162,7 +162,7 @@
     private val _isAlternateBouncerVisible = MutableStateFlow(false)
     override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
     override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
-    private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
+    private val _isAlternateBouncerUIAvailable = MutableStateFlow(false)
     override val isAlternateBouncerUIAvailable: StateFlow<Boolean> =
         _isAlternateBouncerUIAvailable.asStateFlow()
 
@@ -290,6 +290,9 @@
         resourceUpdateRequests
             .logDiffsForTable(buffer, "", "ResourceUpdateRequests", false)
             .launchIn(applicationScope)
+        isAlternateBouncerUIAvailable
+            .logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false)
+            .launchIn(applicationScope)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 81a5828..8715d1f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -34,6 +34,7 @@
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.launch
 
@@ -56,9 +57,14 @@
 
     private fun listenForDreamingToLockscreen() {
         scope.launch {
-            // Using isDreamingWithOverlay provides an optimized path to LOCKSCREEN state, which
-            // otherwise would have gone through OCCLUDED first
-            keyguardInteractor.isAbleToDream
+            // Dependending on the dream, either dream state or occluded change will change first,
+            // so listen for both
+            combine(keyguardInteractor.isAbleToDream, keyguardInteractor.isKeyguardOccluded) {
+                    isAbleToDream,
+                    isKeyguardOccluded ->
+                    isAbleToDream && isKeyguardOccluded
+                }
+                .distinctUntilChanged()
                 .sample(
                     combine(
                         keyguardInteractor.dozeTransitionModel,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 3d39da6..7e86a5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -22,6 +22,8 @@
 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.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
 import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
@@ -31,7 +33,6 @@
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.model.WakefulnessModel
 import com.android.systemui.statusbar.CommandQueue
-import com.android.systemui.statusbar.CommandQueue.Callbacks
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.delay
@@ -41,7 +42,9 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onStart
 
 /**
  * Encapsulates business-logic related to the keyguard but not to a more specific part within it.
@@ -52,6 +55,7 @@
 constructor(
     private val repository: KeyguardRepository,
     private val commandQueue: CommandQueue,
+    featureFlags: FeatureFlags,
 ) {
     /**
      * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -129,6 +133,29 @@
      */
     val biometricUnlockState: Flow<BiometricUnlockModel> = repository.biometricUnlockState
 
+    /** Keyguard is present and is not occluded. */
+    val isKeyguardVisible: Flow<Boolean> =
+        combine(isKeyguardShowing, isKeyguardOccluded) { showing, occluded -> showing && !occluded }
+
+    /** Whether camera is launched over keyguard. */
+    var isSecureCameraActive =
+        if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) {
+            combine(
+                    isKeyguardVisible,
+                    repository.isBouncerShowing,
+                    onCameraLaunchDetected,
+                ) { isKeyguardVisible, isBouncerShowing, cameraLaunchEvent ->
+                    when {
+                        isKeyguardVisible -> false
+                        isBouncerShowing -> false
+                        else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP
+                    }
+                }
+                .onStart { emit(false) }
+        } else {
+            flowOf(false)
+        }
+
     /** The approximate location on the screen of the fingerprint sensor, if one is available. */
     val fingerprintSensorLocation: Flow<Point?> = repository.fingerprintSensorLocation
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 53c80f6..84bcdf9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -42,6 +42,10 @@
 constructor(
     repository: KeyguardTransitionRepository,
 ) {
+    /** (any)->GONE transition information */
+    val anyStateToGoneTransition: Flow<TransitionStep> =
+        repository.transitions.filter { step -> step.to == KeyguardState.GONE }
+
     /** (any)->AOD transition information */
     val anyStateToAodTransition: Flow<TransitionStep> =
         repository.transitions.filter { step -> step.to == KeyguardState.AOD }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
index 8222dd5..3b3ec39 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
@@ -26,4 +26,10 @@
     const val EXPANSION_HIDDEN = 1f
     const val EXPANSION_VISIBLE = 0f
     const val ALPHA_EXPANSION_THRESHOLD = 0.95f
+
+    /**
+     * This value is used for denoting the PIN length at which we want to layout the view in which
+     * PIN hinting is enabled
+     */
+    const val DEFAULT_PIN_LENGTH = 6
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 3319f9d..ab009f4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -381,82 +381,87 @@
             return when (event?.actionMasked) {
                 MotionEvent.ACTION_DOWN ->
                     if (viewModel.configKey != null) {
-                        longPressAnimator =
-                            view
-                                .animate()
-                                .scaleX(PRESSED_SCALE)
-                                .scaleY(PRESSED_SCALE)
-                                .setDuration(longPressDurationMs)
-                                .withEndAction {
-                                    view.setOnClickListener {
-                                        vibratorHelper?.vibrate(
-                                            if (viewModel.isActivated) {
-                                                Vibrations.Activated
-                                            } else {
-                                                Vibrations.Deactivated
-                                            }
-                                        )
-                                        viewModel.onClicked(
-                                            KeyguardQuickAffordanceViewModel.OnClickedParameters(
-                                                configKey = viewModel.configKey,
-                                                expandable = Expandable.fromView(view),
-                                            )
-                                        )
+                        if (isUsingAccurateTool(event)) {
+                            // For accurate tool types (stylus, mouse, etc.), we don't require a
+                            // long-press.
+                        } else {
+                            // When not using a stylus, we require a long-press to activate the
+                            // quick affordance, mostly to do "falsing" (e.g. protect from false
+                            // clicks in the pocket/bag).
+                            longPressAnimator =
+                                view
+                                    .animate()
+                                    .scaleX(PRESSED_SCALE)
+                                    .scaleY(PRESSED_SCALE)
+                                    .setDuration(longPressDurationMs)
+                                    .withEndAction {
+                                        dispatchClick(viewModel.configKey)
+                                        cancel()
                                     }
-                                    view.performClick()
-                                    view.setOnClickListener(null)
-                                    cancel()
-                                }
+                        }
                         true
                     } else {
                         false
                     }
                 MotionEvent.ACTION_MOVE -> {
-                    if (event.historySize > 0) {
-                        val distance =
-                            sqrt(
-                                (event.y - event.getHistoricalY(0)).pow(2) +
-                                    (event.x - event.getHistoricalX(0)).pow(2)
-                            )
-                        if (distance > ViewConfiguration.getTouchSlop()) {
+                    if (!isUsingAccurateTool(event)) {
+                        // Moving too far while performing a long-press gesture cancels that
+                        // gesture.
+                        val distanceMoved = distanceMoved(event)
+                        if (distanceMoved > ViewConfiguration.getTouchSlop()) {
                             cancel()
                         }
                     }
                     true
                 }
                 MotionEvent.ACTION_UP -> {
-                    cancel(
-                        onAnimationEnd =
-                            if (event.eventTime - event.downTime < longPressDurationMs) {
-                                Runnable {
-                                    messageDisplayer.invoke(
-                                        R.string.keyguard_affordance_press_too_short
-                                    )
-                                    val amplitude =
-                                        view.context.resources
-                                            .getDimensionPixelSize(
-                                                R.dimen.keyguard_affordance_shake_amplitude
-                                            )
-                                            .toFloat()
-                                    val shakeAnimator =
-                                        ObjectAnimator.ofFloat(
-                                            view,
-                                            "translationX",
-                                            -amplitude / 2,
-                                            amplitude / 2,
+                    if (isUsingAccurateTool(event)) {
+                        // When using an accurate tool type (stylus, mouse, etc.), we don't require
+                        // a long-press gesture to activate the quick affordance. Therefore, lifting
+                        // the pointer performs a click.
+                        if (
+                            viewModel.configKey != null &&
+                                distanceMoved(event) <= ViewConfiguration.getTouchSlop()
+                        ) {
+                            dispatchClick(viewModel.configKey)
+                        }
+                    } else {
+                        // When not using a stylus, lifting the finger/pointer will actually cancel
+                        // the long-press gesture. Calling cancel after the quick affordance was
+                        // already long-press activated is a no-op, so it's safe to call from here.
+                        cancel(
+                            onAnimationEnd =
+                                if (event.eventTime - event.downTime < longPressDurationMs) {
+                                    Runnable {
+                                        messageDisplayer.invoke(
+                                            R.string.keyguard_affordance_press_too_short
                                         )
-                                    shakeAnimator.duration =
-                                        ShakeAnimationDuration.inWholeMilliseconds
-                                    shakeAnimator.interpolator =
-                                        CycleInterpolator(ShakeAnimationCycles)
-                                    shakeAnimator.start()
+                                        val amplitude =
+                                            view.context.resources
+                                                .getDimensionPixelSize(
+                                                    R.dimen.keyguard_affordance_shake_amplitude
+                                                )
+                                                .toFloat()
+                                        val shakeAnimator =
+                                            ObjectAnimator.ofFloat(
+                                                view,
+                                                "translationX",
+                                                -amplitude / 2,
+                                                amplitude / 2,
+                                            )
+                                        shakeAnimator.duration =
+                                            ShakeAnimationDuration.inWholeMilliseconds
+                                        shakeAnimator.interpolator =
+                                            CycleInterpolator(ShakeAnimationCycles)
+                                        shakeAnimator.start()
 
-                                    vibratorHelper?.vibrate(Vibrations.Shake)
+                                        vibratorHelper?.vibrate(Vibrations.Shake)
+                                    }
+                                } else {
+                                    null
                                 }
-                            } else {
-                                null
-                            }
-                    )
+                        )
+                    }
                     true
                 }
                 MotionEvent.ACTION_CANCEL -> {
@@ -467,6 +472,28 @@
             }
         }
 
+        private fun dispatchClick(
+            configKey: String,
+        ) {
+            view.setOnClickListener {
+                vibratorHelper?.vibrate(
+                    if (viewModel.isActivated) {
+                        Vibrations.Activated
+                    } else {
+                        Vibrations.Deactivated
+                    }
+                )
+                viewModel.onClicked(
+                    KeyguardQuickAffordanceViewModel.OnClickedParameters(
+                        configKey = configKey,
+                        expandable = Expandable.fromView(view),
+                    )
+                )
+            }
+            view.performClick()
+            view.setOnClickListener(null)
+        }
+
         private fun cancel(onAnimationEnd: Runnable? = null) {
             longPressAnimator?.cancel()
             longPressAnimator = null
@@ -475,6 +502,40 @@
 
         companion object {
             private const val PRESSED_SCALE = 1.5f
+
+            /**
+             * Returns `true` if the tool type at the given pointer index is an accurate tool (like
+             * stylus or mouse), which means we can trust it to not be a false click; `false`
+             * otherwise.
+             */
+            private fun isUsingAccurateTool(
+                event: MotionEvent,
+                pointerIndex: Int = 0,
+            ): Boolean {
+                return when (event.getToolType(pointerIndex)) {
+                    MotionEvent.TOOL_TYPE_STYLUS -> true
+                    MotionEvent.TOOL_TYPE_MOUSE -> true
+                    else -> false
+                }
+            }
+
+            /**
+             * Returns the amount of distance the pointer moved since the historical record at the
+             * [since] index.
+             */
+            private fun distanceMoved(
+                event: MotionEvent,
+                since: Int = 0,
+            ): Float {
+                return if (event.historySize > 0) {
+                    sqrt(
+                        (event.y - event.getHistoricalY(since)).pow(2) +
+                            (event.x - event.getHistoricalX(since)).pow(2)
+                    )
+                } else {
+                    0f
+                }
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
index 9f09d53..bb0d260 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBouncerViewBinder.kt
@@ -22,7 +22,6 @@
 import android.window.OnBackAnimationCallback
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
-import com.android.internal.policy.SystemBarUtils
 import com.android.keyguard.KeyguardHostViewController
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -98,14 +97,14 @@
                     viewModel.setBouncerViewDelegate(delegate)
                     launch {
                         viewModel.show.collect {
+                            // Reset Security Container entirely.
+                            hostViewController.reinflateViewFlipper()
                             hostViewController.showPromptReason(it.promptReason)
                             it.errorMessage?.let { errorMessage ->
                                 hostViewController.showErrorMessage(errorMessage)
                             }
                             hostViewController.showPrimarySecurityScreen()
-                            hostViewController.appear(
-                                SystemBarUtils.getStatusBarHeight(view.context)
-                            )
+                            hostViewController.appear()
                             hostViewController.onResume()
                         }
                     }
@@ -114,7 +113,6 @@
                         viewModel.hide.collect {
                             hostViewController.cancelDismissAction()
                             hostViewController.cleanUp()
-                            hostViewController.resetSecurityContainer()
                         }
                     }
 
@@ -160,15 +158,6 @@
                     }
 
                     launch {
-                        viewModel.isBouncerVisible
-                            .filter { !it }
-                            .collect {
-                                // Remove existing input for security reasons.
-                                hostViewController.resetSecurityContainer()
-                            }
-                    }
-
-                    launch {
                         viewModel.keyguardPosition.collect { position ->
                             hostViewController.updateKeyguardPosition(position)
                         }
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 adde595..403576c 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
@@ -38,6 +38,7 @@
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
 import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.systemui.shared.clocks.shared.model.ClockPreviewConstants
 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView
 import dagger.assisted.Assisted
@@ -69,6 +70,8 @@
             KeyguardQuickAffordancePreviewConstants.KEY_HIGHLIGHT_QUICK_AFFORDANCES,
             false,
         )
+    private val shouldHideClock: Boolean =
+        bundle.getBoolean(ClockPreviewConstants.KEY_HIDE_CLOCK, false)
 
     private var host: SurfaceControlViewHost
 
@@ -104,7 +107,9 @@
             val rootView = FrameLayout(context)
 
             setUpBottomArea(rootView)
-            setUpClock(rootView)
+            if (!shouldHideClock) {
+                setUpClock(rootView)
+            }
 
             rootView.measure(
                 View.MeasureSpec.makeMeasureSpec(
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
index 348d941..ccd4060 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/Diffable.kt
@@ -79,10 +79,10 @@
     }
 }
 
-/**
- * Each time the boolean flow is updated with a new value that's different from the previous value,
- * logs the new value to the given [tableLogBuffer].
- */
+// Here and below: Various Flow<SomeType> extension functions that are effectively equivalent to the
+// above [logDiffsForTable] method.
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
 fun Flow<Boolean>.logDiffsForTable(
     tableLogBuffer: TableLogBuffer,
     columnPrefix: String,
@@ -100,10 +100,8 @@
         newVal
     }
 }
-/**
- * Each time the Int flow is updated with a new value that's different from the previous value, logs
- * the new value to the given [tableLogBuffer].
- */
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
 fun Flow<Int>.logDiffsForTable(
     tableLogBuffer: TableLogBuffer,
     columnPrefix: String,
@@ -122,10 +120,26 @@
     }
 }
 
-/**
- * Each time the String? flow is updated with a new value that's different from the previous value,
- * logs the new value to the given [tableLogBuffer].
- */
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
+fun Flow<Int?>.logDiffsForTable(
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String,
+    columnName: String,
+    initialValue: Int?,
+): Flow<Int?> {
+    val initialValueFun = {
+        tableLogBuffer.logChange(columnPrefix, columnName, initialValue)
+        initialValue
+    }
+    return this.pairwiseBy(initialValueFun) { prevVal, newVal: Int? ->
+        if (prevVal != newVal) {
+            tableLogBuffer.logChange(columnPrefix, columnName, newVal)
+        }
+        newVal
+    }
+}
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
 fun Flow<String?>.logDiffsForTable(
     tableLogBuffer: TableLogBuffer,
     columnPrefix: String,
@@ -143,3 +157,23 @@
         newVal
     }
 }
+
+/** See [logDiffsForTable(TableLogBuffer, String, T)]. */
+fun <T> Flow<List<T>>.logDiffsForTable(
+    tableLogBuffer: TableLogBuffer,
+    columnPrefix: String,
+    columnName: String,
+    initialValue: List<T>,
+): Flow<List<T>> {
+    val initialValueFun = {
+        tableLogBuffer.logChange(columnPrefix, columnName, initialValue.toString())
+        initialValue
+    }
+    return this.pairwiseBy(initialValueFun) { prevVal, newVal: List<T> ->
+        if (prevVal != newVal) {
+            // TODO(b/267761156): Can we log list changes without using toString?
+            tableLogBuffer.logChange(columnPrefix, columnName, newVal.toString())
+        }
+        newVal
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt
index 68c297f..4880f80 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableChange.kt
@@ -27,7 +27,7 @@
     var columnName: String = "",
     var type: DataType = DataType.EMPTY,
     var bool: Boolean = false,
-    var int: Int = 0,
+    var int: Int? = null,
     var str: String? = null,
 ) {
     /** Resets to default values so that the object can be recycled. */
@@ -54,7 +54,7 @@
     }
 
     /** Sets this to store an int change. */
-    fun set(value: Int) {
+    fun set(value: Int?) {
         type = DataType.INT
         int = value
     }
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 2c299d6..1712dab 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
@@ -138,7 +138,7 @@
     }
 
     /** Logs a Int change. */
-    fun logChange(prefix: String, columnName: String, value: Int) {
+    fun logChange(prefix: String, columnName: String, value: Int?) {
         logChange(systemClock.currentTimeMillis(), prefix, columnName, value)
     }
 
@@ -155,7 +155,7 @@
         change.set(value)
     }
 
-    private fun logChange(timestamp: Long, prefix: String, columnName: String, value: Int) {
+    private fun logChange(timestamp: Long, prefix: String, columnName: String, value: Int?) {
         val change = obtain(timestamp, prefix, columnName)
         change.set(value)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index a692ad7..52d4171 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -28,12 +28,15 @@
 import android.os.UserHandle
 import android.view.ViewGroup
 import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider
 import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider
 import com.android.internal.app.ChooserActivity
 import com.android.internal.app.ResolverListController
 import com.android.internal.app.chooser.NotSelectableTargetInfo
 import com.android.internal.app.chooser.TargetInfo
 import com.android.systemui.R
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler
@@ -47,6 +50,7 @@
 class MediaProjectionAppSelectorActivity(
     private val componentFactory: MediaProjectionAppSelectorComponent.Factory,
     private val activityLauncher: AsyncActivityLauncher,
+    private val featureFlags: FeatureFlags,
     /** This is used to override the dependency in a screenshot test */
     @VisibleForTesting
     private val listControllerFactory: ((userHandle: UserHandle) -> ResolverListController)?
@@ -56,7 +60,8 @@
     constructor(
         componentFactory: MediaProjectionAppSelectorComponent.Factory,
         activityLauncher: AsyncActivityLauncher,
-    ) : this(componentFactory, activityLauncher, null)
+        featureFlags: FeatureFlags
+    ) : this(componentFactory, activityLauncher, featureFlags, listControllerFactory = null)
 
     private lateinit var configurationController: ConfigurationController
     private lateinit var controller: MediaProjectionAppSelectorController
@@ -91,6 +96,13 @@
 
     override fun appliedThemeResId(): Int = R.style.Theme_SystemUI_MediaProjectionAppSelector
 
+    override fun createBlockerEmptyStateProvider(): EmptyStateProvider =
+        if (featureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
+            component.emptyStateProvider
+        } else {
+            super.createBlockerEmptyStateProvider()
+        }
+
     override fun createListController(userHandle: UserHandle): ResolverListController =
         listControllerFactory?.invoke(userHandle) ?: super.createListController(userHandle)
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index d830fc4..c4e76b2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -45,33 +45,46 @@
 import android.util.Log;
 import android.view.Window;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
+import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
+import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialog;
 import com.android.systemui.screenrecord.MediaProjectionPermissionDialog;
 import com.android.systemui.screenrecord.ScreenShareOption;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.util.Utils;
 
+import javax.inject.Inject;
+
+import dagger.Lazy;
+
 public class MediaProjectionPermissionActivity extends Activity
         implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
     private static final String TAG = "MediaProjectionPermissionActivity";
     private static final float MAX_APP_NAME_SIZE_PX = 500f;
     private static final String ELLIPSIS = "\u2026";
 
+    private final FeatureFlags mFeatureFlags;
+    private final Lazy<ScreenCaptureDevicePolicyResolver> mScreenCaptureDevicePolicyResolver;
+
     private String mPackageName;
     private int mUid;
     private IMediaProjectionManager mService;
-    private FeatureFlags mFeatureFlags;
 
     private AlertDialog mDialog;
 
+    @Inject
+    public MediaProjectionPermissionActivity(FeatureFlags featureFlags,
+            Lazy<ScreenCaptureDevicePolicyResolver> screenCaptureDevicePolicyResolver) {
+        mFeatureFlags = featureFlags;
+        mScreenCaptureDevicePolicyResolver = screenCaptureDevicePolicyResolver;
+    }
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        mFeatureFlags = Dependency.get(FeatureFlags.class);
         mPackageName = getCallingPackage();
         IBinder b = ServiceManager.getService(MEDIA_PROJECTION_SERVICE);
         mService = IMediaProjectionManager.Stub.asInterface(b);
@@ -104,6 +117,12 @@
             return;
         }
 
+        if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)) {
+            if (showScreenCaptureDisabledDialogIfNeeded()) {
+                return;
+            }
+        }
+
         TextPaint paint = new TextPaint();
         paint.setTextSize(42);
 
@@ -171,16 +190,7 @@
             mDialog = dialogBuilder.create();
         }
 
-        SystemUIDialog.registerDismissListener(mDialog);
-        SystemUIDialog.applyFlags(mDialog);
-        SystemUIDialog.setDialogSize(mDialog);
-
-        mDialog.setOnCancelListener(this);
-        mDialog.create();
-        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
-
-        final Window w = mDialog.getWindow();
-        w.addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        setUpDialog(mDialog);
 
         mDialog.show();
     }
@@ -200,6 +210,32 @@
         }
     }
 
+    private void setUpDialog(AlertDialog dialog) {
+        SystemUIDialog.registerDismissListener(dialog);
+        SystemUIDialog.applyFlags(dialog);
+        SystemUIDialog.setDialogSize(dialog);
+
+        dialog.setOnCancelListener(this);
+        dialog.create();
+        dialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
+
+        final Window w = dialog.getWindow();
+        w.addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+    }
+
+    private boolean showScreenCaptureDisabledDialogIfNeeded() {
+        final UserHandle hostUserHandle = getHostUserHandle();
+        if (mScreenCaptureDevicePolicyResolver.get()
+                .isScreenCaptureCompletelyDisabled(hostUserHandle)) {
+            AlertDialog dialog = new ScreenCaptureDisabledDialog(this);
+            setUpDialog(dialog);
+            dialog.show();
+            return true;
+        }
+
+        return false;
+    }
+
     private void grantMediaProjectionPermission(int screenShareMode) {
         try {
             if (screenShareMode == ENTIRE_SCREEN) {
@@ -211,7 +247,7 @@
                 intent.putExtra(MediaProjectionManager.EXTRA_MEDIA_PROJECTION,
                         projection.asBinder());
                 intent.putExtra(MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE,
-                        UserHandle.getUserHandleForUid(getLaunchedFromUid()));
+                        getHostUserHandle());
                 intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
 
                 // Start activity from the current foreground user to avoid creating a separate
@@ -230,6 +266,10 @@
         }
     }
 
+    private UserHandle getHostUserHandle() {
+        return UserHandle.getUserHandleForUid(getLaunchedFromUid());
+    }
+
     private IMediaProjection createProjection(int uid, String packageName) throws RemoteException {
         return mService.createProjection(uid, packageName,
                 MediaProjectionManager.TYPE_SCREEN_CAPTURE, false /* permanentGrant */);
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 0222ea3..5dd532a 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
@@ -51,6 +51,7 @@
 import android.util.Log
 import androidx.media.utils.MediaConstants
 import com.android.internal.logging.InstanceId
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.Dumpable
 import com.android.systemui.R
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -68,6 +69,7 @@
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaDataProvider
 import com.android.systemui.media.controls.resume.MediaResumeListener
+import com.android.systemui.media.controls.resume.ResumeMediaBrowser
 import com.android.systemui.media.controls.util.MediaControllerFactory
 import com.android.systemui.media.controls.util.MediaDataUtils
 import com.android.systemui.media.controls.util.MediaFlags
@@ -177,6 +179,7 @@
     private val mediaFlags: MediaFlags,
     private val logger: MediaUiEventLogger,
     private val smartspaceManager: SmartspaceManager,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
 ) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener {
 
     companion object {
@@ -241,6 +244,7 @@
         mediaFlags: MediaFlags,
         logger: MediaUiEventLogger,
         smartspaceManager: SmartspaceManager,
+        keyguardUpdateMonitor: KeyguardUpdateMonitor,
     ) : this(
         context,
         backgroundExecutor,
@@ -264,6 +268,7 @@
         mediaFlags,
         logger,
         smartspaceManager,
+        keyguardUpdateMonitor,
     )
 
     private val appChangeReceiver =
@@ -1338,7 +1343,9 @@
         Assert.isMainThread()
         val removed = mediaEntries.remove(key) ?: return
 
-        if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) {
+        if (keyguardUpdateMonitor.isUserInLockdown(removed.userId)) {
+            logger.logMediaRemoved(removed.appUid, removed.packageName, removed.instanceId)
+        } else if (useMediaResumption && removed.resumeAction != null && removed.isLocalSession()) {
             convertToResumePlayer(removed)
         } else if (mediaFlags.isRetainingPlayersEnabled()) {
             handlePossibleRemoval(removed, notificationRemoved = true)
@@ -1434,6 +1441,22 @@
             notifyMediaDataLoaded(key = pkg, oldKey = pkg, info = updated)
         }
         logger.logActiveConvertedToResume(updated.appUid, pkg, updated.instanceId)
+
+        // Limit total number of resume controls
+        val resumeEntries = mediaEntries.filter { (key, data) -> data.resumption }
+        val numResume = resumeEntries.size
+        if (numResume > ResumeMediaBrowser.MAX_RESUMPTION_CONTROLS) {
+            resumeEntries
+                .toList()
+                .sortedBy { (key, data) -> data.lastActive }
+                .subList(0, numResume - ResumeMediaBrowser.MAX_RESUMPTION_CONTROLS)
+                .forEach { (key, data) ->
+                    Log.d(TAG, "Removing excess control $key")
+                    mediaEntries.remove(key)
+                    notifyMediaDataRemoved(key)
+                    logger.logMediaRemoved(data.appUid, data.packageName, data.instanceId)
+                }
+        }
     }
 
     fun setMediaResumptionEnabled(isEnabled: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt
index aa46b14..878962d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaTimeoutListener.kt
@@ -40,7 +40,7 @@
 
 @VisibleForTesting
 val RESUME_MEDIA_TIMEOUT =
-    SystemProperties.getLong("debug.sysui.media_timeout_resume", TimeUnit.DAYS.toMillis(3))
+    SystemProperties.getLong("debug.sysui.media_timeout_resume", TimeUnit.DAYS.toMillis(2))
 
 /** Controller responsible for keeping track of playback states and expiring inactive streams. */
 @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index fac1d5e..b72923a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -30,13 +30,20 @@
 import android.view.animation.PathInterpolator
 import android.widget.LinearLayout
 import androidx.annotation.VisibleForTesting
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
 import com.android.internal.logging.InstanceId
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.Dumpable
 import com.android.systemui.R
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.media.controls.models.player.MediaData
 import com.android.systemui.media.controls.models.player.MediaViewHolder
 import com.android.systemui.media.controls.models.recommendation.RecommendationViewHolder
@@ -63,6 +70,10 @@
 import java.util.TreeMap
 import javax.inject.Inject
 import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.launch
 
 private const val TAG = "MediaCarouselController"
 private val settingsIntent = Intent().setAction(ACTION_MEDIA_CONTROLS_SETTINGS)
@@ -91,6 +102,8 @@
     private val logger: MediaUiEventLogger,
     private val debugLogger: MediaCarouselControllerLogger,
     private val mediaFlags: MediaFlags,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
 ) : Dumpable {
     /** The current width of the carousel */
     private var currentCarouselWidth: Int = 0
@@ -213,6 +226,17 @@
             }
         }
 
+    private val keyguardUpdateMonitorCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onStrongAuthStateChanged(userId: Int) {
+                if (keyguardUpdateMonitor.isUserInLockdown(userId)) {
+                    hideMediaCarousel()
+                } else if (keyguardUpdateMonitor.isUserUnlocked(userId)) {
+                    showMediaCarousel()
+                }
+            }
+        }
+
     /**
      * Update MediaCarouselScrollHandler.visibleToUser to reflect media card container visibility.
      * It will be called when the container is out of view.
@@ -487,6 +511,13 @@
                 }
             }
         )
+        keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
+        mediaCarousel.repeatWhenAttached {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                // A backup to show media carousel (if available) once the keyguard is gone.
+                listenForAnyStateToGoneKeyguardTransition(this)
+            }
+        }
     }
 
     private fun inflateSettingsButton() {
@@ -516,6 +547,23 @@
         return mediaCarousel
     }
 
+    private fun hideMediaCarousel() {
+        mediaCarousel.visibility = View.GONE
+    }
+
+    private fun showMediaCarousel() {
+        mediaCarousel.visibility = View.VISIBLE
+    }
+
+    @VisibleForTesting
+    internal fun listenForAnyStateToGoneKeyguardTransition(scope: CoroutineScope): Job {
+        return scope.launch {
+            keyguardTransitionInteractor.anyStateToGoneTransition
+                .filter { it.transitionState == TransitionState.FINISHED }
+                .collect { showMediaCarousel() }
+        }
+    }
+
     private fun reorderAllPlayers(
         previousVisiblePlayerKey: MediaPlayerData.MediaSortKey?,
         key: String? = null
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 1d000eb..6076e58 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
@@ -1139,8 +1139,10 @@
                         /* pixelDensity= */ getContext().getResources().getDisplayMetrics().density,
                         mColorSchemeTransition.getAccentPrimary().getCurrentColor(),
                         /* opacity= */ 100,
-                        /* shouldFillRipple= */ false,
                         /* sparkleStrength= */ 0f,
+                        /* baseRingFadeParams= */ null,
+                        /* sparkleRingFadeParams= */ null,
+                        /* centerFillFadeParams= */ null,
                         /* shouldDistort= */ false
                 )
         );
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index 1e6002c..b9b0459 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -311,16 +311,15 @@
         }
 
         // media player
-        val controlsTop =
-            calculateWidgetGroupAlphaForSquishiness(
-                controlIds,
-                squishedViewState.measureHeight.toFloat(),
-                squishedViewState,
-                squishFraction
-            )
+        calculateWidgetGroupAlphaForSquishiness(
+            controlIds,
+            squishedViewState.measureHeight.toFloat(),
+            squishedViewState,
+            squishFraction
+        )
         calculateWidgetGroupAlphaForSquishiness(
             detailIds,
-            controlsTop,
+            squishedViewState.measureHeight.toFloat(),
             squishedViewState,
             squishFraction
         )
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java
index 85282a1..e95106e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.controls.util;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -61,8 +62,9 @@
      * @param extras
      * @return the progress value between 0-1 inclusive if prsent, otherwise null
      */
-    public static Double getDescriptionProgress(Bundle extras) {
-        if (!extras.containsKey(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS)) {
+    public static Double getDescriptionProgress(@Nullable Bundle extras) {
+        if (extras == null
+                || !extras.containsKey(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS)) {
             return null;
         }
 
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 e57b169..00e9a79 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -16,14 +16,19 @@
 
 package com.android.systemui.media.dialog;
 
+import static android.media.RouteListingPreference.Item.SELECTION_BEHAVIOR_GO_TO_APP;
+import static android.media.RouteListingPreference.Item.SELECTION_BEHAVIOR_NONE;
+import static android.media.RouteListingPreference.Item.SELECTION_BEHAVIOR_TRANSFER;
+import static android.media.RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED;
+import static android.media.RouteListingPreference.Item.SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED;
 import static android.media.RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED;
 
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
-import android.media.RouteListingPreference;
 import android.os.Build;
 import android.util.Log;
 import android.view.View;
@@ -50,6 +55,8 @@
 
     private static final String TAG = "MediaOutputAdapter";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final float DEVICE_DISCONNECTED_ALPHA = 0.5f;
+    private static final float DEVICE_CONNECTED_ALPHA = 1f;
 
     public MediaOutputAdapter(MediaOutputController controller) {
         super(controller);
@@ -140,6 +147,11 @@
 
     @Override
     public int getItemViewType(int position) {
+        if (mController.isAdvancedLayoutSupported()
+                && position >= mController.getMediaItemList().size()) {
+            Log.d(TAG, "Incorrect position for item type: " + position);
+            return MediaItem.MediaItemType.TYPE_GROUP_DIVIDER;
+        }
         return mController.isAdvancedLayoutSupported()
                 ? mController.getMediaItemList().get(position).getMediaItemType()
                 : super.getItemViewType(position);
@@ -168,6 +180,7 @@
             if (mCurrentActivePosition == position) {
                 mCurrentActivePosition = -1;
             }
+            mStatusIcon.setVisibility(View.GONE);
 
             if (mController.isAnyDeviceTransferring()) {
                 if (device.getState() == MediaDeviceState.STATE_CONNECTING
@@ -194,16 +207,51 @@
                     updateFullItemClickListener(v -> onItemClick(v, device));
                     setSingleLineLayout(getItemTitle(device));
                 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
-                        && mController.isSubStatusSupported() && device.hasDisabledReason()) {
-                    //update to subtext with device status
-                    setUpDeviceIcon(device);
-                    mSubTitleText.setText(
-                            Api34Impl.composeDisabledReason(device.getDisableReason(), mContext));
-                    updateConnectionFailedStatusIcon();
-                    updateFullItemClickListener(null);
-                    setTwoLineLayout(device, false /* bFocused */, false /* showSeekBar */,
-                            false /* showProgressBar */, true /* showSubtitle */,
-                            true /* showStatus */);
+                        && mController.isSubStatusSupported()
+                        && mController.isAdvancedLayoutSupported() && device.hasSubtext()) {
+                    boolean isActiveWithOngoingSession =
+                            (device.hasOngoingSession() && currentlyConnected);
+                    boolean isHost = device.isHostForOngoingSession()
+                            && isActiveWithOngoingSession;
+                    if (isHost) {
+                        mCurrentActivePosition = position;
+                        updateTitleIcon(R.drawable.media_output_icon_volume,
+                                mController.getColorItemContent());
+                        mSubTitleText.setText(device.getSubtextString());
+                        updateTwoLineLayoutContentAlpha(DEVICE_CONNECTED_ALPHA);
+                        updateEndClickAreaAsSessionEditing(device);
+                        setTwoLineLayout(device, null /* title */, true /* bFocused */,
+                                true /* showSeekBar */, false /* showProgressBar */,
+                                true /* showSubtitle */, false /* showStatus */,
+                                true /* showEndTouchArea */, false /* isFakeActive */);
+                        initSeekbar(device, isCurrentSeekbarInvisible);
+                    } else {
+                        if (isActiveWithOngoingSession) {
+                            //Selected device which has ongoing session, disable seekbar since we
+                            //only allow volume control on Host
+                            initSeekbar(device, isCurrentSeekbarInvisible);
+                            mCurrentActivePosition = position;
+                        }
+                        setUpDeviceIcon(device);
+                        mSubTitleText.setText(device.getSubtextString());
+                        Drawable deviceStatusIcon =
+                                device.hasOngoingSession() ? mContext.getDrawable(
+                                        R.drawable.ic_sound_bars_anim)
+                                        : Api34Impl.getDeviceStatusIconBasedOnSelectionBehavior(
+                                                device,
+                                                mContext);
+                        if (deviceStatusIcon != null) {
+                            updateDeviceStatusIcon(deviceStatusIcon);
+                        }
+                        updateTwoLineLayoutContentAlpha(
+                                updateClickActionBasedOnSelectionBehavior(device)
+                                        ? DEVICE_CONNECTED_ALPHA : DEVICE_DISCONNECTED_ALPHA);
+                        setTwoLineLayout(device, isActiveWithOngoingSession /* bFocused */,
+                                isActiveWithOngoingSession /* showSeekBar */,
+                                false /* showProgressBar */, true /* showSubtitle */,
+                                deviceStatusIcon != null /* showStatus */,
+                                isActiveWithOngoingSession /* isFakeActive */);
+                    }
                 } else if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
                     setUpDeviceIcon(device);
                     updateConnectionFailedStatusIcon();
@@ -211,7 +259,7 @@
                     updateFullItemClickListener(v -> onItemClick(v, device));
                     setTwoLineLayout(device, false /* bFocused */, false /* showSeekBar */,
                             false /* showProgressBar */, true /* showSubtitle */,
-                            true /* showStatus */);
+                            true /* showStatus */, false /*isFakeActive*/);
                 } else if (device.getState() == MediaDeviceState.STATE_GROUPING) {
                     setUpDeviceIcon(device);
                     updateProgressBarColor();
@@ -220,6 +268,7 @@
                             false /* showEndTouchArea */);
                 } else if (mController.getSelectedMediaDevice().size() > 1
                         && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
+                    // selected device in group
                     boolean isDeviceDeselectable = isDeviceIncluded(
                             mController.getDeselectableMediaDevice(), device);
                     if (!mController.isAdvancedLayoutSupported()) {
@@ -235,6 +284,7 @@
                     initSeekbar(device, isCurrentSeekbarInvisible);
                 } else if (!mController.hasAdjustVolumeUserRestriction()
                         && currentlyConnected) {
+                    // single selected device
                     if (isMutingExpectedDeviceExist
                             && !mController.isCurrentConnectedDeviceRemote()) {
                         // mark as disconnected and set special click listener
@@ -266,6 +316,7 @@
                         initSeekbar(device, isCurrentSeekbarInvisible);
                     }
                 } else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
+                    //groupable device
                     setUpDeviceIcon(device);
                     updateGroupableCheckBox(false, true, device);
                     if (mController.isAdvancedLayoutSupported()) {
@@ -280,7 +331,24 @@
                 } else {
                     setUpDeviceIcon(device);
                     setSingleLineLayout(getItemTitle(device));
-                    updateFullItemClickListener(v -> onItemClick(v, 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);
+                        }
+                        updateTwoLineLayoutContentAlpha(
+                                updateClickActionBasedOnSelectionBehavior(device)
+                                        ? DEVICE_CONNECTED_ALPHA : DEVICE_DISCONNECTED_ALPHA);
+                    } else {
+                        updateFullItemClickListener(v -> onItemClick(v, device));
+                    }
                 }
             }
         }
@@ -292,12 +360,51 @@
                     ColorStateList(states, colors));
         }
 
+        private void updateTwoLineLayoutContentAlpha(float alphaValue) {
+            mSubTitleText.setAlpha(alphaValue);
+            mTitleIcon.setAlpha(alphaValue);
+            mTwoLineTitleText.setAlpha(alphaValue);
+            mStatusIcon.setAlpha(alphaValue);
+        }
+
+        private void updateEndClickAreaAsSessionEditing(MediaDevice device) {
+            mEndClickIcon.setOnClickListener(null);
+            mEndTouchArea.setOnClickListener(null);
+            updateEndClickAreaColor(mController.getColorSeekbarProgress());
+            mEndClickIcon.setColorFilter(mController.getColorItemContent());
+            mEndClickIcon.setOnClickListener(
+                    v -> mController.tryToLaunchInAppRoutingIntent(device.getId(), v));
+            mEndTouchArea.setOnClickListener(v -> mCheckBox.performClick());
+        }
+
+        public void updateEndClickAreaColor(int color) {
+            if (mController.isAdvancedLayoutSupported()) {
+                mEndTouchArea.getBackground().setColorFilter(
+                        new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
+            }
+        }
+
+        private boolean updateClickActionBasedOnSelectionBehavior(MediaDevice device) {
+            View.OnClickListener clickListener = Api34Impl.getClickListenerBasedOnSelectionBehavior(
+                    device, mController, v -> onItemClick(v, device));
+            updateFullItemClickListener(clickListener);
+            return clickListener != null;
+        }
+
         private void updateConnectionFailedStatusIcon() {
             mStatusIcon.setImageDrawable(
                     mContext.getDrawable(R.drawable.media_output_status_failed));
             mStatusIcon.setColorFilter(mController.getColorItemContent());
         }
 
+        private void updateDeviceStatusIcon(Drawable drawable) {
+            mStatusIcon.setImageDrawable(drawable);
+            mStatusIcon.setColorFilter(mController.getColorItemContent());
+            if (drawable instanceof AnimatedVectorDrawable) {
+                ((AnimatedVectorDrawable) drawable).start();
+            }
+        }
+
         private void updateProgressBarColor() {
             mProgressBar.getIndeterminateDrawable().setColorFilter(
                     new PorterDuffColorFilter(
@@ -411,13 +518,30 @@
     @RequiresApi(34)
     private static class Api34Impl {
         @DoNotInline
-        static String composeDisabledReason(
-                @RouteListingPreference.Item.SubText int reason, Context context) {
-            switch(reason) {
-                case SUBTEXT_SUBSCRIPTION_REQUIRED:
-                    return context.getString(R.string.media_output_status_require_premium);
+        static View.OnClickListener getClickListenerBasedOnSelectionBehavior(MediaDevice device,
+                MediaOutputController controller, View.OnClickListener defaultTransferListener) {
+            switch (device.getSelectionBehavior()) {
+                case SELECTION_BEHAVIOR_NONE:
+                    return null;
+                case SELECTION_BEHAVIOR_TRANSFER:
+                    return defaultTransferListener;
+                case SELECTION_BEHAVIOR_GO_TO_APP:
+                    return v -> controller.tryToLaunchInAppRoutingIntent(device.getId(), v);
             }
-            return "";
+            return defaultTransferListener;
+        }
+
+        @DoNotInline
+        static Drawable getDeviceStatusIconBasedOnSelectionBehavior(MediaDevice device,
+                Context context) {
+            switch (device.getSubtext()) {
+                case SUBTEXT_AD_ROUTING_DISALLOWED:
+                case SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED:
+                    return context.getDrawable(R.drawable.media_output_status_failed);
+                case SUBTEXT_SUBSCRIPTION_REQUIRED:
+                    return context.getDrawable(R.drawable.media_output_status_help);
+            }
+            return null;
         }
     }
 }
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 dc75538..2a2cf63 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -147,6 +147,7 @@
         final ImageView mStatusIcon;
         final CheckBox mCheckBox;
         final ViewGroup mEndTouchArea;
+        final ImageView mEndClickIcon;
         @VisibleForTesting
         MediaOutputSeekbar mSeekBar;
         private String mDeviceId;
@@ -168,11 +169,13 @@
             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;
             }
             initAnimator();
         }
@@ -218,20 +221,7 @@
                                 .mutate();
                 mItemLayout.setBackground(backgroundDrawable);
                 if (showSeekBar) {
-                    final ClipDrawable clipDrawable =
-                            (ClipDrawable) ((LayerDrawable) mSeekBar.getProgressDrawable())
-                                    .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());
-                    }
+                    updateSeekbarProgressBackground();
                 }
             }
             mItemLayout.getBackground().setColorFilter(new PorterDuffColorFilter(
@@ -265,25 +255,52 @@
         }
 
         void setTwoLineLayout(MediaDevice device, boolean bFocused, boolean showSeekBar,
-                boolean showProgressBar, boolean showSubtitle, boolean showStatus) {
+                boolean showProgressBar, boolean showSubtitle, boolean showStatus,
+                boolean isFakeActive) {
             setTwoLineLayout(device, null, bFocused, showSeekBar, showProgressBar, showSubtitle,
-                    showStatus);
+                    showStatus, false, isFakeActive);
         }
 
-        private void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused,
+        void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused,
                 boolean showSeekBar, boolean showProgressBar, boolean showSubtitle,
-                boolean showStatus) {
+                boolean showStatus , boolean showEndTouchArea, boolean isFakeActive) {
             mTitleText.setVisibility(View.GONE);
             mTwoLineLayout.setVisibility(View.VISIBLE);
             mStatusIcon.setVisibility(showStatus ? View.VISIBLE : View.GONE);
             mSeekBar.setAlpha(1);
             mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE);
-            final Drawable backgroundDrawable = mContext.getDrawable(
-                            R.drawable.media_output_item_background)
-                    .mutate();
-            backgroundDrawable.setColorFilter(new PorterDuffColorFilter(
-                    mController.getColorItemBackground(),
-                    PorterDuff.Mode.SRC_IN));
+            final Drawable backgroundDrawable;
+            if (mController.isAdvancedLayoutSupported() && mController.isSubStatusSupported()) {
+                backgroundDrawable = mContext.getDrawable(
+                        showSeekBar ? R.drawable.media_output_item_background_active
+                                : R.drawable.media_output_item_background).mutate();
+                backgroundDrawable.setColorFilter(new PorterDuffColorFilter(
+                        showSeekBar ? mController.getColorConnectedItemBackground()
+                                : mController.getColorItemBackground(), PorterDuff.Mode.SRC_IN));
+                mIconAreaLayout.getBackground().setColorFilter(new PorterDuffColorFilter(
+                        showProgressBar || isFakeActive
+                                ? mController.getColorConnectedItemBackground()
+                                : showSeekBar ? mController.getColorSeekbarProgress()
+                                        : mController.getColorItemBackground(),
+                        PorterDuff.Mode.SRC_IN));
+                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.setColorFilter(new PorterDuffColorFilter(
+                        mController.getColorItemBackground(),
+                        PorterDuff.Mode.SRC_IN));
+            }
             mItemLayout.setBackground(backgroundDrawable);
             mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
             mSubTitleText.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
@@ -295,11 +312,28 @@
                     Typeface.NORMAL));
         }
 
+        void updateSeekbarProgressBackground() {
+            final ClipDrawable clipDrawable =
+                    (ClipDrawable) ((LayerDrawable) mSeekBar.getProgressDrawable())
+                            .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());
+            }
+        }
+
         void initSeekbar(MediaDevice device, boolean isCurrentSeekbarInvisible) {
             if (!mController.isVolumeControlEnabled(device)) {
                 disableSeekBar();
             } else {
-                enableSeekBar();
+                enableSeekBar(device);
             }
             mSeekBar.setMaxVolume(device.getMaxVolume());
             final int currentVolume = device.getCurrentVolume();
@@ -335,13 +369,6 @@
             if (mIsInitVolumeFirstTime) {
                 mIsInitVolumeFirstTime = false;
             }
-            if (mController.isAdvancedLayoutSupported()) {
-                updateIconAreaClickListener((v) -> {
-                    mSeekBar.resetVolume();
-                    mController.adjustVolume(device, 0);
-                    updateMutedVolumeIcon();
-                });
-            }
             mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                 @Override
                 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@@ -522,11 +549,21 @@
         protected void disableSeekBar() {
             mSeekBar.setEnabled(false);
             mSeekBar.setOnTouchListener((v, event) -> true);
+            if (mController.isAdvancedLayoutSupported()) {
+                updateIconAreaClickListener(null);
+            }
         }
 
-        private void enableSeekBar() {
+        private void enableSeekBar(MediaDevice device) {
             mSeekBar.setEnabled(true);
             mSeekBar.setOnTouchListener((v, event) -> false);
+            if (mController.isAdvancedLayoutSupported()) {
+                updateIconAreaClickListener((v) -> {
+                    mSeekBar.resetVolume();
+                    mController.adjustVolume(device, 0);
+                    updateMutedVolumeIcon();
+                });
+            }
         }
 
         protected void setUpDeviceIcon(MediaDevice device) {
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 4803371..35819e3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -263,10 +263,10 @@
             mMediaOutputController.releaseSession();
             dismiss();
         });
-        mAppButton.setOnClickListener(v -> mMediaOutputController.tryToLaunchMediaApplication());
+        mAppButton.setOnClickListener(mMediaOutputController::tryToLaunchMediaApplication);
         if (mMediaOutputController.isAdvancedLayoutSupported()) {
             mMediaMetadataSectionLayout.setOnClickListener(
-                    v -> mMediaOutputController.tryToLaunchMediaApplication());
+                    mMediaOutputController::tryToLaunchMediaApplication);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
index 35baf013..12d6b7c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
 import android.text.method.HideReturnsTransformationMethod;
 import android.text.method.PasswordTransformationMethod;
 import android.util.Log;
@@ -64,11 +66,51 @@
     private String mCurrentBroadcastName;
     private String mCurrentBroadcastCode;
     private boolean mIsStopbyUpdateBroadcastCode = false;
+    private TextWatcher mTextWatcher = new TextWatcher() {
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            // Do nothing
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            // Do nothing
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            if (mAlertDialog == null || mBroadcastErrorMessage == null) {
+                return;
+            }
+            boolean breakBroadcastCodeRuleTextLengthLessThanMin =
+                    s.length() > 0 && s.length() < BROADCAST_CODE_MIN_LENGTH;
+            boolean breakBroadcastCodeRuleTextLengthMoreThanMax =
+                    s.length() > BROADCAST_CODE_MAX_LENGTH;
+            boolean breakRule = breakBroadcastCodeRuleTextLengthLessThanMin
+                    || breakBroadcastCodeRuleTextLengthMoreThanMax;
+
+            if (breakBroadcastCodeRuleTextLengthLessThanMin) {
+                mBroadcastErrorMessage.setText(
+                        R.string.media_output_broadcast_code_hint_no_less_than_min);
+            } else if (breakBroadcastCodeRuleTextLengthMoreThanMax) {
+                mBroadcastErrorMessage.setText(
+                        R.string.media_output_broadcast_code_hint_no_more_than_max);
+            }
+
+            mBroadcastErrorMessage.setVisibility(breakRule ? View.VISIBLE : View.INVISIBLE);
+            Button positiveBtn = mAlertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+            if (positiveBtn != null) {
+                positiveBtn.setEnabled(breakRule ? false : true);
+            }
+        }
+    };
 
     static final int METADATA_BROADCAST_NAME = 0;
     static final int METADATA_BROADCAST_CODE = 1;
 
     private static final int MAX_BROADCAST_INFO_UPDATE = 3;
+    private static final int BROADCAST_CODE_MAX_LENGTH = 16;
+    private static final int BROADCAST_CODE_MIN_LENGTH = 4;
 
     MediaOutputBroadcastDialog(Context context, boolean aboveStatusbar,
             BroadcastSender broadcastSender, MediaOutputController mediaOutputController) {
@@ -219,6 +261,9 @@
                 R.layout.media_output_broadcast_update_dialog, null);
         final EditText editText = layout.requireViewById(R.id.broadcast_edit_text);
         editText.setText(editString);
+        if (isBroadcastCode) {
+            editText.addTextChangedListener(mTextWatcher);
+        }
         mBroadcastErrorMessage = layout.requireViewById(R.id.broadcast_error_message);
         mAlertDialog = new Builder(mContext)
                 .setTitle(isBroadcastCode ? R.string.media_output_broadcast_code
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 5f5c686..2aedd36 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.media.dialog;
 
+import static android.media.RouteListingPreference.ACTION_TRANSFER_MEDIA;
+import static android.media.RouteListingPreference.EXTRA_ROUTE_ID;
 import static android.provider.Settings.ACTION_BLUETOOTH_SETTINGS;
 
 import android.annotation.CallbackExecutor;
@@ -24,6 +26,7 @@
 import android.app.Notification;
 import android.app.WallpaperColors;
 import android.bluetooth.BluetoothLeBroadcast;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -382,12 +385,29 @@
         return mContext.getPackageManager().getLaunchIntentForPackage(mPackageName);
     }
 
-    void tryToLaunchMediaApplication() {
+    void tryToLaunchInAppRoutingIntent(String routeId, View view) {
+        ComponentName componentName = mLocalMediaManager.getLinkedItemComponentName();
+        if (componentName != null) {
+            ActivityLaunchAnimator.Controller controller =
+                    mDialogLaunchAnimator.createActivityLaunchController(view);
+            Intent launchIntent = new Intent(ACTION_TRANSFER_MEDIA);
+            launchIntent.setComponent(componentName);
+            launchIntent.putExtra(EXTRA_ROUTE_ID, routeId);
+            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mCallback.dismissDialog();
+            mContext.startActivity(launchIntent);
+            mActivityStarter.startActivity(launchIntent, true, controller);
+        }
+    }
+
+    void tryToLaunchMediaApplication(View view) {
+        ActivityLaunchAnimator.Controller controller =
+                mDialogLaunchAnimator.createActivityLaunchController(view);
         Intent launchIntent = getAppLaunchIntent();
         if (launchIntent != null) {
             launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             mCallback.dismissDialog();
-            mContext.startActivity(launchIntent);
+            mActivityStarter.startActivity(launchIntent, true, controller);
         }
     }
 
@@ -684,19 +704,21 @@
                 devices.removeAll(targetMediaDevices);
                 targetMediaDevices.addAll(devices);
             }
-            mMediaItemList.clear();
-            mMediaItemList.addAll(
-                    targetMediaDevices.stream().map(MediaItem::new).collect(Collectors.toList()));
+            List<MediaItem> finalMediaItems = targetMediaDevices.stream().map(
+                    MediaItem::new).collect(Collectors.toList());
             dividerItems.forEach((key, item) -> {
-                mMediaItemList.add(key, item);
+                finalMediaItems.add(key, item);
             });
-            mMediaItemList.add(new MediaItem());
+            finalMediaItems.add(new MediaItem());
+            mMediaItemList.clear();
+            mMediaItemList.addAll(finalMediaItems);
         }
     }
 
     private void categorizeMediaItems(MediaDevice connectedMediaDevice, List<MediaDevice> devices,
             boolean needToHandleMutingExpectedDevice) {
         synchronized (mMediaDevicesLock) {
+            List<MediaItem> finalMediaItems = new ArrayList<>();
             Set<String> selectedDevicesIds = getSelectedMediaDevice().stream().map(
                     MediaDevice::getId).collect(Collectors.toSet());
             if (connectedMediaDevice != null) {
@@ -706,32 +728,32 @@
             boolean displayGroupAdded = false;
             for (MediaDevice device : devices) {
                 if (needToHandleMutingExpectedDevice && device.isMutingExpectedDevice()) {
-                    mMediaItemList.add(0, new MediaItem(device));
+                    finalMediaItems.add(0, new MediaItem(device));
                 } else if (!needToHandleMutingExpectedDevice && selectedDevicesIds.contains(
                         device.getId())) {
-                    mMediaItemList.add(0, new MediaItem(device));
+                    finalMediaItems.add(0, new MediaItem(device));
                 } else {
                     if (device.isSuggestedDevice() && !suggestedDeviceAdded) {
-                        attachGroupDivider(mContext.getString(
+                        attachGroupDivider(finalMediaItems, mContext.getString(
                                 R.string.media_output_group_title_suggested_device));
                         suggestedDeviceAdded = true;
                     } else if (!device.isSuggestedDevice() && !displayGroupAdded) {
-                        attachGroupDivider(mContext.getString(
+                        attachGroupDivider(finalMediaItems, mContext.getString(
                                 R.string.media_output_group_title_speakers_and_displays));
                         displayGroupAdded = true;
                     }
-                    mMediaItemList.add(new MediaItem(device));
+                    finalMediaItems.add(new MediaItem(device));
                 }
             }
-            mMediaItemList.add(new MediaItem());
+            finalMediaItems.add(new MediaItem());
+            mMediaItemList.clear();
+            mMediaItemList.addAll(finalMediaItems);
         }
     }
 
-    private void attachGroupDivider(String title) {
-        synchronized (mMediaDevicesLock) {
-            mMediaItemList.add(
-                    new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
-        }
+    private void attachGroupDivider(List<MediaItem> mediaItems, String title) {
+        mediaItems.add(
+                new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
     }
 
     private void attachRangeInfo(List<MediaDevice> devices) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index fbd0079..a174b45 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Bundle;
+import android.util.FeatureFlagUtils;
 import android.view.View;
 import android.view.WindowManager;
 
@@ -99,10 +100,18 @@
     @Override
     public boolean isBroadcastSupported() {
         boolean isBluetoothLeDevice = false;
-        if (mMediaOutputController.getCurrentConnectedMediaDevice() != null) {
-            isBluetoothLeDevice = mMediaOutputController.isBluetoothLeDevice(
+        if (FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST)) {
+            if (mMediaOutputController.getCurrentConnectedMediaDevice() != null) {
+                isBluetoothLeDevice = mMediaOutputController.isBluetoothLeDevice(
                     mMediaOutputController.getCurrentConnectedMediaDevice());
+            }
+        } else {
+            // To decouple LE Audio Broadcast and Unicast, it always displays the button when there
+            // is no LE Audio device connected to the phone
+            isBluetoothLeDevice = true;
         }
+
         return mMediaOutputController.isBroadcastSupported() && isBluetoothLeDevice;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index a3ae943..720c44a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -44,25 +44,37 @@
          * @param appPackageName the package name of the app playing the media.
          * @param onPackageNotFoundException a function run if a
          * [PackageManager.NameNotFoundException] occurs.
+         * @param isReceiver indicates whether the icon is displayed in a receiver view.
          */
         fun getIconInfoFromPackageName(
             context: Context,
             appPackageName: String?,
+            isReceiver: Boolean,
             onPackageNotFoundException: () -> Unit,
         ): IconInfo {
             if (appPackageName != null) {
                 val packageManager = context.packageManager
                 try {
+                    val appName =
+                        packageManager
+                            .getApplicationInfo(
+                                appPackageName,
+                                PackageManager.ApplicationInfoFlags.of(0),
+                            )
+                            .loadLabel(packageManager)
+                            .toString()
                     val contentDescription =
-                        ContentDescription.Loaded(
-                            packageManager
-                                .getApplicationInfo(
-                                    appPackageName,
-                                    PackageManager.ApplicationInfoFlags.of(0)
+                        if (isReceiver) {
+                            ContentDescription.Loaded(
+                                context.getString(
+                                    R.string
+                                        .media_transfer_receiver_content_description_with_app_name,
+                                    appName
                                 )
-                                .loadLabel(packageManager)
-                                .toString()
-                        )
+                            )
+                        } else {
+                            ContentDescription.Loaded(appName)
+                        }
                     return IconInfo(
                         contentDescription,
                         MediaTttIcon.Loaded(packageManager.getApplicationIcon(appPackageName)),
@@ -74,7 +86,15 @@
                 }
             }
             return IconInfo(
-                ContentDescription.Resource(R.string.media_output_dialog_unknown_launch_app_name),
+                if (isReceiver) {
+                    ContentDescription.Resource(
+                        R.string.media_transfer_receiver_content_description_unknown_app
+                    )
+                } else {
+                    ContentDescription.Resource(
+                        R.string.media_output_dialog_unknown_launch_app_name
+                    )
+                },
                 MediaTttIcon.Resource(R.drawable.ic_cast),
                 tintAttr = android.R.attr.textColorPrimary,
                 isAppIcon = false
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 34bf74fa..fab8c06 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
@@ -16,7 +16,9 @@
 
 package com.android.systemui.media.taptotransfer.receiver
 
+import android.animation.TimeInterpolator
 import android.annotation.SuppressLint
+import android.animation.ValueAnimator
 import android.app.StatusBarManager
 import android.content.Context
 import android.graphics.Rect
@@ -31,8 +33,10 @@
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
 import android.view.View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+import android.view.View.ACCESSIBILITY_LIVE_REGION_NONE
 import com.android.internal.widget.CachingIconView
 import com.android.systemui.R
+import com.android.systemui.animation.Interpolators
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.ui.binder.TintedIconViewBinder
 import com.android.systemui.dagger.SysUISingleton
@@ -101,6 +105,13 @@
         fitInsetsTypes = 0 // Ignore insets from all system bars
     }
 
+    // Value animator that controls the bouncing animation of views.
+    private val bounceAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
+        repeatCount = ValueAnimator.INFINITE
+        repeatMode = ValueAnimator.REVERSE
+        duration = ICON_BOUNCE_ANIM_DURATION
+    }
+
     private val commandQueueCallbacks = object : CommandQueue.Callbacks {
         override fun updateMediaTapToTransferReceiverDisplay(
             @StatusBarManager.MediaTransferReceiverState displayState: Int,
@@ -173,7 +184,11 @@
 
     override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
         val packageName = newInfo.routeInfo.clientPackageName
-        var iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, packageName) {
+        var iconInfo = MediaTttUtils.getIconInfoFromPackageName(
+            context,
+            packageName,
+            isReceiver = true,
+        ) {
             logger.logPackageNotFound(packageName)
         }
 
@@ -199,44 +214,52 @@
 
         val iconView = currentView.getAppIconView()
         iconView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
-        iconView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE
         TintedIconViewBinder.bind(iconInfo.toTintedIcon(), iconView)
+
+        val iconContainerView = currentView.getIconContainerView()
+        iconContainerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE
     }
 
     override fun animateViewIn(view: ViewGroup) {
-        val appIconView = view.getAppIconView()
+        val iconContainerView = view.getIconContainerView()
         val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple)
         val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple)
-        animateViewTranslationAndFade(appIconView, -1 * getTranslationAmount(), 1f)
-        animateViewTranslationAndFade(iconRippleView, -1 * getTranslationAmount(), 1f)
+        val translationYBy = getTranslationAmount()
+        // Make the icon container view starts animation from bottom of the screen.
+        iconContainerView.translationY += rippleController.getReceiverIconSize()
+        animateViewTranslationAndFade(
+            iconContainerView,
+            translationYBy = -1 * translationYBy,
+            alphaEndValue = 1f,
+            Interpolators.EMPHASIZED_DECELERATE,
+        ) {
+            animateBouncingView(iconContainerView, translationYBy * BOUNCE_TRANSLATION_RATIO)
+        }
         rippleController.expandToInProgressState(rippleView, iconRippleView)
     }
 
     override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
-        val appIconView = view.getAppIconView()
-        val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple)
+        val iconContainerView = view.getIconContainerView()
         val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple)
+        val translationYBy = getTranslationAmount()
+
+        // Remove update listeners from bounce animator to prevent any conflict with
+        // translation animation.
+        bounceAnimator.removeAllUpdateListeners()
+        bounceAnimator.cancel()
         if (removalReason == ChipStateReceiver.TRANSFER_TO_RECEIVER_SUCCEEDED.name &&
                 mediaTttFlags.isMediaTttReceiverSuccessRippleEnabled()) {
             rippleController.expandToSuccessState(rippleView, onAnimationEnd)
             animateViewTranslationAndFade(
-                iconRippleView,
-                -1 * getTranslationAmount(),
-                0f,
-                translationDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
-                alphaDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
-            )
-            animateViewTranslationAndFade(
-                appIconView,
-                -1 * getTranslationAmount(),
+                iconContainerView,
+                -1 * translationYBy,
                 0f,
                 translationDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
                 alphaDuration = ICON_TRANSLATION_SUCCEEDED_DURATION,
             )
         } else {
             rippleController.collapseRipple(rippleView, onAnimationEnd)
-            animateViewTranslationAndFade(iconRippleView, getTranslationAmount(), 0f)
-            animateViewTranslationAndFade(appIconView, getTranslationAmount(), 0f)
+            animateViewTranslationAndFade(iconContainerView, translationYBy, 0f)
         }
     }
 
@@ -248,15 +271,19 @@
 
     /** Animation of view translation and fading. */
     private fun animateViewTranslationAndFade(
-        view: View,
+        view: ViewGroup,
         translationYBy: Float,
         alphaEndValue: Float,
+        interpolator: TimeInterpolator? = null,
         translationDuration: Long = ICON_TRANSLATION_ANIM_DURATION,
         alphaDuration: Long = ICON_ALPHA_ANIM_DURATION,
+        onAnimationEnd: Runnable? = null,
     ) {
         view.animate()
             .translationYBy(translationYBy)
+            .setInterpolator(interpolator)
             .setDuration(translationDuration)
+            .withEndAction { onAnimationEnd?.run() }
             .start()
         view.animate()
             .alpha(alphaEndValue)
@@ -266,17 +293,42 @@
 
     /** Returns the amount that the chip will be translated by in its intro animation. */
     private fun getTranslationAmount(): Float {
-        return rippleController.getRippleSize() * 0.5f -
-            rippleController.getReceiverIconSize()
+        return rippleController.getRippleSize() * 0.5f
     }
 
     private fun View.getAppIconView(): CachingIconView {
         return this.requireViewById(R.id.app_icon)
     }
 
+    private fun View.getIconContainerView(): ViewGroup {
+        return this.requireViewById(R.id.icon_container_view)
+    }
+
+    private fun animateBouncingView(iconContainerView: ViewGroup, translationYBy: Float) {
+        if (bounceAnimator.isStarted) {
+            return
+        }
+
+        addViewToBounceAnimation(iconContainerView, translationYBy)
+
+        // In order not to announce description every time the view animate.
+        iconContainerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_NONE
+        bounceAnimator.start()
+    }
+
+    private fun addViewToBounceAnimation(view: View, translationYBy: Float) {
+        val prevTranslationY = view.translationY
+        bounceAnimator.addUpdateListener { updateListener ->
+            val progress = updateListener.animatedValue as Float
+            view.translationY = prevTranslationY + translationYBy * progress
+        }
+    }
+
     companion object {
         private const val ICON_TRANSLATION_ANIM_DURATION = 500L
+        private const val ICON_BOUNCE_ANIM_DURATION = 750L
         private const val ICON_TRANSLATION_SUCCEEDED_DURATION = 167L
+        private const val BOUNCE_TRANSLATION_RATIO = 0.15f
         private val ICON_ALPHA_ANIM_DURATION = 5.frames
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
index f1acae8..4ff082a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
@@ -34,7 +34,7 @@
 
     init {
         setupShader(RippleShader.RippleShape.CIRCLE)
-        setRippleFill(true)
+        setupRippleFadeParams()
         setSparkleStrength(0f)
         isStarted = false
     }
@@ -72,7 +72,7 @@
         animator.removeAllUpdateListeners()
 
         // Only show the outline as ripple expands and disappears when animation ends.
-        setRippleFill(false)
+        removeRippleFill()
 
         val startingPercentage = calculateStartingPercentage(newHeight)
         animator.duration = EXPAND_TO_FULL_DURATION
@@ -103,6 +103,38 @@
         return 1 - remainingPercentage
     }
 
+    private fun setupRippleFadeParams() {
+        with(rippleShader) {
+            // No fade out for the base ring.
+            baseRingFadeParams.fadeOutStart = 1f
+            baseRingFadeParams.fadeOutEnd = 1f
+
+            // No fade in and outs for the center fill, as we always draw it.
+            centerFillFadeParams.fadeInStart = 0f
+            centerFillFadeParams.fadeInEnd = 0f
+            centerFillFadeParams.fadeOutStart = 1f
+            centerFillFadeParams.fadeOutEnd = 1f
+        }
+    }
+
+    private fun removeRippleFill() {
+        with(rippleShader) {
+            // Set back to default because we modified them in [setupRippleFadeParams].
+            baseRingFadeParams.fadeOutStart = RippleShader.DEFAULT_BASE_RING_FADE_OUT_START
+            baseRingFadeParams.fadeOutEnd = RippleShader.DEFAULT_FADE_OUT_END
+
+            centerFillFadeParams.fadeInStart = RippleShader.DEFAULT_FADE_IN_START
+            centerFillFadeParams.fadeInEnd = RippleShader.DEFAULT_CENTER_FILL_FADE_IN_END
+
+            // To avoid a seam showing up, we should match either:
+            // 1. baseRingFadeParams#fadeInEnd and centerFillFadeParams#fadeOutStart
+            // 2. baseRingFadeParams#fadeOutStart and centerFillFadeOutStart
+            // Here we go with 1 to fade in the centerFill faster.
+            centerFillFadeParams.fadeOutStart = baseRingFadeParams.fadeInEnd
+            centerFillFadeParams.fadeOutEnd = RippleShader.DEFAULT_FADE_OUT_END
+        }
+    }
+
     companion object {
         const val DEFAULT_DURATION = 333L
         const val EXPAND_TO_FULL_DURATION = 1000L
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index 89ca5d3..6bb6906 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
@@ -161,7 +161,7 @@
                 routeInfo.name.toString()
             }
         val icon =
-            MediaTttUtils.getIconInfoFromPackageName(context, packageName) {
+            MediaTttUtils.getIconInfoFromPackageName(context, packageName, isReceiver = false) {
                 logger.logPackageNotFound(packageName)
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
index e665d83..3088d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.media.MediaProjectionAppSelectorActivity
 import com.android.systemui.media.MediaProjectionAppSelectorActivity.Companion.EXTRA_HOST_APP_USER_HANDLE
+import com.android.systemui.media.MediaProjectionPermissionActivity
 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerLabelLoader
 import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerThumbnailLoader
 import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
@@ -67,6 +68,11 @@
     fun provideMediaProjectionAppSelectorActivity(
         activity: MediaProjectionAppSelectorActivity
     ): Activity
+
+    @Binds
+    @IntoMap
+    @ClassKey(MediaProjectionPermissionActivity::class)
+    fun bindsMediaProjectionPermissionActivity(impl: MediaProjectionPermissionActivity): Activity
 }
 
 /**
@@ -104,6 +110,12 @@
         @Provides
         @MediaProjectionAppSelector
         @MediaProjectionAppSelectorScope
+        fun provideCallerPackageName(activity: MediaProjectionAppSelectorActivity): String? =
+            activity.callingPackage
+
+        @Provides
+        @MediaProjectionAppSelector
+        @MediaProjectionAppSelectorScope
         fun bindConfigurationController(
             activity: MediaProjectionAppSelectorActivity
         ): ConfigurationController = ConfigurationControllerImpl(activity)
@@ -149,6 +161,7 @@
 
     val controller: MediaProjectionAppSelectorController
     val recentsViewController: MediaProjectionRecentsViewController
+    val emptyStateProvider: MediaProjectionBlockerEmptyStateProvider
     @get:HostUserHandle val hostUserHandle: UserHandle
     @get:PersonalProfile val personalProfileUserHandle: UserHandle
 
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt
index 52c7ca3..219629b 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorController.kt
@@ -36,16 +36,16 @@
     private val flags: FeatureFlags,
     @HostUserHandle private val hostUserHandle: UserHandle,
     @MediaProjectionAppSelector private val scope: CoroutineScope,
-    @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName
+    @MediaProjectionAppSelector private val appSelectorComponentName: ComponentName,
+    @MediaProjectionAppSelector private val callerPackageName: String?
 ) {
 
     fun init() {
         scope.launch {
             val recentTasks = recentTaskListProvider.loadRecentTasks()
 
-            val tasks = recentTasks
-                .filterDevicePolicyRestrictedTasks()
-                .sortedTasks()
+            val tasks =
+                recentTasks.filterDevicePolicyRestrictedTasks().filterAppSelector().sortedTasks()
 
             view.bind(tasks)
         }
@@ -67,8 +67,13 @@
             filter { UserHandle.of(it.userId) == hostUserHandle }
         }
 
+    private fun List<RecentTask>.filterAppSelector(): List<RecentTask> = filter {
+        // Only take tasks that is not the app selector
+        it.topActivityComponent != appSelectorComponentName
+    }
+
     private fun List<RecentTask>.sortedTasks(): List<RecentTask> = sortedBy {
         // Show normal tasks first and only then tasks with opened app selector
-        it.topActivityComponent == appSelectorComponentName
+        it.topActivityComponent?.packageName == callerPackageName
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 35423f4..d5d7325 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -30,7 +30,6 @@
 import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
-import static android.view.InsetsState.containsType;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
@@ -85,7 +84,6 @@
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.InsetsFrameProvider;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
@@ -97,6 +95,7 @@
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.InternalInsetsInfo;
 import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
+import android.view.WindowInsets;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowInsetsController.Behavior;
@@ -1150,12 +1149,11 @@
     }
 
     @Override
-    public void showTransient(int displayId, @InternalInsetsType int[] types,
-            boolean isGestureOnSystemBar) {
+    public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_NAVIGATION_BAR)) {
+        if ((types & WindowInsets.Type.navigationBars()) == 0) {
             return;
         }
         if (!mTransientShown) {
@@ -1166,11 +1164,11 @@
     }
 
     @Override
-    public void abortTransient(int displayId, @InternalInsetsType int[] types) {
+    public void abortTransient(int displayId, @InsetsType int types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_NAVIGATION_BAR)) {
+        if ((types & WindowInsets.Type.navigationBars()) == 0) {
             return;
         }
         clearTransient();
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index f3712e6..c3d7369 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -20,8 +20,6 @@
 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
-import static android.view.InsetsState.containsType;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
@@ -41,7 +39,6 @@
 
 import android.app.StatusBarManager;
 import android.app.StatusBarManager.WindowVisibleState;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -52,6 +49,7 @@
 import android.util.Log;
 import android.view.Display;
 import android.view.View;
+import android.view.WindowInsets;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowInsetsController.Behavior;
@@ -68,7 +66,6 @@
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -401,11 +398,11 @@
     }
 
     @Override
-    public void showTransient(int displayId, int[] types, boolean isGestureOnSystemBar) {
+    public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_EXTRA_NAVIGATION_BAR)) {
+        if ((types & WindowInsets.Type.navigationBars()) == 0) {
             return;
         }
         if (!mTaskbarTransientShowing) {
@@ -415,11 +412,11 @@
     }
 
     @Override
-    public void abortTransient(int displayId, int[] types) {
+    public void abortTransient(int displayId, @InsetsType int types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_EXTRA_NAVIGATION_BAR)) {
+        if ((types & WindowInsets.Type.navigationBars()) == 0) {
             return;
         }
         clearTransient();
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
index 2822435..f335733 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
@@ -1,14 +1,20 @@
 package com.android.systemui.navigationbar.gestural
 
 import android.content.Context
+import android.content.res.Configuration
+import android.content.res.TypedArray
 import android.graphics.Canvas
 import android.graphics.Paint
 import android.graphics.Path
 import android.graphics.RectF
+import android.util.MathUtils.min
+import android.util.TypedValue
 import android.view.View
+import androidx.appcompat.view.ContextThemeWrapper
 import androidx.dynamicanimation.animation.FloatPropertyCompat
 import androidx.dynamicanimation.animation.SpringAnimation
 import androidx.dynamicanimation.animation.SpringForce
+import com.android.internal.R.style.Theme_DeviceDefault
 import com.android.internal.util.LatencyTracker
 import com.android.settingslib.Utils
 import com.android.systemui.navigationbar.gestural.BackPanelController.DelayedOnAnimationEndListener
@@ -16,7 +22,10 @@
 private const val TAG = "BackPanel"
 private const val DEBUG = false
 
-class BackPanel(context: Context, private val latencyTracker: LatencyTracker) : View(context) {
+class BackPanel(
+        context: Context,
+        private val latencyTracker: LatencyTracker
+) : View(context) {
 
     var arrowsPointLeft = false
         set(value) {
@@ -45,52 +54,54 @@
     /**
      * The length of the arrow measured horizontally. Used for animating [arrowPath]
      */
-    private var arrowLength = AnimatedFloat("arrowLength", SpringForce())
+    private var arrowLength = AnimatedFloat(
+            name = "arrowLength",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS
+    )
 
     /**
      * The height of the arrow measured vertically from its center to its top (i.e. half the total
      * height). Used for animating [arrowPath]
      */
-    private var arrowHeight = AnimatedFloat("arrowHeight", SpringForce())
-
-    private val backgroundWidth = AnimatedFloat(
-        name = "backgroundWidth",
-        SpringForce().apply {
-            stiffness = 600f
-            dampingRatio = 0.65f
-        }
+    var arrowHeight = AnimatedFloat(
+            name = "arrowHeight",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ROTATION_DEGREES
     )
 
-    private val backgroundHeight = AnimatedFloat(
-        name = "backgroundHeight",
-        SpringForce().apply {
-            stiffness = 600f
-            dampingRatio = 0.65f
-        }
+    val backgroundWidth = AnimatedFloat(
+            name = "backgroundWidth",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS,
+            minimumValue = 0f,
+    )
+
+    val backgroundHeight = AnimatedFloat(
+            name = "backgroundHeight",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS,
+            minimumValue = 0f,
     )
 
     /**
      * Corners of the background closer to the edge of the screen (where the arrow appeared from).
      * Used for animating [arrowBackgroundRect]
      */
-    private val backgroundEdgeCornerRadius = AnimatedFloat(
-        name = "backgroundEdgeCornerRadius",
-        SpringForce().apply {
-            stiffness = 400f
-            dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
-        }
-    )
+    val backgroundEdgeCornerRadius = AnimatedFloat("backgroundEdgeCornerRadius")
 
     /**
      * Corners of the background further from the edge of the screens (toward the direction the
      * arrow is being dragged). Used for animating [arrowBackgroundRect]
      */
-    private val backgroundFarCornerRadius = AnimatedFloat(
-        name = "backgroundDragCornerRadius",
-        SpringForce().apply {
-            stiffness = 2200f
-            dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
-        }
+    val backgroundFarCornerRadius = AnimatedFloat("backgroundFarCornerRadius")
+
+    var scale = AnimatedFloat(
+            name = "scale",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_SCALE,
+            minimumValue = 0f
+    )
+
+    val scalePivotX = AnimatedFloat(
+            name = "scalePivotX",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_PIXELS,
+            minimumValue = backgroundWidth.pos / 2,
     )
 
     /**
@@ -98,34 +109,40 @@
      * background's margin relative to the screen edge. The arrow will be centered within the
      * background.
      */
-    private var horizontalTranslation = AnimatedFloat("horizontalTranslation", SpringForce())
+    var horizontalTranslation = AnimatedFloat(name = "horizontalTranslation")
 
-    private val currentAlpha: FloatPropertyCompat<BackPanel> =
-        object : FloatPropertyCompat<BackPanel>("currentAlpha") {
-            override fun setValue(panel: BackPanel, value: Float) {
-                panel.alpha = value
-            }
+    var arrowAlpha = AnimatedFloat(
+            name = "arrowAlpha",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA,
+            minimumValue = 0f,
+            maximumValue = 1f
+    )
 
-            override fun getValue(panel: BackPanel): Float = panel.alpha
-        }
+    val backgroundAlpha = AnimatedFloat(
+            name = "backgroundAlpha",
+            minimumVisibleChange = SpringAnimation.MIN_VISIBLE_CHANGE_ALPHA,
+            minimumValue = 0f,
+            maximumValue = 1f
+    )
 
-    private val alphaAnimation = SpringAnimation(this, currentAlpha)
-        .setSpring(
-            SpringForce()
-                .setStiffness(60f)
-                .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)
-        )
+    private val allAnimatedFloat = setOf(
+            arrowLength,
+            arrowHeight,
+            backgroundWidth,
+            backgroundEdgeCornerRadius,
+            backgroundFarCornerRadius,
+            scalePivotX,
+            scale,
+            horizontalTranslation,
+            arrowAlpha,
+            backgroundAlpha
+    )
 
     /**
      * Canvas vertical translation. How far up/down the arrow and background appear relative to the
      * canvas.
      */
-    private var verticalTranslation: AnimatedFloat = AnimatedFloat(
-        name = "verticalTranslation",
-        SpringForce().apply {
-            stiffness = SpringForce.STIFFNESS_MEDIUM
-        }
-    )
+    var verticalTranslation = AnimatedFloat("verticalTranslation")
 
     /**
      * Use for drawing debug info. Can only be set if [DEBUG]=true
@@ -136,28 +153,67 @@
         }
 
     internal fun updateArrowPaint(arrowThickness: Float) {
-        // Arrow constants
+
         arrowPaint.strokeWidth = arrowThickness
 
-        arrowPaint.color =
-            Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
-        arrowBackgroundPaint.color = Utils.getColorAccentDefaultColor(context)
+        val isDeviceInNightTheme = resources.configuration.uiMode and
+                Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
+
+        val colorControlActivated = ContextThemeWrapper(context, Theme_DeviceDefault)
+                .run {
+                    val typedValue = TypedValue()
+                    val a: TypedArray = obtainStyledAttributes(typedValue.data,
+                            intArrayOf(android.R.attr.colorControlActivated))
+                    val color = a.getColor(0, 0)
+                    a.recycle()
+                    color
+                }
+
+        val colorPrimary =
+                Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
+
+        arrowPaint.color = Utils.getColorAccentDefaultColor(context)
+
+        arrowBackgroundPaint.color = if (isDeviceInNightTheme) {
+            colorPrimary
+        } else {
+            colorControlActivated
+        }
     }
 
-    private inner class AnimatedFloat(name: String, springForce: SpringForce) {
+    inner class AnimatedFloat(
+            name: String,
+            private val minimumVisibleChange: Float? = null,
+            private val minimumValue: Float? = null,
+            private val maximumValue: Float? = null,
+    ) {
+
         // The resting position when not stretched by a touch drag
         private var restingPosition = 0f
 
         // The current position as updated by the SpringAnimation
         var pos = 0f
-            set(v) {
+            private set(v) {
                 if (field != v) {
                     field = v
                     invalidate()
                 }
             }
 
-        val animation: SpringAnimation
+        private val animation: SpringAnimation
+        var spring: SpringForce
+            get() = animation.spring
+            set(value) {
+                animation.cancel()
+                animation.spring = value
+            }
+
+        val isRunning: Boolean
+            get() = animation.isRunning
+
+        fun addEndListener(listener: DelayedOnAnimationEndListener) {
+            animation.addEndListener(listener)
+        }
 
         init {
             val floatProp = object : FloatPropertyCompat<AnimatedFloat>(name) {
@@ -167,8 +223,12 @@
 
                 override fun getValue(animatedFloat: AnimatedFloat): Float = animatedFloat.pos
             }
-            animation = SpringAnimation(this, floatProp)
-            animation.spring = springForce
+            animation = SpringAnimation(this, floatProp).apply {
+                spring = SpringForce()
+                this@AnimatedFloat.minimumValue?.let { setMinValue(it) }
+                this@AnimatedFloat.maximumValue?.let { setMaxValue(it) }
+                this@AnimatedFloat.minimumVisibleChange?.let { minimumVisibleChange = it }
+            }
         }
 
         fun snapTo(newPosition: Float) {
@@ -178,8 +238,24 @@
             pos = newPosition
         }
 
-        fun stretchTo(stretchAmount: Float) {
-            animation.animateToFinalPosition(restingPosition + stretchAmount)
+        fun snapToRestingPosition() {
+            snapTo(restingPosition)
+        }
+
+
+        fun stretchTo(
+                stretchAmount: Float,
+                startingVelocity: Float? = null,
+                springForce: SpringForce? = null
+        ) {
+            animation.apply {
+                startingVelocity?.let {
+                    cancel()
+                    setStartVelocity(it)
+                }
+                springForce?.let { spring = springForce }
+                animateToFinalPosition(restingPosition + stretchAmount)
+            }
         }
 
         /**
@@ -188,18 +264,23 @@
          *
          * The [restingPosition] will remain unchanged. Only the animation is updated.
          */
-        fun stretchBy(finalPosition: Float, amount: Float) {
-            val stretchedAmount = amount * (finalPosition - restingPosition)
+        fun stretchBy(finalPosition: Float?, amount: Float) {
+            val stretchedAmount = amount * ((finalPosition ?: 0f) - restingPosition)
             animation.animateToFinalPosition(restingPosition + stretchedAmount)
         }
 
-        fun updateRestingPosition(pos: Float, animated: Boolean) {
+        fun updateRestingPosition(pos: Float?, animated: Boolean = true) {
+            if (pos == null) return
+
             restingPosition = pos
-            if (animated)
+            if (animated) {
                 animation.animateToFinalPosition(restingPosition)
-            else
+            } else {
                 snapTo(restingPosition)
+            }
         }
+
+        fun cancel() = animation.cancel()
     }
 
     init {
@@ -224,126 +305,203 @@
         return arrowPath
     }
 
-    fun addEndListener(endListener: DelayedOnAnimationEndListener): Boolean {
-        return if (alphaAnimation.isRunning) {
-            alphaAnimation.addEndListener(endListener)
-            true
-        } else if (horizontalTranslation.animation.isRunning) {
-            horizontalTranslation.animation.addEndListener(endListener)
+    fun addAnimationEndListener(
+            animatedFloat: AnimatedFloat,
+            endListener: DelayedOnAnimationEndListener
+    ): Boolean {
+        return if (animatedFloat.isRunning) {
+            animatedFloat.addEndListener(endListener)
             true
         } else {
-            endListener.runNow()
+            endListener.run()
             false
         }
     }
 
+    fun cancelAnimations() {
+        allAnimatedFloat.forEach { it.cancel() }
+    }
+
     fun setStretch(
-        horizontalTranslationStretchAmount: Float,
-        arrowStretchAmount: Float,
-        backgroundWidthStretchAmount: Float,
-        fullyStretchedDimens: EdgePanelParams.BackIndicatorDimens
+            horizontalTranslationStretchAmount: Float,
+            arrowStretchAmount: Float,
+            arrowAlphaStretchAmount: Float,
+            backgroundAlphaStretchAmount: Float,
+            backgroundWidthStretchAmount: Float,
+            backgroundHeightStretchAmount: Float,
+            edgeCornerStretchAmount: Float,
+            farCornerStretchAmount: Float,
+            fullyStretchedDimens: EdgePanelParams.BackIndicatorDimens
     ) {
         horizontalTranslation.stretchBy(
-            finalPosition = fullyStretchedDimens.horizontalTranslation,
-            amount = horizontalTranslationStretchAmount
+                finalPosition = fullyStretchedDimens.horizontalTranslation,
+                amount = horizontalTranslationStretchAmount
         )
         arrowLength.stretchBy(
-            finalPosition = fullyStretchedDimens.arrowDimens.length,
-            amount = arrowStretchAmount
+                finalPosition = fullyStretchedDimens.arrowDimens.length,
+                amount = arrowStretchAmount
         )
         arrowHeight.stretchBy(
-            finalPosition = fullyStretchedDimens.arrowDimens.height,
-            amount = arrowStretchAmount
+                finalPosition = fullyStretchedDimens.arrowDimens.height,
+                amount = arrowStretchAmount
+        )
+        arrowAlpha.stretchBy(
+                finalPosition = fullyStretchedDimens.arrowDimens.alpha,
+                amount = arrowAlphaStretchAmount
+        )
+        backgroundAlpha.stretchBy(
+                finalPosition = fullyStretchedDimens.backgroundDimens.alpha,
+                amount = backgroundAlphaStretchAmount
         )
         backgroundWidth.stretchBy(
-            finalPosition = fullyStretchedDimens.backgroundDimens.width,
-            amount = backgroundWidthStretchAmount
+                finalPosition = fullyStretchedDimens.backgroundDimens.width,
+                amount = backgroundWidthStretchAmount
+        )
+        backgroundHeight.stretchBy(
+                finalPosition = fullyStretchedDimens.backgroundDimens.height,
+                amount = backgroundHeightStretchAmount
+        )
+        backgroundEdgeCornerRadius.stretchBy(
+                finalPosition = fullyStretchedDimens.backgroundDimens.edgeCornerRadius,
+                amount = edgeCornerStretchAmount
+        )
+        backgroundFarCornerRadius.stretchBy(
+                finalPosition = fullyStretchedDimens.backgroundDimens.farCornerRadius,
+                amount = farCornerStretchAmount
         )
     }
 
+    fun popOffEdge(startingVelocity: Float) {
+        val heightStretchAmount = startingVelocity * 50
+        val widthStretchAmount = startingVelocity * 150
+        val scaleStretchAmount = startingVelocity * 0.8f
+        backgroundHeight.stretchTo(stretchAmount = 0f, startingVelocity = -heightStretchAmount)
+        backgroundWidth.stretchTo(stretchAmount = 0f, startingVelocity = widthStretchAmount)
+        scale.stretchTo(stretchAmount = 0f, startingVelocity = -scaleStretchAmount)
+    }
+
+    fun popScale(startingVelocity: Float) {
+        scalePivotX.snapTo(backgroundWidth.pos / 2)
+        scale.stretchTo(stretchAmount = 0f, startingVelocity = startingVelocity)
+    }
+
+    fun popArrowAlpha(startingVelocity: Float, springForce: SpringForce? = null) {
+        arrowAlpha.stretchTo(stretchAmount = 0f, startingVelocity = startingVelocity,
+                springForce = springForce)
+    }
+
     fun resetStretch() {
-        horizontalTranslation.stretchTo(0f)
-        arrowLength.stretchTo(0f)
-        arrowHeight.stretchTo(0f)
-        backgroundWidth.stretchTo(0f)
-        backgroundHeight.stretchTo(0f)
-        backgroundEdgeCornerRadius.stretchTo(0f)
-        backgroundFarCornerRadius.stretchTo(0f)
+        backgroundAlpha.snapTo(1f)
+        verticalTranslation.snapTo(0f)
+        scale.snapTo(1f)
+
+        horizontalTranslation.snapToRestingPosition()
+        arrowLength.snapToRestingPosition()
+        arrowHeight.snapToRestingPosition()
+        arrowAlpha.snapToRestingPosition()
+        backgroundWidth.snapToRestingPosition()
+        backgroundHeight.snapToRestingPosition()
+        backgroundEdgeCornerRadius.snapToRestingPosition()
+        backgroundFarCornerRadius.snapToRestingPosition()
     }
 
     /**
      * Updates resting arrow and background size not accounting for stretch
      */
     internal fun setRestingDimens(
-        restingParams: EdgePanelParams.BackIndicatorDimens,
-        animate: Boolean
+            restingParams: EdgePanelParams.BackIndicatorDimens,
+            animate: Boolean = true
     ) {
-        horizontalTranslation.updateRestingPosition(restingParams.horizontalTranslation, animate)
+        horizontalTranslation.updateRestingPosition(restingParams.horizontalTranslation)
+        scale.updateRestingPosition(restingParams.scale)
+        arrowAlpha.updateRestingPosition(restingParams.arrowDimens.alpha)
+        backgroundAlpha.updateRestingPosition(restingParams.backgroundDimens.alpha)
+
         arrowLength.updateRestingPosition(restingParams.arrowDimens.length, animate)
         arrowHeight.updateRestingPosition(restingParams.arrowDimens.height, animate)
+        scalePivotX.updateRestingPosition(restingParams.backgroundDimens.width, animate)
         backgroundWidth.updateRestingPosition(restingParams.backgroundDimens.width, animate)
         backgroundHeight.updateRestingPosition(restingParams.backgroundDimens.height, animate)
         backgroundEdgeCornerRadius.updateRestingPosition(
-            restingParams.backgroundDimens.edgeCornerRadius,
-            animate
+                restingParams.backgroundDimens.edgeCornerRadius, animate
         )
         backgroundFarCornerRadius.updateRestingPosition(
-            restingParams.backgroundDimens.farCornerRadius,
-            animate
+                restingParams.backgroundDimens.farCornerRadius, animate
         )
     }
 
     fun animateVertically(yPos: Float) = verticalTranslation.stretchTo(yPos)
 
-    fun setArrowStiffness(arrowStiffness: Float, arrowDampingRatio: Float) {
-        arrowLength.animation.spring.apply {
-            stiffness = arrowStiffness
-            dampingRatio = arrowDampingRatio
-        }
-        arrowHeight.animation.spring.apply {
-            stiffness = arrowStiffness
-            dampingRatio = arrowDampingRatio
-        }
+    fun setSpring(
+            horizontalTranslation: SpringForce? = null,
+            verticalTranslation: SpringForce? = null,
+            scale: SpringForce? = null,
+            arrowLength: SpringForce? = null,
+            arrowHeight: SpringForce? = null,
+            arrowAlpha: SpringForce? = null,
+            backgroundAlpha: SpringForce? = null,
+            backgroundFarCornerRadius: SpringForce? = null,
+            backgroundEdgeCornerRadius: SpringForce? = null,
+            backgroundWidth: SpringForce? = null,
+            backgroundHeight: SpringForce? = null,
+    ) {
+        arrowLength?.let { this.arrowLength.spring = it }
+        arrowHeight?.let { this.arrowHeight.spring = it }
+        arrowAlpha?.let { this.arrowAlpha.spring = it }
+        backgroundAlpha?.let { this.backgroundAlpha.spring = it }
+        backgroundFarCornerRadius?.let { this.backgroundFarCornerRadius.spring = it }
+        backgroundEdgeCornerRadius?.let { this.backgroundEdgeCornerRadius.spring = it }
+        scale?.let { this.scale.spring = it }
+        backgroundWidth?.let { this.backgroundWidth.spring = it }
+        backgroundHeight?.let { this.backgroundHeight.spring = it }
+        horizontalTranslation?.let { this.horizontalTranslation.spring = it }
+        verticalTranslation?.let { this.verticalTranslation.spring = it }
     }
 
     override fun hasOverlappingRendering() = false
 
     override fun onDraw(canvas: Canvas) {
-        var edgeCorner = backgroundEdgeCornerRadius.pos
+        val edgeCorner = backgroundEdgeCornerRadius.pos
         val farCorner = backgroundFarCornerRadius.pos
         val halfHeight = backgroundHeight.pos / 2
+        val canvasWidth = width
+        val backgroundWidth = backgroundWidth.pos
+        val scalePivotX = scalePivotX.pos
 
         canvas.save()
 
-        if (!isLeftPanel) canvas.scale(-1f, 1f, width / 2.0f, 0f)
+        if (!isLeftPanel) canvas.scale(-1f, 1f, canvasWidth / 2.0f, 0f)
 
         canvas.translate(
-            horizontalTranslation.pos,
-            height * 0.5f + verticalTranslation.pos
+                horizontalTranslation.pos,
+                height * 0.5f + verticalTranslation.pos
         )
 
+        canvas.scale(scale.pos, scale.pos, scalePivotX, 0f)
+
         val arrowBackground = arrowBackgroundRect.apply {
             left = 0f
             top = -halfHeight
-            right = backgroundWidth.pos
+            right = backgroundWidth
             bottom = halfHeight
         }.toPathWithRoundCorners(
-            topLeft = edgeCorner,
-            bottomLeft = edgeCorner,
-            topRight = farCorner,
-            bottomRight = farCorner
+                topLeft = edgeCorner,
+                bottomLeft = edgeCorner,
+                topRight = farCorner,
+                bottomRight = farCorner
         )
-        canvas.drawPath(arrowBackground, arrowBackgroundPaint)
+        canvas.drawPath(arrowBackground,
+                arrowBackgroundPaint.apply { alpha = (255 * backgroundAlpha.pos).toInt() })
 
         val dx = arrowLength.pos
         val dy = arrowHeight.pos
 
         // How far the arrow bounding box should be from the edge of the screen. Measured from
         // either the tip or the back of the arrow, whichever is closer
-        var arrowOffset = (backgroundWidth.pos - dx) / 2
+        val arrowOffset = (backgroundWidth - dx) / 2
         canvas.translate(
-            /* dx= */ arrowOffset,
-            /* dy= */ 0f /* pass 0 for the y position since the canvas was already translated */
+                /* dx= */ arrowOffset,
+                /* dy= */ 0f /* pass 0 for the y position since the canvas was already translated */
         )
 
         val arrowPointsAwayFromEdge = !arrowsPointLeft.xor(isLeftPanel)
@@ -355,6 +513,8 @@
         }
 
         val arrowPath = calculateArrowPath(dx = dx, dy = dy)
+        val arrowPaint = arrowPaint
+                .apply { alpha = (255 * min(arrowAlpha.pos, backgroundAlpha.pos)).toInt() }
         canvas.drawPath(arrowPath, arrowPaint)
         canvas.restore()
 
@@ -372,26 +532,17 @@
     }
 
     private fun RectF.toPathWithRoundCorners(
-        topLeft: Float = 0f,
-        topRight: Float = 0f,
-        bottomRight: Float = 0f,
-        bottomLeft: Float = 0f
+            topLeft: Float = 0f,
+            topRight: Float = 0f,
+            bottomRight: Float = 0f,
+            bottomLeft: Float = 0f
     ): Path = Path().apply {
         val corners = floatArrayOf(
-            topLeft, topLeft,
-            topRight, topRight,
-            bottomRight, bottomRight,
-            bottomLeft, bottomLeft
+                topLeft, topLeft,
+                topRight, topRight,
+                bottomRight, bottomRight,
+                bottomLeft, bottomLeft
         )
         addRoundRect(this@toPathWithRoundCorners, corners, Path.Direction.CW)
     }
-
-    fun cancelAlphaAnimations() {
-        alphaAnimation.cancel()
-        alpha = 1f
-    }
-
-    fun fadeOut() {
-        alphaAnimation.animateToFinalPosition(0f)
-    }
-}
+}
\ No newline at end of file
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 1950c69..f409b23 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -24,21 +24,18 @@
 import android.os.SystemClock
 import android.os.VibrationEffect
 import android.util.Log
-import android.util.MathUtils.constrain
-import android.util.MathUtils.saturate
+import android.util.MathUtils
 import android.view.Gravity
 import android.view.MotionEvent
 import android.view.VelocityTracker
-import android.view.View
 import android.view.ViewConfiguration
 import android.view.WindowManager
-import android.view.animation.DecelerateInterpolator
-import android.view.animation.PathInterpolator
+import androidx.annotation.VisibleForTesting
+import androidx.core.os.postDelayed
+import androidx.core.view.isVisible
 import androidx.dynamicanimation.animation.DynamicAnimation
-import androidx.dynamicanimation.animation.SpringForce
 import com.android.internal.util.LatencyTracker
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.plugins.MotionEventsHandlerBase
 import com.android.systemui.plugins.NavigationEdgeBackPlugin
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.ConfigurationController
@@ -51,58 +48,42 @@
 import kotlin.math.sign
 
 private const val TAG = "BackPanelController"
-private const val DEBUG = false
-
 private const val ENABLE_FAILSAFE = true
 
-private const val FAILSAFE_DELAY_MS: Long = 350
+private const val PX_PER_SEC = 1000
+private const val PX_PER_MS = 1
 
-/**
- * The time required between the arrow-appears vibration effect and the back-committed vibration
- * effect. If the arrow is flung quickly, the phone only vibrates once. However, if the arrow is
- * held on the screen for a long time, it will vibrate a second time when the back gesture is
- * committed.
- */
-private const val GESTURE_DURATION_FOR_CLICK_MS = 400
+internal const val MIN_DURATION_ACTIVE_ANIMATION = 300L
+private const val MIN_DURATION_CANCELLED_ANIMATION = 200L
+private const val MIN_DURATION_COMMITTED_ANIMATION = 200L
+private const val MIN_DURATION_INACTIVE_BEFORE_FLUNG_ANIMATION = 50L
+private const val MIN_DURATION_CONSIDERED_AS_FLING = 100L
 
-/**
- * The min duration arrow remains on screen during a fling event.
- */
-private const val FLING_MIN_APPEARANCE_DURATION = 235L
+private const val FAILSAFE_DELAY_MS = 350L
+private const val POP_ON_FLING_DELAY = 160L
 
-/**
- * The min duration arrow remains on screen during a fling event.
- */
-private const val MIN_FLING_VELOCITY = 3000
+internal val VIBRATE_ACTIVATED_EFFECT =
+        VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)
 
-/**
- * The amount of rubber banding we do for the vertical translation
- */
-private const val RUBBER_BAND_AMOUNT = 15
+internal val VIBRATE_DEACTIVATED_EFFECT =
+        VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)
 
-private const val ARROW_APPEAR_STIFFNESS = 600f
-private const val ARROW_APPEAR_DAMPING_RATIO = 0.4f
-private const val ARROW_DISAPPEAR_STIFFNESS = 1200f
-private const val ARROW_DISAPPEAR_DAMPING_RATIO = SpringForce.DAMPING_RATIO_NO_BOUNCY
+private const val DEBUG = false
 
-/**
- * The interpolator used to rubber band
- */
-private val RUBBER_BAND_INTERPOLATOR = PathInterpolator(1.0f / 5.0f, 1.0f, 1.0f, 1.0f)
-
-private val DECELERATE_INTERPOLATOR = DecelerateInterpolator()
-
-private val DECELERATE_INTERPOLATOR_SLOW = DecelerateInterpolator(0.7f)
-
-class BackPanelController private constructor(
-    context: Context,
-    private val windowManager: WindowManager,
-    private val viewConfiguration: ViewConfiguration,
-    @Main private val mainHandler: Handler,
-    private val vibratorHelper: VibratorHelper,
-    private val configurationController: ConfigurationController,
-    latencyTracker: LatencyTracker
-) : ViewController<BackPanel>(BackPanel(context, latencyTracker)), NavigationEdgeBackPlugin {
+class BackPanelController internal constructor(
+        context: Context,
+        private val windowManager: WindowManager,
+        private val viewConfiguration: ViewConfiguration,
+        @Main private val mainHandler: Handler,
+        private val vibratorHelper: VibratorHelper,
+        private val configurationController: ConfigurationController,
+        private val latencyTracker: LatencyTracker
+) : ViewController<BackPanel>(
+        BackPanel(
+                context,
+                latencyTracker
+        )
+), NavigationEdgeBackPlugin {
 
     /**
      * Injectable instance to create a new BackPanelController.
@@ -111,44 +92,44 @@
      * BackPanelController, and we need to match EdgeBackGestureHandler's context.
      */
     class Factory @Inject constructor(
-        private val windowManager: WindowManager,
-        private val viewConfiguration: ViewConfiguration,
-        @Main private val mainHandler: Handler,
-        private val vibratorHelper: VibratorHelper,
-        private val configurationController: ConfigurationController,
-        private val latencyTracker: LatencyTracker
+            private val windowManager: WindowManager,
+            private val viewConfiguration: ViewConfiguration,
+            @Main private val mainHandler: Handler,
+            private val vibratorHelper: VibratorHelper,
+            private val configurationController: ConfigurationController,
+            private val latencyTracker: LatencyTracker
     ) {
         /** Construct a [BackPanelController].  */
         fun create(context: Context): BackPanelController {
             val backPanelController = BackPanelController(
-                context,
-                windowManager,
-                viewConfiguration,
-                mainHandler,
-                vibratorHelper,
-                configurationController,
-                latencyTracker
+                    context,
+                    windowManager,
+                    viewConfiguration,
+                    mainHandler,
+                    vibratorHelper,
+                    configurationController,
+                    latencyTracker
             )
             backPanelController.init()
             return backPanelController
         }
     }
 
-    private var params: EdgePanelParams = EdgePanelParams(resources)
-    private var currentState: GestureState = GestureState.GONE
+    @VisibleForTesting
+    internal var params: EdgePanelParams = EdgePanelParams(resources)
+    @VisibleForTesting
+    internal var currentState: GestureState = GestureState.GONE
     private var previousState: GestureState = GestureState.GONE
 
-    // Phone should only vibrate the first time the arrow is activated
-    private var hasHapticPlayed = false
-
     // Screen attributes
     private lateinit var layoutParams: WindowManager.LayoutParams
     private val displaySize = Point()
 
     private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback
-
+    private var previousXTranslationOnActiveOffset = 0f
     private var previousXTranslation = 0f
     private var totalTouchDelta = 0f
+    private var touchDeltaStartX = 0f
     private var velocityTracker: VelocityTracker? = null
         set(value) {
             if (field != value) field?.recycle()
@@ -162,8 +143,18 @@
     // The x,y position of the first touch event
     private var startX = 0f
     private var startY = 0f
+    private var startIsLeft: Boolean? = null
 
-    private var gestureStartTime = 0L
+    private var gestureSinceActionDown = 0L
+    private var gestureEntryTime = 0L
+    private var gestureActiveTime = 0L
+    private var gestureInactiveOrEntryTime = 0L
+    private var gestureArrowStrokeVisibleTime = 0L
+
+    private val elapsedTimeSinceActionDown
+        get() = SystemClock.uptimeMillis() - gestureSinceActionDown
+    private val elapsedTimeSinceEntry
+        get() = SystemClock.uptimeMillis() - gestureEntryTime
 
     // Whether the current gesture has moved a sufficiently large amount,
     // so that we can unambiguously start showing the ENTRY animation
@@ -171,7 +162,7 @@
 
     private val failsafeRunnable = Runnable { onFailsafe() }
 
-    private enum class GestureState {
+    internal enum class GestureState {
         /* Arrow is off the screen and invisible */
         GONE,
 
@@ -192,17 +183,6 @@
 
         /* back action currently cancelling, arrow soon to be GONE */
         CANCELLED;
-
-        /**
-         * @return true if the current state responds to touch move events in some way (e.g. by
-         * stretching the back indicator)
-         */
-        fun isInteractive(): Boolean {
-            return when (this) {
-                ENTRY, ACTIVE, INACTIVE -> true
-                GONE, FLUNG, COMMITTED, CANCELLED -> false
-            }
-        }
     }
 
     /**
@@ -210,50 +190,43 @@
      * runnable is not called if the animation is cancelled
      */
     inner class DelayedOnAnimationEndListener internal constructor(
-        private val handler: Handler,
-        private val runnable: Runnable,
-        private val minDuration: Long
+            private val handler: Handler,
+            private val runnableDelay: Long,
+            val runnable: Runnable,
     ) : DynamicAnimation.OnAnimationEndListener {
+
         override fun onAnimationEnd(
-            animation: DynamicAnimation<*>,
-            canceled: Boolean,
-            value: Float,
-            velocity: Float
+                animation: DynamicAnimation<*>,
+                canceled: Boolean,
+                value: Float,
+                velocity: Float
         ) {
             animation.removeEndListener(this)
+
             if (!canceled) {
-                // Total elapsed time of the gesture and the animation
-                val totalElapsedTime = SystemClock.uptimeMillis() - gestureStartTime
+
                 // The delay between finishing this animation and starting the runnable
-                val delay = max(0, minDuration - totalElapsedTime)
+                val delay = max(0, runnableDelay - elapsedTimeSinceEntry)
+
                 handler.postDelayed(runnable, delay)
             }
         }
 
-        internal fun runNow() {
-            runnable.run()
-        }
+        internal fun run() = runnable.run()
     }
 
-    private val setCommittedEndListener =
-        DelayedOnAnimationEndListener(
-            mainHandler,
-            { updateArrowState(GestureState.COMMITTED) },
-            minDuration = FLING_MIN_APPEARANCE_DURATION
-        )
+    private val onEndSetCommittedStateListener = DelayedOnAnimationEndListener(mainHandler, 0L) {
+        updateArrowState(GestureState.COMMITTED)
+    }
 
-    private val setGoneEndListener =
-        DelayedOnAnimationEndListener(
-            mainHandler,
-            {
+
+    private val onEndSetGoneStateListener =
+            DelayedOnAnimationEndListener(mainHandler, runnableDelay = 0L) {
                 cancelFailsafe()
                 updateArrowState(GestureState.GONE)
-            },
-            minDuration = 0
-        )
+            }
 
-    // Vibration
-    private var vibrationTime: Long = 0
+    private val playAnimationThenSetGoneOnAlphaEnd = Runnable { playAnimationThenSetGoneEnd() }
 
     // Minimum of the screen's width or the predefined threshold
     private var fullyStretchedThreshold = 0f
@@ -280,7 +253,7 @@
         updateConfiguration()
         updateArrowDirection(configurationController.isLayoutRtl)
         updateArrowState(GestureState.GONE, force = true)
-        updateRestingArrowDimens(animated = false, currentState)
+        updateRestingArrowDimens()
         configurationController.addCallback(configurationListener)
     }
 
@@ -297,22 +270,57 @@
         velocityTracker!!.addMovement(event)
         when (event.actionMasked) {
             MotionEvent.ACTION_DOWN -> {
-                resetOnDown()
+                gestureSinceActionDown = SystemClock.uptimeMillis()
+                cancelAllPendingAnimations()
                 startX = event.x
                 startY = event.y
-                gestureStartTime = SystemClock.uptimeMillis()
+
+                updateArrowState(GestureState.GONE)
+                updateYStartPosition(startY)
+
+                // reset animation properties
+                startIsLeft = mView.isLeftPanel
+                hasPassedDragSlop = false
+                mView.resetStretch()
             }
             MotionEvent.ACTION_MOVE -> {
-                // only go to the ENTRY state after some minimum motion has occurred
                 if (dragSlopExceeded(event.x, startX)) {
                     handleMoveEvent(event)
                 }
             }
             MotionEvent.ACTION_UP -> {
-                if (currentState == GestureState.ACTIVE) {
-                    updateArrowState(if (isFlung()) GestureState.FLUNG else GestureState.COMMITTED)
-                } else if (currentState != GestureState.GONE) { // if invisible, skip animation
-                    updateArrowState(GestureState.CANCELLED)
+                when (currentState) {
+                    GestureState.ENTRY -> {
+                        if (isFlungAwayFromEdge(endX = event.x)) {
+                            updateArrowState(GestureState.ACTIVE)
+                            updateArrowState(GestureState.FLUNG)
+                        } else {
+                            updateArrowState(GestureState.CANCELLED)
+                        }
+                    }
+                    GestureState.INACTIVE -> {
+                        if (isFlungAwayFromEdge(endX = event.x)) {
+                            mainHandler.postDelayed(MIN_DURATION_INACTIVE_BEFORE_FLUNG_ANIMATION) {
+                                updateArrowState(GestureState.ACTIVE)
+                                updateArrowState(GestureState.FLUNG)
+                            }
+                        } else {
+                            updateArrowState(GestureState.CANCELLED)
+                        }
+                    }
+                    GestureState.ACTIVE -> {
+                        if (elapsedTimeSinceEntry < MIN_DURATION_CONSIDERED_AS_FLING) {
+                            updateArrowState(GestureState.FLUNG)
+                        } else {
+                            updateArrowState(GestureState.COMMITTED)
+                        }
+                    }
+                    GestureState.GONE,
+                    GestureState.FLUNG,
+                    GestureState.COMMITTED,
+                    GestureState.CANCELLED -> {
+                        updateArrowState(GestureState.CANCELLED)
+                    }
                 }
                 velocityTracker = null
             }
@@ -326,6 +334,14 @@
         }
     }
 
+    private fun cancelAllPendingAnimations() {
+        cancelFailsafe()
+        mView.cancelAnimations()
+        mainHandler.removeCallbacks(onEndSetCommittedStateListener.runnable)
+        mainHandler.removeCallbacks(onEndSetGoneStateListener.runnable)
+        mainHandler.removeCallbacks(playAnimationThenSetGoneOnAlphaEnd)
+    }
+
     /**
      * Returns false until the current gesture exceeds the touch slop threshold,
      * and returns true thereafter (we reset on the subsequent back gesture).
@@ -336,7 +352,7 @@
     private fun dragSlopExceeded(curX: Float, startX: Float): Boolean {
         if (hasPassedDragSlop) return true
 
-        if (abs(curX - startX) > viewConfiguration.scaledTouchSlop) {
+        if (abs(curX - startX) > viewConfiguration.scaledEdgeSlop) {
             // Reset the arrow to the side
             updateArrowState(GestureState.ENTRY)
 
@@ -349,39 +365,46 @@
     }
 
     private fun updateArrowStateOnMove(yTranslation: Float, xTranslation: Float) {
-        if (!currentState.isInteractive())
-            return
+
+        val isWithinYActivationThreshold = xTranslation * 2 >= yTranslation
 
         when (currentState) {
-            // Check if we should transition from ENTRY to ACTIVE
-            GestureState.ENTRY ->
-                if (xTranslation > params.swipeTriggerThreshold) {
+            GestureState.ENTRY -> {
+                if (xTranslation > params.staticTriggerThreshold) {
                     updateArrowState(GestureState.ACTIVE)
                 }
+            }
+            GestureState.ACTIVE -> {
+                val isPastDynamicDeactivationThreshold =
+                        totalTouchDelta <= params.deactivationSwipeTriggerThreshold
+                val isMinDurationElapsed =
+                        elapsedTimeSinceActionDown > MIN_DURATION_ACTIVE_ANIMATION
 
-            // Abort if we had continuous motion toward the edge for a while, OR the direction
-            // in Y is bigger than X * 2
-            GestureState.ACTIVE ->
-                if ((totalTouchDelta < 0 && -totalTouchDelta > params.minDeltaForSwitch) ||
-                    (yTranslation > xTranslation * 2)
+                if (isMinDurationElapsed && (!isWithinYActivationThreshold ||
+                                isPastDynamicDeactivationThreshold)
                 ) {
                     updateArrowState(GestureState.INACTIVE)
                 }
+            }
+            GestureState.INACTIVE -> {
+                val isPastStaticThreshold =
+                        xTranslation > params.staticTriggerThreshold
+                val isPastDynamicReactivationThreshold = totalTouchDelta > 0 &&
+                        abs(totalTouchDelta) >=
+                        params.reactivationTriggerThreshold
 
-            //  Re-activate if we had continuous motion away from the edge for a while
-            GestureState.INACTIVE ->
-                if (totalTouchDelta > 0 && totalTouchDelta > params.minDeltaForSwitch) {
+                if (isPastStaticThreshold &&
+                        isPastDynamicReactivationThreshold &&
+                        isWithinYActivationThreshold
+                ) {
                     updateArrowState(GestureState.ACTIVE)
                 }
-
-            // By default assume the current direction is kept
+            }
             else -> {}
         }
     }
 
     private fun handleMoveEvent(event: MotionEvent) {
-        if (!currentState.isInteractive())
-            return
 
         val x = event.x
         val y = event.y
@@ -401,23 +424,44 @@
         previousXTranslation = xTranslation
 
         if (abs(xDelta) > 0) {
-            if (sign(xDelta) == sign(totalTouchDelta)) {
+            val range =
+                params.run { deactivationSwipeTriggerThreshold..reactivationTriggerThreshold }
+            val isTouchInContinuousDirection =
+                    sign(xDelta) == sign(totalTouchDelta) || totalTouchDelta in range
+
+            if (isTouchInContinuousDirection) {
                 // Direction has NOT changed, so keep counting the delta
                 totalTouchDelta += xDelta
             } else {
                 // Direction has changed, so reset the delta
                 totalTouchDelta = xDelta
+                touchDeltaStartX = x
             }
         }
 
         updateArrowStateOnMove(yTranslation, xTranslation)
+
         when (currentState) {
-            GestureState.ACTIVE ->
-                stretchActiveBackIndicator(fullScreenStretchProgress(xTranslation))
-            GestureState.ENTRY ->
-                stretchEntryBackIndicator(preThresholdStretchProgress(xTranslation))
-            GestureState.INACTIVE ->
-                mView.resetStretch()
+            GestureState.ACTIVE -> {
+                stretchActiveBackIndicator(fullScreenProgress(xTranslation))
+            }
+            GestureState.ENTRY -> {
+                val progress = staticThresholdProgress(xTranslation)
+                stretchEntryBackIndicator(progress)
+
+                params.arrowStrokeAlphaSpring.get(progress).takeIf { it.isNewState }?.let {
+                    mView.popArrowAlpha(0f, it.value)
+                }
+            }
+            GestureState.INACTIVE -> {
+                val progress = reactivationThresholdProgress(totalTouchDelta)
+                stretchInactiveBackIndicator(progress)
+
+                params.arrowStrokeAlphaSpring.get(progress).takeIf { it.isNewState }?.let {
+                    gestureArrowStrokeVisibleTime = SystemClock.uptimeMillis()
+                    mView.popArrowAlpha(0f, it.value)
+                }
+            }
             else -> {}
         }
 
@@ -428,21 +472,22 @@
     private fun setVerticalTranslation(yOffset: Float) {
         val yTranslation = abs(yOffset)
         val maxYOffset = (mView.height - params.entryIndicator.backgroundDimens.height) / 2f
-        val yProgress = saturate(yTranslation / (maxYOffset * RUBBER_BAND_AMOUNT))
-        mView.animateVertically(
-            RUBBER_BAND_INTERPOLATOR.getInterpolation(yProgress) * maxYOffset *
+        val rubberbandAmount = 15f
+        val yProgress = MathUtils.saturate(yTranslation / (maxYOffset * rubberbandAmount))
+        val yPosition = params.translationInterpolator.getInterpolation(yProgress) *
+                maxYOffset *
                 sign(yOffset)
-        )
+        mView.animateVertically(yPosition)
     }
 
     /**
-     * @return the relative position of the drag from the time after the arrow is activated until
+     * Tracks the relative position of the drag from the time after the arrow is activated until
      * the arrow is fully stretched (between 0.0 - 1.0f)
      */
-    private fun fullScreenStretchProgress(xTranslation: Float): Float {
-        return saturate(
-            (xTranslation - params.swipeTriggerThreshold) /
-                (fullyStretchedThreshold - params.swipeTriggerThreshold)
+    private fun fullScreenProgress(xTranslation: Float): Float {
+        return MathUtils.saturate(
+                (xTranslation - previousXTranslationOnActiveOffset) /
+                        (fullyStretchedThreshold - previousXTranslationOnActiveOffset)
         )
     }
 
@@ -450,26 +495,74 @@
      * Tracks the relative position of the drag from the entry until the threshold where the arrow
      * activates (between 0.0 - 1.0f)
      */
-    private fun preThresholdStretchProgress(xTranslation: Float): Float {
-        return saturate(xTranslation / params.swipeTriggerThreshold)
+    private fun staticThresholdProgress(xTranslation: Float): Float {
+        return MathUtils.saturate(xTranslation / params.staticTriggerThreshold)
+    }
+
+    private fun reactivationThresholdProgress(totalTouchDelta: Float): Float {
+        return MathUtils.saturate(totalTouchDelta / params.reactivationTriggerThreshold)
     }
 
     private fun stretchActiveBackIndicator(progress: Float) {
-        val rubberBandIterpolation = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
         mView.setStretch(
-            horizontalTranslationStretchAmount = rubberBandIterpolation,
-            arrowStretchAmount = rubberBandIterpolation,
-            backgroundWidthStretchAmount = DECELERATE_INTERPOLATOR_SLOW.getInterpolation(progress),
-            params.fullyStretchedIndicator
+                horizontalTranslationStretchAmount = params.translationInterpolator
+                        .getInterpolation(progress),
+                arrowStretchAmount = params.arrowAngleInterpolator.getInterpolation(progress),
+                backgroundWidthStretchAmount = params.activeWidthInterpolator
+                        .getInterpolation(progress),
+                backgroundAlphaStretchAmount = 1f,
+                backgroundHeightStretchAmount = 1f,
+                arrowAlphaStretchAmount = 1f,
+                edgeCornerStretchAmount = 1f,
+                farCornerStretchAmount = 1f,
+                fullyStretchedDimens = params.fullyStretchedIndicator
         )
     }
 
     private fun stretchEntryBackIndicator(progress: Float) {
         mView.setStretch(
-            horizontalTranslationStretchAmount = 0f,
-            arrowStretchAmount = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress),
-            backgroundWidthStretchAmount = DECELERATE_INTERPOLATOR.getInterpolation(progress),
-            params.preThresholdIndicator
+                horizontalTranslationStretchAmount = 0f,
+                arrowStretchAmount = params.arrowAngleInterpolator
+                        .getInterpolation(progress),
+                backgroundWidthStretchAmount = params.entryWidthInterpolator
+                        .getInterpolation(progress),
+                backgroundHeightStretchAmount = params.heightInterpolator
+                        .getInterpolation(progress),
+                backgroundAlphaStretchAmount = 1f,
+                arrowAlphaStretchAmount = params.arrowStrokeAlphaInterpolator.get(progress).value,
+                edgeCornerStretchAmount = params.edgeCornerInterpolator.getInterpolation(progress),
+                farCornerStretchAmount = params.farCornerInterpolator.getInterpolation(progress),
+                fullyStretchedDimens = params.preThresholdIndicator
+        )
+    }
+
+    private var previousPreThresholdWidthInterpolator = params.entryWidthTowardsEdgeInterpolator
+    fun preThresholdWidthStretchAmount(progress: Float): Float {
+        val interpolator = run {
+            val isPastSlop = abs(totalTouchDelta) > ViewConfiguration.get(context).scaledTouchSlop
+            if (isPastSlop) {
+                if (totalTouchDelta > 0) {
+                    params.entryWidthInterpolator
+                } else params.entryWidthTowardsEdgeInterpolator
+            } else {
+                previousPreThresholdWidthInterpolator
+            }.also { previousPreThresholdWidthInterpolator = it }
+        }
+        return interpolator.getInterpolation(progress).coerceAtLeast(0f)
+    }
+
+    private fun stretchInactiveBackIndicator(progress: Float) {
+        mView.setStretch(
+                horizontalTranslationStretchAmount = 0f,
+                arrowStretchAmount = params.arrowAngleInterpolator.getInterpolation(progress),
+                backgroundWidthStretchAmount = preThresholdWidthStretchAmount(progress),
+                backgroundHeightStretchAmount = params.heightInterpolator
+                        .getInterpolation(progress),
+                backgroundAlphaStretchAmount = 1f,
+                arrowAlphaStretchAmount = params.arrowStrokeAlphaInterpolator.get(progress).value,
+                edgeCornerStretchAmount = params.edgeCornerInterpolator.getInterpolation(progress),
+                farCornerStretchAmount = params.farCornerInterpolator.getInterpolation(progress),
+                fullyStretchedDimens = params.preThresholdIndicator
         )
     }
 
@@ -487,8 +580,7 @@
         }
     }
 
-    override fun setInsets(insetLeft: Int, insetRight: Int) {
-    }
+    override fun setInsets(insetLeft: Int, insetRight: Int) = Unit
 
     override fun setBackCallback(callback: NavigationEdgeBackPlugin.BackCallback) {
         backCallback = callback
@@ -499,66 +591,54 @@
         windowManager.addView(mView, layoutParams)
     }
 
-    override fun setMotionEventsHandler(motionEventsHandler: MotionEventsHandlerBase?) {
-        TODO("Not yet implemented")
+    private fun isDragAwayFromEdge(velocityPxPerSecThreshold: Int = 0) = velocityTracker!!.run {
+        computeCurrentVelocity(PX_PER_SEC)
+        val velocity = xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1)
+        velocity > velocityPxPerSecThreshold
     }
 
-    private fun isFlung() = velocityTracker!!.run {
-        computeCurrentVelocity(1000)
-        abs(xVelocity) > MIN_FLING_VELOCITY
+    private fun isFlungAwayFromEdge(endX: Float, startX: Float = touchDeltaStartX): Boolean {
+        val minDistanceConsideredForFling = ViewConfiguration.get(context).scaledTouchSlop
+        val flingDistance = abs(endX - startX)
+        val isPastFlingVelocity = isDragAwayFromEdge(
+                velocityPxPerSecThreshold =
+                ViewConfiguration.get(context).scaledMinimumFlingVelocity)
+        return flingDistance > minDistanceConsideredForFling && isPastFlingVelocity
     }
 
-    private fun playFlingBackAnimation() {
-        playAnimation(setCommittedEndListener)
-    }
-
-    private fun playCommitBackAnimation() {
-        // Check if we should vibrate again
-        if (previousState != GestureState.FLUNG) {
-            velocityTracker!!.computeCurrentVelocity(1000)
-            val isSlow = abs(velocityTracker!!.xVelocity) < 500
-            val hasNotVibratedRecently =
-                SystemClock.uptimeMillis() - vibrationTime >= GESTURE_DURATION_FOR_CLICK_MS
-            if (isSlow || hasNotVibratedRecently) {
-                vibratorHelper.vibrate(VibrationEffect.EFFECT_CLICK)
-            }
-        }
-        // Dispatch the actual back trigger
-        if (DEBUG) Log.d(TAG, "playCommitBackAnimation() invoked triggerBack() on backCallback")
-        backCallback.triggerBack()
-
-        playAnimation(setGoneEndListener)
-    }
-
-    private fun playCancelBackAnimation() {
-        backCallback.cancelBack()
-        playAnimation(setGoneEndListener)
-    }
-
-    /**
-     * @return true if the animation is running, false otherwise. Some transitions don't animate
-     */
-    private fun playAnimation(endListener: DelayedOnAnimationEndListener) {
-        updateRestingArrowDimens(animated = true, currentState)
-
-        if (!mView.addEndListener(endListener)) {
+    private fun playHorizontalAnimationThen(onEnd: DelayedOnAnimationEndListener) {
+        updateRestingArrowDimens()
+        if (!mView.addAnimationEndListener(mView.horizontalTranslation, onEnd)) {
             scheduleFailsafe()
         }
     }
 
-    private fun resetOnDown() {
-        hasPassedDragSlop = false
-        hasHapticPlayed = false
-        totalTouchDelta = 0f
-        vibrationTime = 0
-        cancelFailsafe()
+    private fun playAnimationThenSetGoneEnd() {
+        updateRestingArrowDimens()
+        if (!mView.addAnimationEndListener(mView.backgroundAlpha, onEndSetGoneStateListener)) {
+            scheduleFailsafe()
+        }
     }
 
-    private fun updateYPosition(touchY: Float) {
+    private fun playWithBackgroundWidthAnimation(
+            onEnd: DelayedOnAnimationEndListener,
+            delay: Long = 0L
+    ) {
+        if (delay == 0L) {
+            updateRestingArrowDimens()
+            if (!mView.addAnimationEndListener(mView.backgroundWidth, onEnd)) {
+                scheduleFailsafe()
+            }
+        } else {
+            mainHandler.postDelayed(delay) { playWithBackgroundWidthAnimation(onEnd, delay = 0L) }
+        }
+    }
+
+    private fun updateYStartPosition(touchY: Float) {
         var yPosition = touchY - params.fingerOffset
         yPosition = max(yPosition, params.minArrowYPosition.toFloat())
         yPosition -= layoutParams.height / 2.0f
-        layoutParams.y = constrain(yPosition.toInt(), 0, displaySize.y)
+        layoutParams.y = MathUtils.constrain(yPosition.toInt(), 0, displaySize.y)
     }
 
     override fun setDisplaySize(displaySize: Point) {
@@ -569,53 +649,135 @@
     /**
      * Updates resting arrow and background size not accounting for stretch
      */
-    private fun updateRestingArrowDimens(animated: Boolean, currentState: GestureState) {
-        if (animated) {
-            when (currentState) {
-                GestureState.ENTRY, GestureState.ACTIVE, GestureState.FLUNG ->
-                    mView.setArrowStiffness(ARROW_APPEAR_STIFFNESS, ARROW_APPEAR_DAMPING_RATIO)
-                GestureState.CANCELLED -> mView.fadeOut()
-                else ->
-                    mView.setArrowStiffness(
-                        ARROW_DISAPPEAR_STIFFNESS,
-                        ARROW_DISAPPEAR_DAMPING_RATIO
-                    )
+    private fun updateRestingArrowDimens() {
+        when (currentState) {
+            GestureState.GONE,
+            GestureState.ENTRY -> {
+                mView.setSpring(
+                        arrowLength = params.entryIndicator.arrowDimens.lengthSpring,
+                        arrowHeight = params.entryIndicator.arrowDimens.heightSpring,
+                        arrowAlpha = params.entryIndicator.arrowDimens.alphaSpring,
+                        scale = params.entryIndicator.scaleSpring,
+                        verticalTranslation = params.entryIndicator.verticalTranslationSpring,
+                        horizontalTranslation = params.entryIndicator.horizontalTranslationSpring,
+                        backgroundAlpha = params.entryIndicator.backgroundDimens.alphaSpring,
+                        backgroundWidth = params.entryIndicator.backgroundDimens.widthSpring,
+                        backgroundHeight = params.entryIndicator.backgroundDimens.heightSpring,
+                        backgroundEdgeCornerRadius = params.entryIndicator.backgroundDimens
+                                .edgeCornerRadiusSpring,
+                        backgroundFarCornerRadius = params.entryIndicator.backgroundDimens
+                                .farCornerRadiusSpring,
+                )
             }
+            GestureState.INACTIVE -> {
+                mView.setSpring(
+                        arrowLength = params.preThresholdIndicator.arrowDimens.lengthSpring,
+                        arrowHeight = params.preThresholdIndicator.arrowDimens.heightSpring,
+                        horizontalTranslation = params.preThresholdIndicator
+                                .horizontalTranslationSpring,
+                        scale = params.preThresholdIndicator.scaleSpring,
+                        backgroundWidth = params.preThresholdIndicator.backgroundDimens
+                                .widthSpring,
+                        backgroundHeight = params.preThresholdIndicator.backgroundDimens
+                                .heightSpring,
+                        backgroundEdgeCornerRadius = params.preThresholdIndicator.backgroundDimens
+                                .edgeCornerRadiusSpring,
+                        backgroundFarCornerRadius = params.preThresholdIndicator.backgroundDimens
+                                .farCornerRadiusSpring,
+                )
+            }
+            GestureState.ACTIVE -> {
+                mView.setSpring(
+                        arrowLength = params.activeIndicator.arrowDimens.lengthSpring,
+                        arrowHeight = params.activeIndicator.arrowDimens.heightSpring,
+                        scale = params.activeIndicator.scaleSpring,
+                        horizontalTranslation = params.activeIndicator.horizontalTranslationSpring,
+                        backgroundWidth = params.activeIndicator.backgroundDimens.widthSpring,
+                        backgroundHeight = params.activeIndicator.backgroundDimens.heightSpring,
+                        backgroundEdgeCornerRadius = params.activeIndicator.backgroundDimens
+                                .edgeCornerRadiusSpring,
+                        backgroundFarCornerRadius = params.activeIndicator.backgroundDimens
+                                .farCornerRadiusSpring,
+                )
+            }
+            GestureState.FLUNG -> {
+                mView.setSpring(
+                        arrowLength = params.flungIndicator.arrowDimens.lengthSpring,
+                        arrowHeight = params.flungIndicator.arrowDimens.heightSpring,
+                        backgroundWidth = params.flungIndicator.backgroundDimens.widthSpring,
+                        backgroundHeight = params.flungIndicator.backgroundDimens.heightSpring,
+                        backgroundEdgeCornerRadius = params.flungIndicator.backgroundDimens
+                                .edgeCornerRadiusSpring,
+                        backgroundFarCornerRadius = params.flungIndicator.backgroundDimens
+                                .farCornerRadiusSpring,
+                )
+            }
+            GestureState.COMMITTED -> {
+                mView.setSpring(
+                        arrowLength = params.committedIndicator.arrowDimens.lengthSpring,
+                        arrowHeight = params.committedIndicator.arrowDimens.heightSpring,
+                        scale = params.committedIndicator.scaleSpring,
+                        backgroundWidth = params.committedIndicator.backgroundDimens.widthSpring,
+                        backgroundHeight = params.committedIndicator.backgroundDimens.heightSpring,
+                        backgroundEdgeCornerRadius = params.committedIndicator.backgroundDimens
+                                .edgeCornerRadiusSpring,
+                        backgroundFarCornerRadius = params.committedIndicator.backgroundDimens
+                                .farCornerRadiusSpring,
+                )
+            }
+            else -> {}
         }
+
         mView.setRestingDimens(
-            restingParams = EdgePanelParams.BackIndicatorDimens(
-                horizontalTranslation = when (currentState) {
-                    GestureState.GONE -> -params.activeIndicator.backgroundDimens.width
-                    // Position the committed arrow slightly further off the screen so we  do not
-                    // see part of it bouncing
-                    GestureState.COMMITTED ->
-                        -params.activeIndicator.backgroundDimens.width * 1.5f
-                    GestureState.FLUNG -> params.fullyStretchedIndicator.horizontalTranslation
-                    GestureState.ACTIVE -> params.activeIndicator.horizontalTranslation
-                    GestureState.ENTRY, GestureState.INACTIVE, GestureState.CANCELLED ->
-                        params.entryIndicator.horizontalTranslation
-                },
-                arrowDimens = when (currentState) {
-                    GestureState.ACTIVE, GestureState.INACTIVE,
-                    GestureState.COMMITTED, GestureState.FLUNG -> params.activeIndicator.arrowDimens
-                    GestureState.CANCELLED -> params.cancelledArrowDimens
-                    GestureState.GONE, GestureState.ENTRY -> params.entryIndicator.arrowDimens
-                },
-                backgroundDimens = when (currentState) {
-                    GestureState.GONE, GestureState.ENTRY -> params.entryIndicator.backgroundDimens
-                    else ->
-                        params.activeIndicator.backgroundDimens.copy(
-                            edgeCornerRadius =
-                            if (currentState == GestureState.INACTIVE ||
-                                currentState == GestureState.CANCELLED
-                            )
-                                params.cancelledEdgeCornerRadius
-                            else
-                                params.activeIndicator.backgroundDimens.edgeCornerRadius
-                        )
-                }
-            ),
-            animate = animated
+                animate = !(currentState == GestureState.FLUNG ||
+                        currentState == GestureState.COMMITTED),
+                restingParams = EdgePanelParams.BackIndicatorDimens(
+                        scale = when (currentState) {
+                            GestureState.ACTIVE,
+                            GestureState.FLUNG,
+                            -> params.activeIndicator.scale
+                            GestureState.COMMITTED -> params.committedIndicator.scale
+                            else -> params.preThresholdIndicator.scale
+                        },
+                        scalePivotX = when (currentState) {
+                            GestureState.GONE,
+                            GestureState.ENTRY,
+                            GestureState.INACTIVE,
+                            GestureState.CANCELLED -> params.preThresholdIndicator.scalePivotX
+                            else -> params.committedIndicator.scalePivotX
+                        },
+                        horizontalTranslation = when (currentState) {
+                            GestureState.GONE -> {
+                                params.activeIndicator.backgroundDimens.width?.times(-1)
+                            }
+                            GestureState.ENTRY,
+                            GestureState.INACTIVE -> params.entryIndicator.horizontalTranslation
+                            GestureState.FLUNG -> params.activeIndicator.horizontalTranslation
+                            GestureState.ACTIVE -> params.activeIndicator.horizontalTranslation
+                            GestureState.CANCELLED -> {
+                                params.cancelledIndicator.horizontalTranslation
+                            }
+                            else -> null
+                        },
+                        arrowDimens = when (currentState) {
+                            GestureState.GONE,
+                            GestureState.ENTRY,
+                            GestureState.INACTIVE -> params.entryIndicator.arrowDimens
+                            GestureState.ACTIVE -> params.activeIndicator.arrowDimens
+                            GestureState.FLUNG,
+                            GestureState.COMMITTED -> params.committedIndicator.arrowDimens
+                            GestureState.CANCELLED -> params.cancelledIndicator.arrowDimens
+                        },
+                        backgroundDimens = when (currentState) {
+                            GestureState.GONE,
+                            GestureState.ENTRY,
+                            GestureState.INACTIVE -> params.entryIndicator.backgroundDimens
+                            GestureState.ACTIVE -> params.activeIndicator.backgroundDimens
+                            GestureState.FLUNG -> params.activeIndicator.backgroundDimens
+                            GestureState.COMMITTED -> params.committedIndicator.backgroundDimens
+                            GestureState.CANCELLED -> params.cancelledIndicator.backgroundDimens
+                        }
+                )
         )
     }
 
@@ -628,42 +790,123 @@
     private fun updateArrowState(newState: GestureState, force: Boolean = false) {
         if (!force && currentState == newState) return
 
-        if (DEBUG) Log.d(TAG, "updateArrowState $currentState -> $newState")
         previousState = currentState
         currentState = newState
-        if (currentState == GestureState.GONE) {
-            mView.cancelAlphaAnimations()
-            mView.visibility = View.GONE
-        } else {
-            mView.visibility = View.VISIBLE
+
+        when (currentState) {
+            GestureState.CANCELLED -> {
+                backCallback.cancelBack()
+            }
+            GestureState.FLUNG,
+            GestureState.COMMITTED -> {
+                // When flung, trigger back immediately but don't fire again
+                // once state resolves to committed.
+                if (previousState != GestureState.FLUNG) backCallback.triggerBack()
+            }
+            GestureState.ENTRY,
+            GestureState.INACTIVE -> {
+                backCallback.setTriggerBack(false)
+            }
+            GestureState.ACTIVE -> {
+                backCallback.setTriggerBack(true)
+            }
+            GestureState.GONE -> { }
         }
 
         when (currentState) {
             // Transitioning to GONE never animates since the arrow is (presumably) already off the
             // screen
-            GestureState.GONE -> updateRestingArrowDimens(animated = false, currentState)
+            GestureState.GONE -> {
+                updateRestingArrowDimens()
+                mView.isVisible = false
+            }
             GestureState.ENTRY -> {
-                updateYPosition(startY)
-                updateRestingArrowDimens(animated = true, currentState)
+                mView.isVisible = true
+
+                updateRestingArrowDimens()
+                gestureEntryTime = SystemClock.uptimeMillis()
+                gestureInactiveOrEntryTime = SystemClock.uptimeMillis()
             }
             GestureState.ACTIVE -> {
-                updateRestingArrowDimens(animated = true, currentState)
-                // Vibrate the first time we transition to ACTIVE
-                if (!hasHapticPlayed) {
-                    hasHapticPlayed = true
-                    vibrationTime = SystemClock.uptimeMillis()
-                    vibratorHelper.vibrate(VibrationEffect.EFFECT_TICK)
+                previousXTranslationOnActiveOffset = previousXTranslation
+                gestureActiveTime = SystemClock.uptimeMillis()
+
+                updateRestingArrowDimens()
+
+                vibratorHelper.cancel()
+                mainHandler.postDelayed(10L) {
+                    vibratorHelper.vibrate(VIBRATE_ACTIVATED_EFFECT)
+                }
+
+                val startingVelocity = convertVelocityToSpringStartingVelocity(
+                    valueOnFastVelocity = 0f,
+                    valueOnSlowVelocity = if (previousState == GestureState.ENTRY) 2f else 4.5f
+                )
+
+                when (previousState) {
+                    GestureState.ENTRY,
+                    GestureState.INACTIVE -> {
+                        mView.popOffEdge(startingVelocity)
+                    }
+                    GestureState.COMMITTED -> {
+                        // if previous state was committed then this activation
+                        // was due to a quick second swipe. Don't pop the arrow this time
+                    }
+                    else -> { }
                 }
             }
+
             GestureState.INACTIVE -> {
-                updateRestingArrowDimens(animated = true, currentState)
+                gestureInactiveOrEntryTime = SystemClock.uptimeMillis()
+
+                val startingVelocity = convertVelocityToSpringStartingVelocity(
+                        valueOnFastVelocity = -1.05f,
+                        valueOnSlowVelocity = -1.50f
+                )
+                mView.popOffEdge(startingVelocity)
+
+                vibratorHelper.vibrate(VIBRATE_DEACTIVATED_EFFECT)
+                updateRestingArrowDimens()
             }
-            GestureState.FLUNG -> playFlingBackAnimation()
-            GestureState.COMMITTED -> playCommitBackAnimation()
-            GestureState.CANCELLED -> playCancelBackAnimation()
+            GestureState.FLUNG -> {
+                mainHandler.postDelayed(POP_ON_FLING_DELAY) { mView.popScale(1.9f) }
+                playHorizontalAnimationThen(onEndSetCommittedStateListener)
+            }
+            GestureState.COMMITTED -> {
+                if (previousState == GestureState.FLUNG) {
+                    playAnimationThenSetGoneEnd()
+                } else {
+                    mView.popScale(3f)
+                    mainHandler.postDelayed(
+                            playAnimationThenSetGoneOnAlphaEnd,
+                            MIN_DURATION_COMMITTED_ANIMATION
+                    )
+                }
+            }
+            GestureState.CANCELLED -> {
+                val delay = max(0, MIN_DURATION_CANCELLED_ANIMATION - elapsedTimeSinceEntry)
+                playWithBackgroundWidthAnimation(onEndSetGoneStateListener, delay)
+
+                params.arrowStrokeAlphaSpring.get(0f).takeIf { it.isNewState }?.let {
+                    mView.popArrowAlpha(0f, it.value)
+                }
+                mainHandler.postDelayed(10L) { vibratorHelper.cancel() }
+            }
         }
     }
 
+    private fun convertVelocityToSpringStartingVelocity(
+            valueOnFastVelocity: Float,
+            valueOnSlowVelocity: Float,
+    ): Float {
+        val factor = velocityTracker?.run {
+            computeCurrentVelocity(PX_PER_MS)
+            MathUtils.smoothStep(0f, 3f, abs(xVelocity))
+        } ?: valueOnFastVelocity
+
+        return MathUtils.lerp(valueOnFastVelocity, valueOnSlowVelocity, 1 - factor)
+    }
+
     private fun scheduleFailsafe() {
         if (!ENABLE_FAILSAFE) return
         cancelFailsafe()
@@ -690,24 +933,24 @@
     init {
         if (DEBUG) mView.drawDebugInfo = { canvas ->
             val debugStrings = listOf(
-                "$currentState",
-                "startX=$startX",
-                "startY=$startY",
-                "xDelta=${"%.1f".format(totalTouchDelta)}",
-                "xTranslation=${"%.1f".format(previousXTranslation)}",
-                "pre=${"%.0f".format(preThresholdStretchProgress(previousXTranslation) * 100)}%",
-                "post=${"%.0f".format(fullScreenStretchProgress(previousXTranslation) * 100)}%"
+                    "$currentState",
+                    "startX=$startX",
+                    "startY=$startY",
+                    "xDelta=${"%.1f".format(totalTouchDelta)}",
+                    "xTranslation=${"%.1f".format(previousXTranslation)}",
+                    "pre=${"%.0f".format(staticThresholdProgress(previousXTranslation) * 100)}%",
+                    "post=${"%.0f".format(fullScreenProgress(previousXTranslation) * 100)}%"
             )
             val debugPaint = Paint().apply {
                 color = Color.WHITE
             }
             val debugInfoBottom = debugStrings.size * 32f + 4f
             canvas.drawRect(
-                4f,
-                4f,
-                canvas.width.toFloat(),
-                debugStrings.size * 32f + 4f,
-                debugPaint
+                    4f,
+                    4f,
+                    canvas.width.toFloat(),
+                    debugStrings.size * 32f + 4f,
+                    debugPaint
             )
             debugPaint.apply {
                 color = Color.BLACK
@@ -733,9 +976,71 @@
                 canvas.drawLine(x, debugInfoBottom, x, canvas.height.toFloat(), debugPaint)
             }
 
-            drawVerticalLine(x = params.swipeTriggerThreshold, color = Color.BLUE)
+            drawVerticalLine(x = params.staticTriggerThreshold, color = Color.BLUE)
+            drawVerticalLine(x = params.deactivationSwipeTriggerThreshold, color = Color.BLUE)
             drawVerticalLine(x = startX, color = Color.GREEN)
             drawVerticalLine(x = previousXTranslation, color = Color.DKGRAY)
         }
     }
 }
+
+/**
+ * In addition to a typical step function which returns one or two
+ * values based on a threshold, `Step` also gracefully handles quick
+ * changes in input near the threshold value that would typically
+ * result in the output rapidly changing.
+ *
+ * In the context of Back arrow, the arrow's stroke opacity should
+ * always appear transparent or opaque. Using a typical Step function,
+ * this would resulting in a flickering appearance as the output would
+ * change rapidly. `Step` addresses this by moving the threshold after
+ * it is crossed so it cannot be easily crossed again with small changes
+ * in touch events.
+ */
+class Step<T>(
+        private val threshold: Float,
+        private val factor: Float = 1.1f,
+        private val postThreshold: T,
+        private val preThreshold: T
+) {
+
+    data class Value<T>(val value: T, val isNewState: Boolean)
+
+    private val lowerFactor = 2 - factor
+
+    private lateinit var startValue: Value<T>
+    private lateinit var previousValue: Value<T>
+    private var hasCrossedUpperBoundAtLeastOnce = false
+    private var progress: Float = 0f
+
+    init {
+        reset()
+    }
+
+    fun reset() {
+        hasCrossedUpperBoundAtLeastOnce = false
+        progress = 0f
+        startValue = Value(preThreshold, false)
+        previousValue = startValue
+    }
+
+    fun get(progress: Float): Value<T> {
+        this.progress = progress
+
+        val hasCrossedUpperBound = progress > threshold * factor
+        val hasCrossedLowerBound = progress > threshold * lowerFactor
+
+        return when {
+            hasCrossedUpperBound && !hasCrossedUpperBoundAtLeastOnce -> {
+                hasCrossedUpperBoundAtLeastOnce = true
+                Value(postThreshold, true)
+            }
+            hasCrossedLowerBound -> previousValue.copy(isNewState = false)
+            hasCrossedUpperBoundAtLeastOnce -> {
+                hasCrossedUpperBoundAtLeastOnce = false
+                Value(preThreshold, true)
+            }
+            else -> startValue
+        }.also { previousValue = it }
+    }
+}
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 3e6eb05..389034a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -18,7 +18,6 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
 
 import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
-import static com.android.systemui.navigationbar.gestural.Utilities.getTrackpadScale;
 import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;
 
 import android.annotation.NonNull;
@@ -272,7 +271,6 @@
     private LogArray mGestureLogOutsideInsets = new LogArray(MAX_NUM_LOGGED_GESTURES);
 
     private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
-    private final MotionEventsHandler mMotionEventsHandler;
 
     private final NavigationEdgeBackPlugin.BackCallback mBackCallback =
             new NavigationEdgeBackPlugin.BackCallback() {
@@ -404,7 +402,6 @@
 
         mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(
                 mContext.getMainThreadHandler(), mContext, this::onNavigationSettingsChanged);
-        mMotionEventsHandler = new MotionEventsHandler(featureFlags, getTrackpadScale(context));
 
         updateCurrentUserResources();
     }
@@ -624,7 +621,6 @@
             Trace.beginSection("setEdgeBackPlugin");
             mEdgeBackPlugin = edgeBackPlugin;
             mEdgeBackPlugin.setBackCallback(mBackCallback);
-            mEdgeBackPlugin.setMotionEventsHandler(mMotionEventsHandler);
             mEdgeBackPlugin.setLayoutParams(createLayoutParams());
             updateDisplaySize();
         } finally {
@@ -871,7 +867,7 @@
     }
 
     private void onMotionEvent(MotionEvent ev) {
-        mMotionEventsHandler.onMotionEvent(ev);
+        boolean isTrackpadEvent = isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev);
         int action = ev.getActionMasked();
         if (action == MotionEvent.ACTION_DOWN) {
             if (DEBUG_MISSING_GESTURE) {
@@ -881,7 +877,6 @@
             // Verify if this is in within the touch region and we aren't in immersive mode, and
             // either the bouncer is showing or the notification panel is hidden
             mInputEventReceiver.setBatchingEnabled(false);
-            boolean isTrackpadEvent = isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev);
             if (isTrackpadEvent) {
                 // TODO: show the back arrow based on the direction of the swipe.
                 mIsOnLeftEdge = false;
@@ -921,7 +916,7 @@
             if (!mThresholdCrossed) {
                 mEndPoint.x = (int) ev.getX();
                 mEndPoint.y = (int) ev.getY();
-                if (action == MotionEvent.ACTION_POINTER_DOWN) {
+                if (action == MotionEvent.ACTION_POINTER_DOWN && !isTrackpadEvent) {
                     if (mAllowGesture) {
                         logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH);
                         if (DEBUG_MISSING_GESTURE) {
@@ -947,8 +942,8 @@
                         mLogGesture = false;
                         return;
                     }
-                    float dx = Math.abs(mMotionEventsHandler.getDisplacementX(ev));
-                    float dy = Math.abs(mMotionEventsHandler.getDisplacementY(ev));
+                    float dx = Math.abs(ev.getX() - mDownPoint.x);
+                    float dy = Math.abs(ev.getY() - mDownPoint.y);
                     if (dy > dx && dy > mTouchSlop) {
                         if (mAllowGesture) {
                             logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_VERTICAL_MOVE);
@@ -1086,7 +1081,6 @@
         pw.println("  mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
         pw.println("  mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
         pw.println("  mEdgeBackPlugin=" + mEdgeBackPlugin);
-        pw.println("  mMotionEventsHandler=" + mMotionEventsHandler);
         if (mEdgeBackPlugin != null) {
             mEdgeBackPlugin.dump(pw);
         }
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 d56537b..0c00022 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -1,52 +1,82 @@
 package com.android.systemui.navigationbar.gestural
 
 import android.content.res.Resources
+import android.util.TypedValue
+import androidx.core.animation.PathInterpolator
+import androidx.dynamicanimation.animation.SpringForce
 import com.android.systemui.R
 
 data class EdgePanelParams(private var resources: Resources) {
 
     data class ArrowDimens(
-        val length: Float = 0f,
-        val height: Float = 0f
+            val length: Float = 0f,
+            val height: Float = 0f,
+            val alpha: Float = 0f,
+            var alphaSpring: SpringForce? = null,
+            val heightSpring: SpringForce? = null,
+            val lengthSpring: SpringForce? = null,
     )
 
     data class BackgroundDimens(
-        val width: Float = 0f,
-        val height: Float = 0f,
-        val edgeCornerRadius: Float = 0f,
-        val farCornerRadius: Float = 0f
+            val width: Float? = 0f,
+            val height: Float = 0f,
+            val edgeCornerRadius: Float = 0f,
+            val farCornerRadius: Float = 0f,
+            val alpha: Float = 0f,
+            val widthSpring: SpringForce? = null,
+            val heightSpring: SpringForce? = null,
+            val farCornerRadiusSpring: SpringForce? = null,
+            val edgeCornerRadiusSpring: SpringForce? = null,
+            val alphaSpring: SpringForce? = null,
     )
 
     data class BackIndicatorDimens(
-        val horizontalTranslation: Float = 0f,
-        val arrowDimens: ArrowDimens = ArrowDimens(),
-        val backgroundDimens: BackgroundDimens = BackgroundDimens()
+            val horizontalTranslation: Float? = 0f,
+            val scale: Float = 0f,
+            val scalePivotX: Float = 0f,
+            val arrowDimens: ArrowDimens,
+            val backgroundDimens: BackgroundDimens,
+            val verticalTranslationSpring: SpringForce? = null,
+            val horizontalTranslationSpring: SpringForce? = null,
+            val scaleSpring: SpringForce? = null,
     )
 
-    var arrowThickness: Float = 0f
+    lateinit var entryIndicator: BackIndicatorDimens
         private set
-    var entryIndicator = BackIndicatorDimens()
+    lateinit var activeIndicator: BackIndicatorDimens
         private set
-    var activeIndicator = BackIndicatorDimens()
+    lateinit var cancelledIndicator: BackIndicatorDimens
         private set
-    var preThresholdIndicator = BackIndicatorDimens()
+    lateinit var flungIndicator: BackIndicatorDimens
         private set
-    var fullyStretchedIndicator = BackIndicatorDimens()
+    lateinit var committedIndicator: BackIndicatorDimens
         private set
-    var cancelledEdgeCornerRadius: Float = 0f
+    lateinit var preThresholdIndicator: BackIndicatorDimens
         private set
-    var cancelledArrowDimens = ArrowDimens()
+    lateinit var fullyStretchedIndicator: BackIndicatorDimens
+        private set
 
     // navigation bar edge constants
     var arrowPaddingEnd: Int = 0
         private set
+    var arrowThickness: Float = 0f
+        private set
+    lateinit var arrowStrokeAlphaSpring: Step<SpringForce>
+        private set
+    lateinit var arrowStrokeAlphaInterpolator: Step<Float>
+        private set
 
     // The closest to y
     var minArrowYPosition: Int = 0
         private set
     var fingerOffset: Int = 0
         private set
-    var swipeTriggerThreshold: Float = 0f
+    var staticTriggerThreshold: Float = 0f
+        private set
+    var reactivationTriggerThreshold: Float = 0f
+        private set
+    var deactivationSwipeTriggerThreshold: Float = 0f
+        get() = -field
         private set
     var swipeProgressThreshold: Float = 0f
         private set
@@ -55,6 +85,26 @@
     var minDeltaForSwitch: Int = 0
         private set
 
+    var minDragToStartAnimation: Float = 0f
+        private set
+
+    lateinit var entryWidthInterpolator: PathInterpolator
+        private set
+    lateinit var entryWidthTowardsEdgeInterpolator: PathInterpolator
+        private set
+    lateinit var activeWidthInterpolator: PathInterpolator
+        private set
+    lateinit var arrowAngleInterpolator: PathInterpolator
+        private set
+    lateinit var translationInterpolator: PathInterpolator
+        private set
+    lateinit var farCornerInterpolator: PathInterpolator
+        private set
+    lateinit var edgeCornerInterpolator: PathInterpolator
+        private set
+    lateinit var heightInterpolator: PathInterpolator
+        private set
+
     init {
         update(resources)
     }
@@ -63,6 +113,10 @@
         return resources.getDimension(id)
     }
 
+    private fun getDimenFloat(id: Int): Float {
+        return TypedValue().run { resources.getValue(id, this, true); float }
+    }
+
     private fun getPx(id: Int): Int {
         return resources.getDimensionPixelSize(id)
     }
@@ -73,72 +127,200 @@
         arrowPaddingEnd = getPx(R.dimen.navigation_edge_panel_padding)
         minArrowYPosition = getPx(R.dimen.navigation_edge_arrow_min_y)
         fingerOffset = getPx(R.dimen.navigation_edge_finger_offset)
-        swipeTriggerThreshold = getDimen(R.dimen.navigation_edge_action_drag_threshold)
+        staticTriggerThreshold = getDimen(R.dimen.navigation_edge_action_drag_threshold)
+        reactivationTriggerThreshold =
+                getDimen(R.dimen.navigation_edge_action_reactivation_drag_threshold)
+        deactivationSwipeTriggerThreshold =
+                getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold)
         swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold)
         minDeltaForSwitch = getPx(R.dimen.navigation_edge_minimum_x_delta_for_switch)
+        minDragToStartAnimation =
+                getDimen(R.dimen.navigation_edge_action_min_distance_to_start_animation)
+
+        entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f)
+        entryWidthTowardsEdgeInterpolator = PathInterpolator(1f, -3f, 1f, 1.2f)
+        activeWidthInterpolator = PathInterpolator(.15f, .48f, .46f, .89f)
+        arrowAngleInterpolator = entryWidthInterpolator
+        translationInterpolator = PathInterpolator(0.2f, 1.0f, 1.0f, 1.0f)
+        farCornerInterpolator = PathInterpolator(.03f, .19f, .14f, 1.09f)
+        edgeCornerInterpolator = PathInterpolator(0f, 1.11f, .85f, .84f)
+        heightInterpolator = PathInterpolator(1f, .05f, .9f, -0.29f)
+
+        val showArrowOnProgressValue = .2f
+        val showArrowOnProgressValueFactor = 1.05f
+
+        val entryActiveHorizontalTranslationSpring = createSpring(675f, 0.8f)
+        val activeCommittedArrowLengthSpring = createSpring(1500f, 0.29f)
+        val activeCommittedArrowHeightSpring = createSpring(1500f, 0.29f)
+        val flungCommittedEdgeCornerSpring = createSpring(10000f, 1f)
+        val flungCommittedFarCornerSpring = createSpring(10000f, 1f)
+        val flungCommittedWidthSpring = createSpring(10000f, 1f)
+        val flungCommittedHeightSpring = createSpring(10000f, 1f)
 
         entryIndicator = BackIndicatorDimens(
-            horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
-            arrowDimens = ArrowDimens(
-                length = getDimen(R.dimen.navigation_edge_entry_arrow_length),
-                height = getDimen(R.dimen.navigation_edge_entry_arrow_height),
-            ),
-            backgroundDimens = BackgroundDimens(
-                width = getDimen(R.dimen.navigation_edge_entry_background_width),
-                height = getDimen(R.dimen.navigation_edge_entry_background_height),
-                edgeCornerRadius = getDimen(R.dimen.navigation_edge_entry_edge_corners),
-                farCornerRadius = getDimen(R.dimen.navigation_edge_entry_far_corners)
-            )
+                horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
+                scale = getDimenFloat(R.dimen.navigation_edge_entry_scale),
+                scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
+                horizontalTranslationSpring = entryActiveHorizontalTranslationSpring,
+                verticalTranslationSpring = createSpring(10000f, 0.9f),
+                scaleSpring = createSpring(120f, 0.8f),
+                arrowDimens = ArrowDimens(
+                        length = getDimen(R.dimen.navigation_edge_entry_arrow_length),
+                        height = getDimen(R.dimen.navigation_edge_entry_arrow_height),
+                        alpha = 0f,
+                        alphaSpring = createSpring(200f, 1f),
+                        lengthSpring = createSpring(600f, 0.4f),
+                        heightSpring = createSpring(600f, 0.4f),
+                ),
+                backgroundDimens = BackgroundDimens(
+                        alpha = 1f,
+                        width = getDimen(R.dimen.navigation_edge_entry_background_width),
+                        height = getDimen(R.dimen.navigation_edge_entry_background_height),
+                        edgeCornerRadius = getDimen(R.dimen.navigation_edge_entry_edge_corners),
+                        farCornerRadius = getDimen(R.dimen.navigation_edge_entry_far_corners),
+                        alphaSpring = createSpring(900f, 1f),
+                        widthSpring = createSpring(450f, 0.65f),
+                        heightSpring = createSpring(1500f, 0.45f),
+                        farCornerRadiusSpring = createSpring(300f, 0.5f),
+                        edgeCornerRadiusSpring = createSpring(150f, 0.5f),
+                )
         )
 
         activeIndicator = BackIndicatorDimens(
-            horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
-            arrowDimens = ArrowDimens(
-                length = getDimen(R.dimen.navigation_edge_active_arrow_length),
-                height = getDimen(R.dimen.navigation_edge_active_arrow_height),
-            ),
-            backgroundDimens = BackgroundDimens(
-                width = getDimen(R.dimen.navigation_edge_active_background_width),
-                height = getDimen(R.dimen.navigation_edge_active_background_height),
-                edgeCornerRadius = getDimen(R.dimen.navigation_edge_active_edge_corners),
-                farCornerRadius = getDimen(R.dimen.navigation_edge_active_far_corners)
-
-            )
+                horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
+                scale = getDimenFloat(R.dimen.navigation_edge_active_scale),
+                horizontalTranslationSpring = entryActiveHorizontalTranslationSpring,
+                scaleSpring = createSpring(450f, 0.415f),
+                arrowDimens = ArrowDimens(
+                        length = getDimen(R.dimen.navigation_edge_active_arrow_length),
+                        height = getDimen(R.dimen.navigation_edge_active_arrow_height),
+                        alpha = 1f,
+                        lengthSpring = activeCommittedArrowLengthSpring,
+                        heightSpring = activeCommittedArrowHeightSpring,
+                ),
+                backgroundDimens = BackgroundDimens(
+                        alpha = 1f,
+                        width = getDimen(R.dimen.navigation_edge_active_background_width),
+                        height = getDimen(R.dimen.navigation_edge_active_background_height),
+                        edgeCornerRadius = getDimen(R.dimen.navigation_edge_active_edge_corners),
+                        farCornerRadius = getDimen(R.dimen.navigation_edge_active_far_corners),
+                        widthSpring = createSpring(375f, 0.675f),
+                        heightSpring = createSpring(10000f, 1f),
+                        edgeCornerRadiusSpring = createSpring(600f, 0.36f),
+                        farCornerRadiusSpring = createSpring(2500f, 0.855f),
+                )
         )
 
         preThresholdIndicator = BackIndicatorDimens(
-            horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin),
-            arrowDimens = ArrowDimens(
-                length = entryIndicator.arrowDimens.length,
-                height = entryIndicator.arrowDimens.height,
-            ),
-            backgroundDimens = BackgroundDimens(
-                width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
-                height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height),
-                edgeCornerRadius = getDimen(R.dimen.navigation_edge_pre_threshold_edge_corners),
-                farCornerRadius = getDimen(R.dimen.navigation_edge_pre_threshold_far_corners)
-            )
+                horizontalTranslation = getDimen(R.dimen.navigation_edge_pre_threshold_margin),
+                scale = getDimenFloat(R.dimen.navigation_edge_pre_threshold_scale),
+                scalePivotX = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
+                scaleSpring = createSpring(120f, 0.8f),
+                horizontalTranslationSpring = createSpring(6000f, 1f),
+                arrowDimens = ArrowDimens(
+                        length = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_length),
+                        height = getDimen(R.dimen.navigation_edge_pre_threshold_arrow_height),
+                        alpha = 1f,
+                        lengthSpring = createSpring(100f, 0.6f),
+                        heightSpring = createSpring(100f, 0.6f),
+                ),
+                backgroundDimens = BackgroundDimens(
+                        alpha = 1f,
+                        width = getDimen(R.dimen.navigation_edge_pre_threshold_background_width),
+                        height = getDimen(R.dimen.navigation_edge_pre_threshold_background_height),
+                        edgeCornerRadius =
+                                getDimen(R.dimen.navigation_edge_pre_threshold_edge_corners),
+                        farCornerRadius =
+                                getDimen(R.dimen.navigation_edge_pre_threshold_far_corners),
+                        widthSpring = createSpring(200f, 0.65f),
+                        heightSpring = createSpring(1500f, 0.45f),
+                        farCornerRadiusSpring = createSpring(200f, 1f),
+                        edgeCornerRadiusSpring = createSpring(150f, 0.5f),
+                )
+        )
+
+        committedIndicator = activeIndicator.copy(
+                horizontalTranslation = null,
+                arrowDimens = activeIndicator.arrowDimens.copy(
+                        lengthSpring = activeCommittedArrowLengthSpring,
+                        heightSpring = activeCommittedArrowHeightSpring,
+                ),
+                backgroundDimens = activeIndicator.backgroundDimens.copy(
+                        alpha = 0f,
+                        // explicitly set to null to preserve previous width upon state change
+                        width = null,
+                        widthSpring = flungCommittedWidthSpring,
+                        heightSpring = flungCommittedHeightSpring,
+                        edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
+                        farCornerRadiusSpring = flungCommittedFarCornerSpring,
+                ),
+                scale = 0.85f,
+                scaleSpring = createSpring(650f, 1f),
+        )
+
+        flungIndicator = committedIndicator.copy(
+                arrowDimens = committedIndicator.arrowDimens.copy(
+                        lengthSpring = createSpring(850f, 0.46f),
+                        heightSpring = createSpring(850f, 0.46f),
+                ),
+                backgroundDimens = committedIndicator.backgroundDimens.copy(
+                        widthSpring = flungCommittedWidthSpring,
+                        heightSpring = flungCommittedHeightSpring,
+                        edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
+                        farCornerRadiusSpring = flungCommittedFarCornerSpring,
+                )
+        )
+
+        cancelledIndicator = entryIndicator.copy(
+                backgroundDimens = entryIndicator.backgroundDimens.copy(width = 0f)
         )
 
         fullyStretchedIndicator = BackIndicatorDimens(
-            horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin),
-            arrowDimens = ArrowDimens(
-                length = getDimen(R.dimen.navigation_edge_stretched_arrow_length),
-                height = getDimen(R.dimen.navigation_edge_stretched_arrow_height),
-            ),
-            backgroundDimens = BackgroundDimens(
-                width = getDimen(R.dimen.navigation_edge_stretch_background_width),
-                height = getDimen(R.dimen.navigation_edge_stretch_background_height),
-                edgeCornerRadius = getDimen(R.dimen.navigation_edge_stretch_edge_corners),
-                farCornerRadius = getDimen(R.dimen.navigation_edge_stretch_far_corners)
+                horizontalTranslation = getDimen(R.dimen.navigation_edge_stretch_margin),
+                scale = getDimenFloat(R.dimen.navigation_edge_stretch_scale),
+                horizontalTranslationSpring = null,
+                verticalTranslationSpring = null,
+                scaleSpring = null,
+                arrowDimens = ArrowDimens(
+                        length = getDimen(R.dimen.navigation_edge_stretched_arrow_length),
+                        height = getDimen(R.dimen.navigation_edge_stretched_arrow_height),
+                        alpha = 1f,
+                        alphaSpring = null,
+                        heightSpring = null,
+                        lengthSpring = null,
+                ),
+                backgroundDimens = BackgroundDimens(
+                        alpha = 1f,
+                        width = getDimen(R.dimen.navigation_edge_stretch_background_width),
+                        height = getDimen(R.dimen.navigation_edge_stretch_background_height),
+                        edgeCornerRadius = getDimen(R.dimen.navigation_edge_stretch_edge_corners),
+                        farCornerRadius = getDimen(R.dimen.navigation_edge_stretch_far_corners),
+                        alphaSpring = null,
+                        widthSpring = null,
+                        heightSpring = null,
+                        edgeCornerRadiusSpring = null,
+                        farCornerRadiusSpring = null,
+                )
+        )
+
+        arrowStrokeAlphaInterpolator = Step(
+                threshold = showArrowOnProgressValue,
+                factor = showArrowOnProgressValueFactor,
+                postThreshold = 1f,
+                preThreshold = 0f
+        )
+
+        entryIndicator.arrowDimens.alphaSpring?.let { alphaSpring ->
+            arrowStrokeAlphaSpring = Step(
+                    threshold = showArrowOnProgressValue,
+                    factor = showArrowOnProgressValueFactor,
+                    postThreshold = alphaSpring,
+                    preThreshold = SpringForce().setStiffness(2000f).setDampingRatio(1f)
             )
-        )
-
-        cancelledEdgeCornerRadius = getDimen(R.dimen.navigation_edge_cancelled_edge_corners)
-
-        cancelledArrowDimens = ArrowDimens(
-            length = getDimen(R.dimen.navigation_edge_cancelled_arrow_length),
-            height = getDimen(R.dimen.navigation_edge_cancelled_arrow_height)
-        )
+        }
     }
 }
+
+fun createSpring(stiffness: Float, dampingRatio: Float): SpringForce {
+    return SpringForce().setStiffness(stiffness).setDampingRatio(dampingRatio)
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/MotionEventsHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/MotionEventsHandler.java
deleted file mode 100644
index e9b5453..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/MotionEventsHandler.java
+++ /dev/null
@@ -1,114 +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.navigationbar.gestural;
-
-import static android.view.MotionEvent.AXIS_GESTURE_X_OFFSET;
-import static android.view.MotionEvent.AXIS_GESTURE_Y_OFFSET;
-
-import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadMotionEvent;
-
-import android.graphics.PointF;
-import android.view.MotionEvent;
-
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.plugins.MotionEventsHandlerBase;
-
-/** Handles both trackpad and touch events and report displacements in both axis's. */
-public class MotionEventsHandler implements MotionEventsHandlerBase {
-
-    private final boolean mIsTrackpadGestureBackEnabled;
-    private final int mScale;
-
-    private final PointF mDownPos = new PointF();
-    private final PointF mLastPos = new PointF();
-    private float mCurrentTrackpadOffsetX = 0;
-    private float mCurrentTrackpadOffsetY = 0;
-
-    public MotionEventsHandler(FeatureFlags featureFlags, int scale) {
-        mIsTrackpadGestureBackEnabled = featureFlags.isEnabled(Flags.TRACKPAD_GESTURE_BACK);
-        mScale = scale;
-    }
-
-    @Override
-    public void onMotionEvent(MotionEvent ev) {
-        switch (ev.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
-                onActionDown(ev);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                onActionMove(ev);
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                onActionUp(ev);
-                break;
-            default:
-                break;
-        }
-    }
-
-    private void onActionDown(MotionEvent ev) {
-        reset();
-        if (!isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev)) {
-            mDownPos.set(ev.getX(), ev.getY());
-            mLastPos.set(mDownPos);
-        }
-    }
-
-    private void onActionMove(MotionEvent ev) {
-        updateMovements(ev);
-    }
-
-    private void onActionUp(MotionEvent ev) {
-        updateMovements(ev);
-    }
-
-    private void updateMovements(MotionEvent ev) {
-        if (isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev)) {
-            mCurrentTrackpadOffsetX += ev.getAxisValue(AXIS_GESTURE_X_OFFSET) * mScale;
-            mCurrentTrackpadOffsetY += ev.getAxisValue(AXIS_GESTURE_Y_OFFSET) * mScale;
-        } else {
-            mLastPos.set(ev.getX(), ev.getY());
-        }
-    }
-
-    private void reset() {
-        mDownPos.set(0, 0);
-        mLastPos.set(0, 0);
-        mCurrentTrackpadOffsetX = 0;
-        mCurrentTrackpadOffsetY = 0;
-    }
-
-    @Override
-    public float getDisplacementX(MotionEvent ev) {
-        return isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev) ? mCurrentTrackpadOffsetX
-                : mLastPos.x - mDownPos.x;
-    }
-
-    @Override
-    public float getDisplacementY(MotionEvent ev) {
-        return isTrackpadMotionEvent(mIsTrackpadGestureBackEnabled, ev) ? mCurrentTrackpadOffsetY
-                : mLastPos.y - mDownPos.y;
-    }
-
-    @Override
-    public String dump() {
-        return "mDownPos: " + mDownPos + ", mLastPos: " + mLastPos + ", mCurrentTrackpadOffsetX: "
-                + mCurrentTrackpadOffsetX + ", mCurrentTrackpadOffsetY: " + mCurrentTrackpadOffsetY;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index de0f9b2..590efbb 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -53,7 +53,6 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.plugins.MotionEventsHandlerBase;
 import com.android.systemui.plugins.NavigationEdgeBackPlugin;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
@@ -200,6 +199,8 @@
      */
     private boolean mIsLeftPanel;
 
+    private float mStartX;
+    private float mStartY;
     private float mCurrentAngle;
     /**
      * The current translation of the arrow
@@ -230,8 +231,6 @@
     private final Handler mHandler = new Handler();
     private final Runnable mFailsafeRunnable = this::onFailsafe;
 
-    private MotionEventsHandlerBase mMotionEventsHandler;
-
     private DynamicAnimation.OnAnimationEndListener mSetGoneEndListener
             = new DynamicAnimation.OnAnimationEndListener() {
         @Override
@@ -438,11 +437,6 @@
         mWindowManager.addView(this, mLayoutParams);
     }
 
-    @Override
-    public void setMotionEventsHandler(MotionEventsHandlerBase motionEventsHandler) {
-        mMotionEventsHandler = motionEventsHandler;
-    }
-
     /**
      * Adjusts the sampling rect to conform to the actual visible bounding box of the arrow.
      */
@@ -487,6 +481,8 @@
             case MotionEvent.ACTION_DOWN:
                 mDragSlopPassed = false;
                 resetOnDown();
+                mStartX = event.getX();
+                mStartY = event.getY();
                 setVisibility(VISIBLE);
                 updatePosition(event.getY());
                 mRegionSamplingHelper.start(mSamplingRect);
@@ -730,9 +726,10 @@
     }
 
     private void handleMoveEvent(MotionEvent event) {
-        float xOffset = mMotionEventsHandler.getDisplacementX(event);
-        float touchTranslation = MathUtils.abs(xOffset);
-        float yOffset = mMotionEventsHandler.getDisplacementY(event);
+        float x = event.getX();
+        float y = event.getY();
+        float touchTranslation = MathUtils.abs(x - mStartX);
+        float yOffset = y - mStartY;
         float delta = touchTranslation - mPreviousTouchTranslation;
         if (Math.abs(delta) > 0) {
             if (Math.signum(delta) == Math.signum(mTotalTouchDelta)) {
@@ -793,14 +790,16 @@
         }
 
         // Last if the direction in Y is bigger than X * 2 we also abort
-        if (Math.abs(yOffset) > Math.abs(xOffset) * 2) {
+        if (Math.abs(yOffset) > Math.abs(x - mStartX) * 2) {
             triggerBack = false;
         }
         if (DEBUG_MISSING_GESTURE && mTriggerBack != triggerBack) {
             Log.d(DEBUG_MISSING_GESTURE_TAG, "set mTriggerBack=" + triggerBack
                     + ", mTotalTouchDelta=" + mTotalTouchDelta
                     + ", mMinDeltaForSwitch=" + mMinDeltaForSwitch
-                    + ", yOffset=" + yOffset + mMotionEventsHandler.dump());
+                    + ", yOffset=" + yOffset
+                    + ", x=" + x
+                    + ", mStartX=" + mStartX);
         }
         setTriggerBack(triggerBack, true /* animated */);
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
index 335172e..1345c9b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/Utilities.java
@@ -16,25 +16,15 @@
 
 package com.android.systemui.navigationbar.gestural;
 
-import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
+import static android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE;
 
-import android.content.Context;
 import android.view.MotionEvent;
-import android.view.ViewConfiguration;
 
 public final class Utilities {
 
-    private static final int TRACKPAD_GESTURE_SCALE = 60;
-
     public static boolean isTrackpadMotionEvent(boolean isTrackpadGestureBackEnabled,
             MotionEvent event) {
-        // TODO: ideally should use event.getClassification(), but currently only the move
-        // events get assigned the correct classification.
         return isTrackpadGestureBackEnabled
-                && (event.getSource() & SOURCE_TOUCHSCREEN) != SOURCE_TOUCHSCREEN;
-    }
-
-    public static int getTrackpadScale(Context context) {
-        return ViewConfiguration.get(context).getScaledTouchSlop() * TRACKPAD_GESTURE_SCALE;
+                && event.getClassification() == CLASSIFICATION_MULTI_FINGER_SWIPE;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 6bfe1a0..be615d6 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -20,9 +20,12 @@
 import android.content.ActivityNotFoundException
 import android.content.ComponentName
 import android.content.Context
+import android.content.Intent
 import android.content.pm.PackageManager
 import android.os.UserManager
 import android.util.Log
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.util.kotlin.getOrNull
@@ -42,11 +45,12 @@
 @Inject
 constructor(
     private val context: Context,
-    private val intentResolver: NoteTaskIntentResolver,
+    private val resolver: NoteTaskInfoResolver,
     private val optionalBubbles: Optional<Bubbles>,
     private val optionalKeyguardManager: Optional<KeyguardManager>,
     private val optionalUserManager: Optional<UserManager>,
     @NoteTaskEnabledKey private val isEnabled: Boolean,
+    private val uiEventLogger: UiEventLogger,
 ) {
 
     /**
@@ -64,7 +68,9 @@
      *
      * That will let users open other apps in full screen, and take contextual notes.
      */
-    fun showNoteTask(isInMultiWindowMode: Boolean = false) {
+    @JvmOverloads
+    fun showNoteTask(isInMultiWindowMode: Boolean = false, uiEvent: ShowNoteTaskUiEvent? = null) {
+
         if (!isEnabled) return
 
         val bubbles = optionalBubbles.getOrNull() ?: return
@@ -74,9 +80,12 @@
         // TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing.
         if (!userManager.isUserUnlocked) return
 
-        val intent = intentResolver.resolveIntent() ?: return
+        val noteTaskInfo = resolver.resolveInfo() ?: return
+
+        uiEvent?.let { uiEventLogger.log(it, noteTaskInfo.uid, noteTaskInfo.packageName) }
 
         // TODO(b/266686199): We should handle when app not available. For now, we log.
+        val intent = noteTaskInfo.toCreateNoteIntent()
         try {
             if (isInMultiWindowMode || keyguardManager.isKeyguardLocked) {
                 context.startActivity(intent)
@@ -84,9 +93,7 @@
                 bubbles.showOrHideAppBubble(intent)
             }
         } catch (e: ActivityNotFoundException) {
-            val message =
-                "Activity not found for action: ${NoteTaskIntentResolver.ACTION_CREATE_NOTE}."
-            Log.e(TAG, message, e)
+            Log.e(TAG, "Activity not found for action: $ACTION_CREATE_NOTE.", e)
         }
     }
 
@@ -114,10 +121,47 @@
         )
     }
 
+    /** IDs of UI events accepted by [showNoteTask]. */
+    enum class ShowNoteTaskUiEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "User opened a note by tapping on the lockscreen shortcut.")
+        NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE(1294),
+
+        /* ktlint-disable max-line-length */
+        @UiEvent(
+            doc =
+                "User opened a note by pressing the stylus tail button while the screen was unlocked."
+        )
+        NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON(1295),
+        @UiEvent(
+            doc =
+                "User opened a note by pressing the stylus tail button while the screen was locked."
+        )
+        NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED(1296),
+        @UiEvent(doc = "User opened a note by tapping on an app shortcut.")
+        NOTE_OPENED_VIA_SHORTCUT(1297);
+
+        override fun getId() = _id
+    }
+
     companion object {
         private val TAG = NoteTaskController::class.simpleName.orEmpty()
 
+        private fun NoteTaskInfoResolver.NoteTaskInfo.toCreateNoteIntent(): Intent {
+            return Intent(ACTION_CREATE_NOTE)
+                .setPackage(packageName)
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint
+                // was used to start it.
+                .putExtra(INTENT_EXTRA_USE_STYLUS_MODE, true)
+        }
+
         // TODO(b/254604589): Use final KeyEvent.KEYCODE_* instead.
         const val NOTE_TASK_KEY_EVENT = 311
+
+        // TODO(b/265912743): Use Intent.ACTION_CREATE_NOTE instead.
+        const val ACTION_CREATE_NOTE = "android.intent.action.CREATE_NOTE"
+
+        // TODO(b/265912743): Use Intent.INTENT_EXTRA_USE_STYLUS_MODE instead.
+        const val INTENT_EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.kt
new file mode 100644
index 0000000..bd822d4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInfoResolver.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.notetask
+
+import android.app.role.RoleManager
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.UserHandle
+import android.util.Log
+import javax.inject.Inject
+
+internal class NoteTaskInfoResolver
+@Inject
+constructor(
+    private val context: Context,
+    private val roleManager: RoleManager,
+    private val packageManager: PackageManager,
+) {
+    fun resolveInfo(): NoteTaskInfo? {
+        // TODO(b/267634412): Select UserHandle depending on where the user initiated note-taking.
+        val user = context.user
+        val packageName = roleManager.getRoleHoldersAsUser(ROLE_NOTES, user).firstOrNull()
+
+        if (packageName.isNullOrEmpty()) return null
+
+        return NoteTaskInfo(packageName, packageManager.getUidOf(packageName, user))
+    }
+
+    /** Package name and kernel user-ID of a note-taking app. */
+    data class NoteTaskInfo(val packageName: String, val uid: Int)
+
+    companion object {
+        private val TAG = NoteTaskInfoResolver::class.simpleName.orEmpty()
+
+        private val EMPTY_APPLICATION_INFO_FLAGS = PackageManager.ApplicationInfoFlags.of(0)!!
+
+        /**
+         * Returns the kernel user-ID of [packageName] for a [user]. Returns zero if the app cannot
+         * be found.
+         */
+        private fun PackageManager.getUidOf(packageName: String, user: UserHandle): Int {
+            val applicationInfo =
+                try {
+                    getApplicationInfoAsUser(packageName, EMPTY_APPLICATION_INFO_FLAGS, user)
+                } catch (e: PackageManager.NameNotFoundException) {
+                    Log.e(TAG, "Couldn't find notes app UID", e)
+                    return 0
+                }
+            return applicationInfo.uid
+        }
+
+        // TODO(b/265912743): Use RoleManager.NOTES_ROLE instead.
+        const val ROLE_NOTES = "android.app.role.NOTES"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
index d5f4a5a..d40bf2b 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt
@@ -16,8 +16,10 @@
 
 package com.android.systemui.notetask
 
+import android.app.KeyguardManager
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.util.kotlin.getOrNull
 import com.android.wm.shell.bubbles.Bubbles
 import java.util.Optional
 import javax.inject.Inject
@@ -30,6 +32,7 @@
     private val noteTaskController: NoteTaskController,
     private val commandQueue: CommandQueue,
     @NoteTaskEnabledKey private val isEnabled: Boolean,
+    private val optionalKeyguardManager: Optional<KeyguardManager>,
 ) {
 
     @VisibleForTesting
@@ -37,11 +40,21 @@
         object : CommandQueue.Callbacks {
             override fun handleSystemKey(keyCode: Int) {
                 if (keyCode == NoteTaskController.NOTE_TASK_KEY_EVENT) {
-                    noteTaskController.showNoteTask()
+                    showNoteTask()
                 }
             }
         }
 
+    private fun showNoteTask() {
+        val uiEvent =
+            if (optionalKeyguardManager.isKeyguardLocked) {
+                NoteTaskController.ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED
+            } else {
+                NoteTaskController.ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
+            }
+        noteTaskController.showNoteTask(uiEvent = uiEvent)
+    }
+
     fun initialize() {
         if (isEnabled && optionalBubbles.isPresent) {
             commandQueue.addCallback(callbacks)
@@ -49,3 +62,7 @@
         noteTaskController.setNoteTaskShortcutEnabled(isEnabled)
     }
 }
+
+private val Optional<KeyguardManager>.isKeyguardLocked: Boolean
+    // If there's no KeyguardManager, assume that the keyguard is not locked.
+    get() = getOrNull()?.isKeyguardLocked ?: false
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt
deleted file mode 100644
index 11dc1d7..0000000
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskIntentResolver.kt
+++ /dev/null
@@ -1,54 +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.notetask
-
-import android.app.role.RoleManager
-import android.content.Context
-import android.content.Intent
-import javax.inject.Inject
-
-internal class NoteTaskIntentResolver
-@Inject
-constructor(
-    private val context: Context,
-    private val roleManager: RoleManager,
-) {
-
-    fun resolveIntent(): Intent? {
-        val packageName = roleManager.getRoleHoldersAsUser(ROLE_NOTES, context.user).firstOrNull()
-
-        if (packageName.isNullOrEmpty()) return null
-
-        return Intent(ACTION_CREATE_NOTE)
-            .setPackage(packageName)
-            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-            // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint was
-            // used to start it.
-            .putExtra(INTENT_EXTRA_USE_STYLUS_MODE, true)
-    }
-
-    companion object {
-        // TODO(b/265912743): Use Intent.ACTION_CREATE_NOTE instead.
-        const val ACTION_CREATE_NOTE = "android.intent.action.CREATE_NOTE"
-
-        // TODO(b/265912743): Use RoleManager.NOTES_ROLE instead.
-        const val ROLE_NOTES = "android.app.role.NOTES"
-
-        // TODO(b/265912743): Use Intent.INTENT_EXTRA_USE_STYLUS_MODE instead.
-        const val INTENT_EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE"
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
index ec6a16a..b8800a2 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
@@ -51,7 +51,7 @@
             featureFlags: FeatureFlags,
             roleManager: RoleManager,
         ): Boolean {
-            val isRoleAvailable = roleManager.isRoleAvailable(NoteTaskIntentResolver.ROLE_NOTES)
+            val isRoleAvailable = roleManager.isRoleAvailable(NoteTaskInfoResolver.ROLE_NOTES)
             val isFeatureEnabled = featureFlags.isEnabled(Flags.NOTE_TASKS)
             return isRoleAvailable && isFeatureEnabled
         }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index cfbaa48..43869cc 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.PickerScreenState
 import com.android.systemui.notetask.NoteTaskController
+import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
 import com.android.systemui.notetask.NoteTaskEnabledKey
 import javax.inject.Inject
 import kotlinx.coroutines.flow.flowOf
@@ -64,7 +65,9 @@
         }
 
     override fun onTriggered(expandable: Expandable?): OnTriggeredResult {
-        noteTaskController.showNoteTask()
+        noteTaskController.showNoteTask(
+            uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE
+        )
         return OnTriggeredResult.Handled
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
index f203e7a..3ac5bfa 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt
@@ -21,7 +21,7 @@
 import android.os.Bundle
 import androidx.activity.ComponentActivity
 import com.android.systemui.notetask.NoteTaskController
-import com.android.systemui.notetask.NoteTaskIntentResolver
+import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
 import javax.inject.Inject
 
 /** Activity responsible for launching the note experience, and finish. */
@@ -34,7 +34,10 @@
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        noteTaskController.showNoteTask(isInMultiWindowMode)
+        noteTaskController.showNoteTask(
+            isInMultiWindowMode = isInMultiWindowMode,
+            uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT,
+        )
 
         finish()
     }
@@ -46,7 +49,7 @@
             return Intent(context, LaunchNoteTaskActivity::class.java).apply {
                 // Intent's action must be set in shortcuts, or an exception will be thrown.
                 // TODO(b/254606432): Use Intent.ACTION_CREATE_NOTE instead.
-                action = NoteTaskIntentResolver.ACTION_CREATE_NOTE
+                action = NoteTaskController.ACTION_CREATE_NOTE
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
new file mode 100644
index 0000000..245cf89
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/process/ProcessWrapper.java
@@ -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.process;
+
+import javax.inject.Inject;
+
+/**
+ * A simple wrapper that provides access to process-related details. This facilitates testing by
+ * providing a mockable target around these details.
+ */
+public class ProcessWrapper {
+    @Inject
+    public ProcessWrapper() {}
+
+    public int getUserHandleIdentifier() {
+        return android.os.Process.myUserHandle().getIdentifier();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java b/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.java
new file mode 100644
index 0000000..5a21ea0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/process/condition/UserProcessCondition.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.systemui.process.condition;
+
+import com.android.systemui.process.ProcessWrapper;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shared.condition.Condition;
+
+import javax.inject.Inject;
+
+/**
+ * {@link UserProcessCondition} provides a signal when the process handle belongs to the current
+ * user.
+ */
+public class UserProcessCondition extends Condition {
+    private final ProcessWrapper mProcessWrapper;
+    private final UserTracker mUserTracker;
+
+    @Inject
+    public UserProcessCondition(ProcessWrapper processWrapper, UserTracker userTracker) {
+        mProcessWrapper = processWrapper;
+        mUserTracker = userTracker;
+    }
+
+    @Override
+    protected void start() {
+        updateCondition(mUserTracker.getUserId()
+                == mProcessWrapper.getUserHandleIdentifier());
+    }
+
+    @Override
+    protected void stop() {
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 464b6e7..048d40c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
@@ -48,6 +48,7 @@
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_INFORM_JOB_SCHEDULER_OF_PENDING_APP_STOP
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_FOOTER_DOT
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS
@@ -158,6 +159,7 @@
         private const val DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT = false
         private const val DEFAULT_TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS = true
         private const val DEFAULT_TASK_MANAGER_SHOW_USER_VISIBLE_JOBS = true
+        private const val DEFAULT_TASK_MANAGER_INFORM_JOB_SCHEDULER_OF_PENDING_APP_STOP = true
     }
 
     override var newChangesSinceDialogWasDismissed = false
@@ -173,6 +175,9 @@
 
     private var showUserVisibleJobs = DEFAULT_TASK_MANAGER_SHOW_USER_VISIBLE_JOBS
 
+    private var informJobSchedulerOfPendingAppStop =
+        DEFAULT_TASK_MANAGER_INFORM_JOB_SCHEDULER_OF_PENDING_APP_STOP
+
     override val includesUserVisibleJobs: Boolean
         get() = showUserVisibleJobs
 
@@ -233,6 +238,11 @@
                 NAMESPACE_SYSTEMUI,
                 TASK_MANAGER_SHOW_USER_VISIBLE_JOBS, DEFAULT_TASK_MANAGER_SHOW_USER_VISIBLE_JOBS)
 
+            informJobSchedulerOfPendingAppStop = deviceConfigProxy.getBoolean(
+                NAMESPACE_SYSTEMUI,
+                TASK_MANAGER_INFORM_JOB_SCHEDULER_OF_PENDING_APP_STOP,
+                DEFAULT_TASK_MANAGER_INFORM_JOB_SCHEDULER_OF_PENDING_APP_STOP)
+
             try {
                 activityManager.registerForegroundServiceObserver(foregroundServiceObserver)
                 // Clumping FGS and user-visible jobs here and showing a single entry and button
@@ -262,10 +272,13 @@
                     showStopBtnForUserAllowlistedApps)
                 var wasShowingUserVisibleJobs = showUserVisibleJobs
                 showUserVisibleJobs = it.getBoolean(
-                        TASK_MANAGER_SHOW_USER_VISIBLE_JOBS, showUserVisibleJobs)
+                    TASK_MANAGER_SHOW_USER_VISIBLE_JOBS, showUserVisibleJobs)
                 if (showUserVisibleJobs != wasShowingUserVisibleJobs) {
                     onShowUserVisibleJobsFlagChanged()
                 }
+                informJobSchedulerOfPendingAppStop = it.getBoolean(
+                    TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS,
+                    informJobSchedulerOfPendingAppStop)
             }
 
             _isAvailable.value = deviceConfigProxy.getBoolean(
@@ -475,14 +488,11 @@
     private fun stopPackage(userId: Int, packageName: String, timeStarted: Long) {
         logEvent(stopped = true, packageName, userId, timeStarted)
         val userPackageKey = UserPackage(userId, packageName)
-        if (showUserVisibleJobs &&
-                runningTaskIdentifiers[userPackageKey]?.hasRunningJobs() == true) {
+        if (showUserVisibleJobs || informJobSchedulerOfPendingAppStop) {
             // TODO(255768978): allow fine-grained job control
-            jobScheduler.stopUserVisibleJobsForUser(packageName, userId)
+            jobScheduler.notePendingUserRequestedAppStop(packageName, userId, "task manager")
         }
-        if (runningTaskIdentifiers[userPackageKey]?.hasFgs() == true) {
-            activityManager.stopAppForUser(packageName, userId)
-        }
+        activityManager.stopAppForUser(packageName, userId)
     }
 
     private fun onShowUserVisibleJobsFlagChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 628964a..25a5c61 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -22,6 +22,7 @@
 import android.hardware.display.NightDisplayListener;
 import android.os.Handler;
 
+import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.media.dagger.MediaModule;
 import com.android.systemui.qs.AutoAddTracker;
@@ -53,6 +54,7 @@
 public interface QSModule {
 
     @Provides
+    @SysUISingleton
     static AutoTileManager provideAutoTileManager(
             Context context,
             AutoAddTracker.Builder autoAddTrackerBuilder,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
index 5bc209a..7316f46 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DreamTile.java
@@ -203,8 +203,7 @@
         // For now, restrict to debug users.
         return Build.isDebuggable()
                 && mDreamSupported
-                // TODO(b/257333623): Allow the Dock User to be non-SystemUser user in HSUM.
-                && (!mDreamOnlyEnabledForDockUser || mUserTracker.getUserHandle().isSystem());
+                && (!mDreamOnlyEnabledForDockUser || mUserTracker.getUserInfo().isMain());
     }
 
     @VisibleForTesting
@@ -224,7 +223,8 @@
 
     private ComponentName getActiveDream() {
         try {
-            final ComponentName[] dreams = mDreamManager.getDreamComponents();
+            final ComponentName[] dreams = mDreamManager.getDreamComponentsForUser(
+                                                mUserTracker.getUserId());
             return dreams != null && dreams.length > 0 ? dreams[0] : null;
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to get active dream", e);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 64a8a14..ad00069 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -171,8 +171,9 @@
             getHost().collapsePanels();
         };
 
-        Dialog dialog = mController.createScreenRecordDialog(mContext, mFlags,
+        final Dialog dialog = mController.createScreenRecordDialog(mContext, mFlags,
                 mDialogLaunchAnimator, mActivityStarter, onStartRecordingClicked);
+
         ActivityStarter.OnDismissAction dismissAction = () -> {
             if (shouldAnimateFromView) {
                 mDialogLaunchAnimator.showFromView(dialog, view, new DialogCuj(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 206a620..039dafb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -800,6 +800,11 @@
     }
 
     @Override
+    public void onCarrierNetworkChange(boolean active) {
+        mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */));
+    }
+
+    @Override
     @WorkerThread
     public void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries,
             @Nullable WifiEntry connectedEntry, boolean hasMoreWifiEntries) {
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 534155c..f7e7366 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
@@ -206,6 +206,8 @@
     protected boolean mHasEthernet = false;
     @VisibleForTesting
     protected ConnectedWifiInternetMonitor mConnectedWifiInternetMonitor;
+    @VisibleForTesting
+    protected boolean mCarrierNetworkChangeMode;
 
     private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -507,10 +509,13 @@
     Drawable getSignalStrengthIcon(int subId, Context context, int level, int numLevels,
             int iconType, boolean cutOut) {
         boolean isForDds = subId == mDefaultDataSubId;
+        int levelDrawable =
+                mCarrierNetworkChangeMode ? SignalDrawable.getCarrierChangeState(numLevels)
+                        : SignalDrawable.getState(level, numLevels, cutOut);
         if (isForDds) {
-            mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut));
+            mSignalDrawable.setLevel(levelDrawable);
         } else {
-            mSecondarySignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut));
+            mSecondarySignalDrawable.setLevel(levelDrawable);
         }
 
         // Make the network type drawable
@@ -672,10 +677,13 @@
         }
 
         int resId = Objects.requireNonNull(mapIconSets(config).get(iconKey)).dataContentDescription;
+        SignalIcon.MobileIconGroup iconGroup;
         if (isCarrierNetworkActive()) {
-            SignalIcon.MobileIconGroup carrierMergedWifiIconGroup =
-                    TelephonyIcons.CARRIER_MERGED_WIFI;
-            resId = carrierMergedWifiIconGroup.dataContentDescription;
+            iconGroup = TelephonyIcons.CARRIER_MERGED_WIFI;
+            resId = iconGroup.dataContentDescription;
+        } else if (mCarrierNetworkChangeMode) {
+            iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
+            resId = iconGroup.dataContentDescription;
         }
 
         return resId != 0
@@ -1094,7 +1102,8 @@
             TelephonyCallback.DisplayInfoListener,
             TelephonyCallback.ServiceStateListener,
             TelephonyCallback.SignalStrengthsListener,
-            TelephonyCallback.UserMobileDataStateListener {
+            TelephonyCallback.UserMobileDataStateListener,
+            TelephonyCallback.CarrierNetworkListener{
 
         private final int mSubId;
         private InternetTelephonyCallback(int subId) {
@@ -1126,6 +1135,12 @@
         public void onUserMobileDataStateChanged(boolean enabled) {
             mCallback.onUserMobileDataStateChanged(enabled);
         }
+
+        @Override
+        public void onCarrierNetworkChange(boolean active) {
+            mCarrierNetworkChangeMode = active;
+            mCallback.onCarrierNetworkChange(active);
+        }
     }
 
     private class InternetOnSubscriptionChangedListener
@@ -1295,6 +1310,8 @@
 
         void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo);
 
+        void onCarrierNetworkChange(boolean active);
+
         void dismissDialog();
 
         void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries,
diff --git a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java
index 802db7e..dc3c820 100644
--- a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayDialogController.java
@@ -27,7 +27,6 @@
 import com.android.systemui.CoreStartable;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index a979e5a..25ff308b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -25,6 +25,7 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
@@ -99,6 +100,7 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.statusbar.policy.CallbackController;
+import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
 import com.android.wm.shell.sysui.ShellInterface;
 
 import java.io.PrintWriter;
@@ -144,6 +146,7 @@
     private final CommandQueue mCommandQueue;
     private final UserTracker mUserTracker;
     private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController;
+    private final Optional<UnfoldTransitionProgressForwarder> mUnfoldTransitionProgressForwarder;
     private final UiEventLogger mUiEventLogger;
     private final DisplayTracker mDisplayTracker;
 
@@ -415,6 +418,10 @@
             params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows);
             params.putBinder(KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER,
                     mSysuiUnlockAnimationController.asBinder());
+            mUnfoldTransitionProgressForwarder.ifPresent(
+                    unfoldProgressForwarder -> params.putBinder(
+                            KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER,
+                            unfoldProgressForwarder.asBinder()));
             // Add all the interfaces exposed by the shell
             mShellInterface.createExternalInterfaces(params);
 
@@ -512,7 +519,9 @@
             DisplayTracker displayTracker,
             KeyguardUnlockAnimationController sysuiUnlockAnimationController,
             AssistUtils assistUtils,
-            DumpManager dumpManager) {
+            DumpManager dumpManager,
+            Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder
+    ) {
         // b/241601880: This component shouldn't be running for a non-primary user
         if (!Process.myUserHandle().equals(UserHandle.SYSTEM)) {
             Log.e(TAG_OPS, "Unexpected initialization for non-primary user", new Throwable());
@@ -538,6 +547,7 @@
         mSysUiState.addCallback(this::notifySystemUiStateFlags);
         mUiEventLogger = uiEventLogger;
         mDisplayTracker = displayTracker;
+        mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder;
 
         dumpManager.registerDumpable(getClass().getSimpleName(), this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index 431b28f..acb6d96 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -38,6 +38,8 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
+import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
+import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialog;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.settings.UserTracker;
@@ -48,6 +50,8 @@
 
 import javax.inject.Inject;
 
+import dagger.Lazy;
+
 /**
  * Helper class to initiate a screen recording
  */
@@ -63,6 +67,8 @@
     private CountDownTimer mCountDownTimer = null;
     private final Executor mMainExecutor;
     private final BroadcastDispatcher mBroadcastDispatcher;
+    private final Context mContext;
+    private final FeatureFlags mFlags;
     private final UserContextProvider mUserContextProvider;
     private final UserTracker mUserTracker;
 
@@ -73,6 +79,8 @@
     private CopyOnWriteArrayList<RecordingStateChangeCallback> mListeners =
             new CopyOnWriteArrayList<>();
 
+    private final Lazy<ScreenCaptureDevicePolicyResolver> mDevicePolicyResolver;
+
     @VisibleForTesting
     final UserTracker.Callback mUserChangedCallback =
             new UserTracker.Callback() {
@@ -103,9 +111,15 @@
     @Inject
     public RecordingController(@Main Executor mainExecutor,
             BroadcastDispatcher broadcastDispatcher,
+            Context context,
+            FeatureFlags flags,
             UserContextProvider userContextProvider,
+            Lazy<ScreenCaptureDevicePolicyResolver> devicePolicyResolver,
             UserTracker userTracker) {
         mMainExecutor = mainExecutor;
+        mContext = context;
+        mFlags = flags;
+        mDevicePolicyResolver = devicePolicyResolver;
         mBroadcastDispatcher = broadcastDispatcher;
         mUserContextProvider = userContextProvider;
         mUserTracker = userTracker;
@@ -115,14 +129,30 @@
         mInteractiveBroadcastOption = options.toBundle();
     }
 
-    /** Create a dialog to show screen recording options to the user. */
+    /**
+     * MediaProjection host is SystemUI for the screen recorder, so return 'my user handle'
+     */
+    private UserHandle getHostUserHandle() {
+        return UserHandle.of(UserHandle.myUserId());
+    }
+
+    /** Create a dialog to show screen recording options to the user.
+     *  If screen capturing is currently not allowed it will return a dialog
+     *  that warns users about it. */
     public Dialog createScreenRecordDialog(Context context, FeatureFlags flags,
                                            DialogLaunchAnimator dialogLaunchAnimator,
                                            ActivityStarter activityStarter,
                                            @Nullable Runnable onStartRecordingClicked) {
+        if (mFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)
+                && mDevicePolicyResolver.get()
+                        .isScreenCaptureCompletelyDisabled(getHostUserHandle())) {
+            return new ScreenCaptureDisabledDialog(mContext);
+        }
+
         return flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING)
-                ? new ScreenRecordPermissionDialog(context, this, activityStarter,
-                        dialogLaunchAnimator, mUserContextProvider, onStartRecordingClicked)
+                ? new ScreenRecordPermissionDialog(context,  getHostUserHandle(), this,
+                    activityStarter, dialogLaunchAnimator, mUserContextProvider,
+                    onStartRecordingClicked)
                 : new ScreenRecordDialog(context, this, activityStarter,
                 mUserContextProvider, flags, dialogLaunchAnimator, onStartRecordingClicked);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
index 68e3dcd..dd21be9 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialog.kt
@@ -42,6 +42,7 @@
 /** Dialog to select screen recording options */
 class ScreenRecordPermissionDialog(
     context: Context?,
+    private val hostUserHandle: UserHandle,
     private val controller: RecordingController,
     private val activityStarter: ActivityStarter,
     private val dialogLaunchAnimator: DialogLaunchAnimator,
@@ -79,11 +80,9 @@
                     CaptureTargetResultReceiver()
                 )
 
-                // Send SystemUI's user handle as the host app user handle because SystemUI
-                // is the 'host app' (the app that receives screen capture data)
                 intent.putExtra(
                     MediaProjectionAppSelectorActivity.EXTRA_HOST_APP_USER_HANDLE,
-                    UserHandle.of(UserHandle.myUserId())
+                    hostUserHandle
                 )
 
                 val animationController = dialogLaunchAnimator.createActivityLaunchController(v!!)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 72a8e23..8721d71 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -99,6 +99,7 @@
 import com.android.systemui.clipboardoverlay.ClipboardOverlayController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.screenshot.ScreenshotController.SavedImageData.ActionTransition;
 import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback;
 import com.android.systemui.settings.DisplayTracker;
@@ -480,7 +481,7 @@
         }
         mScreenshotView.setScreenshot(screenshot);
 
-        if (screenshot.getTaskId() >= 0) {
+        if (mFlags.isEnabled(Flags.SCREENSHOT_METADATA) && screenshot.getTaskId() >= 0) {
             mAssistContentRequester.requestAssistContent(screenshot.getTaskId(),
                     new AssistContentRequester.Callback() {
                         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 8035d19..111278a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -225,7 +225,7 @@
             return;
         }
 
-        if (mFeatureFlags.isEnabled(Flags.SCREENSHOT_METADATA)) {
+        if (mFeatureFlags.isEnabled(Flags.SCREENSHOT_METADATA_REFACTOR)) {
             Log.d(TAG, "Processing screenshot data");
             ScreenshotData screenshotData = ScreenshotData.fromRequest(request);
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
new file mode 100644
index 0000000..f8d86a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.ACTION_FINISH_FROM_TRAMPOLINE;
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_RESULT_RECEIVER;
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.PERMISSION_SELF;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+
+import androidx.activity.ComponentActivity;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.android.settingslib.Utils;
+import com.android.systemui.R;
+
+import javax.inject.Inject;
+
+/**
+ * An {@link Activity} to take a screenshot for the App Clips flow and presenting a screenshot
+ * editing tool.
+ *
+ * <p>An App Clips flow includes:
+ * <ul>
+ *     <li>Checking if calling activity meets the prerequisites. This is done by
+ *     {@link AppClipsTrampolineActivity}.
+ *     <li>Performing the screenshot.
+ *     <li>Showing a screenshot editing tool.
+ *     <li>Returning the screenshot to the {@link AppClipsTrampolineActivity} so that it can return
+ *     the screenshot to the calling activity after explicit user consent.
+ * </ul>
+ *
+ * <p>This {@link Activity} runs in its own separate process to isolate memory intensive image
+ * editing from SysUI process.
+ *
+ * TODO(b/267309532): Polish UI and animations.
+ */
+public final class AppClipsActivity extends ComponentActivity {
+
+    private final AppClipsViewModel.Factory mViewModelFactory;
+    private final BroadcastReceiver mBroadcastReceiver;
+    private final IntentFilter mIntentFilter;
+
+    private View mLayout;
+    private View mRoot;
+    private ImageView mPreview;
+    private CropView mCropView;
+    private MagnifierView mMagnifierView;
+    private Button mSave;
+    private Button mCancel;
+    private AppClipsViewModel mViewModel;
+
+    private ResultReceiver mResultReceiver;
+
+    @Inject
+    public AppClipsActivity(AppClipsViewModel.Factory viewModelFactory) {
+        mViewModelFactory = viewModelFactory;
+
+        mBroadcastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                // Trampoline activity was dismissed so finish this activity.
+                if (ACTION_FINISH_FROM_TRAMPOLINE.equals(intent.getAction())) {
+                    if (!isFinishing()) {
+                        // Nullify the ResultReceiver so that result cannot be sent as trampoline
+                        // activity is already finishing.
+                        mResultReceiver = null;
+                        finish();
+                    }
+                }
+            }
+        };
+
+        mIntentFilter = new IntentFilter(ACTION_FINISH_FROM_TRAMPOLINE);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        overridePendingTransition(0, 0);
+        super.onCreate(savedInstanceState);
+
+        // Register the broadcast receiver that informs when the trampoline activity is dismissed.
+        registerReceiver(mBroadcastReceiver, mIntentFilter, PERMISSION_SELF, null,
+                RECEIVER_NOT_EXPORTED);
+
+        Intent intent = getIntent();
+        mResultReceiver = intent.getParcelableExtra(EXTRA_RESULT_RECEIVER, ResultReceiver.class);
+        if (mResultReceiver == null) {
+            setErrorThenFinish(Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            return;
+        }
+
+        // Inflate layout but don't add it yet as it should be added after the screenshot is ready
+        // for preview.
+        mLayout = getLayoutInflater().inflate(R.layout.app_clips_screenshot, null);
+        mRoot = mLayout.findViewById(R.id.root);
+
+        mSave = mLayout.findViewById(R.id.save);
+        mCancel = mLayout.findViewById(R.id.cancel);
+        mSave.setOnClickListener(this::onClick);
+        mCancel.setOnClickListener(this::onClick);
+
+        mMagnifierView = mLayout.findViewById(R.id.magnifier);
+        mCropView = mLayout.findViewById(R.id.crop_view);
+        mCropView.setCropInteractionListener(mMagnifierView);
+
+        mPreview = mLayout.findViewById(R.id.preview);
+        mPreview.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+                        updateImageDimensions());
+
+        mViewModel = new ViewModelProvider(this, mViewModelFactory).get(AppClipsViewModel.class);
+        mViewModel.getScreenshot().observe(this, this::setScreenshot);
+        mViewModel.getResultLiveData().observe(this, this::setResultThenFinish);
+        mViewModel.getErrorLiveData().observe(this, this::setErrorThenFinish);
+
+        if (savedInstanceState == null) {
+            mViewModel.performScreenshot();
+        }
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        overridePendingTransition(0, 0);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        unregisterReceiver(mBroadcastReceiver);
+
+        // If neither error nor result was set, it implies that the activity is finishing due to
+        // some other reason such as user dismissing this activity using back gesture. Inform error.
+        if (isFinishing() && mViewModel.getErrorLiveData().getValue() == null
+                && mViewModel.getResultLiveData().getValue() == null) {
+            // Set error but don't finish as the activity is already finishing.
+            setError(Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED);
+        }
+    }
+
+    private void setScreenshot(Bitmap screenshot) {
+        // Set background, status and navigation bar colors as the activity is no longer
+        // translucent.
+        int colorBackgroundFloating = Utils.getColorAttr(this,
+                android.R.attr.colorBackgroundFloating).getDefaultColor();
+        mRoot.setBackgroundColor(colorBackgroundFloating);
+
+        BitmapDrawable drawable = new BitmapDrawable(getResources(), screenshot);
+        mPreview.setImageDrawable(drawable);
+        mPreview.setAlpha(1f);
+
+        mMagnifierView.setDrawable(drawable, screenshot.getWidth(), screenshot.getHeight());
+
+        // Screenshot is now available so set content view.
+        setContentView(mLayout);
+    }
+
+    private void onClick(View view) {
+        mSave.setEnabled(false);
+        mCancel.setEnabled(false);
+
+        int id = view.getId();
+        if (id == R.id.save) {
+            saveScreenshotThenFinish();
+        } else {
+            setErrorThenFinish(Intent.CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED);
+        }
+    }
+
+    private void saveScreenshotThenFinish() {
+        Drawable drawable = mPreview.getDrawable();
+        if (drawable == null) {
+            setErrorThenFinish(Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            return;
+        }
+
+        Rect bounds = mCropView.getCropBoundaries(drawable.getIntrinsicWidth(),
+                drawable.getIntrinsicHeight());
+
+        if (bounds.isEmpty()) {
+            setErrorThenFinish(Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            return;
+        }
+
+        updateImageDimensions();
+        mViewModel.saveScreenshotThenFinish(drawable, bounds);
+    }
+
+    private void setResultThenFinish(Uri uri) {
+        if (mResultReceiver == null) {
+            return;
+        }
+
+        Bundle data = new Bundle();
+        data.putInt(Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE,
+                Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
+        data.putParcelable(EXTRA_SCREENSHOT_URI, uri);
+        try {
+            mResultReceiver.send(Activity.RESULT_OK, data);
+        } catch (Exception e) {
+            // Do nothing.
+        }
+
+        // Nullify the ResultReceiver before finishing to avoid resending the result.
+        mResultReceiver = null;
+        finish();
+    }
+
+    private void setErrorThenFinish(int errorCode) {
+        setError(errorCode);
+        finish();
+    }
+
+    private void setError(int errorCode) {
+        if (mResultReceiver == null) {
+            return;
+        }
+
+        Bundle data = new Bundle();
+        data.putInt(Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, errorCode);
+        try {
+            mResultReceiver.send(RESULT_OK, data);
+        } catch (Exception e) {
+            // Do nothing.
+        }
+
+        // Nullify the ResultReceiver to avoid resending the result.
+        mResultReceiver = null;
+    }
+
+    private void updateImageDimensions() {
+        Drawable drawable = mPreview.getDrawable();
+        if (drawable == null) {
+            return;
+        }
+
+        Rect bounds = drawable.getBounds();
+        float imageRatio = bounds.width() / (float) bounds.height();
+        int previewWidth = mPreview.getWidth() - mPreview.getPaddingLeft()
+                - mPreview.getPaddingRight();
+        int previewHeight = mPreview.getHeight() - mPreview.getPaddingTop()
+                - mPreview.getPaddingBottom();
+        float viewRatio = previewWidth / (float) previewHeight;
+
+        if (imageRatio > viewRatio) {
+            // Image is full width and height is constrained, compute extra padding to inform
+            // CropView.
+            int imageHeight = (int) (previewHeight * viewRatio / imageRatio);
+            int extraPadding = (previewHeight - imageHeight) / 2;
+            mCropView.setExtraPadding(extraPadding, extraPadding);
+            mCropView.setImageWidth(previewWidth);
+        } else {
+            // Image is full height.
+            mCropView.setExtraPadding(mPreview.getPaddingTop(), mPreview.getPaddingBottom());
+            mCropView.setImageWidth((int) (previewHeight * imageRatio));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
new file mode 100644
index 0000000..65fb4c9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.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.systemui.screenshot.appclips;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.view.Display;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.infra.AndroidFuture;
+import com.android.internal.infra.ServiceConnector;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Application;
+
+import javax.inject.Inject;
+
+/** An intermediary singleton object to help communicating with the cross process service. */
+@SysUISingleton
+public class AppClipsCrossProcessHelper {
+
+    private final ServiceConnector<IAppClipsScreenshotHelperService> mProxyConnector;
+
+    @Inject
+    public AppClipsCrossProcessHelper(@Application Context context) {
+        mProxyConnector = new ServiceConnector.Impl<IAppClipsScreenshotHelperService>(context,
+                new Intent(context, AppClipsScreenshotHelperService.class),
+                Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
+                        | Context.BIND_NOT_VISIBLE, context.getUserId(),
+                IAppClipsScreenshotHelperService.Stub::asInterface);
+    }
+
+    /**
+     * Returns a {@link Bitmap} captured in the SysUI process, {@code null} in case of an error.
+     *
+     * <p>Note: The SysUI process captures a {@link ScreenshotHardwareBufferInternal} which is ok to
+     * pass around but not a {@link Bitmap}.
+     */
+    @Nullable
+    public Bitmap takeScreenshot() {
+        try {
+            AndroidFuture<ScreenshotHardwareBufferInternal> future =
+                    mProxyConnector.postForResult(
+                            service -> service.takeScreenshot(Display.DEFAULT_DISPLAY));
+            return future.get().createBitmapThenCloseBuffer();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java
new file mode 100644
index 0000000..6f8c365
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java
@@ -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.screenshot.appclips;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
+import android.window.ScreenCapture.ScreenshotSync;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.screenshot.AppClipsActivity;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+/**
+ * A helper service that runs in SysUI process and helps {@link AppClipsActivity} which runs in its
+ * own separate process take a screenshot.
+ */
+public class AppClipsScreenshotHelperService extends Service {
+
+    private final Optional<Bubbles> mOptionalBubbles;
+
+    @Inject
+    public AppClipsScreenshotHelperService(Optional<Bubbles> optionalBubbles) {
+        mOptionalBubbles = optionalBubbles;
+    }
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new IAppClipsScreenshotHelperService.Stub() {
+            @Override
+            @Nullable
+            public ScreenshotHardwareBufferInternal takeScreenshot(int displayId) {
+                if (mOptionalBubbles.isEmpty()) {
+                    return null;
+                }
+
+                ScreenshotSync screenshotSync =
+                        mOptionalBubbles.get().getScreenshotExcludingBubble(displayId);
+                ScreenshotHardwareBuffer screenshotHardwareBuffer = screenshotSync.get();
+                if (screenshotHardwareBuffer == null) {
+                    return null;
+                }
+
+                return new ScreenshotHardwareBufferInternal(screenshotHardwareBuffer);
+            }
+        };
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
new file mode 100644
index 0000000..d0b7ad3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsService.java
@@ -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.screenshot.appclips;
+
+import static com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS;
+
+import android.app.Activity;
+import android.app.Service;
+import android.app.StatusBarManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.IBinder;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.statusbar.IAppClipsService;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Application;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+/**
+ * A service that communicates with {@link StatusBarManager} to support the
+ * {@link StatusBarManager#canLaunchCaptureContentActivityForNote(Activity)} API.
+ */
+public class AppClipsService extends Service {
+
+    @Application private final Context mContext;
+    private final FeatureFlags mFeatureFlags;
+    private final Optional<Bubbles> mOptionalBubbles;
+    private final DevicePolicyManager mDevicePolicyManager;
+    private final boolean mAreTaskAndTimeIndependentPrerequisitesMet;
+
+    @Inject
+    public AppClipsService(@Application Context context, FeatureFlags featureFlags,
+            Optional<Bubbles> optionalBubbles, DevicePolicyManager devicePolicyManager) {
+        mContext = context;
+        mFeatureFlags = featureFlags;
+        mOptionalBubbles = optionalBubbles;
+        mDevicePolicyManager = devicePolicyManager;
+
+        mAreTaskAndTimeIndependentPrerequisitesMet = checkIndependentVariables();
+    }
+
+    private boolean checkIndependentVariables() {
+        if (!mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)) {
+            return false;
+        }
+
+        if (mOptionalBubbles.isEmpty()) {
+            return false;
+        }
+
+        return isComponentValid();
+    }
+
+    private boolean isComponentValid() {
+        ComponentName componentName;
+        try {
+            componentName = ComponentName.unflattenFromString(
+                    mContext.getString(R.string.config_screenshotAppClipsActivityComponent));
+        } catch (Resources.NotFoundException e) {
+            return false;
+        }
+
+        return componentName != null
+                && !componentName.getPackageName().isEmpty()
+                && !componentName.getClassName().isEmpty();
+    }
+
+    @Nullable
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new IAppClipsService.Stub() {
+            @Override
+            public boolean canLaunchCaptureContentActivityForNote(int taskId) {
+                if (!mAreTaskAndTimeIndependentPrerequisitesMet) {
+                    return false;
+                }
+
+                if (!mOptionalBubbles.get().isAppBubbleTaskId(taskId)) {
+                    return false;
+                }
+
+                return !mDevicePolicyManager.getScreenCaptureDisabled(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
new file mode 100644
index 0000000..4759cc6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN;
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED;
+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 android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.ResultReceiver;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.notetask.NoteTaskController;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+/**
+ * A trampoline activity that is responsible for:
+ * <ul>
+ *     <li>Performing precondition checks before starting the actual screenshot activity.
+ *     <li>Communicating with the screenshot activity and the calling activity.
+ * </ul>
+ *
+ * <p>As this activity is started in a bubble app, the windowing for this activity is restricted
+ * to the parent bubble app. The screenshot editing activity, see {@link AppClipsActivity}, is
+ * started in a regular activity window using {@link Intent#FLAG_ACTIVITY_NEW_TASK}. However,
+ * {@link Activity#startActivityForResult(Intent, int)} is not compatible with
+ * {@link Intent#FLAG_ACTIVITY_NEW_TASK}. So, this activity acts as a trampoline activity to
+ * abstract the complexity of communication with the screenshot editing activity for a simpler
+ * developer experience.
+ *
+ * TODO(b/267309532): Polish UI and animations.
+ */
+public class AppClipsTrampolineActivity extends Activity {
+
+    private static final String TAG = AppClipsTrampolineActivity.class.getSimpleName();
+    public static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
+    public static final String EXTRA_SCREENSHOT_URI = TAG + "SCREENSHOT_URI";
+    public static final String ACTION_FINISH_FROM_TRAMPOLINE = TAG + "FINISH_FROM_TRAMPOLINE";
+    static final String EXTRA_RESULT_RECEIVER = TAG + "RESULT_RECEIVER";
+
+    private final DevicePolicyManager mDevicePolicyManager;
+    private final FeatureFlags mFeatureFlags;
+    private final Optional<Bubbles> mOptionalBubbles;
+    private final NoteTaskController mNoteTaskController;
+    private final ResultReceiver mResultReceiver;
+
+    private Intent mKillAppClipsBroadcastIntent;
+
+    @Inject
+    public AppClipsTrampolineActivity(DevicePolicyManager devicePolicyManager, FeatureFlags flags,
+            Optional<Bubbles> optionalBubbles, NoteTaskController noteTaskController,
+            @Main Handler mainHandler) {
+        mDevicePolicyManager = devicePolicyManager;
+        mFeatureFlags = flags;
+        mOptionalBubbles = optionalBubbles;
+        mNoteTaskController = noteTaskController;
+
+        mResultReceiver = createResultReceiver(mainHandler);
+    }
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (savedInstanceState != null) {
+            return;
+        }
+
+        if (!mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)) {
+            finish();
+            return;
+        }
+
+        if (mOptionalBubbles.isEmpty()) {
+            setErrorResultAndFinish(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            return;
+        }
+
+        if (!mOptionalBubbles.get().isAppBubbleTaskId(getTaskId())) {
+            setErrorResultAndFinish(CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED);
+            return;
+        }
+
+        if (mDevicePolicyManager.getScreenCaptureDisabled(null)) {
+            setErrorResultAndFinish(CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN);
+            return;
+        }
+
+        ComponentName componentName;
+        try {
+            componentName = ComponentName.unflattenFromString(
+                    getString(R.string.config_screenshotAppClipsActivityComponent));
+        } catch (Resources.NotFoundException e) {
+            setErrorResultAndFinish(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            return;
+        }
+
+        if (componentName == null || componentName.getPackageName().isEmpty()
+                || componentName.getClassName().isEmpty()) {
+            setErrorResultAndFinish(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            return;
+        }
+
+        Intent intent = new Intent().setComponent(componentName).addFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK).putExtra(EXTRA_RESULT_RECEIVER, mResultReceiver);
+        try {
+            // Start the App Clips activity.
+            startActivity(intent);
+
+            // Set up the broadcast intent that will inform the above App Clips activity to finish
+            // when this trampoline activity is finished.
+            mKillAppClipsBroadcastIntent =
+                    new Intent(ACTION_FINISH_FROM_TRAMPOLINE)
+                            .setComponent(componentName)
+                            .setPackage(componentName.getPackageName());
+        } catch (ActivityNotFoundException e) {
+            setErrorResultAndFinish(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        if (isFinishing() && mKillAppClipsBroadcastIntent != null) {
+            sendBroadcast(mKillAppClipsBroadcastIntent, PERMISSION_SELF);
+        }
+    }
+
+    private void setErrorResultAndFinish(int errorCode) {
+        setResult(RESULT_OK,
+                new Intent().putExtra(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, errorCode));
+        finish();
+    }
+
+    private class AppClipsResultReceiver extends ResultReceiver {
+
+        AppClipsResultReceiver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            if (isFinishing()) {
+                // It's too late, trampoline activity is finishing or already finished.
+                // Return early.
+                return;
+            }
+
+            // Package the response that should be sent to the calling activity.
+            Intent convertedData = new Intent();
+            int statusCode = CAPTURE_CONTENT_FOR_NOTE_FAILED;
+            if (resultData != null) {
+                statusCode = resultData.getInt(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE,
+                        CAPTURE_CONTENT_FOR_NOTE_FAILED);
+            }
+            convertedData.putExtra(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, statusCode);
+
+            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);
+            }
+
+            // Broadcast no longer required, setting it to null.
+            mKillAppClipsBroadcastIntent = null;
+
+            // Expand the note bubble before returning the result. As App Clips API is only
+            // available when in a bubble, isInMultiWindowMode is always false below.
+            mNoteTaskController.showNoteTask(false);
+            setResult(RESULT_OK, convertedData);
+            finish();
+        }
+    }
+
+    /**
+     * @return a {@link ResultReceiver} by initializing an {@link AppClipsResultReceiver} and
+     * converting it into a generic {@link ResultReceiver} to pass across a different but trusted
+     * process.
+     */
+    private ResultReceiver createResultReceiver(@Main Handler handler) {
+        AppClipsResultReceiver appClipsResultReceiver = new AppClipsResultReceiver(handler);
+        Parcel parcel = Parcel.obtain();
+        appClipsResultReceiver.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        ResultReceiver resultReceiver  = ResultReceiver.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        return resultReceiver;
+    }
+
+    /** This is a test only API for mocking response from {@link AppClipsActivity}. */
+    @VisibleForTesting
+    public ResultReceiver getResultReceiverForTest() {
+        return mResultReceiver;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
new file mode 100644
index 0000000..5a7b5f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot;
+
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.HardwareRenderer;
+import android.graphics.RecordingCanvas;
+import android.graphics.Rect;
+import android.graphics.RenderNode;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Process;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.screenshot.appclips.AppClipsCrossProcessHelper;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.time.ZonedDateTime;
+import java.util.UUID;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/** A {@link ViewModel} to help with the App Clips screenshot flow. */
+final class AppClipsViewModel extends ViewModel {
+
+    private final AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
+    private final ImageExporter mImageExporter;
+    @Main
+    private final Executor mMainExecutor;
+    @Background
+    private final Executor mBgExecutor;
+
+    private final MutableLiveData<Bitmap> mScreenshotLiveData;
+    private final MutableLiveData<Uri> mResultLiveData;
+    private final MutableLiveData<Integer> mErrorLiveData;
+
+    AppClipsViewModel(AppClipsCrossProcessHelper appClipsCrossProcessHelper,
+            ImageExporter imageExporter, @Main Executor mainExecutor,
+            @Background Executor bgExecutor) {
+        mAppClipsCrossProcessHelper = appClipsCrossProcessHelper;
+        mImageExporter = imageExporter;
+        mMainExecutor = mainExecutor;
+        mBgExecutor = bgExecutor;
+
+        mScreenshotLiveData = new MutableLiveData<>();
+        mResultLiveData = new MutableLiveData<>();
+        mErrorLiveData = new MutableLiveData<>();
+    }
+
+    /** Grabs a screenshot and updates the {@link Bitmap} set in screenshot {@link LiveData}. */
+    void performScreenshot() {
+        mBgExecutor.execute(() -> {
+            Bitmap screenshot = mAppClipsCrossProcessHelper.takeScreenshot();
+            mMainExecutor.execute(() -> {
+                if (screenshot == null) {
+                    mErrorLiveData.setValue(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+                } else {
+                    mScreenshotLiveData.setValue(screenshot);
+                }
+            });
+        });
+    }
+
+    /** Returns a {@link LiveData} that holds the captured screenshot. */
+    LiveData<Bitmap> getScreenshot() {
+        return mScreenshotLiveData;
+    }
+
+    /** Returns a {@link LiveData} that holds the {@link Uri} where screenshot is saved. */
+    LiveData<Uri> getResultLiveData() {
+        return mResultLiveData;
+    }
+
+    /**
+     * Returns a {@link LiveData} that holds the error codes for
+     * {@link Intent#EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE}.
+     */
+    LiveData<Integer> getErrorLiveData() {
+        return mErrorLiveData;
+    }
+
+    /**
+     * Saves the provided {@link Drawable} to storage then informs the result {@link Uri} to
+     * {@link LiveData}.
+     */
+    void saveScreenshotThenFinish(Drawable screenshotDrawable, Rect bounds) {
+        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, ZonedDateTime.now(),
+                    Process.myUserHandle());
+
+            // Get the result and update state on main thread.
+            exportFuture.addListener(() -> {
+                try {
+                    ImageExporter.Result result = exportFuture.get();
+                    if (result.uri == null) {
+                        mErrorLiveData.setValue(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+                        return;
+                    }
+
+                    mResultLiveData.setValue(result.uri);
+                } catch (CancellationException | InterruptedException | ExecutionException e) {
+                    mErrorLiveData.setValue(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+                }
+            }, mMainExecutor);
+        });
+    }
+
+    private static Bitmap renderBitmap(Drawable drawable, Rect bounds) {
+        final RenderNode output = new RenderNode("Screenshot save");
+        output.setPosition(0, 0, bounds.width(), bounds.height());
+        RecordingCanvas canvas = output.beginRecording();
+        canvas.translate(-bounds.left, -bounds.top);
+        canvas.clipRect(bounds);
+        drawable.draw(canvas);
+        output.endRecording();
+        return HardwareRenderer.createHardwareBitmap(output, bounds.width(), bounds.height());
+    }
+
+    /** Helper factory to help with injecting {@link AppClipsViewModel}. */
+    static final class Factory implements ViewModelProvider.Factory {
+
+        private final AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
+        private final ImageExporter mImageExporter;
+        @Main
+        private final Executor mMainExecutor;
+        @Background
+        private final Executor mBgExecutor;
+
+        @Inject
+        Factory(AppClipsCrossProcessHelper appClipsCrossProcessHelper,  ImageExporter imageExporter,
+                @Main Executor mainExecutor, @Background Executor bgExecutor) {
+            mAppClipsCrossProcessHelper = appClipsCrossProcessHelper;
+            mImageExporter = imageExporter;
+            mMainExecutor = mainExecutor;
+            mBgExecutor = bgExecutor;
+        }
+
+        @NonNull
+        @Override
+        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
+            if (modelClass != AppClipsViewModel.class) {
+                throw new IllegalArgumentException();
+            }
+
+            //noinspection unchecked
+            return (T) new AppClipsViewModel(mAppClipsCrossProcessHelper, mImageExporter,
+                    mMainExecutor, mBgExecutor);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/IAppClipsScreenshotHelperService.aidl b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/IAppClipsScreenshotHelperService.aidl
new file mode 100644
index 0000000..640e742
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/IAppClipsScreenshotHelperService.aidl
@@ -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.screenshot.appclips;
+
+import android.os.Bundle;
+
+import com.android.systemui.screenshot.appclips.ScreenshotHardwareBufferInternal;
+
+/**
+ * A helper service that runs in SysUI process and helps {@link AppClipsActivity} which runs in its
+ * own separate process take a screenshot.
+ */
+interface IAppClipsScreenshotHelperService {
+    @nullable ScreenshotHardwareBufferInternal takeScreenshot(in int displayId);
+}
diff --git a/packages/SystemUI/res/values-television/strings.xml b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.aidl
similarity index 60%
copy from packages/SystemUI/res/values-television/strings.xml
copy to packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.aidl
index 86106e6..3a7b944 100644
--- a/packages/SystemUI/res/values-television/strings.xml
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.aidl
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
 /**
- * Copyright (c) 2022, The Android Open Source Project
+ * Copyright (C) 2023, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Learn more URL for the log access confirmation dialog. [DO NOT TRANSLATE]-->
-    <string name="log_access_confirmation_learn_more_url" translatable="false"></string>
-</resources>
\ No newline at end of file
+
+package com.android.systemui.screenshot.appclips;
+
+parcelable ScreenshotHardwareBufferInternal;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.java
new file mode 100644
index 0000000..3b107f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.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.systemui.screenshot.appclips;
+
+import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
+import android.graphics.ParcelableColorSpace;
+import android.hardware.HardwareBuffer;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
+
+/**
+ * An internal version of {@link ScreenshotHardwareBuffer} that helps with parceling the information
+ * necessary for creating a {@link Bitmap}.
+ */
+public class ScreenshotHardwareBufferInternal implements Parcelable {
+
+    public static final Creator<ScreenshotHardwareBufferInternal> CREATOR =
+            new Creator<>() {
+                @Override
+                public ScreenshotHardwareBufferInternal createFromParcel(Parcel in) {
+                    return new ScreenshotHardwareBufferInternal(in);
+                }
+
+                @Override
+                public ScreenshotHardwareBufferInternal[] newArray(int size) {
+                    return new ScreenshotHardwareBufferInternal[size];
+                }
+            };
+    private final HardwareBuffer mHardwareBuffer;
+    private final ParcelableColorSpace mParcelableColorSpace;
+
+    public ScreenshotHardwareBufferInternal(
+            ScreenshotHardwareBuffer screenshotHardwareBuffer) {
+        mHardwareBuffer = screenshotHardwareBuffer.getHardwareBuffer();
+        mParcelableColorSpace = new ParcelableColorSpace(
+                screenshotHardwareBuffer.getColorSpace());
+    }
+
+    private ScreenshotHardwareBufferInternal(Parcel in) {
+        mHardwareBuffer = in.readParcelable(HardwareBuffer.class.getClassLoader(),
+                HardwareBuffer.class);
+        mParcelableColorSpace = in.readParcelable(ParcelableColorSpace.class.getClassLoader(),
+                ParcelableColorSpace.class);
+    }
+
+    /**
+     * Returns a {@link Bitmap} represented by the underlying data and successively closes the
+     * internal {@link HardwareBuffer}. See,
+     * {@link Bitmap#wrapHardwareBuffer(HardwareBuffer, ColorSpace)} and
+     * {@link HardwareBuffer#close()} for more information.
+     */
+    public Bitmap createBitmapThenCloseBuffer() {
+        Bitmap bitmap = Bitmap.wrapHardwareBuffer(mHardwareBuffer,
+                mParcelableColorSpace.getColorSpace());
+        mHardwareBuffer.close();
+        return bitmap;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mHardwareBuffer, flags);
+        dest.writeParcelable(mParcelableColorSpace, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ScreenshotHardwareBufferInternal)) {
+            return false;
+        }
+
+        ScreenshotHardwareBufferInternal other = (ScreenshotHardwareBufferInternal) obj;
+        return mHardwareBuffer.equals(other.mHardwareBuffer) && mParcelableColorSpace.equals(
+                other.mParcelableColorSpace);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
index fdb0100..22e238c0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
@@ -24,6 +24,8 @@
 import com.android.systemui.screenshot.ScreenshotPolicyImpl;
 import com.android.systemui.screenshot.ScreenshotProxyService;
 import com.android.systemui.screenshot.TakeScreenshotService;
+import com.android.systemui.screenshot.appclips.AppClipsScreenshotHelperService;
+import com.android.systemui.screenshot.appclips.AppClipsService;
 
 import dagger.Binds;
 import dagger.Module;
@@ -52,4 +54,13 @@
     @Binds
     abstract ImageCapture bindImageCaptureImpl(ImageCaptureImpl capture);
 
+    @Binds
+    @IntoMap
+    @ClassKey(AppClipsScreenshotHelperService.class)
+    abstract Service bindAppClipsScreenshotHelperService(AppClipsScreenshotHelperService service);
+
+    @Binds
+    @IntoMap
+    @ClassKey(AppClipsService.class)
+    abstract Service bindAppClipsService(AppClipsService service);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 2ac7f7a..9286d29 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -685,6 +685,7 @@
     private boolean mInstantExpanding;
     private boolean mAnimateAfterExpanding;
     private boolean mIsFlinging;
+    private boolean mLastFlingWasExpanding;
     private String mViewName;
     private float mInitialExpandY;
     private float mInitialExpandX;
@@ -2142,6 +2143,8 @@
     @VisibleForTesting
     void flingToHeight(float vel, boolean expand, float target,
             float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
+        mLastFlingWasExpanding = expand;
+        mShadeLog.logLastFlingWasExpanding(expand);
         mHeadsUpTouchHelper.notifyFling(!expand);
         mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */);
         setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
@@ -2531,7 +2534,7 @@
         }
         // defer touches on QQS to shade while shade is collapsing. Added margin for error
         // as sometimes the qsExpansionFraction can be a tiny value instead of 0 when in QQS.
-        if (!mSplitShadeEnabled
+        if (!mSplitShadeEnabled && !mLastFlingWasExpanding
                 && computeQsExpansionFraction() <= 0.01 && getExpandedFraction() < 1.0) {
             mShadeLog.logMotionEvent(event,
                     "handleQsTouch: shade touched while collapsing, QS tracking disabled");
@@ -4125,7 +4128,7 @@
 
                     if (didFaceAuthRun) {
                         mUpdateMonitor.requestActiveUnlock(
-                                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT,
+                                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
                                 "lockScreenEmptySpaceTap");
                     } else {
                         mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
@@ -4622,6 +4625,7 @@
         ipw.println(mBlockingExpansionForCurrentTouch);
         ipw.print("mExpectingSynthesizedDown="); ipw.println(mExpectingSynthesizedDown);
         ipw.print("mLastEventSynthesizedDown="); ipw.println(mLastEventSynthesizedDown);
+        ipw.print("mLastFlingWasExpanding="); ipw.println(mLastFlingWasExpanding);
         ipw.print("mInterpolatedDarkAmount="); ipw.println(mInterpolatedDarkAmount);
         ipw.print("mLinearDarkAmount="); ipw.println(mLinearDarkAmount);
         ipw.print("mPulsing="); ipw.println(mPulsing);
@@ -6135,6 +6139,11 @@
 
             switch (event.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN:
+                    if (mTracking) {
+                        // TODO(b/247126247) fix underlying issue. Should be ACTION_POINTER_DOWN.
+                        mShadeLog.d("Don't intercept down event while already tracking");
+                        return false;
+                    }
                     mCentralSurfaces.userActivity();
                     mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation;
                     mMinExpandHeight = 0.0f;
@@ -6222,6 +6231,11 @@
                             "onTouch: duplicate down event detected... ignoring");
                     return true;
                 }
+                if (mTracking) {
+                    // TODO(b/247126247) fix underlying issue. Should be ACTION_POINTER_DOWN.
+                    mShadeLog.d("Don't handle down event while already tracking");
+                    return true;
+                }
                 mLastTouchDownTime = event.getDownTime();
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index 11617be..26c839de 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -20,7 +20,6 @@
 import com.android.systemui.log.dagger.ShadeLog
 import com.android.systemui.plugins.log.LogBuffer
 import com.android.systemui.plugins.log.LogLevel
-import com.android.systemui.plugins.log.LogMessage
 import com.google.errorprone.annotations.CompileTimeConstant
 import javax.inject.Inject
 
@@ -234,4 +233,19 @@
             }
         )
     }
+
+    fun logLastFlingWasExpanding(
+            expand: Boolean
+    ) {
+        buffer.log(
+                TAG,
+                LogLevel.VERBOSE,
+                {
+                    bool1 = expand
+                },
+                {
+                    "NPVC mLastFlingWasExpanding set to: $bool1"
+                }
+        )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 3aaad87..2cf1f53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -53,7 +53,6 @@
 import android.os.RemoteException;
 import android.util.Pair;
 import android.util.SparseArray;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowInsetsController.Behavior;
@@ -371,22 +370,22 @@
                 String packageName, LetterboxDetails[] letterboxDetails) { }
 
         /**
-         * @see IStatusBar#showTransient(int, int[], boolean).
+         * @see IStatusBar#showTransient(int, int, boolean).
          */
-        default void showTransient(int displayId, @InternalInsetsType int[] types) { }
+        default void showTransient(int displayId, @InsetsType int types) { }
 
         /**
-         * @see IStatusBar#showTransient(int, int[], boolean).
+         * @see IStatusBar#showTransient(int, int, boolean).
          */
-        default void showTransient(int displayId, @InternalInsetsType int[] types,
+        default void showTransient(int displayId, @InsetsType int types,
                 boolean isGestureOnSystemBar) {
             showTransient(displayId, types);
         }
 
         /**
-         * @see IStatusBar#abortTransient(int, int[]).
+         * @see IStatusBar#abortTransient(int, int).
          */
-        default void abortTransient(int displayId, @InternalInsetsType int[] types) { }
+        default void abortTransient(int displayId, @InsetsType int types) { }
 
         /**
          * Called to notify System UI that a warning about the device going to sleep
@@ -1131,17 +1130,23 @@
     }
 
     @Override
-    public void showTransient(int displayId, int[] types, boolean isGestureOnSystemBar) {
+    public void showTransient(int displayId, int types, boolean isGestureOnSystemBar) {
         synchronized (mLock) {
-            mHandler.obtainMessage(MSG_SHOW_TRANSIENT, displayId, isGestureOnSystemBar ? 1 : 0,
-                    types).sendToTarget();
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = displayId;
+            args.argi2 = types;
+            args.argi3 = isGestureOnSystemBar ? 1 : 0;
+            mHandler.obtainMessage(MSG_SHOW_TRANSIENT, args).sendToTarget();
         }
     }
 
     @Override
-    public void abortTransient(int displayId, int[] types) {
+    public void abortTransient(int displayId, int types) {
         synchronized (mLock) {
-            mHandler.obtainMessage(MSG_ABORT_TRANSIENT, displayId, 0, types).sendToTarget();
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = displayId;
+            args.argi2 = types;
+            mHandler.obtainMessage(MSG_ABORT_TRANSIENT, args).sendToTarget();
         }
     }
 
@@ -1644,17 +1649,21 @@
                     args.recycle();
                     break;
                 case MSG_SHOW_TRANSIENT: {
-                    final int displayId = msg.arg1;
-                    final int[] types = (int[]) msg.obj;
-                    final boolean isGestureOnSystemBar = msg.arg2 != 0;
+                    args = (SomeArgs) msg.obj;
+                    final int displayId = args.argi1;
+                    final int types = args.argi2;
+                    final boolean isGestureOnSystemBar = args.argi3 != 0;
+                    args.recycle();
                     for (int i = 0; i < mCallbacks.size(); i++) {
                         mCallbacks.get(i).showTransient(displayId, types, isGestureOnSystemBar);
                     }
                     break;
                 }
                 case MSG_ABORT_TRANSIENT: {
-                    final int displayId = msg.arg1;
-                    final int[] types = (int[]) msg.obj;
+                    args = (SomeArgs) msg.obj;
+                    final int displayId = args.argi1;
+                    final int types = args.argi2;
+                    args.recycle();
                     for (int i = 0; i < mCallbacks.size(); i++) {
                         mCallbacks.get(i).abortTransient(displayId, types);
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 1c4e319..250900e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -25,7 +25,9 @@
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
 import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION;
@@ -95,6 +97,7 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
 import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.log.LogLevel;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
@@ -127,7 +130,7 @@
 @SysUISingleton
 public class KeyguardIndicationController {
 
-    private static final String TAG = "KeyguardIndication";
+    public static final String TAG = "KeyguardIndication";
     private static final boolean DEBUG_CHARGING_SPEED = false;
 
     private static final int MSG_SHOW_ACTION_TO_UNLOCK = 1;
@@ -327,9 +330,11 @@
         mInitialTextColorState = mTopIndicationView != null
                 ? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
         mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
-            mLockScreenIndicationView,
-            mExecutor,
-            mStatusBarStateController);
+                mLockScreenIndicationView,
+                mExecutor,
+                mStatusBarStateController,
+                mKeyguardLogger
+        );
         updateDeviceEntryIndication(false /* animate */);
         updateOrganizedOwnedDevice();
         if (mBroadcastReceiver == null) {
@@ -551,23 +556,23 @@
                             .build(),
                     true
             );
-            if (!TextUtils.isEmpty(mBiometricMessageFollowUp)) {
-                mRotateTextViewController.updateIndication(
-                        INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
-                        new KeyguardIndication.Builder()
-                                .setMessage(mBiometricMessageFollowUp)
-                                .setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
-                                .setTextColor(mInitialTextColorState)
-                                .build(),
-                        true
-                );
-            } else {
-                mRotateTextViewController.hideIndication(
-                        INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP);
-            }
         } else {
-            mRotateTextViewController.hideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
-            mRotateTextViewController.hideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP);
+            mRotateTextViewController.hideIndication(
+                    INDICATION_TYPE_BIOMETRIC_MESSAGE);
+        }
+        if (!TextUtils.isEmpty(mBiometricMessageFollowUp)) {
+            mRotateTextViewController.updateIndication(
+                    INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                    new KeyguardIndication.Builder()
+                            .setMessage(mBiometricMessageFollowUp)
+                            .setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
+                            .setTextColor(mInitialTextColorState)
+                            .build(),
+                    true
+            );
+        } else {
+            mRotateTextViewController.hideIndication(
+                    INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP);
         }
     }
 
@@ -796,7 +801,8 @@
      */
     private void showBiometricMessage(CharSequence biometricMessage,
             @Nullable CharSequence biometricMessageFollowUp) {
-        if (TextUtils.equals(biometricMessage, mBiometricMessage)) {
+        if (TextUtils.equals(biometricMessage, mBiometricMessage)
+                && TextUtils.equals(biometricMessageFollowUp, mBiometricMessageFollowUp)) {
             return;
         }
 
@@ -805,7 +811,8 @@
 
         mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
         hideBiometricMessageDelayed(
-                mBiometricMessageFollowUp != null
+                !TextUtils.isEmpty(mBiometricMessage)
+                        && !TextUtils.isEmpty(mBiometricMessageFollowUp)
                         ? IMPORTANT_MSG_MIN_DURATION * 2
                         : DEFAULT_HIDE_DELAY_MS
         );
@@ -839,6 +846,7 @@
      * may continuously be cycled through.
      */
     protected final void updateDeviceEntryIndication(boolean animate) {
+        mKeyguardLogger.logUpdateDeviceEntryIndication(animate, mVisible, mDozing);
         if (!mVisible) {
             return;
         }
@@ -1089,20 +1097,27 @@
                 }
             }
 
+            final boolean faceAuthUnavailable = biometricSourceType == FACE
+                    && msgId == BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
+
             // TODO(b/141025588): refactor to reduce repetition of code/comments
             // Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
             // as long as primary auth, i.e. PIN/pattern/password, is not required), so it's ok to
             // pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the
             // check of whether non-strong biometric is allowed
             if (!mKeyguardUpdateMonitor
-                    .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)) {
+                    .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)
+                    && !faceAuthUnavailable) {
                 return;
             }
 
             final boolean faceAuthSoftError = biometricSourceType == FACE
-                    && msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
+                    && msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED
+                    && msgId != BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
             final boolean faceAuthFailed = biometricSourceType == FACE
                     && msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed
+            final boolean fpAuthFailed = biometricSourceType == FINGERPRINT
+                    && msgId == BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; // ran matcher & failed
             final boolean isUnlockWithFingerprintPossible = canUnlockWithFingerprint();
             final boolean isCoExFaceAcquisitionMessage =
                     faceAuthSoftError && isUnlockWithFingerprintPossible;
@@ -1125,6 +1140,29 @@
                             mContext.getString(R.string.keyguard_face_failed),
                             mContext.getString(R.string.keyguard_suggest_fingerprint)
                     );
+                } else if (fpAuthFailed
+                        && mKeyguardUpdateMonitor.getUserUnlockedWithFace(getCurrentUser())) {
+                    // face had already previously unlocked the device, so instead of showing a
+                    // fingerprint error, tell them they have already unlocked with face auth
+                    // and how to enter their device
+                    showBiometricMessage(
+                            mContext.getString(R.string.keyguard_face_successful_unlock),
+                            mContext.getString(R.string.keyguard_unlock)
+                    );
+                } else if (fpAuthFailed
+                        && mKeyguardUpdateMonitor.getUserHasTrust(
+                                KeyguardUpdateMonitor.getCurrentUser())) {
+                    showBiometricMessage(
+                            getTrustGrantedIndication(),
+                            mContext.getString(R.string.keyguard_unlock)
+                    );
+                } else if (faceAuthUnavailable) {
+                    showBiometricMessage(
+                            helpString,
+                            isUnlockWithFingerprintPossible
+                                    ? mContext.getString(R.string.keyguard_suggest_fingerprint)
+                                    : mContext.getString(R.string.keyguard_unlock)
+                    );
                 } else {
                     showBiometricMessage(helpString);
                 }
@@ -1408,6 +1446,7 @@
         public void onKeyguardShowingChanged() {
             // All transient messages are gone the next time keyguard is shown
             if (!mKeyguardStateController.isShowing()) {
+                mKeyguardLogger.log(TAG, LogLevel.DEBUG, "clear messages");
                 mTopIndicationView.clearMessages();
                 mRotateTextViewController.clearMessages();
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 7d0ac18..59f59ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -268,30 +268,31 @@
         if (!rankingMap.getRanking(key, ranking)) {
             ranking.populate(
                     key,
-                    0,
-                    false,
-                    0,
-                    0,
-                    0,
-                    null,
-                    null,
-                    null,
-                    new ArrayList<>(),
-                    new ArrayList<>(),
-                    false,
-                    0,
-                    false,
-                    0,
-                    false,
-                    new ArrayList<>(),
-                    new ArrayList<>(),
-                    false,
-                    false,
-                    false,
-                    null,
-                    0,
-                    false,
-                    0
+                    /* rank= */ 0,
+                    /* matchesInterruptionFilter= */ false,
+                    /* visibilityOverride= */ 0,
+                    /* suppressedVisualEffects= */ 0,
+                    /* importance= */ 0,
+                    /* explanation= */ null,
+                    /* overrideGroupKey= */ null,
+                    /* channel= */ null,
+                    /* overridePeople= */ new ArrayList<>(),
+                    /* snoozeCriteria= */ new ArrayList<>(),
+                    /* showBadge= */ false,
+                    /* userSentiment= */ 0,
+                    /* hidden= */ false,
+                    /* lastAudiblyAlertedMs= */ 0,
+                    /* noisy= */ false,
+                    /* smartActions= */ new ArrayList<>(),
+                    /* smartReplies= */ new ArrayList<>(),
+                    /* canBubble= */ false,
+                    /* isTextChanged= */ false,
+                    /* isConversation= */ false,
+                    /* shortcutInfo= */ null,
+                    /* rankingAdjustment= */ 0,
+                    /* isBubble= */ false,
+                    /* proposedImportance= */ 0,
+                    /* sensitiveContent= */ false
             );
         }
         return ranking;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 56c34a0..8f1e0a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -23,6 +23,7 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.IndentingPrintWriter;
 import android.util.MathUtils;
 import android.view.View;
 import android.view.ViewGroup;
@@ -52,6 +53,9 @@
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
+import com.android.systemui.util.DumpUtilsKt;
+
+import java.io.PrintWriter;
 
 /**
  * A notification shelf view that is placed inside the notification scroller. It manages the
@@ -86,7 +90,6 @@
     private boolean mInteractive;
     private boolean mAnimationsEnabled = true;
     private boolean mShowNotificationShelf;
-    private float mFirstElementRoundness;
     private Rect mClipRect = new Rect();
     private int mIndexOfFirstViewInShelf = -1;
     private float mCornerAnimationDistance;
@@ -263,8 +266,7 @@
         final float actualWidth = mAmbientState.isOnKeyguard()
                 ? MathUtils.lerp(shortestWidth, getWidth(), fractionToShade)
                 : getWidth();
-        ActivatableNotificationView anv = (ActivatableNotificationView) this;
-        anv.setBackgroundWidth((int) actualWidth);
+        setBackgroundWidth((int) actualWidth);
         if (mShelfIcons != null) {
             mShelfIcons.setActualLayoutWidth((int) actualWidth);
         }
@@ -365,9 +367,7 @@
         boolean expandingAnimated = mAmbientState.isExpansionChanging()
                 && !mAmbientState.isPanelTracking();
         int baseZHeight = mAmbientState.getBaseZHeight();
-        int backgroundTop = 0;
         int clipTopAmount = 0;
-        float firstElementRoundness = 0.0f;
 
         for (int i = 0; i < mHostLayoutController.getChildCount(); i++) {
             ExpandableView child = mHostLayoutController.getChildAt(i);
@@ -420,18 +420,6 @@
                 if (notGoneIndex != 0 || !aboveShelf) {
                     expandableRow.setAboveShelf(false);
                 }
-                if (notGoneIndex == 0) {
-                    StatusBarIconView icon = expandableRow.getEntry().getIcons().getShelfIcon();
-                    NotificationIconContainer.IconState iconState = getIconState(icon);
-                    // The icon state might be null in rare cases where the notification is actually
-                    // added to the layout, but not to the shelf. An example are replied messages,
-                    // since they don't show up on AOD
-                    if (iconState != null && iconState.clampedAppearAmount == 1.0f) {
-                        // only if the first icon is fully in the shelf we want to clip to it!
-                        backgroundTop = (int) (child.getTranslationY() - getTranslationY());
-                        firstElementRoundness = expandableRow.getTopRoundness();
-                    }
-                }
 
                 previousColor = ownColorUntinted;
                 notGoneIndex++;
@@ -467,8 +455,6 @@
 
         // TODO(b/172289889) transition last icon in shelf to notification icon and vice versa.
         setVisibility(isHidden ? View.INVISIBLE : View.VISIBLE);
-        setBackgroundTop(backgroundTop);
-        setFirstElementRoundness(firstElementRoundness);
         mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex());
         mShelfIcons.calculateIconXTranslations();
         mShelfIcons.applyIconStates();
@@ -570,12 +556,6 @@
         }
     }
 
-    private void setFirstElementRoundness(float firstElementRoundness) {
-        if (mFirstElementRoundness != firstElementRoundness) {
-            mFirstElementRoundness = firstElementRoundness;
-        }
-    }
-
     private void updateIconClipAmount(ExpandableNotificationRow row) {
         float maxTop = row.getTranslationY();
         if (getClipTopAmount() != 0) {
@@ -1011,6 +991,18 @@
         expandableView.requestRoundnessReset(LegacySourceType.OnScroll);
     }
 
+    @Override
+    public void dump(PrintWriter pwOriginal, String[] args) {
+        IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+        super.dump(pw, args);
+        if (DUMP_VERBOSE) {
+            DumpUtilsKt.withIncreasedIndent(pw, () -> {
+                pw.println("mActualWidth: " + mActualWidth);
+                pw.println("mStatusBarHeight: " + mStatusBarHeight);
+            });
+        }
+    }
+
     public class ShelfState extends ExpandableViewState {
         private boolean hasItemsInStableShelf;
         private ExpandableView firstViewInShelf;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerExt.kt b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerExt.kt
new file mode 100644
index 0000000..6148b40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerExt.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/** Returns a [Flow] that emits whenever [StatusBarStateController.isExpanded] changes value. */
+val StatusBarStateController.expansionChanges: Flow<Boolean>
+    get() = conflatedCallbackFlow {
+        val listener =
+            object : StatusBarStateController.StateListener {
+                override fun onExpandedChanged(isExpanded: Boolean) {
+                    trySend(isExpanded)
+                }
+            }
+        trySend(isExpanded)
+        addCallback(listener)
+        awaitClose { removeCallback(listener) }
+    }
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 02d0f94..93aff7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -31,15 +31,19 @@
 import android.os.UserHandle
 import android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
 import android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS
+import android.provider.Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED
 import android.util.Log
 import android.view.ContextThemeWrapper
 import android.view.View
 import android.view.ViewGroup
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.settingslib.Utils
+import com.android.systemui.Dumpable
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
@@ -54,12 +58,13 @@
 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.Weather
+import com.android.systemui.plugins.Weather
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.util.concurrency.Execution
 import com.android.systemui.util.settings.SecureSettings
+import java.io.PrintWriter
 import java.time.Instant
 import java.util.Optional
 import java.util.concurrent.Executor
@@ -83,6 +88,8 @@
         private val statusBarStateController: StatusBarStateController,
         private val deviceProvisionedController: DeviceProvisionedController,
         private val bypassController: KeyguardBypassController,
+        private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+        private val dumpManager: DumpManager,
         private val execution: Execution,
         @Main private val uiExecutor: Executor,
         @Background private val bgExecutor: Executor,
@@ -93,7 +100,7 @@
         optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>,
         optionalPlugin: Optional<BcSmartspaceDataPlugin>,
         optionalConfigPlugin: Optional<BcSmartspaceConfigPlugin>,
-) {
+) : Dumpable {
     companion object {
         private const val TAG = "LockscreenSmartspaceController"
     }
@@ -176,10 +183,10 @@
         }
         if (weatherTarget != null) {
             val weatherData = Weather.fromBundle(weatherTarget.baseAction.extras)
+            keyguardUpdateMonitor.sendWeatherData(weatherData)
         }
     }
 
-
     private val userTrackerCallback = object : UserTracker.Callback {
         override fun onUserChanged(newUser: Int, userContext: Context) {
             execution.assertIsMainThread()
@@ -228,6 +235,7 @@
 
     init {
         deviceProvisionedController.addCallback(deviceProvisionedListener)
+        dumpManager.registerDumpable(this)
     }
 
     fun isEnabled(): Boolean {
@@ -243,6 +251,17 @@
                 datePlugin != null && weatherPlugin != null
     }
 
+    fun isWeatherEnabled(): Boolean {
+       execution.assertIsMainThread()
+       val defaultValue = context.getResources().getBoolean(
+               com.android.internal.R.bool.config_lockscreenWeatherEnabledByDefault)
+       val showWeather = secureSettings.getIntForUser(
+           LOCK_SCREEN_WEATHER_ENABLED,
+           if (defaultValue) 1 else 0,
+           userTracker.userId) == 1
+       return showWeather
+    }
+
     private fun updateBypassEnabled() {
         val bypassEnabled = bypassController.bypassEnabled
         smartspaceViews.forEach { it.setKeyguardBypassEnabled(bypassEnabled) }
@@ -530,4 +549,11 @@
         }
         return null
     }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("Region Samplers: ${regionSamplers.size}")
+        regionSamplers.map { (_, sampler) ->
+            sampler.dump(pw)
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
index 4856759..fc89be2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
@@ -17,13 +17,16 @@
 package com.android.systemui.statusbar.notification
 
 import android.content.Context
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.FlagResolver
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import javax.inject.Inject
 
 class NotifPipelineFlags @Inject constructor(
     val context: Context,
-    val featureFlags: FeatureFlags
+    val featureFlags: FeatureFlags,
+    val sysPropFlags: FlagResolver,
 ) {
     init {
         featureFlags.addListener(Flags.DISABLE_FSI) { event -> event.requestNoRestart() }
@@ -39,11 +42,21 @@
 
     fun disableFsi(): Boolean = featureFlags.isEnabled(Flags.DISABLE_FSI)
 
-    val shouldFilterUnseenNotifsOnKeyguard: Boolean by lazy {
-        featureFlags.isEnabled(Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD)
-    }
+    fun forceDemoteFsi(): Boolean =
+            sysPropFlags.isEnabled(NotificationFlags.FSI_FORCE_DEMOTE)
 
-    val isNoHunForOldWhenEnabled: Boolean by lazy {
-        featureFlags.isEnabled(Flags.NO_HUN_FOR_OLD_WHEN)
-    }
+    fun showStickyHunForDeniedFsi(): Boolean =
+            sysPropFlags.isEnabled(NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI)
+
+    fun allowDismissOngoing(): Boolean =
+            sysPropFlags.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)
+
+    fun isOtpRedactionEnabled(): Boolean =
+            sysPropFlags.isEnabled(NotificationFlags.OTP_REDACTION)
+
+    val shouldFilterUnseenNotifsOnKeyguard: Boolean
+        get() = featureFlags.isEnabled(Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD)
+
+    val isNoHunForOldWhenEnabled: Boolean
+        get() = featureFlags.isEnabled(Flags.NO_HUN_FOR_OLD_WHEN)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index df35c9e..32b8e09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -96,6 +96,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
 import com.android.systemui.statusbar.notification.collection.notifcollection.RankingAppliedEvent;
 import com.android.systemui.statusbar.notification.collection.notifcollection.RankingUpdatedEvent;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.time.SystemClock;
 
@@ -151,6 +152,7 @@
     private final LogBufferEulogizer mEulogizer;
     private final DumpManager mDumpManager;
     private final NotifCollectionInconsistencyTracker mInconsistencyTracker;
+    private final NotificationDismissibilityProvider mDismissibilityProvider;
 
     private final Map<String, NotificationEntry> mNotificationSet = new ArrayMap<>();
     private final Collection<NotificationEntry> mReadOnlyNotificationSet =
@@ -178,7 +180,8 @@
             @Main Handler mainHandler,
             @Background Executor bgExecutor,
             LogBufferEulogizer logBufferEulogizer,
-            DumpManager dumpManager) {
+            DumpManager dumpManager,
+            NotificationDismissibilityProvider dismissibilityProvider) {
         mStatusBarService = statusBarService;
         mClock = clock;
         mNotifPipelineFlags = notifPipelineFlags;
@@ -188,6 +191,7 @@
         mEulogizer = logBufferEulogizer;
         mDumpManager = dumpManager;
         mInconsistencyTracker = new NotifCollectionInconsistencyTracker(mLogger);
+        mDismissibilityProvider = dismissibilityProvider;
     }
 
     /** Initializes the NotifCollection and registers it to receive notification events. */
@@ -554,6 +558,10 @@
                 .findFirst().orElse(null);
     }
 
+    private boolean isDismissable(NotificationEntry entry) {
+        return mDismissibilityProvider.isDismissable(entry);
+    }
+
     /**
      * Checks if the entry is the only child in the logical group;
      * it need not have a summary to qualify
@@ -1006,6 +1014,7 @@
     public class FutureDismissal implements Runnable {
         private final NotificationEntry mEntry;
         private final DismissedByUserStatsCreator mStatsCreator;
+
         @Nullable
         private final NotificationEntry mSummaryToDismiss;
         private final String mLabel;
@@ -1030,7 +1039,7 @@
             if (isOnlyChildInGroup(entry)) {
                 String group = entry.getSbn().getGroupKey();
                 NotificationEntry summary = getGroupSummary(group);
-                if (summary != null && summary.isDismissable()) return summary;
+                if (summary != null && isDismissable(summary)) return summary;
             }
             return null;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 37d82ca..e34096e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -731,12 +731,28 @@
     }
 
     /**
+     * Determines whether the NotificationEntry is dismissable based on the Notification flags and
+     * the given state. It doesn't recurse children or depend on the view attach state.
+     *
+     * @param isLocked if the device is locked or unlocked
+     * @return true if this NotificationEntry is dismissable.
+     */
+    public boolean isDismissableForState(boolean isLocked) {
+        if (mSbn.isNonDismissable()) {
+            // don't dismiss exempted Notifications
+            return false;
+        }
+        // don't dismiss ongoing Notifications when the device is locked
+        return !mSbn.isOngoing() || !isLocked;
+    }
+
+    /**
      * @return Can the underlying notification be individually dismissed?
      * @see #canViewBeDismissed()
      */
     // TODO: This logic doesn't belong on NotificationEntry. It should be moved to a controller
     // that can be added as a dependency to any class that needs to answer this question.
-    public boolean isDismissable() {
+    public boolean legacyIsDismissableRecursive() {
         if  (mSbn.isOngoing()) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java
index 058042c..0c95eab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinator.java
@@ -71,11 +71,9 @@
      * marking them as relevant for setup are allowed to show when device is unprovisioned
      */
     private boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
-        final boolean hasPermission = checkUidPermission(
-                Manifest.permission.NOTIFICATION_DURING_SETUP,
-                sbn.getUid()) == PackageManager.PERMISSION_GRANTED;
-        return hasPermission
-                && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
+        // system_server checks the permission so systemui can just check whether the
+        // extra exists
+        return sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
     }
 
     private int checkUidPermission(String permission, int uid) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinator.kt
new file mode 100644
index 0000000..1fccf82
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinator.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProviderImpl
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import javax.inject.Inject
+
+/** Decides if a Notification can be dismissed by the user. */
+@CoordinatorScope
+class DismissibilityCoordinator
+@Inject
+constructor(
+    private val keyguardStateController: KeyguardStateController,
+    private val provider: NotificationDismissibilityProviderImpl
+) : Coordinator {
+
+    override fun attach(pipeline: NotifPipeline) {
+        pipeline.addOnBeforeRenderListListener(::onBeforeRenderListListener)
+    }
+
+    private fun onBeforeRenderListListener(entries: List<ListEntry>) {
+        val isLocked = !keyguardStateController.isUnlocked
+        val nonDismissableEntryKeys = mutableSetOf<String>()
+        markNonDismissibleEntries(nonDismissableEntryKeys, entries, isLocked)
+        provider.update(nonDismissableEntryKeys)
+    }
+
+    /**
+     * Visits every entry and its children to mark the dismissible entries.
+     * @param markedKeys set to store the marked entry keys
+     * @param entries to visit
+     * @param isLocked the locked state of the device
+     * @return true if any of the entries were marked as non-dismissible.
+     */
+    private fun markNonDismissibleEntries(
+        markedKeys: MutableSet<String>,
+        entries: List<ListEntry>,
+        isLocked: Boolean
+    ): Boolean {
+        var anyNonDismissableEntries = false
+
+        for (entry in entries) {
+            entry.representativeEntry?.let { notifEntry ->
+                // mark the entry if it is non-dismissible
+                if (!notifEntry.isDismissableForState(isLocked)) {
+                    markedKeys.add(notifEntry.key)
+                    anyNonDismissableEntries = true
+                }
+            }
+
+            if (entry is GroupEntry) {
+                if (markNonDismissibleEntries(markedKeys, entry.children, isLocked)) {
+                    // if any child is non-dismissible, mark the parent as well
+                    entry.representativeEntry?.let { markedKeys.add(it.key) }
+                    anyNonDismissableEntries = true
+                }
+            }
+        }
+
+        return anyNonDismissableEntries
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index e996b78..6bf7668 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -16,16 +16,15 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator
 
-import android.database.ContentObserver
 import android.os.UserHandle
 import android.provider.Settings
 import androidx.annotation.VisibleForTesting
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.expansionChanges
 import com.android.systemui.statusbar.notification.NotifPipelineFlags
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -35,15 +34,14 @@
 import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
+import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.statusbar.policy.headsUpEvents
 import com.android.systemui.util.settings.SecureSettings
-import com.android.systemui.util.settings.SettingsProxy
+import com.android.systemui.util.settings.SettingsProxyExt.observerFlow
 import javax.inject.Inject
-import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.conflate
 import kotlinx.coroutines.flow.flowOn
@@ -60,6 +58,7 @@
 @Inject
 constructor(
     @Background private val bgDispatcher: CoroutineDispatcher,
+    private val headsUpManager: HeadsUpManager,
     private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
     private val keyguardRepository: KeyguardRepository,
     private val notifPipelineFlags: NotifPipelineFlags,
@@ -87,28 +86,53 @@
     private fun attachUnseenFilter(pipeline: NotifPipeline) {
         pipeline.addFinalizeFilter(unseenNotifFilter)
         pipeline.addCollectionListener(collectionListener)
-        scope.launch { clearUnseenWhenKeyguardIsDismissed() }
+        scope.launch { trackUnseenNotificationsWhileUnlocked() }
         scope.launch { invalidateWhenUnseenSettingChanges() }
     }
 
-    private suspend fun clearUnseenWhenKeyguardIsDismissed() {
-        // Use collectLatest so that the suspending block is cancelled if isKeyguardShowing changes
-        // during the timeout period
+    private suspend fun trackUnseenNotificationsWhileUnlocked() {
+        // Use collectLatest so that trackUnseenNotifications() is cancelled when the keyguard is
+        // showing again
         keyguardRepository.isKeyguardShowing.collectLatest { isKeyguardShowing ->
             if (!isKeyguardShowing) {
                 unseenNotifFilter.invalidateList("keyguard no longer showing")
-                delay(SEEN_TIMEOUT)
+                trackUnseenNotifications()
+            }
+        }
+    }
+
+    private suspend fun trackUnseenNotifications() {
+        coroutineScope {
+            launch { clearUnseenNotificationsWhenShadeIsExpanded() }
+            launch { markHeadsUpNotificationsAsSeen() }
+        }
+    }
+
+    private suspend fun clearUnseenNotificationsWhenShadeIsExpanded() {
+        statusBarStateController.expansionChanges.collect { isExpanded ->
+            if (isExpanded) {
                 unseenNotifications.clear()
             }
         }
     }
 
+    private suspend fun markHeadsUpNotificationsAsSeen() {
+        headsUpManager.allEntries
+            .filter { it.isRowPinned }
+            .forEach { unseenNotifications.remove(it) }
+        headsUpManager.headsUpEvents.collect { (entry, isHun) ->
+            if (isHun) {
+                unseenNotifications.remove(entry)
+            }
+        }
+    }
+
     private suspend fun invalidateWhenUnseenSettingChanges() {
         secureSettings
             // emit whenever the setting has changed
-            .settingChangesForUser(
-                Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
+            .observerFlow(
                 UserHandle.USER_ALL,
+                Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS,
             )
             // perform a query immediately
             .onStart { emit(Unit) }
@@ -136,13 +160,17 @@
     private val collectionListener =
         object : NotifCollectionListener {
             override fun onEntryAdded(entry: NotificationEntry) {
-                if (keyguardRepository.isKeyguardShowing()) {
+                if (
+                    keyguardRepository.isKeyguardShowing() || !statusBarStateController.isExpanded
+                ) {
                     unseenNotifications.add(entry)
                 }
             }
 
             override fun onEntryUpdated(entry: NotificationEntry) {
-                if (keyguardRepository.isKeyguardShowing()) {
+                if (
+                    keyguardRepository.isKeyguardShowing() || !statusBarStateController.isExpanded
+                ) {
                     unseenNotifications.add(entry)
                 }
             }
@@ -212,18 +240,5 @@
 
     companion object {
         private const val TAG = "KeyguardCoordinator"
-        private val SEEN_TIMEOUT = 5.seconds
     }
 }
-
-private fun SettingsProxy.settingChangesForUser(name: String, userHandle: Int): Flow<Unit> =
-    conflatedCallbackFlow {
-        val observer =
-            object : ContentObserver(null) {
-                override fun onChange(selfChange: Boolean) {
-                    trySend(Unit)
-                }
-            }
-        registerContentObserverForUser(name, observer, userHandle)
-        awaitClose { unregisterContentObserver(observer) }
-    }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index 03a3ca5..8a82bca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -55,6 +55,7 @@
     viewConfigCoordinator: ViewConfigCoordinator,
     visualStabilityCoordinator: VisualStabilityCoordinator,
     sensitiveContentCoordinator: SensitiveContentCoordinator,
+    dismissibilityCoordinator: DismissibilityCoordinator
 ) : NotifCoordinators {
 
     private val mCoordinators: MutableList<Coordinator> = ArrayList()
@@ -93,6 +94,7 @@
         mCoordinators.add(gutsCoordinator)
         mCoordinators.add(preparationCoordinator)
         mCoordinators.add(remoteInputCoordinator)
+        mCoordinators.add(dismissibilityCoordinator)
 
         // Manually add Ordered Sections
         // HeadsUp > FGS > People > Alerting > Silent > Minimized > Unknown/Default
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationDismissibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationDismissibilityProvider.kt
new file mode 100644
index 0000000..53f2366
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationDismissibilityProvider.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.statusbar.notification.collection.provider
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+
+/** Keeps track of the dismissibility of Notifications currently handed over to the view layer. */
+interface NotificationDismissibilityProvider {
+    /** @return true if the given {NotificationEntry} can currently be dismissed by the user */
+    fun isDismissable(entry: NotificationEntry): Boolean
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationDismissibilityProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationDismissibilityProviderImpl.kt
new file mode 100644
index 0000000..049321b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationDismissibilityProviderImpl.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.provider
+
+import androidx.annotation.VisibleForTesting
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING
+import com.android.systemui.Dumpable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.util.asIndenting
+import com.android.systemui.util.withIncreasedIndent
+import java.io.PrintWriter
+import javax.inject.Inject
+
+@SysUISingleton
+class NotificationDismissibilityProviderImpl @Inject constructor(dumpManager: DumpManager) :
+    NotificationDismissibilityProvider, Dumpable {
+
+    init {
+        dumpManager.registerNormalDumpable(TAG, this)
+    }
+
+    @VisibleForTesting
+    @Volatile
+    var nonDismissableEntryKeys = setOf<String>()
+        private set
+
+    override fun isDismissable(entry: NotificationEntry): Boolean {
+        // TODO(b/268380968): inject FlagResolver
+        return if (SystemUiSystemPropertiesFlags.getResolver().isEnabled(ALLOW_DISMISS_ONGOING)) {
+            entry.key !in nonDismissableEntryKeys
+        } else {
+            entry.legacyIsDismissableRecursive()
+        }
+    }
+
+    @Synchronized
+    fun update(nonDismissableEntryKeys: Set<String>) {
+        this.nonDismissableEntryKeys = nonDismissableEntryKeys.toSet()
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) =
+        pw.asIndenting().run {
+            println("non-dismissible entries: ${nonDismissableEntryKeys.size}")
+
+            withIncreasedIndent { nonDismissableEntryKeys.forEach(this::println) }
+        }
+
+    companion object {
+        private const val TAG = "NotificationDismissibilityProvider"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 8436ff7..b100d44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -38,6 +38,8 @@
 import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
 import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProviderImpl;
 import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl;
 import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderModule;
 import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
@@ -65,14 +67,14 @@
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 
-import java.util.concurrent.Executor;
-
-import javax.inject.Provider;
-
 import dagger.Binds;
 import dagger.Module;
 import dagger.Provides;
 
+import java.util.concurrent.Executor;
+
+import javax.inject.Provider;
+
 /**
  * Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
  */
@@ -164,6 +166,13 @@
     CommonNotifCollection provideCommonNotifCollection(NotifPipeline pipeline);
 
     /**
+     * Provide the object which can be used to obtain dismissibility of a Notification.
+     */
+    @Binds
+    NotificationDismissibilityProvider provideNotificationDismissibilityProvider(
+            NotificationDismissibilityProviderImpl impl);
+
+    /**
      * Provide the object which can be used to obtain NotificationVisibility objects.
      */
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 5f6a5cb..26f97de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -63,7 +63,7 @@
  * are not.
  */
 public class NotificationLogger implements StateListener {
-    private static final String TAG = "NotificationLogger";
+    static final String TAG = "NotificationLogger";
     private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
 
     /** The minimum delay in ms between reports of notification visibility. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
index ec8501a..cc1103d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLogger.kt
@@ -18,6 +18,7 @@
 package com.android.systemui.statusbar.notification.logging
 
 import android.app.StatsManager
+import android.util.Log
 import android.util.StatsEvent
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -25,6 +26,7 @@
 import com.android.systemui.shared.system.SysUiStatsLog
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.util.traceSection
+import java.lang.Exception
 import java.util.concurrent.Executor
 import javax.inject.Inject
 import kotlin.math.roundToInt
@@ -82,43 +84,56 @@
                 return StatsManager.PULL_SKIP
             }
 
-            // Notifications can only be retrieved on the main thread, so switch to that thread.
-            val notifications = getAllNotificationsOnMainThread()
-            val notificationMemoryUse =
-                NotificationMemoryMeter.notificationMemoryUse(notifications)
-                    .sortedWith(
-                        compareBy(
-                            { it.packageName },
-                            { it.objectUsage.style },
-                            { it.notificationKey }
+            try {
+                // Notifications can only be retrieved on the main thread, so switch to that thread.
+                val notifications = getAllNotificationsOnMainThread()
+                val notificationMemoryUse =
+                    NotificationMemoryMeter.notificationMemoryUse(notifications)
+                        .sortedWith(
+                            compareBy(
+                                { it.packageName },
+                                { it.objectUsage.style },
+                                { it.notificationKey }
+                            )
+                        )
+                val usageData = aggregateMemoryUsageData(notificationMemoryUse)
+                usageData.forEach { (_, use) ->
+                    data.add(
+                        SysUiStatsLog.buildStatsEvent(
+                            SysUiStatsLog.NOTIFICATION_MEMORY_USE,
+                            use.uid,
+                            use.style,
+                            use.count,
+                            use.countWithInflatedViews,
+                            toKb(use.smallIconObject),
+                            use.smallIconBitmapCount,
+                            toKb(use.largeIconObject),
+                            use.largeIconBitmapCount,
+                            toKb(use.bigPictureObject),
+                            use.bigPictureBitmapCount,
+                            toKb(use.extras),
+                            toKb(use.extenders),
+                            toKb(use.smallIconViews),
+                            toKb(use.largeIconViews),
+                            toKb(use.systemIconViews),
+                            toKb(use.styleViews),
+                            toKb(use.customViews),
+                            toKb(use.softwareBitmaps),
+                            use.seenCount
                         )
                     )
-            val usageData = aggregateMemoryUsageData(notificationMemoryUse)
-            usageData.forEach { (_, use) ->
-                data.add(
-                    SysUiStatsLog.buildStatsEvent(
-                        SysUiStatsLog.NOTIFICATION_MEMORY_USE,
-                        use.uid,
-                        use.style,
-                        use.count,
-                        use.countWithInflatedViews,
-                        toKb(use.smallIconObject),
-                        use.smallIconBitmapCount,
-                        toKb(use.largeIconObject),
-                        use.largeIconBitmapCount,
-                        toKb(use.bigPictureObject),
-                        use.bigPictureBitmapCount,
-                        toKb(use.extras),
-                        toKb(use.extenders),
-                        toKb(use.smallIconViews),
-                        toKb(use.largeIconViews),
-                        toKb(use.systemIconViews),
-                        toKb(use.styleViews),
-                        toKb(use.customViews),
-                        toKb(use.softwareBitmaps),
-                        use.seenCount
-                    )
-                )
+                }
+            } catch (e: InterruptedException) {
+                // This can happen if the device is sleeping or view walking takes too long.
+                // The statsd collector will interrupt the thread and we need to handle it
+                // gracefully.
+                Log.w(NotificationLogger.TAG, "Timed out when measuring notification memory.", e)
+                return@traceSection StatsManager.PULL_SKIP
+            } catch (e: Exception) {
+                // Error while collecting data, this should not crash prod SysUI. Just
+                // log WTF and move on.
+                Log.wtf(NotificationLogger.TAG, "Failed to measure notification memory.", e)
+                return@traceSection StatsManager.PULL_SKIP
             }
 
             return StatsManager.PULL_SUCCESS
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
index 2d04211..6491223 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryViewWalker.kt
@@ -184,19 +184,21 @@
     private fun computeDrawableUse(drawable: Drawable, seenObjects: HashSet<Int>): Int =
         when (drawable) {
             is BitmapDrawable -> {
-                val ref = System.identityHashCode(drawable.bitmap)
-                if (seenObjects.contains(ref)) {
-                    0
-                } else {
-                    seenObjects.add(ref)
-                    drawable.bitmap.allocationByteCount
-                }
+                drawable.bitmap?.let {
+                    val ref = System.identityHashCode(it)
+                    if (seenObjects.contains(ref)) {
+                        0
+                    } else {
+                        seenObjects.add(ref)
+                        it.allocationByteCount
+                    }
+                } ?: 0
             }
             else -> 0
         }
 
     private fun isDrawableSoftwareBitmap(drawable: Drawable) =
-        drawable is BitmapDrawable && drawable.bitmap.config != Bitmap.Config.HARDWARE
+        drawable is BitmapDrawable && drawable.bitmap?.config != Bitmap.Config.HARDWARE
 
     private fun identifierForView(view: View) =
         if (view.id == View.NO_ID) {
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 7addc8f..68ad49be 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
@@ -23,6 +23,7 @@
 import android.graphics.Canvas;
 import android.graphics.Point;
 import android.util.AttributeSet;
+import android.util.IndentingPrintWriter;
 import android.util.MathUtils;
 import android.view.Choreographer;
 import android.view.MotionEvent;
@@ -43,7 +44,9 @@
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.util.DumpUtilsKt;
 
+import java.io.PrintWriter;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -651,11 +654,6 @@
         mBackgroundNormal.setRadius(topRadius, bottomRadius);
     }
 
-    @Override
-    protected void setBackgroundTop(int backgroundTop) {
-        mBackgroundNormal.setBackgroundTop(backgroundTop);
-    }
-
     protected abstract View getContentView();
 
     public int calculateBgColor() {
@@ -819,6 +817,22 @@
         mOnDetachResetRoundness.add(sourceType);
     }
 
+    @Override
+    public void dump(PrintWriter pwOriginal, String[] args) {
+        IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+        super.dump(pw, args);
+        if (DUMP_VERBOSE) {
+            DumpUtilsKt.withIncreasedIndent(pw, () -> {
+                pw.println("mBackgroundNormal: " + mBackgroundNormal);
+                if (mBackgroundNormal != null) {
+                    DumpUtilsKt.withIncreasedIndent(pw, () -> {
+                        mBackgroundNormal.dump(pw, args);
+                    });
+                }
+            });
+        }
+    }
+
     public interface OnActivatedListener {
         void onActivated(ActivatableNotificationView view);
         void onActivationReset(ActivatableNotificationView view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index a6b71dc..79e9ff2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -99,6 +99,7 @@
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.SourceType;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.logging.NotificationCounters;
@@ -179,6 +180,7 @@
     private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
     private Optional<BubblesManager> mBubblesManagerOptional;
     private MetricsLogger mMetricsLogger;
+    private NotificationDismissibilityProvider mDismissibilityProvider;
     private FeatureFlags mFeatureFlags;
     private int mIconTransformContentShift;
     private int mMaxHeadsUpHeightBeforeN;
@@ -591,7 +593,6 @@
         }
         mShowingPublicInitialized = false;
         updateNotificationColor();
-        updateLongClickable();
         if (mMenuRow != null) {
             mMenuRow.onNotificationUpdated(mEntry.getSbn());
             mMenuRow.setAppName(mAppName);
@@ -1197,26 +1198,8 @@
         return getShowingLayout().getVisibleWrapper();
     }
 
-    private boolean isNotificationRowLongClickable() {
-        if (mLongPressListener == null) {
-            return false;
-        }
-
-        if (!areGutsExposed()) { // guts is not opened
-            return true;
-        }
-
-        // if it is leave behind, it shouldn't be long clickable.
-        return !isGutsLeaveBehind();
-    }
-
-    private void updateLongClickable() {
-        setLongClickable(isNotificationRowLongClickable());
-    }
-
     public void setLongPressListener(LongPressListener longPressListener) {
         mLongPressListener = longPressListener;
-        updateLongClickable();
     }
 
     public void setDragController(ExpandableNotificationRowDragController dragController) {
@@ -1562,7 +1545,7 @@
     public void performDismiss(boolean fromAccessibility) {
         mMetricsLogger.count(NotificationCounters.NOTIFICATION_DISMISSED, 1);
         dismiss(fromAccessibility);
-        if (mEntry.isDismissable()) {
+        if (canEntryBeDismissed()) {
             if (mOnUserInteractionCallback != null) {
                 mOnUserInteractionCallback.registerFutureDismissal(mEntry, REASON_CANCEL).run();
             }
@@ -1722,6 +1705,7 @@
             OnUserInteractionCallback onUserInteractionCallback,
             Optional<BubblesManager> bubblesManagerOptional,
             NotificationGutsManager gutsManager,
+            NotificationDismissibilityProvider dismissibilityProvider,
             MetricsLogger metricsLogger,
             SmartReplyConstants smartReplyConstants,
             SmartReplyController smartReplyController,
@@ -1760,6 +1744,7 @@
         mBubblesManagerOptional = bubblesManagerOptional;
         mNotificationGutsManager = gutsManager;
         mMetricsLogger = metricsLogger;
+        mDismissibilityProvider = dismissibilityProvider;
         mFeatureFlags = featureFlags;
     }
 
@@ -2063,13 +2048,11 @@
     void onGutsOpened() {
         resetTranslation();
         updateContentAccessibilityImportanceForGuts(false /* isEnabled */);
-        updateLongClickable();
     }
 
     void onGutsClosed() {
         updateContentAccessibilityImportanceForGuts(true /* isEnabled */);
         mIsSnoozed = false;
-        updateLongClickable();
     }
 
     /**
@@ -2902,11 +2885,14 @@
 
     /**
      * @return Whether this view is allowed to be dismissed. Only valid for visible notifications as
-     * otherwise some state might not be updated. To request about the general clearability
-     * see {@link NotificationEntry#isDismissable()}.
+     * otherwise some state might not be updated.
      */
     public boolean canViewBeDismissed() {
-        return mEntry.isDismissable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
+        return canEntryBeDismissed() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
+    }
+
+    private boolean canEntryBeDismissed() {
+        return mDismissibilityProvider.isDismissable(mEntry);
     }
 
     /**
@@ -2968,10 +2954,6 @@
         return (mGuts != null && mGuts.isExposed());
     }
 
-    private boolean isGutsLeaveBehind() {
-        return (mGuts != null && mGuts.isLeavebehind());
-    }
-
     @Override
     public boolean isContentExpandable() {
         if (mIsSummaryWithChildren && !shouldShowPublic()) {
@@ -3710,7 +3692,7 @@
             pw.print("visibility: " + getVisibility());
             pw.print(", alpha: " + getAlpha());
             pw.print(", translation: " + getTranslation());
-            pw.print(", Entry isDismissable: " + mEntry.isDismissable());
+            pw.print(", entry dismissable: " + canEntryBeDismissed());
             pw.print(", mOnUserInteractionCallback null: " + (mOnUserInteractionCallback == null));
             pw.print(", removed: " + isRemoved());
             pw.print(", expandAnimationRunning: " + mExpandAnimationRunning);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index bb92dfc..f1694ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -40,6 +40,7 @@
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.collection.render.NodeController;
@@ -100,6 +101,7 @@
     private final SmartReplyConstants mSmartReplyConstants;
     private final SmartReplyController mSmartReplyController;
     private final ExpandableNotificationRowDragController mDragController;
+    private final NotificationDismissibilityProvider mDismissibilityProvider;
     private final ExpandableNotificationRow.ExpandableNotificationRowLogger mLoggerCallback =
             new ExpandableNotificationRow.ExpandableNotificationRowLogger() {
                 @Override
@@ -157,7 +159,8 @@
             FeatureFlags featureFlags,
             PeopleNotificationIdentifier peopleNotificationIdentifier,
             Optional<BubblesManager> bubblesManagerOptional,
-            ExpandableNotificationRowDragController dragController) {
+            ExpandableNotificationRowDragController dragController,
+            NotificationDismissibilityProvider dismissibilityProvider) {
         mView = view;
         mListContainer = listContainer;
         mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
@@ -189,6 +192,7 @@
         mLogBufferLogger = logBufferLogger;
         mSmartReplyConstants = smartReplyConstants;
         mSmartReplyController = smartReplyController;
+        mDismissibilityProvider = dismissibilityProvider;
     }
 
     /**
@@ -217,6 +221,7 @@
                 mOnUserInteractionCallback,
                 mBubblesManagerOptional,
                 mNotificationGutsManager,
+                mDismissibilityProvider,
                 mMetricsLogger,
                 mSmartReplyConstants,
                 mSmartReplyController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 2041245..197caa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -24,12 +24,16 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.util.IndentingPrintWriter;
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.RoundableState;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
+import com.android.systemui.util.DumpUtilsKt;
+
+import java.io.PrintWriter;
 
 /**
  * Like {@link ExpandableView}, but setting an outline for the height and clipping.
@@ -43,7 +47,6 @@
     private float mOutlineAlpha = -1f;
     private boolean mAlwaysRoundBothCorners;
     private Path mTmpPath = new Path();
-    private int mBackgroundTop;
 
     /**
      * {@code false} if the children views of the {@link ExpandableOutlineView} are translated when
@@ -59,7 +62,7 @@
                 // Only when translating just the contents, does the outline need to be shifted.
                 int translation = !mDismissUsingRowTranslationX ? (int) getTranslation() : 0;
                 int left = Math.max(translation, 0);
-                int top = mClipTopAmount + mBackgroundTop;
+                int top = mClipTopAmount;
                 int right = getWidth() + Math.min(translation, 0);
                 int bottom = Math.max(getActualHeight() - mClipBottomAmount, top);
                 outline.setRect(left, top, right, bottom);
@@ -92,7 +95,7 @@
                     ? (int) getTranslation() : 0;
             int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
             left = Math.max(translation, 0) - halfExtraWidth;
-            top = mClipTopAmount + mBackgroundTop;
+            top = mClipTopAmount;
             right = getWidth() + halfExtraWidth + Math.min(translation, 0);
             // If the top is rounded we want the bottom to be at most at the top roundness, in order
             // to avoid the shadow changing when scrolling up.
@@ -228,13 +231,6 @@
         super.applyRoundnessAndInvalidate();
     }
 
-    protected void setBackgroundTop(int backgroundTop) {
-        if (mBackgroundTop != backgroundTop) {
-            mBackgroundTop = backgroundTop;
-            invalidateOutline();
-        }
-    }
-
     public void onDensityOrFontScaleChanged() {
         initDimens();
         applyRoundnessAndInvalidate();
@@ -350,4 +346,18 @@
     public Path getCustomClipPath(View child) {
         return null;
     }
+
+    @Override
+    public void dump(PrintWriter pwOriginal, String[] args) {
+        IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+        super.dump(pw, args);
+        DumpUtilsKt.withIncreasedIndent(pw, () -> {
+            pw.println("Roundness: " + getRoundableState().debugString());
+            if (DUMP_VERBOSE) {
+                pw.println("mCustomOutline: " + mCustomOutline + " mOutlineRect: " + mOutlineRect);
+                pw.println("mOutlineAlpha: " + mOutlineAlpha);
+                pw.println("mAlwaysRoundBothCorners: " + mAlwaysRoundBothCorners);
+            }
+        });
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 955d7c1..25c7264 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -51,6 +51,8 @@
  */
 public abstract class ExpandableView extends FrameLayout implements Dumpable, Roundable {
     private static final String TAG = "ExpandableView";
+    /** whether the dump() for this class should include verbose details */
+    protected static final boolean DUMP_VERBOSE = false;
 
     private RoundableState mRoundableState = null;
     protected OnHeightChangedListener mOnHeightChangedListener;
@@ -825,6 +827,14 @@
                 viewState.dump(pw, args);
                 pw.println();
             }
+            if (DUMP_VERBOSE) {
+                pw.println("mClipTopAmount: " + mClipTopAmount);
+                pw.println("mClipBottomAmount " + mClipBottomAmount);
+                pw.println("mClipToActualHeight: " + mClipToActualHeight);
+                pw.println("mExtraWidthForClipping: " + mExtraWidthForClipping);
+                pw.println("mMinimumHeightForClipping: " + mMinimumHeightForClipping);
+                pw.println("getClipBounds(): " + getClipBounds());
+            }
         });
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 5171569..da8d2d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -28,12 +28,16 @@
 import android.view.View;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 
+import java.io.PrintWriter;
+import java.util.Arrays;
+
 /**
  * A view that can be used for both the dimmed and normal background of an notification.
  */
-public class NotificationBackgroundView extends View {
+public class NotificationBackgroundView extends View implements Dumpable {
 
     private final boolean mDontModifyCorners;
     private Drawable mBackground;
@@ -42,7 +46,6 @@
     private int mTintColor;
     private final float[] mCornerRadii = new float[8];
     private boolean mBottomIsRounded;
-    private int mBackgroundTop;
     private boolean mBottomAmountClips = true;
     private int mActualHeight = -1;
     private int mActualWidth = -1;
@@ -60,8 +63,7 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (mClipTopAmount + mClipBottomAmount < getActualHeight() - mBackgroundTop
-                || mExpandAnimationRunning) {
+        if (mClipTopAmount + mClipBottomAmount < getActualHeight() || mExpandAnimationRunning) {
             canvas.save();
             if (!mExpandAnimationRunning) {
                 canvas.clipRect(0, mClipTopAmount, getWidth(),
@@ -74,7 +76,7 @@
 
     private void draw(Canvas canvas, Drawable drawable) {
         if (drawable != null) {
-            int top = mBackgroundTop;
+            int top = 0;
             int bottom = getActualHeight();
             if (mBottomIsRounded
                     && mBottomAmountClips
@@ -261,11 +263,6 @@
         }
     }
 
-    public void setBackgroundTop(int backgroundTop) {
-        mBackgroundTop = backgroundTop;
-        invalidate();
-    }
-
     /** Set the current expand animation size. */
     public void setExpandAnimationSize(int width, int height) {
         mExpandAnimationHeight = height;
@@ -291,4 +288,16 @@
     public void setPressedAllowed(boolean allowed) {
         mIsPressedAllowed = allowed;
     }
+
+    @Override
+    public void dump(PrintWriter pw, String[] args) {
+        pw.println("mDontModifyCorners: " + mDontModifyCorners);
+        pw.println("mClipTopAmount: " + mClipTopAmount);
+        pw.println("mClipBottomAmount: " + mClipBottomAmount);
+        pw.println("mCornerRadii: " + Arrays.toString(mCornerRadii));
+        pw.println("mBottomIsRounded: " + mBottomIsRounded);
+        pw.println("mBottomAmountClips: " + mBottomAmountClips);
+        pw.println("mActualWidth: " + mActualWidth);
+        pw.println("mActualHeight: " + mActualHeight);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index c534860..39e4000 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -28,8 +28,11 @@
 import android.content.ContextWrapper;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.CancellationSignal;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
@@ -38,6 +41,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ImageMessageConsumer;
+import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.media.controls.util.MediaFeatureFlag;
@@ -468,6 +472,7 @@
                             result.packageContext,
                             parentLayout,
                             remoteViewClickHandler);
+                    validateView(v, entry, row.getResources());
                     v.setIsRootNamespace(true);
                     applyCallback.setResultView(v);
                 } else {
@@ -475,6 +480,7 @@
                             result.packageContext,
                             existingView,
                             remoteViewClickHandler);
+                    validateView(existingView, entry, row.getResources());
                     existingWrapper.onReinflated();
                 }
             } catch (Exception e) {
@@ -496,6 +502,13 @@
 
             @Override
             public void onViewApplied(View v) {
+                String invalidReason = isValidView(v, entry, row.getResources());
+                if (invalidReason != null) {
+                    handleInflationError(runningInflations, new InflationException(invalidReason),
+                            row.getEntry(), callback);
+                    runningInflations.remove(inflationId);
+                    return;
+                }
                 if (isNewView) {
                     v.setIsRootNamespace(true);
                     applyCallback.setResultView(v);
@@ -553,6 +566,65 @@
         runningInflations.put(inflationId, cancellationSignal);
     }
 
+    /**
+     * Checks if the given View is a valid notification View.
+     *
+     * @return null == valid, non-null == invalid, String represents reason for rejection.
+     */
+    @VisibleForTesting
+    @Nullable
+    static String isValidView(View view,
+            NotificationEntry entry,
+            Resources resources) {
+        if (!satisfiesMinHeightRequirement(view, entry, resources)) {
+            return "inflated notification does not meet minimum height requirement";
+        }
+        return null;
+    }
+
+    private static boolean satisfiesMinHeightRequirement(View view,
+            NotificationEntry entry,
+            Resources resources) {
+        if (!requiresHeightCheck(entry)) {
+            return true;
+        }
+        Trace.beginSection("NotificationContentInflater#satisfiesMinHeightRequirement");
+        int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+        int referenceWidth = resources.getDimensionPixelSize(
+                R.dimen.notification_validation_reference_width);
+        int widthSpec = View.MeasureSpec.makeMeasureSpec(referenceWidth, View.MeasureSpec.EXACTLY);
+        view.measure(widthSpec, heightSpec);
+        int minHeight = resources.getDimensionPixelSize(
+                R.dimen.notification_validation_minimum_allowed_height);
+        boolean result = view.getMeasuredHeight() >= minHeight;
+        Trace.endSection();
+        return result;
+    }
+
+    private static boolean requiresHeightCheck(NotificationEntry entry) {
+        // Undecorated custom views are disallowed from S onwards
+        if (entry.targetSdk >= Build.VERSION_CODES.S) {
+            return false;
+        }
+        // No need to check if the app isn't using any custom views
+        Notification notification = entry.getSbn().getNotification();
+        if (notification.contentView == null
+                && notification.bigContentView == null
+                && notification.headsUpContentView == null) {
+            return false;
+        }
+        return true;
+    }
+
+    private static void validateView(View view,
+            NotificationEntry entry,
+            Resources resources) throws InflationException {
+        String invalidReason = isValidView(view, entry, resources);
+        if (invalidReason != null) {
+            throw new InflationException(invalidReason);
+        }
+    }
+
     private static void handleInflationError(
             HashMap<Integer, CancellationSignal> runningInflations, Exception e,
             NotificationEntry notification, @Nullable InflationCallback callback) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index efcbb3c..37ff11d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -586,9 +586,7 @@
         }
 
         final ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-        if (view.isLongClickable()) {
-            view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-        }
+        view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
         if (row.areGutsExposed()) {
             closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                     true /* removeControls */, -1 /* x */, -1 /* y */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 42d122d..2868116 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -90,6 +90,7 @@
 import com.android.systemui.statusbar.notification.collection.PipelineDumper;
 import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider;
 import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
@@ -191,6 +192,7 @@
     private final boolean mUseRoundnessSourceTypes;
     private final NotificationTargetsHelper mNotificationTargetsHelper;
     private final SecureSettings mSecureSettings;
+    private final NotificationDismissibilityProvider mDismissibilityProvider;
 
     private View mLongPressedView;
 
@@ -510,7 +512,7 @@
                                 && (parent.areGutsExposed()
                                 || mSwipeHelper.getExposedMenuView() == parent
                                 || (parent.getAttachedChildren().size() == 1
-                                && parent.getEntry().isDismissable()))) {
+                                && mDismissibilityProvider.isDismissable(parent.getEntry())))) {
                             // In this case the group is expanded and showing the menu for the
                             // group, further interaction should apply to the group, not any
                             // child notifications so we use the parent of the child. We also do the
@@ -670,7 +672,8 @@
             NotificationStackSizeCalculator notificationStackSizeCalculator,
             FeatureFlags featureFlags,
             NotificationTargetsHelper notificationTargetsHelper,
-            SecureSettings secureSettings) {
+            SecureSettings secureSettings,
+            NotificationDismissibilityProvider dismissibilityProvider) {
         mStackStateLogger = stackLogger;
         mLogger = logger;
         mAllowLongPress = allowLongPress;
@@ -713,6 +716,7 @@
         mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
         mNotificationTargetsHelper = notificationTargetsHelper;
         mSecureSettings = secureSettings;
+        mDismissibilityProvider = dismissibilityProvider;
         updateResources();
     }
 
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 6e63960..51125b1 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
@@ -483,7 +483,7 @@
         return stackHeight / stackEndHeight;
     }
 
-    public boolean hasOngoingNotifs(StackScrollAlgorithmState algorithmState) {
+    private boolean hasNonDismissableNotifs(StackScrollAlgorithmState algorithmState) {
         for (int i = 0; i < algorithmState.visibleChildren.size(); i++) {
             View child = algorithmState.visibleChildren.get(i);
             if (!(child instanceof ExpandableNotificationRow)) {
@@ -565,7 +565,7 @@
                 ((FooterView.FooterViewState) viewState).hideContent =
                         isShelfShowing || noSpaceForFooter
                                 || (ambientState.isClearAllInProgress()
-                                && !hasOngoingNotifs(algorithmState));
+                                && !hasNonDismissableNotifs(algorithmState));
             }
         } else {
             if (view instanceof EmptyShadeView) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 8b1a02b..576df7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -29,6 +29,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.R;
 import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
@@ -47,6 +48,7 @@
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Objects;
 
 import javax.inject.Named;
@@ -165,9 +167,10 @@
         if (!mAutoTracker.isAdded(BRIGHTNESS) && mIsReduceBrightColorsAvailable) {
             mReduceBrightColorsController.addCallback(mReduceBrightColorsCallback);
         }
-        if (!mAutoTracker.isAdded(DEVICE_CONTROLS)) {
-            mDeviceControlsController.setCallback(mDeviceControlsCallback);
-        }
+        // We always want this callback, because if the feature stops being supported,
+        // we want to remove the tile from AutoAddTracker. That way it will be re-added when the
+        // feature is reenabled (similar to work tile).
+        mDeviceControlsController.setCallback(mDeviceControlsCallback);
         if (!mAutoTracker.isAdded(WALLET)) {
             initWalletController();
         }
@@ -323,14 +326,30 @@
         @Override
         public void onControlsUpdate(@Nullable Integer position) {
             if (mAutoTracker.isAdded(DEVICE_CONTROLS)) return;
-            if (position != null) {
+            if (position != null && !hasTile(DEVICE_CONTROLS)) {
                 mHost.addTile(DEVICE_CONTROLS, position);
+                mAutoTracker.setTileAdded(DEVICE_CONTROLS);
             }
-            mAutoTracker.setTileAdded(DEVICE_CONTROLS);
             mHandler.post(() -> mDeviceControlsController.removeCallback());
         }
+
+        @Override
+        public void removeControlsAutoTracker() {
+            mAutoTracker.setTileRemoved(DEVICE_CONTROLS);
+        }
     };
 
+    private boolean hasTile(String tileSpec) {
+        if (tileSpec == null) return false;
+        Collection<QSTile> tiles = mHost.getTiles();
+        for (QSTile tile : tiles) {
+            if (tileSpec.equals(tile.getTileSpec())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void initWalletController() {
         if (mAutoTracker.isAdded(WALLET)) return;
         Integer position = mWalletController.getWalletPosition();
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 856d7de..fecaa3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.containsType;
-
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
 
@@ -36,8 +33,8 @@
 import android.os.Vibrator;
 import android.util.Log;
 import android.util.Slog;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.KeyEvent;
+import android.view.WindowInsets;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowInsetsController.Behavior;
@@ -168,11 +165,11 @@
     }
 
     @Override
-    public void abortTransient(int displayId, @InternalInsetsType int[] types) {
+    public void abortTransient(int displayId, @InsetsType int types) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_STATUS_BAR)) {
+        if ((types & WindowInsets.Type.statusBars()) == 0) {
             return;
         }
         mCentralSurfaces.clearTransient();
@@ -489,12 +486,11 @@
     }
 
     @Override
-    public void showTransient(int displayId, @InternalInsetsType int[] types,
-            boolean isGestureOnSystemBar) {
+    public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) {
         if (displayId != mDisplayId) {
             return;
         }
-        if (!containsType(types, ITYPE_STATUS_BAR)) {
+        if ((types & WindowInsets.Type.statusBars()) == 0) {
             return;
         }
         mCentralSurfaces.showTransientUnchecked();
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 e595ddf..1966a66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -21,8 +21,6 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.WindowVisibleState;
 import static android.app.StatusBarManager.windowStateToString;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
-import static android.view.InsetsState.containsType;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
@@ -100,6 +98,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
+import android.view.WindowInsets;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
@@ -943,7 +942,7 @@
         // Set up the initial notification state. This needs to happen before CommandQueue.disable()
         setUpPresenter();
 
-        if (containsType(result.mTransientBarTypes, ITYPE_STATUS_BAR)) {
+        if ((result.mTransientBarTypes & WindowInsets.Type.statusBars()) != 0) {
             showTransientUnchecked();
         }
         mCommandQueueCallbacks.onSystemBarAttributesChanged(mDisplayId, result.mAppearance,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 01af486..c163a89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -89,14 +89,19 @@
     private float mPanelExpansion;
 
     /**
-     * Burn-in prevention x translation.
+     * Max burn-in prevention x translation.
      */
-    private int mBurnInPreventionOffsetX;
+    private int mMaxBurnInPreventionOffsetX;
 
     /**
-     * Burn-in prevention y translation for clock layouts.
+     * Max burn-in prevention y translation for clock layouts.
      */
-    private int mBurnInPreventionOffsetYClock;
+    private int mMaxBurnInPreventionOffsetYClock;
+
+    /**
+     * Current burn-in prevention y translation.
+     */
+    private float mCurrentBurnInOffsetY;
 
     /**
      * Doze/AOD transition amount.
@@ -155,9 +160,9 @@
 
         mContainerTopPadding =
                 res.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
-        mBurnInPreventionOffsetX = res.getDimensionPixelSize(
+        mMaxBurnInPreventionOffsetX = res.getDimensionPixelSize(
                 R.dimen.burn_in_prevention_offset_x);
-        mBurnInPreventionOffsetYClock = res.getDimensionPixelSize(
+        mMaxBurnInPreventionOffsetYClock = res.getDimensionPixelSize(
                 R.dimen.burn_in_prevention_offset_y_clock);
     }
 
@@ -215,7 +220,10 @@
         if (mBypassEnabled) {
             return (int) (mUnlockedStackScrollerPadding + mOverStretchAmount);
         } else if (mIsSplitShade) {
-            return clockYPosition - mSplitShadeTopNotificationsMargin + mUserSwitchHeight;
+            // mCurrentBurnInOffsetY is subtracted to make notifications not follow clock adjustment
+            // for burn-in. It can make pulsing notification go too high and it will get clipped
+            return clockYPosition - mSplitShadeTopNotificationsMargin + mUserSwitchHeight
+                    - (int) mCurrentBurnInOffsetY;
         } else {
             return clockYPosition + mKeyguardStatusHeight;
         }
@@ -255,11 +263,11 @@
 
         // This will keep the clock at the top but out of the cutout area
         float shift = 0;
-        if (clockY - mBurnInPreventionOffsetYClock < mCutoutTopInset) {
-            shift = mCutoutTopInset - (clockY - mBurnInPreventionOffsetYClock);
+        if (clockY - mMaxBurnInPreventionOffsetYClock < mCutoutTopInset) {
+            shift = mCutoutTopInset - (clockY - mMaxBurnInPreventionOffsetYClock);
         }
 
-        int burnInPreventionOffsetY = mBurnInPreventionOffsetYClock; // requested offset
+        int burnInPreventionOffsetY = mMaxBurnInPreventionOffsetYClock; // requested offset
         final boolean hasUdfps = mUdfpsTop > -1;
         if (hasUdfps && !mIsClockTopAligned) {
             // ensure clock doesn't overlap with the udfps icon
@@ -267,8 +275,8 @@
                 // sometimes the clock textView extends beyond udfps, so let's just use the
                 // space above the KeyguardStatusView/clock as our burn-in offset
                 burnInPreventionOffsetY = (int) (clockY - mCutoutTopInset) / 2;
-                if (mBurnInPreventionOffsetYClock < burnInPreventionOffsetY) {
-                    burnInPreventionOffsetY = mBurnInPreventionOffsetYClock;
+                if (mMaxBurnInPreventionOffsetYClock < burnInPreventionOffsetY) {
+                    burnInPreventionOffsetY = mMaxBurnInPreventionOffsetYClock;
                 }
                 shift = -burnInPreventionOffsetY;
             } else {
@@ -276,16 +284,18 @@
                 float lowerSpace = mUdfpsTop - mClockBottom;
                 // center the burn-in offset within the upper + lower space
                 burnInPreventionOffsetY = (int) (lowerSpace + upperSpace) / 2;
-                if (mBurnInPreventionOffsetYClock < burnInPreventionOffsetY) {
-                    burnInPreventionOffsetY = mBurnInPreventionOffsetYClock;
+                if (mMaxBurnInPreventionOffsetYClock < burnInPreventionOffsetY) {
+                    burnInPreventionOffsetY = mMaxBurnInPreventionOffsetYClock;
                 }
                 shift = (lowerSpace - upperSpace) / 2;
             }
         }
 
+        float fullyDarkBurnInOffset = burnInPreventionOffsetY(burnInPreventionOffsetY);
         float clockYDark = clockY
-                + burnInPreventionOffsetY(burnInPreventionOffsetY)
+                + fullyDarkBurnInOffset
                 + shift;
+        mCurrentBurnInOffsetY = MathUtils.lerp(0, fullyDarkBurnInOffset, darkAmount);
         return (int) (MathUtils.lerp(clockY, clockYDark, darkAmount) + mOverStretchAmount);
     }
 
@@ -325,7 +335,7 @@
     }
 
     private float burnInPreventionOffsetX() {
-        return getBurnInOffset(mBurnInPreventionOffsetX, true /* xAxis */);
+        return getBurnInOffset(mMaxBurnInPreventionOffsetX, true /* xAxis */);
     }
 
     public static class Result {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index d24469e..b1553b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -165,6 +165,13 @@
         }
     }
 
+    /**
+     * Get the message that should be shown after the previous text animates out.
+     */
+    public CharSequence getMessage() {
+        return mMessage;
+    }
+
     private AnimatorSet getOutAnimator() {
         AnimatorSet animatorSet = new AnimatorSet();
         Animator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index 4550cb2..8ee2c6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -76,7 +76,7 @@
                 FaceAuthApiRequestReason.PICK_UP_GESTURE_TRIGGERED
             )
             keyguardUpdateMonitor.requestActiveUnlock(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE,
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE,
                 "KeyguardLiftController")
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 416bc71..0727c5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -163,7 +163,7 @@
         for (int i = currentSlots.size() - 1; i >= 0; i--) {
             Slot s = currentSlots.get(i);
             slotsToReAdd.put(s, s.getHolderList());
-            removeAllIconsForSlot(s.getName());
+            removeAllIconsForSlot(s.getName(), /* fromNewPipeline */ false);
         }
 
         // Add them all back
@@ -285,7 +285,7 @@
         // Because of the way we cache the icon holders, we need to remove everything any time
         // we get a new set of subscriptions. This might change in the future, but is required
         // to support demo mode for now
-        removeAllIconsForSlot(slotName);
+        removeAllIconsForSlot(slotName, /* fromNewPipeline */ true);
 
         Collections.reverse(subIds);
 
@@ -428,6 +428,14 @@
     /** */
     @Override
     public void removeIcon(String slot, int tag) {
+        // If the new pipeline is on for this icon, don't allow removal, since the new pipeline
+        // will never call this method
+        if (mStatusBarPipelineFlags.isIconControlledByFlags(slot)) {
+            Log.i(TAG, "Ignoring removal of (" + slot + "). "
+                    + "It should be controlled elsewhere");
+            return;
+        }
+
         if (mStatusBarIconList.getIconHolder(slot, tag) == null) {
             return;
         }
@@ -444,6 +452,18 @@
     /** */
     @Override
     public void removeAllIconsForSlot(String slotName) {
+        removeAllIconsForSlot(slotName, /* fromNewPipeline */ false);
+    }
+
+    private void removeAllIconsForSlot(String slotName, boolean fromNewPipeline) {
+        // If the new pipeline is on for this icon, don't allow removal, since the new pipeline
+        // will never call this method
+        if (!fromNewPipeline && mStatusBarPipelineFlags.isIconControlledByFlags(slotName)) {
+            Log.i(TAG, "Ignoring removal of (" + slotName + "). "
+                    + "It should be controlled elsewhere");
+            return;
+        }
+
         Slot slot = mStatusBarIconList.getSlot(slotName);
         if (!slot.hasIconsInSlot()) {
             return;
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 c2ca7c6..b115233 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -753,7 +753,7 @@
             mKeyguardMessageAreaController.setMessage("");
         }
         mBypassController.setAltBouncerShowing(isShowingAlternateBouncer);
-        mKeyguardUpdateManager.setUdfpsBouncerShowing(isShowingAlternateBouncer);
+        mKeyguardUpdateManager.setAlternateBouncerShowing(isShowingAlternateBouncer);
 
         if (updateScrim) {
             mCentralSurfaces.updateScrimController();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index f7f8f4c..2027305 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -45,8 +45,11 @@
 import com.android.systemui.R;
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.util.DialogKt;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -68,6 +71,7 @@
     private static final boolean DEFAULT_DISMISS_ON_DEVICE_LOCK = true;
 
     private final Context mContext;
+    private final FeatureFlags mFeatureFlags;
     @Nullable private final DismissReceiver mDismissReceiver;
     private final Handler mHandler = new Handler();
     private final SystemUIDialogManager mDialogManager;
@@ -92,16 +96,23 @@
         // TODO(b/219008720): Remove those calls to Dependency.get by introducing a
         // SystemUIDialogFactory and make all other dialogs create a SystemUIDialog to which we set
         // the content and attach listeners.
-        this(context, theme, dismissOnDeviceLock, Dependency.get(SystemUIDialogManager.class),
-                Dependency.get(SysUiState.class), Dependency.get(BroadcastDispatcher.class),
+        this(context, theme, dismissOnDeviceLock,
+                Dependency.get(FeatureFlags.class),
+                Dependency.get(SystemUIDialogManager.class),
+                Dependency.get(SysUiState.class),
+                Dependency.get(BroadcastDispatcher.class),
                 Dependency.get(DialogLaunchAnimator.class));
     }
 
     public SystemUIDialog(Context context, int theme, boolean dismissOnDeviceLock,
-            SystemUIDialogManager dialogManager, SysUiState sysUiState,
-            BroadcastDispatcher broadcastDispatcher, DialogLaunchAnimator dialogLaunchAnimator) {
+            FeatureFlags featureFlags,
+            SystemUIDialogManager dialogManager,
+            SysUiState sysUiState,
+            BroadcastDispatcher broadcastDispatcher,
+            DialogLaunchAnimator dialogLaunchAnimator) {
         super(context, theme);
         mContext = context;
+        mFeatureFlags = featureFlags;
 
         applyFlags(this);
         WindowManager.LayoutParams attrs = getWindow().getAttributes();
@@ -126,6 +137,12 @@
         for (int i = 0; i < mOnCreateRunnables.size(); i++) {
             mOnCreateRunnables.get(i).run();
         }
+        if (mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_QS_DIALOG_ANIM)) {
+            DialogKt.registerAnimationOnBackInvoked(
+                    /* dialog = */ this,
+                    /* targetView = */ getWindow().getDecorView()
+            );
+        }
     }
 
     private void updateWindowSize() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
index 15fed32..4a684d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/StatusBarPipelineFlags.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline
 
+import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -23,7 +24,15 @@
 
 /** All flagging methods related to the new status bar pipeline (see b/238425913). */
 @SysUISingleton
-class StatusBarPipelineFlags @Inject constructor(private val featureFlags: FeatureFlags) {
+class StatusBarPipelineFlags
+@Inject
+constructor(
+    context: Context,
+    private val featureFlags: FeatureFlags,
+) {
+    private val mobileSlot = context.getString(com.android.internal.R.string.status_bar_mobile)
+    private val wifiSlot = context.getString(com.android.internal.R.string.status_bar_wifi)
+
     /** True if we should display the mobile icons using the new status bar data pipeline. */
     fun useNewMobileIcons(): Boolean = featureFlags.isEnabled(Flags.NEW_STATUS_BAR_MOBILE_ICONS)
 
@@ -54,4 +63,13 @@
      */
     fun useDebugColoring(): Boolean =
         featureFlags.isEnabled(Flags.NEW_STATUS_BAR_ICONS_DEBUG_COLORING)
+
+    /**
+     * For convenience in the StatusBarIconController, we want to gate some actions based on slot
+     * name and the flag together.
+     *
+     * @return true if this icon is controlled by any of the status bar pipeline flags
+     */
+    fun isIconControlledByFlags(slotName: String): Boolean =
+        slotName == wifiSlot && useNewWifiIcon() || slotName == mobileSlot && useNewMobileIcons()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileSummaryLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileSummaryLog.kt
new file mode 100644
index 0000000..2ac9ab3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileSummaryLog.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.statusbar.pipeline.dagger
+
+import javax.inject.Qualifier
+
+/**
+ * Logs for mobile data that's **the same across all connections**.
+ *
+ * This buffer should only be used for the mobile parent classes like [MobileConnectionsRepository]
+ * and [MobileIconsInteractor]. It should *not* be used for classes that represent an individual
+ * connection, like [MobileConnectionRepository] or [MobileIconInteractor].
+ */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class MobileSummaryLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 0993ab370..60de1a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl
 import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
 import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigCoreStartable
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileRepositorySwitcher
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository
@@ -82,6 +83,11 @@
     @ClassKey(MobileUiAdapter::class)
     abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable
 
+    @Binds
+    @IntoMap
+    @ClassKey(CarrierConfigCoreStartable::class)
+    abstract fun bindCarrierConfigStartable(impl: CarrierConfigCoreStartable): CoreStartable
+
     companion object {
         @Provides
         @SysUISingleton
@@ -112,5 +118,12 @@
         fun provideAirplaneTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer {
             return factory.create("AirplaneTableLog", 30)
         }
+
+        @Provides
+        @SysUISingleton
+        @MobileSummaryLog
+        fun provideMobileSummaryLogBuffer(factory: TableLogBufferFactory): TableLogBuffer {
+            return factory.create("MobileSummaryLog", 100)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/DataConnectionState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/DataConnectionState.kt
index 5479b92..85729c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/DataConnectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/DataConnectionState.kt
@@ -20,16 +20,21 @@
 import android.telephony.TelephonyManager.DATA_CONNECTING
 import android.telephony.TelephonyManager.DATA_DISCONNECTED
 import android.telephony.TelephonyManager.DATA_DISCONNECTING
+import android.telephony.TelephonyManager.DATA_HANDOVER_IN_PROGRESS
+import android.telephony.TelephonyManager.DATA_SUSPENDED
 import android.telephony.TelephonyManager.DATA_UNKNOWN
 import android.telephony.TelephonyManager.DataState
 
 /** Internal enum representation of the telephony data connection states */
-enum class DataConnectionState(@DataState val dataState: Int) {
-    Connected(DATA_CONNECTED),
-    Connecting(DATA_CONNECTING),
-    Disconnected(DATA_DISCONNECTED),
-    Disconnecting(DATA_DISCONNECTING),
-    Unknown(DATA_UNKNOWN),
+enum class DataConnectionState {
+    Connected,
+    Connecting,
+    Disconnected,
+    Disconnecting,
+    Suspended,
+    HandoverInProgress,
+    Unknown,
+    Invalid,
 }
 
 fun @receiver:DataState Int.toDataConnectionType(): DataConnectionState =
@@ -38,6 +43,8 @@
         DATA_CONNECTING -> DataConnectionState.Connecting
         DATA_DISCONNECTED -> DataConnectionState.Disconnected
         DATA_DISCONNECTING -> DataConnectionState.Disconnecting
+        DATA_SUSPENDED -> DataConnectionState.Suspended
+        DATA_HANDOVER_IN_PROGRESS -> DataConnectionState.HandoverInProgress
         DATA_UNKNOWN -> DataConnectionState.Unknown
-        else -> throw IllegalArgumentException("unknown data state received $this")
+        else -> DataConnectionState.Invalid
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
index 012b9ec..ed7f60b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModel.kt
@@ -26,6 +26,7 @@
 import android.telephony.TelephonyCallback.SignalStrengthsListener
 import android.telephony.TelephonyDisplayInfo
 import android.telephony.TelephonyManager
+import androidx.annotation.VisibleForTesting
 import com.android.systemui.log.table.Diffable
 import com.android.systemui.log.table.TableRowLogger
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Disconnected
@@ -94,7 +95,7 @@
 ) : Diffable<MobileConnectionModel> {
     override fun logDiffs(prevVal: MobileConnectionModel, row: TableRowLogger) {
         if (prevVal.dataConnectionState != dataConnectionState) {
-            row.logChange(COL_CONNECTION_STATE, dataConnectionState.toString())
+            row.logChange(COL_CONNECTION_STATE, dataConnectionState.name)
         }
 
         if (prevVal.isEmergencyOnly != isEmergencyOnly) {
@@ -125,8 +126,12 @@
             row.logChange(COL_PRIMARY_LEVEL, primaryLevel)
         }
 
-        if (prevVal.dataActivityDirection != dataActivityDirection) {
-            row.logChange(COL_ACTIVITY_DIRECTION, dataActivityDirection.toString())
+        if (prevVal.dataActivityDirection.hasActivityIn != dataActivityDirection.hasActivityIn) {
+            row.logChange(COL_ACTIVITY_DIRECTION_IN, dataActivityDirection.hasActivityIn)
+        }
+
+        if (prevVal.dataActivityDirection.hasActivityOut != dataActivityDirection.hasActivityOut) {
+            row.logChange(COL_ACTIVITY_DIRECTION_OUT, dataActivityDirection.hasActivityOut)
         }
 
         if (prevVal.carrierNetworkChangeActive != carrierNetworkChangeActive) {
@@ -139,7 +144,7 @@
     }
 
     override fun logFull(row: TableRowLogger) {
-        row.logChange(COL_CONNECTION_STATE, dataConnectionState.toString())
+        row.logChange(COL_CONNECTION_STATE, dataConnectionState.name)
         row.logChange(COL_EMERGENCY, isEmergencyOnly)
         row.logChange(COL_ROAMING, isRoaming)
         row.logChange(COL_OPERATOR, operatorAlphaShort)
@@ -147,11 +152,13 @@
         row.logChange(COL_IS_GSM, isGsm)
         row.logChange(COL_CDMA_LEVEL, cdmaLevel)
         row.logChange(COL_PRIMARY_LEVEL, primaryLevel)
-        row.logChange(COL_ACTIVITY_DIRECTION, dataActivityDirection.toString())
+        row.logChange(COL_ACTIVITY_DIRECTION_IN, dataActivityDirection.hasActivityIn)
+        row.logChange(COL_ACTIVITY_DIRECTION_OUT, dataActivityDirection.hasActivityOut)
         row.logChange(COL_CARRIER_NETWORK_CHANGE, carrierNetworkChangeActive)
         row.logChange(COL_RESOLVED_NETWORK_TYPE, resolvedNetworkType.toString())
     }
 
+    @VisibleForTesting
     companion object {
         const val COL_EMERGENCY = "EmergencyOnly"
         const val COL_ROAMING = "Roaming"
@@ -161,7 +168,8 @@
         const val COL_CDMA_LEVEL = "CdmaLevel"
         const val COL_PRIMARY_LEVEL = "PrimaryLevel"
         const val COL_CONNECTION_STATE = "ConnectionState"
-        const val COL_ACTIVITY_DIRECTION = "DataActivity"
+        const val COL_ACTIVITY_DIRECTION_IN = "DataActivity.In"
+        const val COL_ACTIVITY_DIRECTION_OUT = "DataActivity.Out"
         const val COL_CARRIER_NETWORK_CHANGE = "CarrierNetworkChangeActive"
         const val COL_RESOLVED_NETWORK_TYPE = "NetworkType"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt
index e618905..97a537a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectivityModel.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.pipeline.mobile.data.model
 
 import android.net.NetworkCapabilities
+import com.android.systemui.log.table.Diffable
+import com.android.systemui.log.table.TableRowLogger
 
 /** Provides information about a mobile network connection */
 data class MobileConnectivityModel(
@@ -24,4 +26,24 @@
     val isConnected: Boolean = false,
     /** Whether the mobile transport is validated [NetworkCapabilities.NET_CAPABILITY_VALIDATED] */
     val isValidated: Boolean = false,
-)
+) : Diffable<MobileConnectivityModel> {
+    // TODO(b/267767715): Can we implement [logDiffs] and [logFull] generically for data classes?
+    override fun logDiffs(prevVal: MobileConnectivityModel, row: TableRowLogger) {
+        if (prevVal.isConnected != isConnected) {
+            row.logChange(COL_IS_CONNECTED, isConnected)
+        }
+        if (prevVal.isValidated != isValidated) {
+            row.logChange(COL_IS_VALIDATED, isValidated)
+        }
+    }
+
+    override fun logFull(row: TableRowLogger) {
+        row.logChange(COL_IS_CONNECTED, isConnected)
+        row.logChange(COL_IS_VALIDATED, isValidated)
+    }
+
+    companion object {
+        private const val COL_IS_CONNECTED = "isConnected"
+        private const val COL_IS_VALIDATED = "isValidated"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
index c50d82a..78231e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/NetworkNameModel.kt
@@ -48,15 +48,31 @@
      * This name has been derived from telephony intents. see
      * [android.telephony.TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED]
      */
-    data class Derived(override val name: String) : NetworkNameModel {
+    data class IntentDerived(override val name: String) : NetworkNameModel {
         override fun logDiffs(prevVal: NetworkNameModel, row: TableRowLogger) {
-            if (prevVal !is Derived || prevVal.name != name) {
-                row.logChange(COL_NETWORK_NAME, "Derived($name)")
+            if (prevVal !is IntentDerived || prevVal.name != name) {
+                row.logChange(COL_NETWORK_NAME, "IntentDerived($name)")
             }
         }
 
         override fun logFull(row: TableRowLogger) {
-            row.logChange(COL_NETWORK_NAME, "Derived($name)")
+            row.logChange(COL_NETWORK_NAME, "IntentDerived($name)")
+        }
+    }
+
+    /**
+     * This name has been derived from the sim via
+     * [android.telephony.TelephonyManager.getSimOperatorName].
+     */
+    data class SimDerived(override val name: String) : NetworkNameModel {
+        override fun logDiffs(prevVal: NetworkNameModel, row: TableRowLogger) {
+            if (prevVal !is SimDerived || prevVal.name != name) {
+                row.logChange(COL_NETWORK_NAME, "SimDerived($name)")
+            }
+        }
+
+        override fun logFull(row: TableRowLogger) {
+            row.logChange(COL_NETWORK_NAME, "SimDerived($name)")
         }
     }
 
@@ -84,5 +100,5 @@
         str.append(spn)
     }
 
-    return if (str.isNotEmpty()) NetworkNameModel.Derived(str.toString()) else null
+    return if (str.isNotEmpty()) NetworkNameModel.IntentDerived(str.toString()) else null
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt
new file mode 100644
index 0000000..8c82fba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfig.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.model
+
+import android.os.PersistableBundle
+import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL
+import android.telephony.CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL
+import androidx.annotation.VisibleForTesting
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/**
+ * Represents, for a given subscription ID, the set of keys about which SystemUI cares.
+ *
+ * Upon first creation, this config represents only the default configuration (see
+ * [android.telephony.CarrierConfigManager.getDefaultConfig]).
+ *
+ * Upon request (see
+ * [com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository]), an
+ * instance of this class may be created for a given subscription Id, and will default to
+ * representing the default carrier configuration. However, once a carrier config is received for
+ * this [subId], all fields will reflect those in the received config, using [PersistableBundle]'s
+ * default of false for any config that is not present in the override.
+ *
+ * To keep things relatively simple, this class defines a wrapper around each config key which
+ * exposes a StateFlow<Boolean> for each config we care about. It also tracks whether or not it is
+ * using the default config for logging purposes.
+ *
+ * NOTE to add new keys to be tracked:
+ * 1. Define a new `private val` wrapping the key using [BooleanCarrierConfig]
+ * 2. Define a public `val` exposing the wrapped flow using [BooleanCarrierConfig.config]
+ * 3. Add the new [BooleanCarrierConfig] to the list of tracked configs, so they are properly
+ * updated when a new carrier config comes down
+ */
+class SystemUiCarrierConfig
+internal constructor(
+    val subId: Int,
+    defaultConfig: PersistableBundle,
+) {
+    @VisibleForTesting
+    var isUsingDefault = true
+        private set
+
+    private val inflateSignalStrength =
+        BooleanCarrierConfig(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, defaultConfig)
+    /** Flow tracking the [KEY_INFLATE_SIGNAL_STRENGTH_BOOL] carrier config */
+    val shouldInflateSignalStrength: StateFlow<Boolean> = inflateSignalStrength.config
+
+    private val showOperatorName =
+        BooleanCarrierConfig(KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL, defaultConfig)
+    /** Flow tracking the [KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL] config */
+    val showOperatorNameInStatusBar: StateFlow<Boolean> = showOperatorName.config
+
+    private val trackedConfigs =
+        listOf(
+            inflateSignalStrength,
+            showOperatorName,
+        )
+
+    /** Ingest a new carrier config, and switch all of the tracked keys over to the new values */
+    fun processNewCarrierConfig(config: PersistableBundle) {
+        isUsingDefault = false
+        trackedConfigs.forEach { it.update(config) }
+    }
+
+    /** For dumpsys, shortcut if we haven't overridden any keys */
+    fun toStringConsideringDefaults(): String {
+        return if (isUsingDefault) {
+            "using defaults"
+        } else {
+            trackedConfigs.joinToString { it.toString() }
+        }
+    }
+
+    override fun toString(): String = trackedConfigs.joinToString { it.toString() }
+}
+
+/** Extracts [key] from the carrier config, and stores it in a flow */
+private class BooleanCarrierConfig(
+    val key: String,
+    defaultConfig: PersistableBundle,
+) {
+    private val _configValue = MutableStateFlow(defaultConfig.getBoolean(key))
+    val config = _configValue.asStateFlow()
+
+    fun update(config: PersistableBundle) {
+        _configValue.value = config.getBoolean(key)
+    }
+
+    override fun toString(): String {
+        return "$key=${config.value}"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigCoreStartable.kt
new file mode 100644
index 0000000..af58999
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigCoreStartable.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.statusbar.pipeline.mobile.data.repository
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.qualifiers.Application
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+/**
+ * Core startable which configures the [CarrierConfigRepository] to listen for updates for the
+ * lifetime of the process
+ */
+class CarrierConfigCoreStartable
+@Inject
+constructor(
+    private val carrierConfigRepository: CarrierConfigRepository,
+    @Application private val scope: CoroutineScope,
+) : CoreStartable {
+
+    override fun start() {
+        scope.launch { carrierConfigRepository.startObservingCarrierConfigUpdates() }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt
new file mode 100644
index 0000000..5769f90
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.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.statusbar.pipeline.mobile.data.repository
+
+import android.content.IntentFilter
+import android.os.PersistableBundle
+import android.telephony.CarrierConfigManager
+import android.telephony.SubscriptionManager
+import android.util.SparseArray
+import androidx.annotation.VisibleForTesting
+import androidx.core.util.getOrElse
+import androidx.core.util.isEmpty
+import androidx.core.util.keyIterator
+import com.android.systemui.Dumpable
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import java.io.PrintWriter
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.shareIn
+
+/**
+ * Meant to be the source of truth regarding CarrierConfigs. These are configuration objects defined
+ * on a per-subscriptionId basis, and do not trigger a device configuration event.
+ *
+ * Designed to supplant [com.android.systemui.util.CarrierConfigTracker].
+ *
+ * See [SystemUiCarrierConfig] for details on how to add carrier config keys to be tracked
+ */
+@SysUISingleton
+class CarrierConfigRepository
+@Inject
+constructor(
+    broadcastDispatcher: BroadcastDispatcher,
+    private val carrierConfigManager: CarrierConfigManager,
+    dumpManager: DumpManager,
+    logger: ConnectivityPipelineLogger,
+    @Application scope: CoroutineScope,
+) : Dumpable {
+    private var isListening = false
+    private val defaultConfig: PersistableBundle by lazy { CarrierConfigManager.getDefaultConfig() }
+    // Used for logging the default config in the dumpsys
+    private val defaultConfigForLogs: SystemUiCarrierConfig by lazy {
+        SystemUiCarrierConfig(-1, defaultConfig)
+    }
+
+    private val configs = SparseArray<SystemUiCarrierConfig>()
+
+    init {
+        dumpManager.registerNormalDumpable(this)
+    }
+
+    @VisibleForTesting
+    val carrierConfigStream: SharedFlow<Pair<Int, PersistableBundle>> =
+        broadcastDispatcher
+            .broadcastFlow(IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+                intent,
+                _ ->
+                intent.getIntExtra(
+                    CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                    SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                )
+            }
+            .onEach { logger.logCarrierConfigChanged(it) }
+            .filter { SubscriptionManager.isValidSubscriptionId(it) }
+            .mapNotNull { subId ->
+                val config = carrierConfigManager.getConfigForSubId(subId)
+                config?.let { subId to it }
+            }
+            .shareIn(scope, SharingStarted.WhileSubscribed())
+
+    /**
+     * Start this repository observing broadcasts for **all** carrier configuration updates. Must be
+     * called in order to keep SystemUI in sync with [CarrierConfigManager].
+     */
+    suspend fun startObservingCarrierConfigUpdates() {
+        isListening = true
+        carrierConfigStream.collect { updateCarrierConfig(it.first, it.second) }
+    }
+
+    /** Update or create the [SystemUiCarrierConfig] for subId with the override */
+    private fun updateCarrierConfig(subId: Int, config: PersistableBundle) {
+        val configToUpdate = getOrCreateConfigForSubId(subId)
+        configToUpdate.processNewCarrierConfig(config)
+    }
+
+    /** Gets a cached [SystemUiCarrierConfig], or creates a new one which will track the defaults */
+    fun getOrCreateConfigForSubId(subId: Int): SystemUiCarrierConfig {
+        return configs.getOrElse(subId) {
+            val config = SystemUiCarrierConfig(subId, defaultConfig)
+            val carrierConfig = carrierConfigManager.getConfigForSubId(subId)
+            if (carrierConfig != null) config.processNewCarrierConfig(carrierConfig)
+            configs.put(subId, config)
+            config
+        }
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("isListening: $isListening")
+        if (configs.isEmpty()) {
+            pw.println("no carrier configs loaded")
+        } else {
+            pw.println("Carrier configs by subId")
+            configs.keyIterator().forEach {
+                pw.println("  subId=$it")
+                pw.println("    config=${configs.get(it).toStringConsideringDefaults()}")
+            }
+            // Finally, print the default config
+            pw.println("Default config:")
+            pw.println("  $defaultConfigForLogs")
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
index e0d156a..be30ea4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileConnectionsRepository.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.data.repository
 
-import android.provider.Settings
 import android.telephony.CarrierConfigManager
 import android.telephony.SubscriptionManager
 import com.android.settingslib.SignalIcon.MobileIconGroup
@@ -35,8 +34,14 @@
     /** Observable list of current mobile subscriptions */
     val subscriptions: StateFlow<List<SubscriptionModel>>
 
-    /** Observable for the subscriptionId of the current mobile data connection */
-    val activeMobileDataSubscriptionId: StateFlow<Int>
+    /**
+     * Observable for the subscriptionId of the current mobile data connection. Null if we don't
+     * have a valid subscription id
+     */
+    val activeMobileDataSubscriptionId: StateFlow<Int?>
+
+    /** Repo that tracks the current [activeMobileDataSubscriptionId] */
+    val activeMobileDataRepository: StateFlow<MobileConnectionRepository?>
 
     /**
      * Observable event for when the active data sim switches but the group stays the same. E.g.,
@@ -53,9 +58,6 @@
     /** Get or create a repository for the line of service for the given subscription ID */
     fun getRepoForSubId(subId: Int): MobileConnectionRepository
 
-    /** Observe changes to the [Settings.Global.MOBILE_DATA] setting */
-    val globalMobileDataSettingChangedEvent: Flow<Unit>
-
     /**
      * [Config] is an object that tracks relevant configuration flags for a given subscription ID.
      * In the case of [MobileMappings], it's hard-coded to check the default data subscription's
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 b939856..d54531a 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
@@ -47,7 +47,6 @@
  * interface in its own repository, completely separate from the real version, while still using all
  * of the prod implementations for the rest of the pipeline (interactors and onward). Looks
  * something like this:
- *
  * ```
  * RealRepository
  *                 │
@@ -115,7 +114,7 @@
             .flatMapLatest { it.subscriptions }
             .stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.subscriptions.value)
 
-    override val activeMobileDataSubscriptionId: StateFlow<Int> =
+    override val activeMobileDataSubscriptionId: StateFlow<Int?> =
         activeRepo
             .flatMapLatest { it.activeMobileDataSubscriptionId }
             .stateIn(
@@ -124,6 +123,15 @@
                 realRepository.activeMobileDataSubscriptionId.value
             )
 
+    override val activeMobileDataRepository: StateFlow<MobileConnectionRepository?> =
+        activeRepo
+            .flatMapLatest { it.activeMobileDataRepository }
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                realRepository.activeMobileDataRepository.value
+            )
+
     override val activeSubChangedInGroupEvent: Flow<Unit> =
         activeRepo.flatMapLatest { it.activeSubChangedInGroupEvent }
 
@@ -156,9 +164,6 @@
                 realRepository.defaultMobileNetworkConnectivity.value
             )
 
-    override val globalMobileDataSettingChangedEvent: Flow<Unit> =
-        activeRepo.flatMapLatest { it.globalMobileDataSettingChangedEvent }
-
     override fun getRepoForSubId(subId: Int): MobileConnectionRepository {
         if (isDemoMode.value) {
             return demoMobileConnectionsRepository.getRepoForSubId(subId)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
index 1088345..e924832 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepository.kt
@@ -55,6 +55,7 @@
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
@@ -121,6 +122,15 @@
                 subscriptions.value.firstOrNull()?.subscriptionId ?: INVALID_SUBSCRIPTION_ID
             )
 
+    override val activeMobileDataRepository: StateFlow<MobileConnectionRepository?> =
+        activeMobileDataSubscriptionId
+            .map { getRepoForSubId(it) }
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                getRepoForSubId(activeMobileDataSubscriptionId.value)
+            )
+
     // TODO(b/261029387): consider adding a demo command for this
     override val activeSubChangedInGroupEvent: Flow<Unit> = flowOf()
 
@@ -185,8 +195,6 @@
         return CacheContainer(repo, lastMobileState = null)
     }
 
-    override val globalMobileDataSettingChangedEvent = MutableStateFlow(Unit)
-
     fun startProcessingCommands() {
         mobileDemoCommandJob =
             scope.launch {
@@ -242,7 +250,7 @@
 
         // This is always true here, because we split out disabled states at the data-source level
         connection.dataEnabled.value = true
-        connection.networkName.value = NetworkNameModel.Derived(state.name)
+        connection.networkName.value = NetworkNameModel.IntentDerived(state.name)
 
         connection.cdmaRoaming.value = state.roaming
         connection.connectionInfo.value = state.toMobileConnectionModel()
@@ -260,10 +268,13 @@
         maybeCreateSubscription(subId)
         carrierMergedSubId = subId
 
+        // TODO(b/261029387): until we have a command, use the most recent subId
+        defaultDataSubId.value = subId
+
         val connection = getRepoForSubId(subId)
         // This is always true here, because we split out disabled states at the data-source level
         connection.dataEnabled.value = true
-        connection.networkName.value = NetworkNameModel.Derived(CARRIER_MERGED_NAME)
+        connection.networkName.value = NetworkNameModel.IntentDerived(CARRIER_MERGED_NAME)
         connection.numberOfLevels.value = event.numberOfLevels
         connection.cdmaRoaming.value = false
         connection.connectionInfo.value = event.toMobileConnectionModel()
@@ -338,7 +349,10 @@
     }
 
     private fun FakeWifiEventModel.CarrierMerged.toMobileConnectionModel(): MobileConnectionModel {
-        return createCarrierMergedConnectionModel(this.level)
+        return createCarrierMergedConnectionModel(
+            this.level,
+            activity.toMobileDataActivityModel(),
+        )
     }
 
     private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
@@ -373,5 +387,5 @@
 
     override val cdmaRoaming = MutableStateFlow(false)
 
-    override val networkName = MutableStateFlow(NetworkNameModel.Derived("demo network"))
+    override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo network"))
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
index c783b12..938c734 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
 
+import android.telephony.TelephonyManager
 import android.util.Log
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -37,7 +38,6 @@
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
@@ -54,10 +54,18 @@
 class CarrierMergedConnectionRepository(
     override val subId: Int,
     override val tableLogBuffer: TableLogBuffer,
-    defaultNetworkName: NetworkNameModel,
+    private val telephonyManager: TelephonyManager,
     @Application private val scope: CoroutineScope,
     val wifiRepository: WifiRepository,
 ) : MobileConnectionRepository {
+    init {
+        if (telephonyManager.subscriptionId != subId) {
+            throw IllegalStateException(
+                "CarrierMergedRepo: TelephonyManager should be created with subId($subId). " +
+                    "Found ${telephonyManager.subscriptionId} instead."
+            )
+        }
+    }
 
     /**
      * Outputs the carrier merged network to use, or null if we don't have a valid carrier merged
@@ -87,20 +95,28 @@
         }
 
     override val connectionInfo: StateFlow<MobileConnectionModel> =
-        network
-            .map { it.toMobileConnectionModel() }
+        combine(network, wifiRepository.wifiActivity) { network, activity ->
+                if (network == null) {
+                    MobileConnectionModel()
+                } else {
+                    createCarrierMergedConnectionModel(network.level, activity)
+                }
+            }
             .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectionModel())
 
-    // TODO(b/238425913): Add logging to this class.
-    // TODO(b/238425913): Make sure SignalStrength.getEmptyState is used when appropriate.
+    override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(ROAMING).asStateFlow()
 
-    // Carrier merged is never roaming.
-    override val cdmaRoaming: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
-
-    // TODO(b/238425913): Fetch the carrier merged network name.
     override val networkName: StateFlow<NetworkNameModel> =
-        flowOf(defaultNetworkName)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName)
+        network
+            // The SIM operator name should be the same throughout the lifetime of a subId, **but**
+            // it may not be available when this repo is created because it takes time to load. To
+            // be safe, we re-fetch it each time the network has changed.
+            .map { NetworkNameModel.SimDerived(telephonyManager.simOperatorName) }
+            .stateIn(
+                scope,
+                SharingStarted.WhileSubscribed(),
+                NetworkNameModel.SimDerived(telephonyManager.simOperatorName),
+            )
 
     override val numberOfLevels: StateFlow<Int> =
         wifiRepository.wifiNetwork
@@ -115,37 +131,24 @@
 
     override val dataEnabled: StateFlow<Boolean> = wifiRepository.isWifiEnabled
 
-    private fun WifiNetworkModel.CarrierMerged?.toMobileConnectionModel(): MobileConnectionModel {
-        if (this == null) {
-            return MobileConnectionModel()
-        }
-
-        return createCarrierMergedConnectionModel(level)
-    }
-
     companion object {
         /**
          * Creates an instance of [MobileConnectionModel] that represents a carrier merged network
-         * with the given [level].
+         * with the given [level] and [activity].
          */
-        fun createCarrierMergedConnectionModel(level: Int): MobileConnectionModel {
+        fun createCarrierMergedConnectionModel(
+            level: Int,
+            activity: DataActivityModel,
+        ): MobileConnectionModel {
             return MobileConnectionModel(
                 primaryLevel = level,
                 cdmaLevel = level,
-                // A [WifiNetworkModel.CarrierMerged] instance is always connected.
-                // (A [WifiNetworkModel.Inactive] represents a disconnected network.)
-                dataConnectionState = DataConnectionState.Connected,
-                // TODO(b/238425913): This should come from [WifiRepository.wifiActivity].
-                dataActivityDirection =
-                    DataActivityModel(
-                        hasActivityIn = false,
-                        hasActivityOut = false,
-                    ),
+                dataActivityDirection = activity,
+                // Here and below: These values are always the same for every carrier-merged
+                // connection.
                 resolvedNetworkType = ResolvedNetworkType.CarrierMergedNetworkType,
-                // Carrier merged is never roaming
-                isRoaming = false,
-
-                // TODO(b/238425913): Verify that these fields never change for carrier merged.
+                dataConnectionState = DataConnectionState.Connected,
+                isRoaming = ROAMING,
                 isEmergencyOnly = false,
                 operatorAlphaShort = null,
                 isInService = true,
@@ -153,24 +156,27 @@
                 carrierNetworkChangeActive = false,
             )
         }
+
+        // Carrier merged is never roaming
+        private const val ROAMING = false
     }
 
     @SysUISingleton
     class Factory
     @Inject
     constructor(
+        private val telephonyManager: TelephonyManager,
         @Application private val scope: CoroutineScope,
         private val wifiRepository: WifiRepository,
     ) {
         fun build(
             subId: Int,
             mobileLogger: TableLogBuffer,
-            defaultNetworkName: NetworkNameModel,
         ): MobileConnectionRepository {
             return CarrierMergedConnectionRepository(
                 subId,
                 mobileLogger,
-                defaultNetworkName,
+                telephonyManager.createForSubscriptionId(subId),
                 scope,
                 wifiRepository,
             )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
index 0f30ae2..a39ea0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepository.kt
@@ -26,7 +26,6 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
@@ -50,7 +49,6 @@
     override val tableLogBuffer: TableLogBuffer,
     private val defaultNetworkName: NetworkNameModel,
     private val networkNameSeparator: String,
-    private val globalMobileDataSettingChangedEvent: Flow<Unit>,
     @Application scope: CoroutineScope,
     private val mobileRepoFactory: MobileConnectionRepositoryImpl.Factory,
     private val carrierMergedRepoFactory: CarrierMergedConnectionRepository.Factory,
@@ -84,12 +82,11 @@
             tableLogBuffer,
             defaultNetworkName,
             networkNameSeparator,
-            globalMobileDataSettingChangedEvent,
         )
     }
 
     private val carrierMergedRepo: MobileConnectionRepository by lazy {
-        carrierMergedRepoFactory.build(subId, tableLogBuffer, defaultNetworkName)
+        carrierMergedRepoFactory.build(subId, tableLogBuffer)
     }
 
     @VisibleForTesting
@@ -120,11 +117,22 @@
     override val connectionInfo =
         activeRepo
             .flatMapLatest { it.connectionInfo }
+            .logDiffsForTable(
+                tableLogBuffer,
+                columnPrefix = "",
+                initialValue = activeRepo.value.connectionInfo.value,
+            )
             .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.connectionInfo.value)
 
     override val dataEnabled =
         activeRepo
             .flatMapLatest { it.dataEnabled }
+            .logDiffsForTable(
+                tableLogBuffer,
+                columnPrefix = "",
+                columnName = "dataEnabled",
+                initialValue = activeRepo.value.dataEnabled.value,
+            )
             .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.dataEnabled.value)
 
     override val numberOfLevels =
@@ -135,6 +143,11 @@
     override val networkName =
         activeRepo
             .flatMapLatest { it.networkName }
+            .logDiffsForTable(
+                tableLogBuffer,
+                columnPrefix = "",
+                initialValue = activeRepo.value.networkName.value,
+            )
             .stateIn(scope, SharingStarted.WhileSubscribed(), activeRepo.value.networkName.value)
 
     class Factory
@@ -150,7 +163,6 @@
             startingIsCarrierMerged: Boolean,
             defaultNetworkName: NetworkNameModel,
             networkNameSeparator: String,
-            globalMobileDataSettingChangedEvent: Flow<Unit>,
         ): FullMobileConnectionRepository {
             val mobileLogger =
                 logFactory.getOrCreate(tableBufferLogName(subId), MOBILE_CONNECTION_BUFFER_SIZE)
@@ -161,7 +173,6 @@
                 mobileLogger,
                 defaultNetworkName,
                 networkNameSeparator,
-                globalMobileDataSettingChangedEvent,
                 scope,
                 mobileRepoFactory,
                 carrierMergedRepoFactory,
@@ -173,7 +184,7 @@
             const val MOBILE_CONNECTION_BUFFER_SIZE = 100
 
             /** Returns a log buffer name for a mobile connection with the given [subId]. */
-            fun tableBufferLogName(subId: Int): String = "MobileConnectionLog [$subId]"
+            fun tableBufferLogName(subId: Int): String = "MobileConnectionLog[$subId]"
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index 3f2ce40..dcce0ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -18,8 +18,6 @@
 
 import android.content.Context
 import android.content.IntentFilter
-import android.database.ContentObserver
-import android.provider.Settings.Global
 import android.telephony.CellSignalStrength
 import android.telephony.CellSignalStrengthCdma
 import android.telephony.ServiceState
@@ -38,20 +36,20 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
-import com.android.systemui.util.settings.GlobalSettings
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -60,13 +58,15 @@
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.scan
+import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.flow.stateIn
 
 /**
@@ -81,19 +81,18 @@
     defaultNetworkName: NetworkNameModel,
     networkNameSeparator: String,
     private val telephonyManager: TelephonyManager,
-    private val globalSettings: GlobalSettings,
+    systemUiCarrierConfig: SystemUiCarrierConfig,
     broadcastDispatcher: BroadcastDispatcher,
-    globalMobileDataSettingChangedEvent: Flow<Unit>,
-    mobileMappingsProxy: MobileMappingsProxy,
+    private val mobileMappingsProxy: MobileMappingsProxy,
     bgDispatcher: CoroutineDispatcher,
     logger: ConnectivityPipelineLogger,
-    mobileLogger: TableLogBuffer,
+    override val tableLogBuffer: TableLogBuffer,
     scope: CoroutineScope,
 ) : MobileConnectionRepository {
     init {
         if (telephonyManager.subscriptionId != subId) {
             throw IllegalStateException(
-                "TelephonyManager should be created with subId($subId). " +
+                "MobileRepo: TelephonyManager should be created with subId($subId). " +
                     "Found ${telephonyManager.subscriptionId} instead."
             )
         }
@@ -101,10 +100,15 @@
 
     private val telephonyCallbackEvent = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
 
-    override val tableLogBuffer: TableLogBuffer = mobileLogger
-
-    override val connectionInfo: StateFlow<MobileConnectionModel> = run {
-        var state = MobileConnectionModel()
+    /**
+     * This flow defines the single shared connection to system_server via TelephonyCallback. Any
+     * new callback should be added to this listener and funneled through callbackEvents via a data
+     * class. See [CallbackEvent] for defining new callbacks.
+     *
+     * The reason we need to do this is because TelephonyManager limits the number of registered
+     * listeners per-process, so we don't want to create a new listener for every callback.
+     */
+    private val callbackEvents: SharedFlow<CallbackEvent> =
         conflatedCallbackFlow {
                 val callback =
                     object :
@@ -114,41 +118,16 @@
                         TelephonyCallback.DataConnectionStateListener,
                         TelephonyCallback.DataActivityListener,
                         TelephonyCallback.CarrierNetworkListener,
-                        TelephonyCallback.DisplayInfoListener {
+                        TelephonyCallback.DisplayInfoListener,
+                        TelephonyCallback.DataEnabledListener {
                         override fun onServiceStateChanged(serviceState: ServiceState) {
                             logger.logOnServiceStateChanged(serviceState, subId)
-                            state =
-                                state.copy(
-                                    isEmergencyOnly = serviceState.isEmergencyOnly,
-                                    isRoaming = serviceState.roaming,
-                                    operatorAlphaShort = serviceState.operatorAlphaShort,
-                                    isInService = Utils.isInService(serviceState),
-                                )
-                            trySend(state)
+                            trySend(CallbackEvent.OnServiceStateChanged(serviceState))
                         }
 
                         override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
                             logger.logOnSignalStrengthsChanged(signalStrength, subId)
-                            val cdmaLevel =
-                                signalStrength
-                                    .getCellSignalStrengths(CellSignalStrengthCdma::class.java)
-                                    .let { strengths ->
-                                        if (!strengths.isEmpty()) {
-                                            strengths[0].level
-                                        } else {
-                                            CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
-                                        }
-                                    }
-
-                            val primaryLevel = signalStrength.level
-
-                            state =
-                                state.copy(
-                                    cdmaLevel = cdmaLevel,
-                                    primaryLevel = primaryLevel,
-                                    isGsm = signalStrength.isGsm,
-                                )
-                            trySend(state)
+                            trySend(CallbackEvent.OnSignalStrengthChanged(signalStrength))
                         }
 
                         override fun onDataConnectionStateChanged(
@@ -156,101 +135,131 @@
                             networkType: Int
                         ) {
                             logger.logOnDataConnectionStateChanged(dataState, networkType, subId)
-                            state =
-                                state.copy(dataConnectionState = dataState.toDataConnectionType())
-                            trySend(state)
+                            trySend(CallbackEvent.OnDataConnectionStateChanged(dataState))
                         }
 
                         override fun onDataActivity(direction: Int) {
                             logger.logOnDataActivity(direction, subId)
-                            state =
-                                state.copy(
-                                    dataActivityDirection = direction.toMobileDataActivityModel()
-                                )
-                            trySend(state)
+                            trySend(CallbackEvent.OnDataActivity(direction))
                         }
 
                         override fun onCarrierNetworkChange(active: Boolean) {
                             logger.logOnCarrierNetworkChange(active, subId)
-                            state = state.copy(carrierNetworkChangeActive = active)
-                            trySend(state)
+                            trySend(CallbackEvent.OnCarrierNetworkChange(active))
                         }
 
                         override fun onDisplayInfoChanged(
                             telephonyDisplayInfo: TelephonyDisplayInfo
                         ) {
                             logger.logOnDisplayInfoChanged(telephonyDisplayInfo, subId)
+                            trySend(CallbackEvent.OnDisplayInfoChanged(telephonyDisplayInfo))
+                        }
 
-                            val networkType =
-                                if (telephonyDisplayInfo.networkType == NETWORK_TYPE_UNKNOWN) {
-                                    UnknownNetworkType
-                                } else if (
-                                    telephonyDisplayInfo.overrideNetworkType ==
-                                        OVERRIDE_NETWORK_TYPE_NONE
-                                ) {
-                                    DefaultNetworkType(
-                                        mobileMappingsProxy.toIconKey(
-                                            telephonyDisplayInfo.networkType
-                                        )
-                                    )
-                                } else {
-                                    OverrideNetworkType(
-                                        mobileMappingsProxy.toIconKeyOverride(
-                                            telephonyDisplayInfo.overrideNetworkType
-                                        )
-                                    )
-                                }
-                            state = state.copy(resolvedNetworkType = networkType)
-                            trySend(state)
+                        override fun onDataEnabledChanged(enabled: Boolean, reason: Int) {
+                            logger.logOnDataEnabledChanged(enabled, subId)
+                            trySend(CallbackEvent.OnDataEnabledChanged(enabled))
                         }
                     }
                 telephonyManager.registerTelephonyCallback(bgDispatcher.asExecutor(), callback)
                 awaitClose { telephonyManager.unregisterTelephonyCallback(callback) }
             }
-            .onEach { telephonyCallbackEvent.tryEmit(Unit) }
-            .logDiffsForTable(
-                mobileLogger,
-                columnPrefix = "MobileConnection ($subId)",
-                initialValue = state,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), state)
+            .shareIn(scope, SharingStarted.WhileSubscribed())
+
+    private fun updateConnectionState(
+        prevState: MobileConnectionModel,
+        callbackEvent: CallbackEvent,
+    ): MobileConnectionModel =
+        when (callbackEvent) {
+            is CallbackEvent.OnServiceStateChanged -> {
+                val serviceState = callbackEvent.serviceState
+                prevState.copy(
+                    isEmergencyOnly = serviceState.isEmergencyOnly,
+                    isRoaming = serviceState.roaming,
+                    operatorAlphaShort = serviceState.operatorAlphaShort,
+                    isInService = Utils.isInService(serviceState),
+                )
+            }
+            is CallbackEvent.OnSignalStrengthChanged -> {
+                val signalStrength = callbackEvent.signalStrength
+                val cdmaLevel =
+                    signalStrength.getCellSignalStrengths(CellSignalStrengthCdma::class.java).let {
+                        strengths ->
+                        if (!strengths.isEmpty()) {
+                            strengths[0].level
+                        } else {
+                            CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
+                        }
+                    }
+
+                val primaryLevel = signalStrength.level
+
+                prevState.copy(
+                    cdmaLevel = cdmaLevel,
+                    primaryLevel = primaryLevel,
+                    isGsm = signalStrength.isGsm,
+                )
+            }
+            is CallbackEvent.OnDataConnectionStateChanged -> {
+                prevState.copy(dataConnectionState = callbackEvent.dataState.toDataConnectionType())
+            }
+            is CallbackEvent.OnDataActivity -> {
+                prevState.copy(
+                    dataActivityDirection = callbackEvent.direction.toMobileDataActivityModel()
+                )
+            }
+            is CallbackEvent.OnCarrierNetworkChange -> {
+                prevState.copy(carrierNetworkChangeActive = callbackEvent.active)
+            }
+            is CallbackEvent.OnDisplayInfoChanged -> {
+                val telephonyDisplayInfo = callbackEvent.telephonyDisplayInfo
+                val networkType =
+                    if (telephonyDisplayInfo.networkType == NETWORK_TYPE_UNKNOWN) {
+                        UnknownNetworkType
+                    } else if (
+                        telephonyDisplayInfo.overrideNetworkType == OVERRIDE_NETWORK_TYPE_NONE
+                    ) {
+                        DefaultNetworkType(
+                            mobileMappingsProxy.toIconKey(telephonyDisplayInfo.networkType)
+                        )
+                    } else {
+                        OverrideNetworkType(
+                            mobileMappingsProxy.toIconKeyOverride(
+                                telephonyDisplayInfo.overrideNetworkType
+                            )
+                        )
+                    }
+                prevState.copy(resolvedNetworkType = networkType)
+            }
+            is CallbackEvent.OnDataEnabledChanged -> {
+                // Not part of this object, handled in a separate flow
+                prevState
+            }
+        }
+
+    override val connectionInfo = run {
+        val initial = MobileConnectionModel()
+        callbackEvents
+            .scan(initial, ::updateConnectionState)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
     }
 
-    // This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL]
-    // once it's wired up inside of [CarrierConfigTracker].
-    override val numberOfLevels: StateFlow<Int> =
-        flowOf(DEFAULT_NUM_LEVELS)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
-
-    /** Produces whenever the mobile data setting changes for this subId */
-    private val localMobileDataSettingChangedEvent: Flow<Unit> = conflatedCallbackFlow {
-        val observer =
-            object : ContentObserver(null) {
-                override fun onChange(selfChange: Boolean) {
-                    trySend(Unit)
+    override val numberOfLevels =
+        systemUiCarrierConfig.shouldInflateSignalStrength
+            .map { shouldInflate ->
+                if (shouldInflate) {
+                    DEFAULT_NUM_LEVELS + 1
+                } else {
+                    DEFAULT_NUM_LEVELS
                 }
             }
-
-        globalSettings.registerContentObserver(
-            globalSettings.getUriFor("${Global.MOBILE_DATA}$subId"),
-            /* notifyForDescendants */ true,
-            observer
-        )
-
-        awaitClose { context.contentResolver.unregisterContentObserver(observer) }
-    }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
 
     /**
      * There are a few cases where we will need to poll [TelephonyManager] so we can update some
      * internal state where callbacks aren't provided. Any of those events should be merged into
      * this flow, which can be used to trigger the polling.
      */
-    private val telephonyPollingEvent: Flow<Unit> =
-        merge(
-            telephonyCallbackEvent,
-            localMobileDataSettingChangedEvent,
-            globalMobileDataSettingChangedEvent,
-        )
+    private val telephonyPollingEvent: Flow<Unit> = callbackEvents.map { Unit }
 
     override val cdmaRoaming: StateFlow<Boolean> =
         telephonyPollingEvent
@@ -259,39 +268,23 @@
 
     override val networkName: StateFlow<NetworkNameModel> =
         broadcastDispatcher
-            .broadcastFlow(IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)) {
-                intent,
-                _ ->
-                if (intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, INVALID_SUBSCRIPTION_ID) != subId) {
-                    defaultNetworkName
-                } else {
-                    intent.toNetworkNameModel(networkNameSeparator) ?: defaultNetworkName
-                }
-            }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                mobileLogger,
-                columnPrefix = "",
-                initialValue = defaultNetworkName,
+            .broadcastFlow(
+                filter = IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED),
+                map = { intent, _ -> intent },
             )
+            .filter { intent ->
+                intent.getIntExtra(EXTRA_SUBSCRIPTION_ID, INVALID_SUBSCRIPTION_ID) == subId
+            }
+            .map { intent -> intent.toNetworkNameModel(networkNameSeparator) ?: defaultNetworkName }
             .stateIn(scope, SharingStarted.WhileSubscribed(), defaultNetworkName)
 
-    override val dataEnabled: StateFlow<Boolean> = run {
-        val initial = dataConnectionAllowed()
-        telephonyPollingEvent
-            .mapLatest { dataConnectionAllowed() }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                mobileLogger,
-                columnPrefix = "",
-                columnName = "dataEnabled",
-                initialValue = initial,
-            )
+    override val dataEnabled = run {
+        val initial = telephonyManager.isDataConnectionAllowed
+        callbackEvents
+            .mapNotNull { (it as? CallbackEvent.OnDataEnabledChanged)?.enabled }
             .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
     }
 
-    private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed
-
     class Factory
     @Inject
     constructor(
@@ -299,7 +292,7 @@
         private val context: Context,
         private val telephonyManager: TelephonyManager,
         private val logger: ConnectivityPipelineLogger,
-        private val globalSettings: GlobalSettings,
+        private val carrierConfigRepository: CarrierConfigRepository,
         private val mobileMappingsProxy: MobileMappingsProxy,
         @Background private val bgDispatcher: CoroutineDispatcher,
         @Application private val scope: CoroutineScope,
@@ -309,7 +302,6 @@
             mobileLogger: TableLogBuffer,
             defaultNetworkName: NetworkNameModel,
             networkNameSeparator: String,
-            globalMobileDataSettingChangedEvent: Flow<Unit>,
         ): MobileConnectionRepository {
             return MobileConnectionRepositoryImpl(
                 context,
@@ -317,9 +309,8 @@
                 defaultNetworkName,
                 networkNameSeparator,
                 telephonyManager.createForSubscriptionId(subId),
-                globalSettings,
+                carrierConfigRepository.getOrCreateConfigForSubId(subId),
                 broadcastDispatcher,
-                globalMobileDataSettingChangedEvent,
                 mobileMappingsProxy,
                 bgDispatcher,
                 logger,
@@ -329,3 +320,17 @@
         }
     }
 }
+
+/**
+ * Wrap every [TelephonyCallback] we care about in a data class so we can accept them in a single
+ * shared flow and then split them back out into other flows.
+ */
+private sealed interface CallbackEvent {
+    data class OnServiceStateChanged(val serviceState: ServiceState) : CallbackEvent
+    data class OnSignalStrengthChanged(val signalStrength: SignalStrength) : CallbackEvent
+    data class OnDataConnectionStateChanged(val dataState: Int) : CallbackEvent
+    data class OnDataActivity(val direction: Int) : CallbackEvent
+    data class OnCarrierNetworkChange(val active: Boolean) : CallbackEvent
+    data class OnDisplayInfoChanged(val telephonyDisplayInfo: TelephonyDisplayInfo) : CallbackEvent
+    data class OnDataEnabledChanged(val enabled: Boolean) : CallbackEvent
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 39ad31f..c9049d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -19,14 +19,12 @@
 import android.annotation.SuppressLint
 import android.content.Context
 import android.content.IntentFilter
-import android.database.ContentObserver
 import android.net.ConnectivityManager
 import android.net.ConnectivityManager.NetworkCallback
 import android.net.Network
 import android.net.NetworkCapabilities
 import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
 import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
-import android.provider.Settings.Global.MOBILE_DATA
 import android.telephony.CarrierConfigManager
 import android.telephony.SubscriptionInfo
 import android.telephony.SubscriptionManager
@@ -44,6 +42,9 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -54,7 +55,6 @@
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
 import com.android.systemui.util.kotlin.pairwise
-import com.android.systemui.util.settings.GlobalSettings
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -85,9 +85,9 @@
     private val subscriptionManager: SubscriptionManager,
     private val telephonyManager: TelephonyManager,
     private val logger: ConnectivityPipelineLogger,
+    @MobileSummaryLog private val tableLogger: TableLogBuffer,
     mobileMappingsProxy: MobileMappingsProxy,
     broadcastDispatcher: BroadcastDispatcher,
-    private val globalSettings: GlobalSettings,
     private val context: Context,
     @Background private val bgDispatcher: CoroutineDispatcher,
     @Application private val scope: CoroutineScope,
@@ -118,6 +118,12 @@
                 }
             }
             .distinctUntilChanged()
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "carrierMergedSubId",
+                initialValue = null,
+            )
             .stateIn(scope, started = SharingStarted.WhileSubscribed(), null)
 
     private val mobileSubscriptionsChangeEvent: Flow<Unit> = conflatedCallbackFlow {
@@ -143,17 +149,26 @@
     override val subscriptions: StateFlow<List<SubscriptionModel>> =
         merge(mobileSubscriptionsChangeEvent, carrierMergedSubId)
             .mapLatest { fetchSubscriptionsList().map { it.toSubscriptionModel() } }
-            .logInputChange(logger, "onSubscriptionsChanged")
             .onEach { infos -> updateRepos(infos) }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "subscriptions",
+                initialValue = listOf(),
+            )
             .stateIn(scope, started = SharingStarted.WhileSubscribed(), listOf())
 
-    /** StateFlow that keeps track of the current active mobile data subscription */
-    override val activeMobileDataSubscriptionId: StateFlow<Int> =
+    override val activeMobileDataSubscriptionId: StateFlow<Int?> =
         conflatedCallbackFlow {
                 val callback =
                     object : TelephonyCallback(), ActiveDataSubscriptionIdListener {
                         override fun onActiveDataSubscriptionIdChanged(subId: Int) {
-                            trySend(subId)
+                            if (subId != INVALID_SUBSCRIPTION_ID) {
+                                trySend(subId)
+                            } else {
+                                trySend(null)
+                            }
                         }
                     }
 
@@ -161,8 +176,24 @@
                 awaitClose { telephonyManager.unregisterTelephonyCallback(callback) }
             }
             .distinctUntilChanged()
-            .logInputChange(logger, "onActiveDataSubscriptionIdChanged")
-            .stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID)
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "activeSubId",
+                initialValue = INVALID_SUBSCRIPTION_ID,
+            )
+            .stateIn(scope, started = SharingStarted.WhileSubscribed(), null)
+
+    override val activeMobileDataRepository =
+        activeMobileDataSubscriptionId
+            .map { activeSubId ->
+                if (activeSubId == null) {
+                    null
+                } else {
+                    getOrCreateRepoForSubId(activeSubId)
+                }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
 
     private val defaultDataSubIdChangeEvent: MutableSharedFlow<Unit> =
         MutableSharedFlow(extraBufferCapacity = 1)
@@ -175,7 +206,12 @@
                 intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID)
             }
             .distinctUntilChanged()
-            .logInputChange(logger, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED")
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "defaultSubId",
+                initialValue = SubscriptionManager.getDefaultDataSubscriptionId(),
+            )
             .onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) }
             .stateIn(
                 scope,
@@ -218,32 +254,12 @@
             )
         }
 
-        return subIdRepositoryCache[subId]
-            ?: createRepositoryForSubId(subId).also { subIdRepositoryCache[subId] = it }
+        return getOrCreateRepoForSubId(subId)
     }
 
-    /**
-     * In single-SIM devices, the [MOBILE_DATA] setting is phone-wide. For multi-SIM, the individual
-     * connection repositories also observe the URI for [MOBILE_DATA] + subId.
-     */
-    override val globalMobileDataSettingChangedEvent: Flow<Unit> =
-        conflatedCallbackFlow {
-                val observer =
-                    object : ContentObserver(null) {
-                        override fun onChange(selfChange: Boolean) {
-                            trySend(Unit)
-                        }
-                    }
-
-                globalSettings.registerContentObserver(
-                    globalSettings.getUriFor(MOBILE_DATA),
-                    true,
-                    observer
-                )
-
-                awaitClose { context.contentResolver.unregisterContentObserver(observer) }
-            }
-            .logInputChange(logger, "globalMobileDataSettingChangedEvent")
+    private fun getOrCreateRepoForSubId(subId: Int) =
+        subIdRepositoryCache[subId]
+            ?: createRepositoryForSubId(subId).also { subIdRepositoryCache[subId] = it }
 
     @SuppressLint("MissingPermission")
     override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> =
@@ -274,7 +290,11 @@
                 awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
             }
             .distinctUntilChanged()
-            .logInputChange(logger, "defaultMobileNetworkConnectivity")
+            .logDiffsForTable(
+                tableLogger,
+                columnPrefix = "$LOGGING_PREFIX.defaultConnection",
+                initialValue = MobileConnectivityModel(),
+            )
             .stateIn(scope, SharingStarted.WhileSubscribed(), MobileConnectivityModel())
 
     /**
@@ -289,7 +309,9 @@
     override val activeSubChangedInGroupEvent =
         activeMobileDataSubscriptionId
             .pairwise()
-            .mapNotNull { (prevVal: Int, newVal: Int) ->
+            .mapNotNull { (prevVal: Int?, newVal: Int?) ->
+                if (prevVal == null || newVal == null) return@mapNotNull null
+
                 val prevSub = subscriptionManager.getActiveSubscriptionInfo(prevVal)?.groupUuid
                 val nextSub = subscriptionManager.getActiveSubscriptionInfo(newVal)?.groupUuid
 
@@ -297,15 +319,7 @@
             }
             .flowOn(bgDispatcher)
 
-    private fun isValidSubId(subId: Int): Boolean {
-        subscriptions.value.forEach {
-            if (it.subscriptionId == subId) {
-                return true
-            }
-        }
-
-        return false
-    }
+    private fun isValidSubId(subId: Int): Boolean = checkSub(subId, subscriptions.value)
 
     @VisibleForTesting fun getSubIdRepoCache() = subIdRepositoryCache
 
@@ -315,7 +329,6 @@
             isCarrierMerged(subId),
             defaultNetworkName,
             networkNameSeparator,
-            globalMobileDataSettingChangedEvent,
         )
     }
 
@@ -333,12 +346,27 @@
     private fun dropUnusedReposFromCache(newInfos: List<SubscriptionModel>) {
         // Remove any connection repository from the cache that isn't in the new set of IDs. They
         // will get garbage collected once their subscribers go away
-        val currentValidSubscriptionIds = newInfos.map { it.subscriptionId }
-
         subIdRepositoryCache =
-            subIdRepositoryCache
-                .filter { currentValidSubscriptionIds.contains(it.key) }
-                .toMutableMap()
+            subIdRepositoryCache.filter { checkSub(it.key, newInfos) }.toMutableMap()
+    }
+
+    /**
+     * True if the checked subId is in the list of current subs or the active mobile data subId
+     *
+     * @param checkedSubs the list to validate [subId] against. To invalidate the cache, pass in the
+     * new subscription list. Otherwise use [subscriptions.value] to validate a subId against the
+     * current known subscriptions
+     */
+    private fun checkSub(subId: Int, checkedSubs: List<SubscriptionModel>): Boolean {
+        if (activeMobileDataSubscriptionId.value == subId) return true
+
+        checkedSubs.forEach {
+            if (it.subscriptionId == subId) {
+                return true
+            }
+        }
+
+        return false
     }
 
     private suspend fun fetchSubscriptionsList(): List<SubscriptionInfo> =
@@ -349,4 +377,8 @@
             subscriptionId = subscriptionId,
             isOpportunistic = isOpportunistic,
         )
+
+    companion object {
+        private const val LOGGING_PREFIX = "Repo"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 9cdff96..7b0f952 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -33,7 +33,9 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
 interface MobileIconInteractor {
@@ -109,6 +111,9 @@
 
     /** Based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL], either 4 or 5 */
     val numberOfLevels: StateFlow<Int>
+
+    /** See [MobileIconsInteractor.isForceHidden]. */
+    val isForceHidden: Flow<Boolean>
 }
 
 /** Interactor for a single mobile connection. This connection _should_ have one subscription ID */
@@ -124,6 +129,7 @@
     defaultMobileIconGroup: StateFlow<MobileIconGroup>,
     defaultDataSubId: StateFlow<Int>,
     override val isDefaultConnectionFailed: StateFlow<Boolean>,
+    override val isForceHidden: Flow<Boolean>,
     connectionRepository: MobileConnectionRepository,
 ) : MobileIconInteractor {
     private val connectionInfo = connectionRepository.connectionInfo
@@ -152,7 +158,7 @@
                 if (
                     networkName is NetworkNameModel.Default && connection.operatorAlphaShort != null
                 ) {
-                    NetworkNameModel.Derived(connection.operatorAlphaShort)
+                    NetworkNameModel.IntentDerived(connection.operatorAlphaShort)
                 } else {
                     networkName
                 }
@@ -181,6 +187,16 @@
                     else -> mapping[info.resolvedNetworkType.lookupKey] ?: defaultGroup
                 }
             }
+            .distinctUntilChanged()
+            .onEach {
+                // Doesn't use [logDiffsForTable] because [MobileIconGroup] can't implement the
+                // [Diffable] interface.
+                tableLogBuffer.logChange(
+                    prefix = "",
+                    columnName = "networkTypeIcon",
+                    value = it.name
+                )
+            }
             .stateIn(scope, SharingStarted.WhileSubscribed(), defaultMobileIconGroup.value)
 
     override val isEmergencyOnly: StateFlow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index 0e4a432..72d5113 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -18,17 +18,21 @@
 
 import android.telephony.CarrierConfigManager
 import android.telephony.SubscriptionManager
-import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import com.android.settingslib.SignalIcon.MobileIconGroup
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.statusbar.pipeline.dagger.MobileSummaryLog
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
+import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
 import com.android.systemui.util.CarrierConfigTracker
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -42,8 +46,8 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.transformLatest
 
@@ -88,6 +92,10 @@
     val isDefaultConnectionFailed: StateFlow<Boolean>
     /** True once the user has been set up */
     val isUserSetup: StateFlow<Boolean>
+
+    /** True if we're configured to force-hide the mobile icons and false otherwise. */
+    val isForceHidden: Flow<Boolean>
+
     /**
      * Vends out a [MobileIconInteractor] tracking the [MobileConnectionRepository] for the given
      * subId. Will throw if the ID is invalid
@@ -104,25 +112,13 @@
     private val mobileConnectionsRepo: MobileConnectionsRepository,
     private val carrierConfigTracker: CarrierConfigTracker,
     private val logger: ConnectivityPipelineLogger,
+    @MobileSummaryLog private val tableLogger: TableLogBuffer,
+    connectivityRepository: ConnectivityRepository,
     userSetupRepo: UserSetupRepository,
     @Application private val scope: CoroutineScope,
 ) : MobileIconsInteractor {
-    private val activeMobileDataSubscriptionId =
-        mobileConnectionsRepo.activeMobileDataSubscriptionId
-
-    private val activeMobileDataConnectionRepo: StateFlow<MobileConnectionRepository?> =
-        activeMobileDataSubscriptionId
-            .mapLatest { activeId ->
-                if (activeId == INVALID_SUBSCRIPTION_ID) {
-                    null
-                } else {
-                    mobileConnectionsRepo.getRepoForSubId(activeId)
-                }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
     override val activeDataConnectionHasDataEnabled: StateFlow<Boolean> =
-        activeMobileDataConnectionRepo
+        mobileConnectionsRepo.activeMobileDataRepository
             .flatMapLatest { it?.dataEnabled ?: flowOf(false) }
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
@@ -143,37 +139,45 @@
      * and by checking which subscription is opportunistic, or which one is active.
      */
     override val filteredSubscriptions: Flow<List<SubscriptionModel>> =
-        combine(unfilteredSubscriptions, activeMobileDataSubscriptionId) { unfilteredSubs, activeId
-            ->
-            // Based on the old logic,
-            if (unfilteredSubs.size != 2) {
-                return@combine unfilteredSubs
-            }
+        combine(
+                unfilteredSubscriptions,
+                mobileConnectionsRepo.activeMobileDataSubscriptionId,
+            ) { unfilteredSubs, activeId ->
+                // Based on the old logic,
+                if (unfilteredSubs.size != 2) {
+                    return@combine unfilteredSubs
+                }
 
-            val info1 = unfilteredSubs[0]
-            val info2 = unfilteredSubs[1]
-            // If both subscriptions are primary, show both
-            if (!info1.isOpportunistic && !info2.isOpportunistic) {
-                return@combine unfilteredSubs
-            }
+                val info1 = unfilteredSubs[0]
+                val info2 = unfilteredSubs[1]
+                // If both subscriptions are primary, show both
+                if (!info1.isOpportunistic && !info2.isOpportunistic) {
+                    return@combine unfilteredSubs
+                }
 
-            // NOTE: at this point, we are now returning a single SubscriptionInfo
+                // NOTE: at this point, we are now returning a single SubscriptionInfo
 
-            // If carrier required, always show the icon of the primary subscription.
-            // Otherwise, show whichever subscription is currently active for internet.
-            if (carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) {
-                // return the non-opportunistic info
-                return@combine if (info1.isOpportunistic) listOf(info2) else listOf(info1)
-            } else {
-                return@combine if (info1.subscriptionId == activeId) {
-                    listOf(info1)
+                // If carrier required, always show the icon of the primary subscription.
+                // Otherwise, show whichever subscription is currently active for internet.
+                if (carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) {
+                    // return the non-opportunistic info
+                    return@combine if (info1.isOpportunistic) listOf(info2) else listOf(info1)
                 } else {
-                    listOf(info2)
+                    return@combine if (info1.subscriptionId == activeId) {
+                        listOf(info1)
+                    } else {
+                        listOf(info2)
+                    }
                 }
             }
-        }
             .distinctUntilChanged()
-            .onEach { logger.logFilteredSubscriptionsChanged(it) }
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "filteredSubscriptions",
+                initialValue = listOf(),
+            )
+            .stateIn(scope, SharingStarted.WhileSubscribed(), listOf())
 
     override val defaultDataSubId = mobileConnectionsRepo.defaultDataSubId
 
@@ -195,6 +199,12 @@
                 delay(2000)
                 emit(false)
             }
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "forcingValidation",
+                initialValue = false,
+            )
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> =
@@ -211,6 +221,12 @@
                     networkConnectivity
                 }
             }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                tableLogger,
+                columnPrefix = "$LOGGING_PREFIX.defaultConnection",
+                initialValue = mobileConnectionsRepo.defaultMobileNetworkConnectivity.value,
+            )
             .stateIn(
                 scope,
                 SharingStarted.WhileSubscribed(),
@@ -259,10 +275,21 @@
                     !connectivityModel.isValidated
                 }
             }
+            .logDiffsForTable(
+                tableLogger,
+                LOGGING_PREFIX,
+                columnName = "isDefaultConnectionFailed",
+                initialValue = false,
+            )
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val isUserSetup: StateFlow<Boolean> = userSetupRepo.isUserSetupFlow
 
+    override val isForceHidden: Flow<Boolean> =
+        connectivityRepository.forceHiddenSlots
+            .map { it.contains(ConnectivitySlot.MOBILE) }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
     /** Vends out new [MobileIconInteractor] for a particular subId */
     override fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor =
         MobileIconInteractorImpl(
@@ -275,6 +302,11 @@
             defaultMobileIconGroup,
             defaultDataSubId,
             isDefaultConnectionFailed,
+            isForceHidden,
             mobileConnectionsRepo.getRepoForSubId(subId),
         )
+
+    companion object {
+        private const val LOGGING_PREFIX = "Intr"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
index a4b2abc..db585e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/MobileIconBinder.kt
@@ -91,10 +91,17 @@
                     }
                 }
 
+                launch { viewModel.isVisible.collect { isVisible -> view.isVisible = isVisible } }
+
                 // Set the icon for the triangle
                 launch {
-                    viewModel.iconId.distinctUntilChanged().collect { iconId ->
-                        mobileDrawable.level = iconId
+                    viewModel.icon.distinctUntilChanged().collect { icon ->
+                        mobileDrawable.level =
+                            SignalDrawable.getState(
+                                icon.level,
+                                icon.numberOfLevels,
+                                icon.showExclamationMark,
+                            )
                     }
                 }
 
@@ -148,8 +155,7 @@
 
         return object : ModernStatusBarViewBinding {
             override fun getShouldIconBeVisible(): Boolean {
-                // If this view model exists, then the icon should be visible.
-                return true
+                return viewModel.isVisible.value
             }
 
             override fun onVisibilityStateChanged(@StatusBarIconView.VisibleState state: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.kt
new file mode 100644
index 0000000..16e1766
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/model/SignalIconModel.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.statusbar.pipeline.mobile.ui.model
+
+import com.android.systemui.log.table.Diffable
+import com.android.systemui.log.table.TableRowLogger
+
+/** A model that will be consumed by [SignalDrawable] to show the mobile triangle icon. */
+data class SignalIconModel(
+    val level: Int,
+    val numberOfLevels: Int,
+    val showExclamationMark: Boolean,
+) : Diffable<SignalIconModel> {
+    // TODO(b/267767715): Can we implement [logDiffs] and [logFull] generically for data classes?
+    override fun logDiffs(prevVal: SignalIconModel, row: TableRowLogger) {
+        if (prevVal.level != level) {
+            row.logChange(COL_LEVEL, level)
+        }
+        if (prevVal.numberOfLevels != numberOfLevels) {
+            row.logChange(COL_NUM_LEVELS, numberOfLevels)
+        }
+        if (prevVal.showExclamationMark != showExclamationMark) {
+            row.logChange(COL_SHOW_EXCLAMATION, showExclamationMark)
+        }
+    }
+
+    override fun logFull(row: TableRowLogger) {
+        row.logChange(COL_LEVEL, level)
+        row.logChange(COL_NUM_LEVELS, numberOfLevels)
+        row.logChange(COL_SHOW_EXCLAMATION, showExclamationMark)
+    }
+
+    companion object {
+        /** Creates a [SignalIconModel] representing an empty and invalidated state. */
+        fun createEmptyState(numberOfLevels: Int) =
+            SignalIconModel(level = 0, numberOfLevels, showExclamationMark = true)
+
+        private const val COL_LEVEL = "level"
+        private const val COL_NUM_LEVELS = "numLevels"
+        private const val COL_SHOW_EXCLAMATION = "showExclamation"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
index 9e2024a..0496278 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModel.kt
@@ -22,10 +22,11 @@
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -37,14 +38,14 @@
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
 /** Common interface for all of the location-based mobile icon view models. */
 interface MobileIconViewModelCommon {
     val subscriptionId: Int
-    /** An int consumable by [SignalDrawable] for display */
-    val iconId: Flow<Int>
+    /** True if this view should be visible at all. */
+    val isVisible: StateFlow<Boolean>
+    val icon: Flow<SignalIconModel>
     val contentDescription: Flow<ContentDescription>
     val roaming: Flow<Boolean>
     /** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
@@ -73,7 +74,7 @@
 constructor(
     override val subscriptionId: Int,
     iconInteractor: MobileIconInteractor,
-    logger: ConnectivityPipelineLogger,
+    airplaneModeInteractor: AirplaneModeInteractor,
     constants: ConnectivityConstants,
     scope: CoroutineScope,
 ) : MobileIconViewModelCommon {
@@ -81,8 +82,28 @@
     private val showExclamationMark: Flow<Boolean> =
         iconInteractor.isDefaultDataEnabled.mapLatest { !it }
 
-    override val iconId: Flow<Int> = run {
-        val initial = SignalDrawable.getEmptyState(iconInteractor.numberOfLevels.value)
+    override val isVisible: StateFlow<Boolean> =
+        if (!constants.hasDataCapabilities) {
+                flowOf(false)
+            } else {
+                combine(
+                    airplaneModeInteractor.isAirplaneMode,
+                    iconInteractor.isForceHidden,
+                ) { isAirplaneMode, isForceHidden ->
+                    !isAirplaneMode && !isForceHidden
+                }
+            }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                iconInteractor.tableLogBuffer,
+                columnPrefix = "",
+                columnName = "visible",
+                initialValue = false,
+            )
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
+    override val icon: Flow<SignalIconModel> = run {
+        val initial = SignalIconModel.createEmptyState(iconInteractor.numberOfLevels.value)
         combine(
                 iconInteractor.level,
                 iconInteractor.numberOfLevels,
@@ -90,16 +111,15 @@
                 iconInteractor.isInService,
             ) { level, numberOfLevels, showExclamationMark, isInService ->
                 if (!isInService) {
-                    SignalDrawable.getEmptyState(numberOfLevels)
+                    SignalIconModel.createEmptyState(numberOfLevels)
                 } else {
-                    SignalDrawable.getState(level, numberOfLevels, showExclamationMark)
+                    SignalIconModel(level, numberOfLevels, showExclamationMark)
                 }
             }
             .distinctUntilChanged()
             .logDiffsForTable(
                 iconInteractor.tableLogBuffer,
-                columnPrefix = "",
-                columnName = "iconId",
+                columnPrefix = "icon",
                 initialValue = initial,
             )
             .stateIn(scope, SharingStarted.WhileSubscribed(), initial)
@@ -124,14 +144,22 @@
 
     private val showNetworkTypeIcon: Flow<Boolean> =
         combine(
-            iconInteractor.isDataConnected,
-            iconInteractor.isDataEnabled,
-            iconInteractor.isDefaultConnectionFailed,
-            iconInteractor.alwaysShowDataRatIcon,
-            iconInteractor.isConnected,
-        ) { dataConnected, dataEnabled, failedConnection, alwaysShow, connected ->
-            alwaysShow || (dataConnected && dataEnabled && !failedConnection && connected)
-        }
+                iconInteractor.isDataConnected,
+                iconInteractor.isDataEnabled,
+                iconInteractor.isDefaultConnectionFailed,
+                iconInteractor.alwaysShowDataRatIcon,
+                iconInteractor.isConnected,
+            ) { dataConnected, dataEnabled, failedConnection, alwaysShow, connected ->
+                alwaysShow || (dataConnected && dataEnabled && !failedConnection && connected)
+            }
+            .distinctUntilChanged()
+            .logDiffsForTable(
+                iconInteractor.tableLogBuffer,
+                columnPrefix = "",
+                columnName = "showNetworkTypeIcon",
+                initialValue = false,
+            )
+            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val networkTypeIcon: Flow<Icon?> =
         combine(
@@ -149,14 +177,6 @@
                 }
             }
             .distinctUntilChanged()
-            .onEach {
-                // This is done as an onEach side effect since Icon is not Diffable (yet)
-                iconInteractor.tableLogBuffer.logChange(
-                    prefix = "",
-                    columnName = "networkTypeIcon",
-                    value = it.toString(),
-                )
-            }
             .stateIn(scope, SharingStarted.WhileSubscribed(), null)
 
     override val roaming: StateFlow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
index 24370d2..185b668 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
@@ -17,9 +17,11 @@
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
 import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
@@ -39,6 +41,7 @@
 constructor(
     val subscriptionIdsFlow: StateFlow<List<Int>>,
     private val interactor: MobileIconsInteractor,
+    private val airplaneModeInteractor: AirplaneModeInteractor,
     private val logger: ConnectivityPipelineLogger,
     private val constants: ConnectivityConstants,
     @Application private val scope: CoroutineScope,
@@ -56,7 +59,7 @@
                 ?: MobileIconViewModel(
                         subId,
                         interactor.createMobileConnectionInteractorForSubId(subId),
-                        logger,
+                        airplaneModeInteractor,
                         constants,
                         scope,
                     )
@@ -74,10 +77,12 @@
         subIdsToRemove.forEach { mobileIconSubIdCache.remove(it) }
     }
 
+    @SysUISingleton
     class Factory
     @Inject
     constructor(
         private val interactor: MobileIconsInteractor,
+        private val airplaneModeInteractor: AirplaneModeInteractor,
         private val logger: ConnectivityPipelineLogger,
         private val constants: ConnectivityConstants,
         @Application private val scope: CoroutineScope,
@@ -87,6 +92,7 @@
             return MobileIconsViewModel(
                 subscriptionIdsFlow,
                 interactor,
+                airplaneModeInteractor,
                 logger,
                 constants,
                 scope,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
index 7c7ffaf..45036969 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
@@ -204,15 +204,6 @@
 
     // TODO(b/238425913): We should split this class into mobile-specific and wifi-specific loggers.
 
-    fun logFilteredSubscriptionsChanged(subs: List<SubscriptionModel>) {
-        buffer.log(
-            SB_LOGGING_TAG,
-            LogLevel.INFO,
-            { str1 = subs.toString() },
-            { "Filtered subscriptions updated: $str1" },
-        )
-    }
-
     fun logUiAdapterSubIdsUpdated(subs: List<Int>) {
         buffer.log(
             SB_LOGGING_TAG,
@@ -231,6 +222,27 @@
         )
     }
 
+    fun logCarrierConfigChanged(subId: Int) {
+        buffer.log(
+            SB_LOGGING_TAG,
+            LogLevel.INFO,
+            { int1 = subId },
+            { "onCarrierConfigChanged: subId=$int1" },
+        )
+    }
+
+    fun logOnDataEnabledChanged(enabled: Boolean, subId: Int) {
+        buffer.log(
+            SB_LOGGING_TAG,
+            LogLevel.INFO,
+            {
+                int1 = subId
+                bool1 = enabled
+            },
+            { "onDataEnabledChanged: subId=$int1 enabled=$bool1" },
+        )
+    }
+
     companion object {
         const val SB_LOGGING_TAG = "SbConnectivity"
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
index caac8fa..7d2501ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
@@ -53,7 +53,7 @@
 
     private fun Bundle.activeWifiEvent(): FakeWifiEventModel.Wifi {
         val level = getString("level")?.toInt()
-        val activity = getString("activity")?.toActivity()
+        val activity = getString("activity").toActivity()
         val ssid = getString("ssid")
         val validated = getString("fully").toBoolean()
 
@@ -69,11 +69,12 @@
         val subId = getString("slot")?.toInt() ?: DEFAULT_CARRIER_MERGED_SUB_ID
         val level = getString("level")?.toInt() ?: 0
         val numberOfLevels = getString("numlevels")?.toInt() ?: DEFAULT_NUM_LEVELS
+        val activity = getString("activity").toActivity()
 
-        return FakeWifiEventModel.CarrierMerged(subId, level, numberOfLevels)
+        return FakeWifiEventModel.CarrierMerged(subId, level, numberOfLevels, activity)
     }
 
-    private fun String.toActivity(): Int =
+    private fun String?.toActivity(): Int =
         when (this) {
             "inout" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT
             "in" -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
index e161b3e..a19c3c3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
@@ -80,17 +80,14 @@
     private fun processEnabledWifiState(event: FakeWifiEventModel.Wifi) {
         _isWifiEnabled.value = true
         _isWifiDefault.value = true
-        _wifiActivity.value =
-            event.activity?.toWifiDataActivityModel()
-                ?: DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        _wifiActivity.value = event.activity.toWifiDataActivityModel()
         _wifiNetwork.value = event.toWifiNetworkModel()
     }
 
     private fun processCarrierMergedWifiState(event: FakeWifiEventModel.CarrierMerged) {
         _isWifiEnabled.value = true
         _isWifiDefault.value = true
-        // TODO(b/238425913): Support activity in demo mode.
-        _wifiActivity.value = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        _wifiActivity.value = event.activity.toWifiDataActivityModel()
         _wifiNetwork.value = event.toCarrierMergedModel()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
index 518f8ce..f5035cbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model
 
+import android.telephony.Annotation
+
 /**
  * Model for demo wifi commands, ported from [NetworkControllerImpl]
  *
@@ -24,7 +26,7 @@
 sealed interface FakeWifiEventModel {
     data class Wifi(
         val level: Int?,
-        val activity: Int?,
+        @Annotation.DataActivityType val activity: Int,
         val ssid: String?,
         val validated: Boolean?,
     ) : FakeWifiEventModel
@@ -33,6 +35,7 @@
         val subscriptionId: Int,
         val level: Int,
         val numberOfLevels: Int,
+        @Annotation.DataActivityType val activity: Int,
     ) : FakeWifiEventModel
 
     object WifiDisabled : FakeWifiEventModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
index 8669047..c45b420 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -95,7 +95,7 @@
             .logDiffsForTable(
                 wifiTableLogBuffer,
                 columnPrefix = "",
-                columnName = "isWifiEnabled",
+                columnName = "isEnabled",
                 initialValue = wifiManager.isWifiEnabled,
             )
             .stateIn(
@@ -141,7 +141,7 @@
             .logDiffsForTable(
                 wifiTableLogBuffer,
                 columnPrefix = "",
-                columnName = "isWifiDefault",
+                columnName = "isDefault",
                 initialValue = false,
             )
             .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
@@ -212,7 +212,7 @@
             .distinctUntilChanged()
             .logDiffsForTable(
                 wifiTableLogBuffer,
-                columnPrefix = "wifiNetwork",
+                columnPrefix = "",
                 initialValue = WIFI_NETWORK_DEFAULT,
             )
             // There will be multiple wifi icons in different places that will frequently
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt
index e491d2b..094bcf9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt
@@ -53,4 +53,4 @@
     }
 }
 
-private const val COL_ICON = "wifiIcon"
+private const val COL_ICON = "icon"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
index e2bebbe..f0949ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
@@ -25,6 +25,8 @@
          * If controls become available, initiate this callback with the desired position
          */
         fun onControlsUpdate(position: Int?)
+
+        fun removeControlsAutoTracker()
     }
 
     /** Add callback, supporting only a single callback at once */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
index 341eb3b..4950482 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -21,16 +21,15 @@
 import android.content.SharedPreferences
 import android.provider.Settings
 import android.util.Log
-
 import com.android.systemui.R
 import com.android.systemui.controls.ControlsServiceInfo
 import com.android.systemui.controls.dagger.ControlsComponent
 import com.android.systemui.controls.management.ControlsListingController
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.statusbar.phone.AutoTileManager
 import com.android.systemui.statusbar.policy.DeviceControlsController.Callback
 import com.android.systemui.util.settings.SecureSettings
-
 import javax.inject.Inject
 
 /**
@@ -87,6 +86,10 @@
      * incorrect.
      */
     override fun setCallback(callback: Callback) {
+        if (!controlsComponent.isEnabled()) {
+            callback.removeControlsAutoTracker()
+            return
+        }
         // Treat any additional call as a reset before recalculating
         removeCallback()
         this.callback = callback
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerExt.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerExt.kt
new file mode 100644
index 0000000..5e36750
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerExt.kt
@@ -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.statusbar.policy
+
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Returns a [Flow] that emits events whenever a [NotificationEntry] enters or exists the "heads up"
+ * state.
+ */
+val HeadsUpManager.headsUpEvents: Flow<Pair<NotificationEntry, Boolean>>
+    get() = conflatedCallbackFlow {
+        val listener =
+            object : OnHeadsUpChangedListener {
+                override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
+                    trySend(entry to isHeadsUp)
+                }
+            }
+        addListener(listener)
+        awaitClose { removeListener(listener) }
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index cc6fdcc..9ad36fd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -438,6 +438,11 @@
         }
 
         @Override
+        public void onLockedOutStateChanged(BiometricSourceType biometricSourceType) {
+            update(false /* updateAlways */);
+        }
+
+        @Override
         public void onKeyguardVisibilityChanged(boolean visible) {
             update(false /* updateAlways */);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index b22af3b..3f54aebf 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -25,6 +25,7 @@
 import android.util.ArrayMap
 import android.util.Log
 import android.view.InputDevice
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.flags.FeatureFlags
@@ -47,6 +48,7 @@
     @Background private val handler: Handler,
     @Background private val executor: Executor,
     private val featureFlags: FeatureFlags,
+    private val uiEventLogger: UiEventLogger,
 ) :
     InputManager.InputDeviceListener,
     InputManager.InputDeviceBatteryListener,
@@ -186,6 +188,7 @@
     }
 
     private fun onStylusBluetoothConnected(btAddress: String) {
+        uiEventLogger.log(StylusUiEvent.BLUETOOTH_STYLUS_CONNECTED)
         val device: BluetoothDevice = bluetoothAdapter?.getRemoteDevice(btAddress) ?: return
         try {
             bluetoothAdapter.addOnMetadataChangedListener(device, executor, this)
@@ -195,6 +198,7 @@
     }
 
     private fun onStylusBluetoothDisconnected(btAddress: String) {
+        uiEventLogger.log(StylusUiEvent.BLUETOOTH_STYLUS_DISCONNECTED)
         val device: BluetoothDevice = bluetoothAdapter?.getRemoteDevice(btAddress) ?: return
         try {
             bluetoothAdapter.removeOnMetadataChangedListener(device, this)
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUiEvent.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUiEvent.kt
new file mode 100644
index 0000000..99da4ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUiEvent.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.stylus
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+
+enum class StylusUiEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
+    @UiEvent(doc = "UiEvent for USI low battery notification shown")
+    STYLUS_LOW_BATTERY_NOTIFICATION_SHOWN(1298),
+    @UiEvent(doc = "UiEvent for USI low battery notification clicked")
+    STYLUS_LOW_BATTERY_NOTIFICATION_CLICKED(1299),
+    @UiEvent(doc = "UiEvent for USI low battery notification dismissed")
+    STYLUS_LOW_BATTERY_NOTIFICATION_DISMISSED(1300),
+    @UiEvent(doc = "UIEvent for Toast shown when stylus started charging")
+    STYLUS_STARTED_CHARGING(1302),
+    @UiEvent(doc = "UIEvent for Toast shown when stylus stopped charging")
+    STYLUS_STOPPED_CHARGING(1303),
+    @UiEvent(doc = "UIEvent for bluetooth stylus connected") BLUETOOTH_STYLUS_CONNECTED(1304),
+    @UiEvent(doc = "UIEvent for bluetooth stylus disconnected") BLUETOOTH_STYLUS_DISCONNECTED(1305);
+
+    override fun getId() = _id
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 9050dad..89453ad 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.stylus
 
 import android.Manifest
+import android.app.ActivityManager
 import android.app.PendingIntent
 import android.content.ActivityNotFoundException
 import android.content.BroadcastReceiver
@@ -32,6 +33,7 @@
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationManagerCompat
 import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -53,6 +55,7 @@
     private val notificationManager: NotificationManagerCompat,
     private val inputManager: InputManager,
     @Background private val handler: Handler,
+    private val uiEventLogger: UiEventLogger,
 ) {
 
     // These values must only be accessed on the handler.
@@ -79,12 +82,13 @@
 
     fun refresh() {
         handler.post refreshNotification@{
-            if (!suppressed && !hasConnectedBluetoothStylus() && isBatteryBelowThreshold()) {
+            val batteryBelowThreshold = isBatteryBelowThreshold()
+            if (!suppressed && !hasConnectedBluetoothStylus() && batteryBelowThreshold) {
                 showOrUpdateNotification()
                 return@refreshNotification
             }
 
-            if (!isBatteryBelowThreshold()) {
+            if (!batteryBelowThreshold) {
                 // Reset suppression when stylus battery is recharged, so that the next time
                 // it reaches a low battery, the notification will show again.
                 suppressed = false
@@ -143,6 +147,7 @@
                 .setAutoCancel(true)
                 .build()
 
+        logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_SHOWN)
         notificationManager.notify(USI_NOTIFICATION_ID, notification)
     }
 
@@ -168,8 +173,12 @@
         object : BroadcastReceiver() {
             override fun onReceive(context: Context, intent: Intent) {
                 when (intent.action) {
-                    ACTION_DISMISSED_LOW_BATTERY -> updateSuppression(true)
+                    ACTION_DISMISSED_LOW_BATTERY -> {
+                        logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_DISMISSED)
+                        updateSuppression(true)
+                    }
                     ACTION_CLICKED_LOW_BATTERY -> {
+                        logUiEvent(StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_CLICKED)
                         updateSuppression(true)
                         if (inputDeviceId == null) return
 
@@ -195,6 +204,15 @@
             }
         }
 
+    private fun logUiEvent(metricId: StylusUiEvent) {
+        uiEventLogger.logWithPosition(
+            metricId,
+            ActivityManager.getCurrentUser(),
+            context.packageName,
+            (batteryCapacity * 100.0).toInt()
+        )
+    }
+
     companion object {
         // Low battery threshold matches CrOS, see:
         // https://source.chromium.org/chromium/chromium/src/+/main:ash/system/power/peripheral_battery_notifier.cc;l=41
@@ -203,10 +221,14 @@
         private val USI_NOTIFICATION_ID = R.string.stylus_battery_low_percentage
 
         @VisibleForTesting const val ACTION_DISMISSED_LOW_BATTERY = "StylusUsiPowerUI.dismiss"
+
         @VisibleForTesting const val ACTION_CLICKED_LOW_BATTERY = "StylusUsiPowerUI.click"
+
         @VisibleForTesting
         const val ACTION_STYLUS_USI_DETAILS = "com.android.settings.STYLUS_USI_DETAILS_SETTINGS"
+
         @VisibleForTesting const val KEY_DEVICE_INPUT_ID = "device_input_id"
+
         @VisibleForTesting const val KEY_SETTINGS_FRAGMENT_ARGS = ":settings:show_fragment_args"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
new file mode 100644
index 0000000..c1f0c58
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.theme
+
+import android.util.Pair
+import com.android.systemui.monet.dynamiccolor.DynamicColor
+import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors as MDC
+
+class DynamicColors {
+    companion object {
+        @JvmField
+        val ALL_DYNAMIC_COLORS_MAPPED: List<Pair<String, DynamicColor>> =
+            arrayListOf(
+                Pair.create("primary_container", MDC.primaryContainer),
+                Pair.create("on_primary_container", MDC.onPrimaryContainer),
+                Pair.create("primary", MDC.primary),
+                Pair.create("on_primary", MDC.onPrimary),
+                Pair.create("secondary_container", MDC.secondaryContainer),
+                Pair.create("on_secondary_container", MDC.onSecondaryContainer),
+                Pair.create("secondary", MDC.secondary),
+                Pair.create("on_secondary", MDC.onSecondary),
+                Pair.create("tertiary_container", MDC.tertiaryContainer),
+                Pair.create("on_tertiary_container", MDC.onTertiaryContainer),
+                Pair.create("tertiary", MDC.tertiary),
+                Pair.create("on_tertiary", MDC.onTertiary),
+                Pair.create("background", MDC.background),
+                Pair.create("on_background", MDC.onBackground),
+                Pair.create("surface", MDC.surface),
+                Pair.create("on_surface", MDC.onSurface),
+                Pair.create("surface_container_low", MDC.surfaceContainerLow),
+                Pair.create("surface_container_lowest", MDC.surfaceContainerLowest),
+                Pair.create("surface_container", MDC.surfaceContainer),
+                Pair.create("surface_container_high", MDC.surfaceContainerHigh),
+                Pair.create("surface_container_highest", MDC.surfaceContainerHighest),
+                Pair.create("surface_bright", MDC.surfaceBright),
+                Pair.create("surface_dim", MDC.surfaceDim),
+                Pair.create("surface_variant", MDC.surfaceVariant),
+                Pair.create("on_surface_variant", MDC.onSurfaceVariant),
+                Pair.create("outline", MDC.outline),
+                Pair.create("error", MDC.error),
+                Pair.create("on_error", MDC.onError),
+                Pair.create("error_container", MDC.errorContainer),
+                Pair.create("on_error_container", MDC.onErrorContainer),
+                Pair.create("primary_fixed", MDC.primaryFixed),
+                Pair.create("primary_fixed_darker", MDC.primaryFixedDarker),
+                Pair.create("on_primary_fixed", MDC.onPrimaryFixed),
+                Pair.create("on_primary_fixed_variant", MDC.onPrimaryFixedVariant),
+                Pair.create("secondary_fixed", MDC.secondaryFixed),
+                Pair.create("secondary_fixed_darker", MDC.secondaryFixedDarker),
+                Pair.create("on_secondary_fixed", MDC.onSecondaryFixed),
+                Pair.create("on_secondary_fixed_variant", MDC.onSecondaryFixedVariant),
+                Pair.create("tertiary_fixed", MDC.tertiaryFixed),
+                Pair.create("tertiary_fixed_darker", MDC.tertiaryFixedDarker),
+                Pair.create("on_tertiary_fixed", MDC.onTertiaryFixed),
+                Pair.create("on_tertiary_fixed_variant", MDC.onTertiaryFixedVariant),
+                Pair.create("control_activated", MDC.controlActivated),
+                Pair.create("control_normal", MDC.controlNormal),
+                Pair.create("control_highlight", MDC.controlHighlight),
+                Pair.create("text_primary_inverse", MDC.textPrimaryInverse),
+                Pair.create(
+                    "text_secondary_and_tertiary_inverse",
+                    MDC.textSecondaryAndTertiaryInverse
+                ),
+                Pair.create("text_primary_inverse_disable_only", MDC.textPrimaryInverseDisableOnly),
+                Pair.create(
+                    "text_secondary_and_tertiary_inverse_disabled",
+                    MDC.textSecondaryAndTertiaryInverseDisabled
+                ),
+                Pair.create("text_hint_inverse", MDC.textHintInverse),
+                Pair.create("palette_key_color_primary", MDC.primaryPaletteKeyColor),
+                Pair.create("palette_key_color_secondary", MDC.secondaryPaletteKeyColor),
+                Pair.create("palette_key_color_tertiary", MDC.tertiaryPaletteKeyColor),
+                Pair.create("palette_key_color_neutral", MDC.neutralPaletteKeyColor),
+                Pair.create("palette_key_color_neutral_variant", MDC.neutralVariantPaletteKeyColor)
+            )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
index ba39367..3376e23 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
@@ -65,6 +65,8 @@
     @VisibleForTesting
     static final String SYSUI_PACKAGE = "com.android.systemui";
 
+    static final String OVERLAY_CATEGORY_DYNAMIC_COLOR =
+            "android.theme.customization.dynamic_color";
     static final String OVERLAY_CATEGORY_ACCENT_COLOR =
             "android.theme.customization.accent_color";
     static final String OVERLAY_CATEGORY_SYSTEM_PALETTE =
@@ -117,6 +119,7 @@
             OVERLAY_CATEGORY_SHAPE,
             OVERLAY_CATEGORY_FONT,
             OVERLAY_CATEGORY_ACCENT_COLOR,
+            OVERLAY_CATEGORY_DYNAMIC_COLOR,
             OVERLAY_CATEGORY_ICON_ANDROID,
             OVERLAY_CATEGORY_ICON_SYSUI,
             OVERLAY_CATEGORY_ICON_SETTINGS,
@@ -127,6 +130,7 @@
     static final Set<String> SYSTEM_USER_CATEGORIES = Sets.newHashSet(
             OVERLAY_CATEGORY_SYSTEM_PALETTE,
             OVERLAY_CATEGORY_ACCENT_COLOR,
+            OVERLAY_CATEGORY_DYNAMIC_COLOR,
             OVERLAY_CATEGORY_FONT,
             OVERLAY_CATEGORY_SHAPE,
             OVERLAY_CATEGORY_ICON_ANDROID,
@@ -153,6 +157,7 @@
         mThemePickerPackage = themePickerPackage;
         mTargetPackageToCategories.put(ANDROID_PACKAGE, Sets.newHashSet(
                 OVERLAY_CATEGORY_SYSTEM_PALETTE, OVERLAY_CATEGORY_ACCENT_COLOR,
+                OVERLAY_CATEGORY_DYNAMIC_COLOR,
                 OVERLAY_CATEGORY_FONT, OVERLAY_CATEGORY_SHAPE,
                 OVERLAY_CATEGORY_ICON_ANDROID));
         mTargetPackageToCategories.put(SYSUI_PACKAGE,
@@ -164,6 +169,7 @@
         mTargetPackageToCategories.put(mThemePickerPackage,
                 Sets.newHashSet(OVERLAY_CATEGORY_ICON_THEME_PICKER));
         mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, ANDROID_PACKAGE);
+        mCategoryToTargetPackage.put(OVERLAY_CATEGORY_DYNAMIC_COLOR, ANDROID_PACKAGE);
         mCategoryToTargetPackage.put(OVERLAY_CATEGORY_FONT, ANDROID_PACKAGE);
         mCategoryToTargetPackage.put(OVERLAY_CATEGORY_SHAPE, ANDROID_PACKAGE);
         mCategoryToTargetPackage.put(OVERLAY_CATEGORY_ICON_ANDROID, ANDROID_PACKAGE);
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 6b507ba..2ad3558 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -15,11 +15,14 @@
  */
 package com.android.systemui.theme;
 
+import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
+
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_HOME;
 import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_LOCK;
 import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_PRESET;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_DYNAMIC_COLOR;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_SYSTEM_PALETTE;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_BOTH;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_COLOR_INDEX;
@@ -51,7 +54,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
-import android.util.TypedValue;
+import android.view.accessibility.AccessibilityManager;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
@@ -70,6 +73,16 @@
 import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.monet.Style;
 import com.android.systemui.monet.TonalPalette;
+import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors;
+import com.android.systemui.monet.hct.Hct;
+import com.android.systemui.monet.scheme.DynamicScheme;
+import com.android.systemui.monet.scheme.SchemeExpressive;
+import com.android.systemui.monet.scheme.SchemeFruitSalad;
+import com.android.systemui.monet.scheme.SchemeMonochrome;
+import com.android.systemui.monet.scheme.SchemeNeutral;
+import com.android.systemui.monet.scheme.SchemeRainbow;
+import com.android.systemui.monet.scheme.SchemeTonalSpot;
+import com.android.systemui.monet.scheme.SchemeVibrant;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -105,9 +118,6 @@
     protected static final String TAG = "ThemeOverlayController";
     private static final boolean DEBUG = true;
 
-    protected static final int NEUTRAL = 0;
-    protected static final int ACCENT = 1;
-
     private final ThemeOverlayApplier mThemeManager;
     private final UserManager mUserManager;
     private final BroadcastDispatcher mBroadcastDispatcher;
@@ -130,12 +140,17 @@
     private boolean mNeedsOverlayCreation;
     // Dominant color extracted from wallpaper, NOT the color used on the overlay
     protected int mMainWallpaperColor = Color.TRANSPARENT;
+    // UI contrast as reported by AccessibilityManager
+    private float mUiContrast = 0;
     // Theme variant: Vibrant, Tonal, Expressive, etc
-    private Style mThemeStyle = Style.TONAL_SPOT;
+    @VisibleForTesting
+    protected Style mThemeStyle = Style.TONAL_SPOT;
     // Accent colors overlay
     private FabricatedOverlay mSecondaryOverlay;
     // Neutral system colors overlay
     private FabricatedOverlay mNeutralOverlay;
+    // Dynamic colors overlay
+    private FabricatedOverlay mDynamicOverlay;
     // If wallpaper color event will be accepted and change the UI colors.
     private boolean mAcceptColorEvents = true;
     // If non-null (per user), colors that were sent to the framework, and processing was deferred
@@ -143,6 +158,9 @@
     private final SparseArray<WallpaperColors> mDeferredWallpaperColors = new SparseArray<>();
     private final SparseIntArray mDeferredWallpaperColorsFlags = new SparseIntArray();
     private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private final AccessibilityManager mAccessibilityManager;
+    private DynamicScheme mDynamicSchemeDark;
+    private DynamicScheme mDynamicSchemeLight;
 
     // Defers changing themes until Setup Wizard is done.
     private boolean mDeferredThemeEvaluation;
@@ -304,6 +322,7 @@
                 mSkipSettingChange = true;
                 if (jsonObject.has(OVERLAY_CATEGORY_ACCENT_COLOR) || jsonObject.has(
                         OVERLAY_CATEGORY_SYSTEM_PALETTE)) {
+                    jsonObject.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR);
                     jsonObject.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
                     jsonObject.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
                     jsonObject.remove(OVERLAY_COLOR_INDEX);
@@ -372,7 +391,8 @@
             DumpManager dumpManager,
             FeatureFlags featureFlags,
             @Main Resources resources,
-            WakefulnessLifecycle wakefulnessLifecycle) {
+            WakefulnessLifecycle wakefulnessLifecycle,
+            AccessibilityManager accessibilityManager) {
         mContext = context;
         mIsMonochromaticEnabled = featureFlags.isEnabled(Flags.MONOCHROMATIC_THEME);
         mIsMonetEnabled = featureFlags.isEnabled(Flags.MONET);
@@ -388,6 +408,7 @@
         mUserTracker = userTracker;
         mResources = resources;
         mWakefulnessLifecycle = wakefulnessLifecycle;
+        mAccessibilityManager = accessibilityManager;
         dumpManager.registerDumpable(TAG, this);
     }
 
@@ -424,6 +445,12 @@
                     }
                 },
                 UserHandle.USER_ALL);
+        mUiContrast = mAccessibilityManager.getUiContrast();
+        mAccessibilityManager.addUiContrastChangeListener(mMainExecutor, uiContrast -> {
+            mUiContrast = uiContrast;
+            // Force reload so that we update even when the main color has not changed
+            reevaluateSystemTheme(true /* forceReload */);
+        });
 
         if (!mIsMonetEnabled) {
             return;
@@ -496,12 +523,11 @@
 
         if (mIsMonetEnabled) {
             mThemeStyle = fetchThemeStyleFromSetting();
-            mSecondaryOverlay = getOverlay(mMainWallpaperColor, ACCENT, mThemeStyle);
-            mNeutralOverlay = getOverlay(mMainWallpaperColor, NEUTRAL, mThemeStyle);
+            createOverlays(mMainWallpaperColor);
             mNeedsOverlayCreation = true;
             if (DEBUG) {
                 Log.d(TAG, "fetched overlays. accent: " + mSecondaryOverlay
-                        + " neutral: " + mNeutralOverlay);
+                        + " neutral: " + mNeutralOverlay + " dynamic: " + mDynamicOverlay);
             }
         }
 
@@ -519,42 +545,95 @@
         return ColorScheme.getSeedColor(wallpaperColors);
     }
 
-    /**
-     * Given a color candidate, return an overlay definition.
-     */
-    protected FabricatedOverlay getOverlay(int color, int type, Style style) {
-        boolean nightMode = (mResources.getConfiguration().uiMode
-                & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
-
-        mColorScheme = new ColorScheme(color, nightMode, style);
-        String name = type == ACCENT ? "accent" : "neutral";
-
-        FabricatedOverlay.Builder overlay =
-                new FabricatedOverlay.Builder("com.android.systemui", name, "android");
-
-        if (type == ACCENT) {
-            assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1());
-            assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2());
-            assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3());
-        } else {
-            assignTonalPaletteToOverlay("neutral1", overlay, mColorScheme.getNeutral1());
-            assignTonalPaletteToOverlay("neutral2", overlay, mColorScheme.getNeutral2());
+    private static DynamicScheme dynamicSchemeFromStyle(Style style, int color,
+            boolean isDark, double contrastLevel) {
+        Hct sourceColorHct = Hct.fromInt(color);
+        switch (style) {
+            case EXPRESSIVE:
+                return new SchemeExpressive(sourceColorHct, isDark, contrastLevel);
+            case SPRITZ:
+                return new SchemeNeutral(sourceColorHct, isDark, contrastLevel);
+            case TONAL_SPOT:
+                return new SchemeTonalSpot(sourceColorHct, isDark, contrastLevel);
+            case FRUIT_SALAD:
+                return new SchemeFruitSalad(sourceColorHct, isDark, contrastLevel);
+            case RAINBOW:
+                return new SchemeRainbow(sourceColorHct, isDark, contrastLevel);
+            case VIBRANT:
+                return new SchemeVibrant(sourceColorHct, isDark, contrastLevel);
+            case MONOCHROMATIC:
+                return new SchemeMonochrome(sourceColorHct, isDark, contrastLevel);
+            default:
+                return null;
         }
-
-        return overlay.build();
     }
 
-    private void assignTonalPaletteToOverlay(String name,
-            FabricatedOverlay.Builder overlay, TonalPalette tonalPalette) {
+    @VisibleForTesting
+    protected boolean isNightMode() {
+        return (mResources.getConfiguration().uiMode
+                & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
+    }
 
+    @VisibleForTesting
+    protected FabricatedOverlay newFabricatedOverlay(String name) {
+        return new FabricatedOverlay.Builder("com.android.systemui", name, "android").build();
+    }
+
+    private void createOverlays(int color) {
+        boolean nightMode = isNightMode();
+        mColorScheme = new ColorScheme(color, nightMode, mThemeStyle);
+        mNeutralOverlay = createNeutralOverlay();
+        mSecondaryOverlay = createAccentOverlay();
+
+        mDynamicSchemeDark = dynamicSchemeFromStyle(
+                mThemeStyle, color, true /* isDark */, mUiContrast);
+        mDynamicSchemeLight = dynamicSchemeFromStyle(
+                mThemeStyle, color, false /* isDark */, mUiContrast);
+        mDynamicOverlay = createDynamicOverlay();
+    }
+
+    protected FabricatedOverlay createNeutralOverlay() {
+        FabricatedOverlay overlay = newFabricatedOverlay("neutral");
+        assignTonalPaletteToOverlay("neutral1", overlay, mColorScheme.getNeutral1());
+        assignTonalPaletteToOverlay("neutral2", overlay, mColorScheme.getNeutral2());
+        return overlay;
+    }
+
+    protected FabricatedOverlay createAccentOverlay() {
+        FabricatedOverlay overlay = newFabricatedOverlay("accent");
+        assignTonalPaletteToOverlay("accent1", overlay, mColorScheme.getAccent1());
+        assignTonalPaletteToOverlay("accent2", overlay, mColorScheme.getAccent2());
+        assignTonalPaletteToOverlay("accent3", overlay, mColorScheme.getAccent3());
+        return overlay;
+    }
+
+    private void assignTonalPaletteToOverlay(String name, FabricatedOverlay overlay,
+            TonalPalette tonalPalette) {
         String resourcePrefix = "android:color/system_" + name;
-        int colorDataType = TypedValue.TYPE_INT_COLOR_ARGB8;
 
         tonalPalette.getAllShadesMapped().forEach((key, value) -> {
             String resourceName = resourcePrefix + "_" + key;
             int colorValue = ColorUtils.setAlphaComponent(value, 0xFF);
-            overlay.setResourceValue(resourceName, colorDataType,
-                    colorValue);
+            overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
+                    null /* configuration */);
+        });
+    }
+
+    protected FabricatedOverlay createDynamicOverlay() {
+        FabricatedOverlay overlay = newFabricatedOverlay("dynamic");
+        assignDynamicPaletteToOverlay(overlay, true /* isDark */);
+        assignDynamicPaletteToOverlay(overlay, false /* isDark */);
+        return overlay;
+    }
+
+    private void assignDynamicPaletteToOverlay(FabricatedOverlay overlay, boolean isDark) {
+        String suffix = isDark ? "dark" : "light";
+        DynamicScheme scheme = isDark ? mDynamicSchemeDark : mDynamicSchemeLight;
+        DynamicColors.ALL_DYNAMIC_COLORS_MAPPED.forEach(p -> {
+            String resourceName = "android:color/system_" + p.first + "_" + suffix;
+            int colorValue = p.second.getArgb(scheme);
+            overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
+                    null /* configuration */);
         });
     }
 
@@ -568,16 +647,21 @@
         for (UserHandle userHandle : allProfiles) {
             Resources res = userHandle.isSystem()
                     ? mResources : mContext.createContextAsUser(userHandle, 0).getResources();
-            if (!(res.getColor(android.R.color.system_accent1_500, mContext.getTheme())
+            Resources.Theme theme = mContext.getTheme();
+            if (!(res.getColor(android.R.color.system_accent1_500, theme)
                     == mColorScheme.getAccent1().getS500()
-                    && res.getColor(android.R.color.system_accent2_500, mContext.getTheme())
+                    && res.getColor(android.R.color.system_accent2_500, theme)
                     == mColorScheme.getAccent2().getS500()
-                    && res.getColor(android.R.color.system_accent3_500, mContext.getTheme())
+                    && res.getColor(android.R.color.system_accent3_500, theme)
                     == mColorScheme.getAccent3().getS500()
-                    && res.getColor(android.R.color.system_neutral1_500, mContext.getTheme())
+                    && res.getColor(android.R.color.system_neutral1_500, theme)
                     == mColorScheme.getNeutral1().getS500()
-                    && res.getColor(android.R.color.system_neutral2_500, mContext.getTheme())
-                    == mColorScheme.getNeutral2().getS500())) {
+                    && res.getColor(android.R.color.system_neutral2_500, theme)
+                    == mColorScheme.getNeutral2().getS500()
+                    && res.getColor(android.R.color.system_primary_container_dark, theme)
+                    == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeDark)
+                    && res.getColor(android.R.color.system_primary_container_light, theme)
+                    == MaterialDynamicColors.primaryContainer.getArgb(mDynamicSchemeLight))) {
                 return false;
             }
         }
@@ -614,12 +698,11 @@
                 if (!colorString.startsWith("#")) {
                     colorString = "#" + colorString;
                 }
-                int color = Color.parseColor(colorString);
-                mNeutralOverlay = getOverlay(color, NEUTRAL, mThemeStyle);
-                mSecondaryOverlay = getOverlay(color, ACCENT, mThemeStyle);
+                createOverlays(Color.parseColor(colorString));
                 mNeedsOverlayCreation = true;
                 categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
                 categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
+                categoryToPackage.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR);
             } catch (Exception e) {
                 // Color.parseColor doesn't catch any exceptions from the calls it makes
                 Log.w(TAG, "Invalid color definition: " + systemPalette.getPackageName(), e);
@@ -631,6 +714,7 @@
                 // fail.
                 categoryToPackage.remove(OVERLAY_CATEGORY_SYSTEM_PALETTE);
                 categoryToPackage.remove(OVERLAY_CATEGORY_ACCENT_COLOR);
+                categoryToPackage.remove(OVERLAY_CATEGORY_DYNAMIC_COLOR);
             } catch (NumberFormatException e) {
                 // This is a package name. All good, let's continue
             }
@@ -647,6 +731,10 @@
                 && mSecondaryOverlay != null) {
             categoryToPackage.put(OVERLAY_CATEGORY_ACCENT_COLOR, mSecondaryOverlay.getIdentifier());
         }
+        if (!categoryToPackage.containsKey(OVERLAY_CATEGORY_DYNAMIC_COLOR)
+                && mDynamicOverlay != null) {
+            categoryToPackage.put(OVERLAY_CATEGORY_DYNAMIC_COLOR, mDynamicOverlay.getIdentifier());
+        }
 
         Set<UserHandle> managedProfiles = new HashSet<>();
         for (UserInfo userInfo : mUserManager.getEnabledProfiles(currentUser)) {
@@ -668,7 +756,7 @@
         if (mNeedsOverlayCreation) {
             mNeedsOverlayCreation = false;
             mThemeManager.applyCurrentUserOverlays(categoryToPackage, new FabricatedOverlay[]{
-                    mSecondaryOverlay, mNeutralOverlay
+                    mSecondaryOverlay, mNeutralOverlay, mDynamicOverlay
             }, currentUser, managedProfiles);
         } else {
             mThemeManager.applyCurrentUserOverlays(categoryToPackage, null, currentUser,
@@ -710,6 +798,7 @@
         pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor));
         pw.println("mSecondaryOverlay=" + mSecondaryOverlay);
         pw.println("mNeutralOverlay=" + mNeutralOverlay);
+        pw.println("mDynamicOverlay=" + mDynamicOverlay);
         pw.println("mIsMonetEnabled=" + mIsMonetEnabled);
         pw.println("mColorScheme=" + mColorScheme);
         pw.println("mNeedsOverlayCreation=" + mNeedsOverlayCreation);
diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
index e5ab473..70523bb 100644
--- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
@@ -47,12 +47,14 @@
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.withContext
@@ -76,6 +78,9 @@
     /** Whether user switching is currently in progress. */
     val userSwitchingInProgress: Flow<Boolean>
 
+    /** User ID of the main user. */
+    val mainUserId: Int
+
     /** User ID of the last non-guest selected user. */
     val lastSelectedNonGuestUserId: Int
 
@@ -120,9 +125,25 @@
     featureFlags: FeatureFlags,
 ) : UserRepository {
 
-    private val _userSwitcherSettings = MutableStateFlow(runBlocking { getSettings() })
-    override val userSwitcherSettings: Flow<UserSwitcherSettingsModel> =
-        _userSwitcherSettings.asStateFlow().filterNotNull()
+    private val _userSwitcherSettings: StateFlow<UserSwitcherSettingsModel> =
+        globalSettings
+            .observerFlow(
+                names =
+                    arrayOf(
+                        SETTING_SIMPLE_USER_SWITCHER,
+                        Settings.Global.ADD_USERS_WHEN_LOCKED,
+                        Settings.Global.USER_SWITCHER_ENABLED,
+                    ),
+                userId = UserHandle.USER_SYSTEM,
+            )
+            .onStart { emit(Unit) } // Forces an initial update.
+            .map { getSettings() }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = runBlocking { getSettings() },
+            )
+    override val userSwitcherSettings: Flow<UserSwitcherSettingsModel> = _userSwitcherSettings
 
     private val _userInfos = MutableStateFlow<List<UserInfo>?>(null)
     override val userInfos: Flow<List<UserInfo>> = _userInfos.filterNotNull()
@@ -130,7 +151,9 @@
     private val _selectedUserInfo = MutableStateFlow<UserInfo?>(null)
     override val selectedUserInfo: Flow<UserInfo> = _selectedUserInfo.filterNotNull()
 
-    override var lastSelectedNonGuestUserId: Int = UserHandle.USER_SYSTEM
+    override var mainUserId: Int = UserHandle.USER_NULL
+        private set
+    override var lastSelectedNonGuestUserId: Int = UserHandle.USER_NULL
         private set
 
     override val isGuestUserAutoCreated: Boolean =
@@ -154,7 +177,6 @@
 
     init {
         observeSelectedUser()
-        observeUserSettings()
         if (featureFlags.isEnabled(FACE_AUTH_REFACTOR)) {
             observeUserSwitching()
         }
@@ -172,6 +194,11 @@
                         // The guest user is always last, regardless of creation time.
                         .sortedBy { it.isGuest }
             }
+
+            if (mainUserId == UserHandle.USER_NULL) {
+                val mainUser = withContext(backgroundDispatcher) { manager.mainUser }
+                mainUser?.let { mainUserId = it.identifier }
+            }
         }
     }
 
@@ -237,23 +264,6 @@
             .launchIn(applicationScope)
     }
 
-    private fun observeUserSettings() {
-        globalSettings
-            .observerFlow(
-                names =
-                    arrayOf(
-                        SETTING_SIMPLE_USER_SWITCHER,
-                        Settings.Global.ADD_USERS_WHEN_LOCKED,
-                        Settings.Global.USER_SWITCHER_ENABLED,
-                    ),
-                userId = UserHandle.USER_SYSTEM,
-            )
-            .onStart { emit(Unit) } // Forces an initial update.
-            .map { getSettings() }
-            .onEach { _userSwitcherSettings.value = it }
-            .launchIn(applicationScope)
-    }
-
     private suspend fun getSettings(): UserSwitcherSettingsModel {
         return withContext(backgroundDispatcher) {
             val isSimpleUserSwitcher =
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt
index a374885..0a07439 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/GuestUserInteractor.kt
@@ -139,11 +139,11 @@
         }
 
         applicationScope.launch {
-            var newUserId = UserHandle.USER_SYSTEM
+            var newUserId = repository.mainUserId
             if (targetUserId == UserHandle.USER_NULL) {
                 // When a target user is not specified switch to last non guest user:
                 val lastSelectedNonGuestUserHandle = repository.lastSelectedNonGuestUserId
-                if (lastSelectedNonGuestUserHandle != UserHandle.USER_SYSTEM) {
+                if (lastSelectedNonGuestUserHandle != repository.mainUserId) {
                     val info =
                         withContext(backgroundDispatcher) {
                             manager.getUserInfo(lastSelectedNonGuestUserHandle)
@@ -215,8 +215,11 @@
             // Create a new guest in the foreground, and then immediately switch to it
             val newGuestId = create(showDialog, dismissDialog)
             if (newGuestId == UserHandle.USER_NULL) {
-                Log.e(TAG, "Could not create new guest, switching back to system user")
-                switchUser(UserHandle.USER_SYSTEM)
+                Log.e(TAG, "Could not create new guest, switching back to main user")
+                val mainUser = withContext(backgroundDispatcher) { manager.mainUser?.identifier }
+
+                mainUser?.let { switchUser(it) }
+
                 withContext(backgroundDispatcher) {
                     manager.removeUserWhenPossible(
                         UserHandle.of(currentUser.id),
diff --git a/packages/SystemUI/src/com/android/systemui/util/BackupManagerProxy.kt b/packages/SystemUI/src/com/android/systemui/util/BackupManagerProxy.kt
new file mode 100644
index 0000000..f542434
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/BackupManagerProxy.kt
@@ -0,0 +1,17 @@
+package com.android.systemui.util
+
+import android.app.backup.BackupManager
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** Wrapper around [BackupManager] useful for testing. */
+@SysUISingleton
+class BackupManagerProxy @Inject constructor() {
+
+    /** Wrapped version of [BackupManager.dataChanged] */
+    fun dataChanged(packageName: String) = BackupManager.dataChanged(packageName)
+
+    /** Wrapped version of [BackupManager.dataChangedForUser] */
+    fun dataChangedForUser(userId: Int, packageName: String) =
+        BackupManager.dataChangedForUser(userId, packageName)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java b/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java
new file mode 100644
index 0000000..b41bca0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/condition/ConditionalCoreStartable.java
@@ -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.util.condition;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.shared.condition.Condition;
+import com.android.systemui.shared.condition.Monitor;
+
+import java.util.Set;
+
+/**
+ * {@link ConditionalCoreStartable} is a {@link com.android.systemui.CoreStartable} abstract
+ * implementation where conditions must be met before routines are executed.
+ */
+public abstract class ConditionalCoreStartable implements CoreStartable {
+    private final Monitor mMonitor;
+    private final Set<Condition> mConditionSet;
+    private Monitor.Subscription.Token mStartToken;
+    private Monitor.Subscription.Token mBootCompletedToken;
+
+    public ConditionalCoreStartable(Monitor monitor) {
+        this(monitor, null);
+    }
+
+    public ConditionalCoreStartable(Monitor monitor, Set<Condition> conditionSet) {
+        mMonitor = monitor;
+        mConditionSet = conditionSet;
+    }
+
+    @Override
+    public final void start() {
+        if (mConditionSet == null || mConditionSet.isEmpty()) {
+            onStart();
+            return;
+        }
+
+        mStartToken = mMonitor.addSubscription(
+                new Monitor.Subscription.Builder(allConditionsMet -> {
+                    if (allConditionsMet) {
+                        mMonitor.removeSubscription(mStartToken);
+                        mStartToken = null;
+                        onStart();
+                    }
+                }).addConditions(mConditionSet)
+                        .build());
+    }
+
+    protected abstract void onStart();
+
+    @Override
+    public final void onBootCompleted() {
+        if (mConditionSet == null || mConditionSet.isEmpty()) {
+            bootCompleted();
+            return;
+        }
+
+        mBootCompletedToken = mMonitor.addSubscription(
+                new Monitor.Subscription.Builder(allConditionsMet -> {
+                    if (allConditionsMet) {
+                        mMonitor.removeSubscription(mBootCompletedToken);
+                        mBootCompletedToken = null;
+                        bootCompleted();
+                    }
+                }).addConditions(mConditionSet)
+                        .build());
+    }
+
+    protected void bootCompleted() {
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 0f9ae39..559423b 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1244,13 +1244,13 @@
             rescheduleTimeoutH();
         }
 
-        if (mODICaptionsTooltipView != null) {
-            mODICaptionsTooltipView.setAlpha(0.0f);
+        // We need to wait for layout and then center the caption view. Since the height of the
+        // dialog is now dynamic (with the variable ringer drawer height changing the height of
+        // the dialog), we need to do this here in code vs. in XML.
+        mHandler.post(() -> {
+            if (mODICaptionsTooltipView != null) {
+                mODICaptionsTooltipView.setAlpha(0.0f);
 
-            // We need to wait for layout and then center the caption view. Since the height of the
-            // dialog is now dynamic (with the variable ringer drawer height changing the height of
-            // the dialog), we need to do this here in code vs. in XML.
-            mHandler.post(() -> {
                 final int[] odiTooltipLocation = mODICaptionsTooltipView.getLocationOnScreen();
                 final int[] odiButtonLocation = mODICaptionsIcon.getLocationOnScreen();
 
@@ -1276,8 +1276,8 @@
                             }
                         })
                         .start();
-            });
-        }
+            }
+        });
     }
 
     private void hideCaptionsTooltip() {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index 5d896cb..0dae918 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -25,6 +25,7 @@
 import static android.service.notification.NotificationStats.DISMISSAL_BUBBLE;
 import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
 
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING;
 import static com.android.systemui.flags.Flags.WM_BUBBLE_BAR;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
@@ -50,6 +51,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.flags.FeatureFlags;
@@ -617,11 +619,22 @@
     }
 
     static BubbleEntry notifToBubbleEntry(NotificationEntry e) {
-        return new BubbleEntry(e.getSbn(), e.getRanking(), e.isDismissable(),
+        return new BubbleEntry(e.getSbn(), e.getRanking(), isDismissableFromBubbles(e),
                 e.shouldSuppressNotificationDot(), e.shouldSuppressNotificationList(),
                 e.shouldSuppressPeek());
     }
 
+    private static boolean isDismissableFromBubbles(NotificationEntry e) {
+        // TODO(b/268380968): inject FlagResolver
+        if (SystemUiSystemPropertiesFlags.getResolver().isEnabled(ALLOW_DISMISS_ONGOING)) {
+            // Bubbles are only accessible from the unlocked state,
+            // so we can calculate this from the Notification flags only.
+            return e.isDismissableForState(/*isLocked=*/ false);
+        } else {
+            return e.legacyIsDismissableRecursive();
+        }
+    }
+
     /**
      * Callback for when the BubbleController wants to interact with the notification pipeline to:
      * - Remove a previously bubbled notification
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 2c1e681..ed2772a 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -159,6 +159,12 @@
             android:enabled="false"
             tools:replace="android:authorities"
             android:grantUriPermissions="true" />
+
+        <activity
+            android:name="com.android.systemui.screenshot.appclips.AppClipsTrampolineActivityTest$AppClipsTrampolineActivityTestable"
+            android:exported="false"
+            android:permission="com.android.systemui.permission.SELF"
+            android:excludeFromRecents="true" />
     </application>
 
     <instrumentation android:name="android.testing.TestableInstrumentation"
diff --git a/packages/SystemUI/tests/res/layout/invalid_notification_height.xml b/packages/SystemUI/tests/res/layout/invalid_notification_height.xml
new file mode 100644
index 0000000..aac43bf
--- /dev/null
+++ b/packages/SystemUI/tests/res/layout/invalid_notification_height.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="5dp"/>
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index 39cc34b..e8d50ca 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -21,6 +21,8 @@
 import android.hardware.biometrics.BiometricFaceConstants
 import android.net.Uri
 import android.os.Handler
+import android.os.PowerManager
+import android.os.PowerManager.WAKE_REASON_BIOMETRIC
 import android.os.UserHandle
 import android.provider.Settings
 import androidx.test.filters.SmallTest
@@ -48,6 +50,8 @@
     private val fakeFaceErrorsUri = Uri.Builder().appendPath("face-errors").build()
     private val fakeFaceAcquiredUri = Uri.Builder().appendPath("face-acquired").build()
     private val fakeUnlockIntentBioEnroll = Uri.Builder().appendPath("unlock-intent-bio").build()
+    private val fakeWakeupsConsideredUnlockIntents =
+        Uri.Builder().appendPath("wakeups-considered-unlock-intent").build()
 
     @Mock
     private lateinit var secureSettings: SecureSettings
@@ -82,6 +86,9 @@
         `when`(secureSettings.getUriFor(
                 Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED))
                 .thenReturn(fakeUnlockIntentBioEnroll)
+        `when`(secureSettings.getUriFor(
+            Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
+            .thenReturn(fakeWakeupsConsideredUnlockIntents)
 
         activeUnlockConfig = ActiveUnlockConfig(
                 handler,
@@ -92,18 +99,18 @@
     }
 
     @Test
-    fun testRegsitersForSettingsChanges() {
+    fun registersForSettingsChanges() {
         verifyRegisterSettingObserver()
     }
 
     @Test
-    fun testOnWakeupSettingChanged() {
+    fun onWakeupSettingChanged() {
         verifyRegisterSettingObserver()
 
         // GIVEN no active unlock settings enabled
         assertFalse(
                 activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE)
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE)
         )
 
         // WHEN unlock on wake is allowed
@@ -114,26 +121,26 @@
         // THEN active unlock triggers allowed on: wake, unlock-intent, and biometric failure
         assertTrue(
                 activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE)
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE)
         )
         assertTrue(
                 activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT)
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT)
         )
         assertTrue(
                 activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL)
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL)
         )
     }
 
     @Test
-    fun testOnUnlockIntentSettingChanged() {
+    fun onUnlockIntentSettingChanged() {
         verifyRegisterSettingObserver()
 
         // GIVEN no active unlock settings enabled
         assertFalse(
                 activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                        ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT)
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT)
         )
 
         // WHEN unlock on biometric failed is allowed
@@ -143,15 +150,15 @@
 
         // THEN active unlock triggers allowed on: biometric failure ONLY
         assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE))
         assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT))
         assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
     }
 
     @Test
-    fun testOnBioFailSettingChanged() {
+    fun onBioFailSettingChanged() {
         verifyRegisterSettingObserver()
 
         // GIVEN no active unlock settings enabled and triggering unlock intent on biometric
@@ -161,7 +168,7 @@
                 0)).thenReturn("")
         updateSetting(fakeUnlockIntentBioEnroll)
         assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
 
         // WHEN unlock on biometric failed is allowed
         `when`(secureSettings.getIntForUser(Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
@@ -170,15 +177,15 @@
 
         // THEN active unlock triggers allowed on: biometric failure ONLY
         assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE))
         assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT))
         assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
     }
 
     @Test
-    fun testFaceErrorSettingsChanged() {
+    fun faceErrorSettingsChanged() {
         verifyRegisterSettingObserver()
 
         // GIVEN unlock on biometric fail
@@ -200,7 +207,7 @@
     }
 
     @Test
-    fun testFaceAcquiredSettingsChanged() {
+    fun faceAcquiredSettingsChanged() {
         verifyRegisterSettingObserver()
 
         // GIVEN unlock on biometric fail
@@ -228,7 +235,7 @@
     }
 
     @Test
-    fun testTriggerOnUnlockIntentWhenBiometricEnrolledNone() {
+    fun triggerOnUnlockIntentWhenBiometricEnrolledNone() {
         verifyRegisterSettingObserver()
 
         // GIVEN unlock on biometric fail
@@ -244,16 +251,16 @@
         // WHEN unlock intent is allowed when NO biometrics are enrolled (0)
         `when`(secureSettings.getStringForUser(
                 Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
-                0)).thenReturn("${ActiveUnlockConfig.BIOMETRIC_TYPE_NONE}")
+                0)).thenReturn("${ActiveUnlockConfig.BiometricType.NONE.intValue}")
         updateSetting(fakeUnlockIntentBioEnroll)
 
         // THEN active unlock triggers allowed on unlock intent
         assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT))
     }
 
     @Test
-    fun testTriggerOnUnlockIntentWhenBiometricEnrolledFingerprintOrFaceOnly() {
+    fun triggerOnUnlockIntentWhenBiometricEnrolledFingerprintOrFaceOnly() {
         verifyRegisterSettingObserver()
 
         // GIVEN unlock on biometric fail
@@ -263,7 +270,7 @@
 
         // GIVEN fingerprint and face are both enrolled
         activeUnlockConfig.keyguardUpdateMonitor = keyguardUpdateMonitor
-        `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true)
+        `when`(keyguardUpdateMonitor.isFaceEnrolled).thenReturn(true)
         `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(true)
 
         // WHEN unlock intent is allowed when ONLY fingerprint is enrolled or NO biometircs
@@ -271,29 +278,99 @@
         `when`(secureSettings.getStringForUser(
                 Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
                 0)).thenReturn(
-                "${ActiveUnlockConfig.BIOMETRIC_TYPE_ANY_FACE}" +
-                        "|${ActiveUnlockConfig.BIOMETRIC_TYPE_ANY_FINGERPRINT}")
+                "${ActiveUnlockConfig.BiometricType.ANY_FACE.intValue}" +
+                        "|${ActiveUnlockConfig.BiometricType.ANY_FINGERPRINT.intValue}")
         updateSetting(fakeUnlockIntentBioEnroll)
 
         // THEN active unlock triggers NOT allowed on unlock intent
         assertFalse(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT))
 
         // WHEN fingerprint ONLY enrolled
-        `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(false)
+        `when`(keyguardUpdateMonitor.isFaceEnrolled).thenReturn(false)
         `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(true)
 
         // THEN active unlock triggers allowed on unlock intent
         assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT))
 
         // WHEN face ONLY enrolled
-        `when`(keyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true)
+        `when`(keyguardUpdateMonitor.isFaceEnrolled).thenReturn(true)
         `when`(keyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(0)).thenReturn(false)
 
         // THEN active unlock triggers allowed on unlock intent
         assertTrue(activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.UNLOCK_INTENT))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT))
+    }
+
+    @Test
+    fun isWakeupConsideredUnlockIntent_singleValue() {
+        verifyRegisterSettingObserver()
+
+        // GIVEN lift is considered an unlock intent
+        `when`(secureSettings.getStringForUser(
+            Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
+            0)).thenReturn(PowerManager.WAKE_REASON_LIFT.toString())
+        updateSetting(fakeWakeupsConsideredUnlockIntents)
+
+        // THEN only WAKE_REASON_LIFT is considered an unlock intent
+        for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
+            if (wakeReason == PowerManager.WAKE_REASON_LIFT) {
+                assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
+            } else {
+                assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
+            }
+        }
+    }
+
+    @Test
+    fun isWakeupConsideredUnlockIntent_multiValue() {
+        verifyRegisterSettingObserver()
+
+        // GIVEN lift and tap are considered an unlock intent
+        `when`(secureSettings.getStringForUser(
+            Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
+            0)).thenReturn(
+            PowerManager.WAKE_REASON_LIFT.toString() +
+                    "|" +
+                    PowerManager.WAKE_REASON_TAP.toString()
+        )
+        updateSetting(fakeWakeupsConsideredUnlockIntents)
+
+        // THEN WAKE_REASON_LIFT and WAKE_REASON TAP are considered an unlock intent
+        for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
+            if (wakeReason == PowerManager.WAKE_REASON_LIFT ||
+                wakeReason == PowerManager.WAKE_REASON_TAP) {
+                assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
+            } else {
+                assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
+            }
+        }
+        assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_LIFT))
+        assertTrue(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP))
+        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(
+            PowerManager.WAKE_REASON_UNFOLD_DEVICE))
+    }
+
+    @Test
+    fun isWakeupConsideredUnlockIntent_emptyValues() {
+        verifyRegisterSettingObserver()
+
+        // GIVEN lift and tap are considered an unlock intent
+        `when`(secureSettings.getStringForUser(
+            Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
+            0)).thenReturn(" ")
+        updateSetting(fakeWakeupsConsideredUnlockIntents)
+
+        // THEN no wake up gestures are considered an unlock intent
+        for (wakeReason in 0..WAKE_REASON_BIOMETRIC) {
+            assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason))
+        }
+        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(
+            PowerManager.WAKE_REASON_LIFT))
+        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(PowerManager.WAKE_REASON_TAP))
+        assertFalse(activeUnlockConfig.isWakeupConsideredUnlockIntent(
+            PowerManager.WAKE_REASON_UNFOLD_DEVICE))
     }
 
     private fun updateSetting(uri: Uri) {
@@ -312,6 +389,7 @@
         verifyRegisterSettingObserver(fakeFaceErrorsUri)
         verifyRegisterSettingObserver(fakeFaceAcquiredUri)
         verifyRegisterSettingObserver(fakeUnlockIntentBioEnroll)
+        verifyRegisterSettingObserver(fakeWakeupsConsideredUnlockIntents)
     }
 
     private fun verifyRegisterSettingObserver(uri: Uri) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 43a2017..f7fec80 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -58,7 +58,7 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
-import java.util.*
+import java.util.TimeZone
 import java.util.concurrent.Executor
 import org.mockito.Mockito.`when` as whenever
 
@@ -105,7 +105,9 @@
         repository = FakeKeyguardRepository()
 
         underTest = ClockEventController(
-            KeyguardInteractor(repository = repository, commandQueue = commandQueue),
+            KeyguardInteractor(repository = repository,
+                    commandQueue = commandQueue,
+                    featureFlags = featureFlags),
             KeyguardTransitionInteractor(repository = transitionRepository),
             broadcastDispatcher,
             batteryController,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index 36b3f89..ccc4e4a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -300,8 +300,9 @@
         ArgumentCaptor<ContentObserver> observerCaptor =
                 ArgumentCaptor.forClass(ContentObserver.class);
         mController.init();
-        verify(mSecureSettings).registerContentObserverForUser(any(String.class),
-                anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL));
+        verify(mSecureSettings).registerContentObserverForUser(
+                eq(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK),
+                    anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL));
         ContentObserver observer = observerCaptor.getValue();
         mExecutor.runAllReady();
 
@@ -347,6 +348,22 @@
         assertEquals(0, mController.getClockBottom(10));
     }
 
+    @Test
+    public void testChangeLockscreenWeatherEnabledSetsWeatherViewVisible() {
+        when(mSmartspaceController.isWeatherEnabled()).thenReturn(true);
+        ArgumentCaptor<ContentObserver> observerCaptor =
+                ArgumentCaptor.forClass(ContentObserver.class);
+        mController.init();
+        verify(mSecureSettings).registerContentObserverForUser(
+                eq(Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED), anyBoolean(),
+                    observerCaptor.capture(), eq(UserHandle.USER_ALL));
+        ContentObserver observer = observerCaptor.getValue();
+        mExecutor.runAllReady();
+        // When a settings change has occurred, check that view is visible.
+        observer.onChange(true);
+        mExecutor.runAllReady();
+        assertEquals(View.VISIBLE, mFakeWeatherView.getVisibility());
+    }
 
     private void verifyAttachment(VerificationMode times) {
         verify(mClockRegistry, times).registerClockChangeListener(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 8dc1e8f..254f953 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -16,7 +16,6 @@
 
 package com.android.keyguard;
 
-import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
@@ -190,7 +189,6 @@
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
         assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
         assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
-        assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
@@ -200,7 +198,6 @@
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
         assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
         assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
-        assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
@@ -215,7 +212,6 @@
         // only big clock is removed at switch
         assertThat(mLargeClockFrame.getParent()).isNull();
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
-        assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
@@ -227,7 +223,6 @@
         // only big clock is removed at switch
         assertThat(mLargeClockFrame.getParent()).isNull();
         assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
-        assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index d912793..082c8cc 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -134,4 +134,10 @@
     keyguardPasswordViewController.startAppearAnimation()
     verify(mKeyguardMessageAreaController, never()).setMessage(anyString(), anyBoolean())
   }
+
+  @Test
+  fun testMessageIsSetWhenReset() {
+    keyguardPasswordViewController.resetState()
+    verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_password)
+  }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index b742100..0881e61 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -120,4 +120,10 @@
     public void testGetInitialMessageResId() {
         assertThat(mKeyguardPinViewController.getInitialMessageResId()).isNotEqualTo(0);
     }
+
+    @Test
+    public void testMessageIsSetWhenReset() {
+        mKeyguardPinViewController.resetState();
+        verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pin);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
index cdb7bbb..a1af8e8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
@@ -27,11 +27,14 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.classifier.FalsingCollectorFake
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.statusbar.policy.DevicePostureController
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Mock
 import org.mockito.Mockito
@@ -71,6 +74,11 @@
     private val falsingCollector: FalsingCollector = FalsingCollectorFake()
     @Mock lateinit var postureController: DevicePostureController
 
+    @Mock lateinit var featureFlags: FeatureFlags
+    @Mock lateinit var passwordTextView: PasswordTextView
+    @Mock lateinit var deleteButton: NumPadButton
+    @Mock lateinit var enterButton: View
+
     lateinit var pinViewController: KeyguardPinViewController
 
     @Before
@@ -82,7 +90,13 @@
                 keyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea::class.java))
             )
             .thenReturn(keyguardMessageAreaController)
+        `when`(keyguardPinView.passwordTextViewId).thenReturn(R.id.pinEntry)
+        `when`(keyguardPinView.findViewById<PasswordTextView>(R.id.pinEntry))
+            .thenReturn(passwordTextView)
         `when`(keyguardPinView.resources).thenReturn(context.resources)
+        `when`(keyguardPinView.findViewById<NumPadButton>(R.id.delete_button))
+            .thenReturn(deleteButton)
+        `when`(keyguardPinView.findViewById<View>(R.id.key_enter)).thenReturn(enterButton)
         pinViewController =
             KeyguardPinViewController(
                 keyguardPinView,
@@ -95,7 +109,8 @@
                 liftToActivateListener,
                 mEmergencyButtonController,
                 falsingCollector,
-                postureController
+                postureController,
+                featureFlags
             )
     }
 
@@ -112,4 +127,18 @@
         pinViewController.startAppearAnimation()
         verify(keyguardMessageAreaController, Mockito.never()).setMessage(anyString(), anyBoolean())
     }
+
+    @Test
+    fun startAppearAnimation_withAutoPinConfirmation() {
+        `when`(featureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)).thenReturn(true)
+        `when`(lockPatternUtils.getPinLength(anyInt())).thenReturn(6)
+        `when`(lockPatternUtils.isAutoPinConfirmEnabled(anyInt())).thenReturn(true)
+        `when`(passwordTextView.text).thenReturn("")
+
+        pinViewController.startAppearAnimation()
+        verify(deleteButton).visibility = View.INVISIBLE
+        verify(enterButton).visibility = View.INVISIBLE
+        verify(passwordTextView).setUsePinShapes(true)
+        verify(passwordTextView).setIsPinHinting(true)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 075ef9d..7b0d091d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -583,6 +583,8 @@
         verify(mKeyguardSecurityViewFlipperController).clearViews();
         verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class),
                 any(KeyguardSecurityCallback.class));
+        verify(mView).reset();
+        verify(mKeyguardSecurityViewFlipperController).reset();
     }
 
     @Test
@@ -600,6 +602,14 @@
                 any(KeyguardSecurityCallback.class));
     }
 
+    @Test
+    public void testReinflateViewFlipper() {
+        mKeyguardSecurityContainerController.reinflateViewFlipper();
+        verify(mKeyguardSecurityViewFlipperController).clearViews();
+        verify(mKeyguardSecurityViewFlipperController).getSecurityView(any(SecurityMode.class),
+                any(KeyguardSecurityCallback.class));
+    }
+
     private KeyguardSecurityContainer.SwipeListener getRegisteredSwipeListener() {
         mKeyguardSecurityContainerController.onViewAttached();
         verify(mView).setSwipeListener(mSwipeListenerArgumentCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 4d95a22..4110b5a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -28,6 +28,7 @@
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 import static com.android.keyguard.FaceAuthApiRequestReason.NOTIFICATION_PANEL_CLICKED;
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_STATE_CANCELLING_RESTARTING;
 import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
 import static com.android.keyguard.KeyguardUpdateMonitor.HAL_POWER_PRESS_TIMEOUT;
@@ -241,7 +242,7 @@
     @Mock
     private FingerprintInteractiveToAuthProvider mInteractiveToAuthProvider;
 
-
+    private List<FingerprintSensorPropertiesInternal> mFingerprintSensorProperties;
     private final int mCurrentUserId = 100;
     private final UserInfo mCurrentUserInfo = new UserInfo(mCurrentUserId, "Test user", 0);
 
@@ -280,9 +281,7 @@
         when(mFaceSensorProperties.get(anyInt())).thenReturn(
                 createFaceSensorProperties(/* supportsFaceDetection = */ false));
 
-        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
-        when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
-        when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(List.of(
+        mFingerprintSensorProperties = List.of(
                 new FingerprintSensorPropertiesInternal(1 /* sensorId */,
                         FingerprintSensorProperties.STRENGTH_STRONG,
                         1 /* maxEnrollmentsPerUser */,
@@ -291,7 +290,11 @@
                                 "1.01" /* firmwareVersion */,
                                 "00000001" /* serialNumber */, "" /* softwareVersion */)),
                         FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
-                        false /* resetLockoutRequiresHAT */)));
+                        false /* resetLockoutRequiresHAT */));
+        when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+        when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
+        when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(
+                mFingerprintSensorProperties);
         when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
         when(mUserManager.isPrimaryUser()).thenReturn(true);
         when(mStrongAuthTracker.getStub()).thenReturn(mock(IStrongAuthTracker.Stub.class));
@@ -685,12 +688,36 @@
         // WHEN fingerprint is locked out
         fingerprintErrorLockedOut();
 
-        // THEN unlocking with fingeprint is not allowed
+        // THEN unlocking with fingerprint is not allowed
         Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
                 BiometricSourceType.FINGERPRINT));
     }
 
     @Test
+    public void trustAgentHasTrust() {
+        // WHEN user has trust
+        mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null);
+
+        // THEN user is considered as "having trust" and bouncer can be skipped
+        Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
+        Assert.assertTrue(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()));
+    }
+
+    @Test
+    public void trustAgentHasTrust_fingerprintLockout() {
+        // GIVEN user has trust
+        mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null);
+        Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
+
+        // WHEN fingerprint is locked out
+        fingerprintErrorLockedOut();
+
+        // THEN user is NOT considered as "having trust" and bouncer cannot be skipped
+        Assert.assertFalse(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
+        Assert.assertFalse(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()));
+    }
+
+    @Test
     public void testTriesToAuthenticate_whenBouncer() {
         setKeyguardBouncerVisibility(true);
 
@@ -745,12 +772,43 @@
     }
 
     @Test
+    public void nofaceDetect_whenStrongAuthRequiredAndBypassUdfpsSupportedAndFpRunning() {
+        // GIVEN mocked keyguardUpdateMonitorCallback
+        KeyguardUpdateMonitorCallback keyguardUpdateMonitorCallback =
+                mock(KeyguardUpdateMonitorCallback.class);
+        mKeyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback);
+
+        // GIVEN bypass is enabled, face detection is supported
+        lockscreenBypassIsAllowed();
+        supportsFaceDetection();
+        keyguardIsVisible();
+
+        // GIVEN udfps is supported and strong auth required for weak biometrics (face) only
+        givenUdfpsSupported();
+        strongAuthRequiredForWeakBiometricOnly(); // this allows fingerprint to run but not face
+
+        // WHEN the device wakes up
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+        mTestableLooper.processAllMessages();
+
+        // THEN face detect and authenticate are NOT triggered
+        verify(mFaceManager, never()).detectFace(any(), any(), anyInt());
+        verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+                anyBoolean());
+
+        // THEN biometric help message sent to callback
+        verify(keyguardUpdateMonitorCallback).onBiometricHelp(
+                eq(BIOMETRIC_HELP_FACE_NOT_AVAILABLE), anyString(), eq(BiometricSourceType.FACE));
+    }
+
+    @Test
     public void faceDetect_whenStrongAuthRequiredAndBypass() {
         // GIVEN bypass is enabled, face detection is supported and strong auth is required
         lockscreenBypassIsAllowed();
         supportsFaceDetection();
         strongAuthRequiredEncrypted();
         keyguardIsVisible();
+        // fingerprint is NOT running, UDFPS is NOT supported
 
         // WHEN the device wakes up
         mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
@@ -1708,7 +1766,7 @@
     }
 
     @Test
-    public void testShouldListenForFace_whenOccludingAppRequestsFaceAuth_returnsTrue()
+    public void shouldListenForFace_secureCameraLaunchedButAlternateBouncerIsLaunched_returnsTrue()
             throws RemoteException {
         // Face auth should run when the following is true.
         keyguardNotGoingAway();
@@ -1724,7 +1782,7 @@
 
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
 
-        occludingAppRequestsFaceAuth();
+        alternateBouncerVisible();
         mTestableLooper.processAllMessages();
 
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
@@ -1814,7 +1872,7 @@
     }
 
     @Test
-    public void testShouldListenForFace_whenUdfpsBouncerIsShowing_returnsTrue()
+    public void testShouldListenForFace_whenAlternateBouncerIsShowing_returnsTrue()
             throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
@@ -1826,13 +1884,13 @@
         mTestableLooper.processAllMessages();
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
 
-        mKeyguardUpdateMonitor.setUdfpsBouncerShowing(true);
+        mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
 
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
     }
 
     @Test
-    public void testShouldListenForFace_udfpsBouncerIsShowingButDeviceGoingToSleep_returnsFalse()
+    public void testShouldListenForFace_alternateBouncerShowingButDeviceGoingToSleep_returnsFalse()
             throws RemoteException {
         // Preconditions for face auth to run
         keyguardNotGoingAway();
@@ -1842,7 +1900,7 @@
         biometricsEnabledForCurrentUser();
         userNotCurrentlySwitching();
         deviceNotGoingToSleep();
-        mKeyguardUpdateMonitor.setUdfpsBouncerShowing(true);
+        alternateBouncerVisible();
         mTestableLooper.processAllMessages();
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
 
@@ -1852,6 +1910,10 @@
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isFalse();
     }
 
+    private void alternateBouncerVisible() {
+        mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
+    }
+
     @Test
     public void testShouldListenForFace_whenFaceIsLockedOut_returnsTrue()
             throws RemoteException {
@@ -1862,7 +1924,7 @@
         biometricsNotDisabledThroughDevicePolicyManager();
         biometricsEnabledForCurrentUser();
         userNotCurrentlySwitching();
-        mKeyguardUpdateMonitor.setUdfpsBouncerShowing(true);
+        mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
         mTestableLooper.processAllMessages();
         assertThat(mKeyguardUpdateMonitor.shouldListenForFace()).isTrue();
 
@@ -2182,7 +2244,7 @@
 
         // GIVEN active unlock triggers on biometric failures
         when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
                 .thenReturn(true);
 
         // WHEN fingerprint fails
@@ -2205,7 +2267,7 @@
 
         // GIVEN active unlock triggers on biometric failures
         when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
                 .thenReturn(true);
 
         // WHEN face fails & bypass is not allowed
@@ -2229,7 +2291,7 @@
 
         // GIVEN active unlock triggers on biometric failures
         when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
                 .thenReturn(true);
 
         // WHEN face fails & bypass is not allowed
@@ -2251,7 +2313,7 @@
 
         // GIVEN active unlock triggers on biometric failures
         when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.BIOMETRIC_FAIL))
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL))
                 .thenReturn(true);
 
         // WHEN face fails & on the bouncer
@@ -2441,6 +2503,11 @@
         when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
     }
 
+    private void strongAuthRequiredForWeakBiometricOnly() {
+        when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(eq(true))).thenReturn(true);
+        when(mStrongAuthTracker.isUnlockingWithBiometricAllowed(eq(false))).thenReturn(false);
+    }
+
     private void strongAuthNotRequired() {
         when(mStrongAuthTracker.getStrongAuthForUser(KeyguardUpdateMonitor.getCurrentUser()))
                 .thenReturn(0);
@@ -2495,6 +2562,12 @@
         mTestableLooper.processAllMessages();
     }
 
+    private void givenUdfpsSupported() {
+        Assert.assertFalse(mFingerprintSensorProperties.isEmpty());
+        when(mAuthController.getUdfpsProps()).thenReturn(mFingerprintSensorProperties);
+        Assert.assertTrue(mKeyguardUpdateMonitor.isUdfpsSupported());
+    }
+
     private void setBroadcastReceiverPendingResult(BroadcastReceiver receiver) {
         BroadcastReceiver.PendingResult pendingResult =
                 new BroadcastReceiver.PendingResult(Activity.RESULT_OK,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 05bd1e4..3d0d036 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -159,7 +159,9 @@
                 mAuthRippleController,
                 mResources,
                 new KeyguardTransitionInteractor(mTransitionRepository),
-                new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue),
+                new KeyguardInteractor(new FakeKeyguardRepository(),
+                        mCommandQueue,
+                        mFeatureFlags),
                 mFeatureFlags
         );
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
new file mode 100644
index 0000000..42e12df
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class PinShapeHintingViewTest : SysuiTestCase() {
+    lateinit var underTest: PinShapeHintingView
+
+    @Before
+    fun setup() {
+        underTest =
+            LayoutInflater.from(context).inflate(R.layout.keyguard_pin_shape_hinting_view, null)
+                as PinShapeHintingView
+    }
+
+    @Test
+    fun testAppend() {
+        // Add more when animation part is complete
+        underTest.append()
+        Truth.assertThat(underTest.childCount).isEqualTo(6)
+    }
+
+    @Test
+    fun testDelete() {
+        underTest.delete()
+        Truth.assertThat(underTest.childCount).isEqualTo(6)
+    }
+
+    @Test
+    fun testReset() {
+        for (i in 0 until 3) {
+            underTest.append()
+        }
+        underTest.reset()
+        Truth.assertThat(underTest.childCount).isEqualTo(6)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
new file mode 100644
index 0000000..c04fd39
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class PinShapeNonHintingViewTest : SysuiTestCase() {
+    lateinit var underTest: PinShapeNonHintingView
+
+    @Before
+    fun setup() {
+        underTest =
+            LayoutInflater.from(context).inflate(R.layout.keyguard_pin_shape_non_hinting_view, null)
+                as PinShapeNonHintingView
+    }
+
+    @Test
+    fun testAppend() {
+        // Add more when animation part is complete
+        underTest.append()
+        Truth.assertThat(underTest.childCount).isEqualTo(1)
+    }
+
+    @Test
+    fun testDelete() {
+        for (i in 0 until 3) {
+            underTest.append()
+        }
+        underTest.delete()
+
+        underTest.postDelayed(
+            { Truth.assertThat(underTest.childCount).isEqualTo(2) },
+            PasswordTextView.DISAPPEAR_DURATION + 100L
+        )
+    }
+
+    @Test
+    fun testReset() {
+        for (i in 0 until 3) {
+            underTest.append()
+        }
+        underTest.reset()
+        underTest.postDelayed(
+            { Truth.assertThat(underTest.childCount).isEqualTo(0) },
+            PasswordTextView.DISAPPEAR_DURATION + 100L
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
index 32edf8f..babbe45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
@@ -11,6 +11,7 @@
 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
@@ -102,7 +103,7 @@
     @Test
     fun initialize_enablesUnbundledChooser_whenFlagEnabled() {
         // Arrange
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true)
+        setFlagMock(true)
 
         // Act
         chooserSelector.start()
@@ -118,7 +119,7 @@
     @Test
     fun initialize_disablesUnbundledChooser_whenFlagDisabled() {
         // Arrange
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+        setFlagMock(false)
 
         // Act
         chooserSelector.start()
@@ -134,7 +135,7 @@
     @Test
     fun enablesUnbundledChooser_whenFlagBecomesEnabled() {
         // Arrange
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+        setFlagMock(false)
         chooserSelector.start()
         verify(mockFeatureFlags).addListener(
                 eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
@@ -147,7 +148,7 @@
         )
 
         // Act
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true)
+        setFlagMock(true)
         flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name))
 
         // Assert
@@ -161,7 +162,7 @@
     @Test
     fun disablesUnbundledChooser_whenFlagBecomesDisabled() {
         // Arrange
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true)
+        setFlagMock(true)
         chooserSelector.start()
         verify(mockFeatureFlags).addListener(
                 eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
@@ -174,7 +175,7 @@
         )
 
         // Act
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+        setFlagMock(false)
         flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.name))
 
         // Assert
@@ -188,7 +189,7 @@
     @Test
     fun doesNothing_whenAnotherFlagChanges() {
         // Arrange
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+        setFlagMock(false)
         chooserSelector.start()
         verify(mockFeatureFlags).addListener(
                 eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED),
@@ -197,13 +198,17 @@
         clearInvocations(mockPackageManager)
 
         // Act
-        whenever(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
         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/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index fc11148..4cf5a4b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -34,8 +34,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -104,8 +106,12 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -119,7 +125,7 @@
     private WindowManager mWindowManager;
     private DisplayManager mDisplayManager;
     private SecureSettings mSecureSettings;
-    private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+    private FakeExecutor mExecutor;
     private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
     private FakeThreadFactory mThreadFactory;
     private ArrayList<DecorProvider> mPrivacyDecorProviders;
@@ -161,6 +167,8 @@
     private PrivacyDotViewController.ShowingListener mPrivacyDotShowingListener;
     @Mock
     private CutoutDecorProviderFactory mCutoutFactory;
+    @Captor
+    private ArgumentCaptor<AuthController.Callback> mAuthControllerCallback;
     private List<DecorProvider> mMockCutoutList;
 
     @Before
@@ -169,6 +177,7 @@
 
         Handler mainHandler = new Handler(TestableLooper.get(this).getLooper());
         mSecureSettings = new FakeSettings();
+        mExecutor = new FakeExecutor(new FakeSystemClock());
         mThreadFactory = new FakeThreadFactory(mExecutor);
         mThreadFactory.setHandler(mainHandler);
 
@@ -1166,6 +1175,44 @@
     }
 
     @Test
+    public void faceSensorLocationChangesReloadsFaceScanningOverlay() {
+        mFaceScanningProviders = new ArrayList<>();
+        mFaceScanningProviders.add(mFaceScanningDecorProvider);
+        when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders);
+        when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(true);
+        ScreenDecorations screenDecorations = new ScreenDecorations(mContext, mExecutor,
+                mSecureSettings, mTunerService, mUserTracker, mDisplayTracker, mDotViewController,
+                mThreadFactory, mPrivacyDotDecorProviderFactory, mFaceScanningProviderFactory,
+                new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")), mAuthController);
+        screenDecorations.start();
+        verify(mAuthController).addCallback(mAuthControllerCallback.capture());
+        when(mContext.getDisplay()).thenReturn(mDisplay);
+        when(mDisplay.getDisplayInfo(any())).thenAnswer(new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                DisplayInfo displayInfo = invocation.getArgument(0);
+                int modeId = 1;
+                displayInfo.modeId = modeId;
+                displayInfo.supportedModes = new Display.Mode[]{new Display.Mode(modeId, 1024, 1024,
+                        90)};
+                return false;
+            }
+        });
+        mExecutor.runAllReady();
+        clearInvocations(mFaceScanningDecorProvider);
+
+        AuthController.Callback callback = mAuthControllerCallback.getValue();
+        callback.onFaceSensorLocationChanged();
+        mExecutor.runAllReady();
+
+        verify(mFaceScanningDecorProvider).onReloadResAndMeasure(any(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                any());
+    }
+
+    @Test
     public void testPrivacyDotShowingListenerWorkWellWithNullParameter() {
         mPrivacyDotShowingListener.onPrivacyDotShown(null);
         mPrivacyDotShowingListener.onPrivacyDotHidden(null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index 728ea1e..5bb5e01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -165,14 +165,14 @@
     }
 
     @Test
-    public void tiggerDismissMenuAction_hideFloatingMenu() {
+    public void triggerDismissMenuAction_hideFloatingMenu() {
         mMenuViewLayer.mDismissMenuAction.run();
 
         verify(mFloatingMenu).hide();
     }
 
     @Test
-    public void tiggerDismissMenuAction_matchA11yButtonTargetsResult() {
+    public void triggerDismissMenuAction_matchA11yButtonTargetsResult() {
         mMenuViewLayer.mDismissMenuAction.run();
         verify(mSecureSettings).putStringForUser(
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "",
@@ -180,24 +180,8 @@
     }
 
     @Test
-    public void tiggerDismissMenuAction_matchEnabledA11yServicesResult() {
-        Settings.Secure.putString(mContext.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
-        final ResolveInfo resolveInfo = new ResolveInfo();
-        final ServiceInfo serviceInfo = new ServiceInfo();
-        final ApplicationInfo applicationInfo = new ApplicationInfo();
-        resolveInfo.serviceInfo = serviceInfo;
-        serviceInfo.applicationInfo = applicationInfo;
-        applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
-        final AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
-        accessibilityServiceInfo.setResolveInfo(resolveInfo);
-        accessibilityServiceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
-        final List<AccessibilityServiceInfo> serviceInfoList = new ArrayList<>();
-        accessibilityServiceInfo.setComponentName(TEST_SELECT_TO_SPEAK_COMPONENT_NAME);
-        serviceInfoList.add(accessibilityServiceInfo);
-        when(mStubAccessibilityManager.getEnabledAccessibilityServiceList(
-                AccessibilityServiceInfo.FEEDBACK_ALL_MASK)).thenReturn(serviceInfoList);
+    public void triggerDismissMenuAction_matchEnabledA11yServicesResult() {
+        setupEnabledAccessibilityServiceList();
 
         mMenuViewLayer.mDismissMenuAction.run();
         final String value = Settings.Secure.getString(mContext.getContentResolver(),
@@ -207,6 +191,21 @@
     }
 
     @Test
+    public void triggerDismissMenuAction_hasHardwareKeyShortcut_keepEnabledStatus() {
+        setupEnabledAccessibilityServiceList();
+        final List<String> stubShortcutTargets = new ArrayList<>();
+        stubShortcutTargets.add(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
+        when(mStubAccessibilityManager.getAccessibilityShortcutTargets(
+                AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY)).thenReturn(stubShortcutTargets);
+
+        mMenuViewLayer.mDismissMenuAction.run();
+        final String value = Settings.Secure.getString(mContext.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+
+        assertThat(value).isEqualTo(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
+    }
+
+    @Test
     public void showingImeInsetsChange_notOverlapOnIme_menuKeepOriginalPosition() {
         final float menuTop = STATUS_BAR_HEIGHT + 100;
         mMenuAnimationController.moveAndPersistPosition(new PointF(0, menuTop));
@@ -241,6 +240,27 @@
         assertThat(mMenuView.getTranslationY()).isEqualTo(menuTop);
     }
 
+    private void setupEnabledAccessibilityServiceList() {
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
+
+        final ResolveInfo resolveInfo = new ResolveInfo();
+        final ServiceInfo serviceInfo = new ServiceInfo();
+        final ApplicationInfo applicationInfo = new ApplicationInfo();
+        resolveInfo.serviceInfo = serviceInfo;
+        serviceInfo.applicationInfo = applicationInfo;
+        applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
+        final AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
+        accessibilityServiceInfo.setResolveInfo(resolveInfo);
+        accessibilityServiceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
+        final List<AccessibilityServiceInfo> serviceInfoList = new ArrayList<>();
+        accessibilityServiceInfo.setComponentName(TEST_SELECT_TO_SPEAK_COMPONENT_NAME);
+        serviceInfoList.add(accessibilityServiceInfo);
+        when(mStubAccessibilityManager.getEnabledAccessibilityServiceList(
+                AccessibilityServiceInfo.FEEDBACK_ALL_MASK)).thenReturn(serviceInfoList);
+    }
+
     private void dispatchShowingImeInsets() {
         final WindowInsets fakeShowingImeInsets = fakeImeInsets(/* isImeVisible= */ true);
         doReturn(fakeShowingImeInsets).when(mWindowMetrics).getWindowInsets();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
index 1e62fd23..316de59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
@@ -268,6 +268,12 @@
         }
     }
 
+    @Test
+    fun showFromDialogDoesNotCrashWhenShownFromRandomDialog() {
+        val dialog = createDialogAndShowFromDialog(animateFrom = TestDialog(context))
+        dialog.dismiss()
+    }
+
     private fun createAndShowDialog(
         animator: DialogLaunchAnimator = dialogLaunchAnimator,
     ): TestDialog {
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 5afe49e..0d00e8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -85,6 +85,7 @@
 import com.android.internal.R;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settingslib.udfps.UdfpsUtils;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.domain.interactor.BiometricPromptCredentialInteractor;
 import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
@@ -167,6 +168,8 @@
     private BiometricPromptCredentialInteractor mBiometricPromptCredentialInteractor;
     @Mock
     private CredentialViewModel mCredentialViewModel;
+    @Mock
+    private UdfpsUtils mUdfpsUtils;
 
     @Captor
     private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mFpAuthenticatorsRegisteredCaptor;
@@ -958,7 +961,7 @@
                     mPanelInteractionDetector, mUserManager, mLockPatternUtils, mUdfpsLogger,
                     mLogContextInteractor, () -> mBiometricPromptCredentialInteractor,
                     () -> mCredentialViewModel, mInteractionJankMonitor, mHandler,
-                    mBackgroundExecutor, mVibratorHelper);
+                    mBackgroundExecutor, mVibratorHelper, mUdfpsUtils);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 36ed6d5..bb037642 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -21,12 +21,9 @@
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_OTHER
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_ENROLLING
-import android.hardware.biometrics.BiometricOverlayConstants.REASON_ENROLL_FIND_SENSOR
 import android.hardware.biometrics.BiometricOverlayConstants.ShowReason
 import android.hardware.fingerprint.FingerprintManager
 import android.hardware.fingerprint.IUdfpsOverlayControllerCallback
-import android.provider.Settings
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.LayoutInflater
@@ -38,6 +35,8 @@
 import android.view.accessibility.AccessibilityManager
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.settingslib.udfps.UdfpsOverlayParams
+import com.android.settingslib.udfps.UdfpsUtils
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityLaunchAnimator
@@ -104,12 +103,12 @@
     @Mock private lateinit var controllerCallback: IUdfpsOverlayControllerCallback
     @Mock private lateinit var udfpsController: UdfpsController
     @Mock private lateinit var udfpsView: UdfpsView
-    @Mock private lateinit var udfpsEnrollView: UdfpsEnrollView
     @Mock private lateinit var udfpsKeyguardView: UdfpsKeyguardView
     @Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
     @Mock private lateinit var featureFlags: FeatureFlags
     @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
     @Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
+    @Mock private lateinit var udfpsUtils: UdfpsUtils
     @Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
 
     private val onTouch = { _: View, _: MotionEvent, _: Boolean -> true }
@@ -118,18 +117,14 @@
 
     @Before
     fun setup() {
-        context.orCreateTestableResources.addOverride(R.integer.config_udfpsEnrollProgressBar, 20)
         whenever(inflater.inflate(R.layout.udfps_view, null, false))
             .thenReturn(udfpsView)
-        whenever(inflater.inflate(R.layout.udfps_enroll_view, null))
-            .thenReturn(udfpsEnrollView)
         whenever(inflater.inflate(R.layout.udfps_bp_view, null))
             .thenReturn(mock(UdfpsBpView::class.java))
         whenever(inflater.inflate(R.layout.udfps_keyguard_view, null))
             .thenReturn(udfpsKeyguardView)
         whenever(inflater.inflate(R.layout.udfps_fpm_empty_view, null))
             .thenReturn(mock(UdfpsFpmEmptyView::class.java))
-        whenever(udfpsEnrollView.context).thenReturn(context)
     }
 
     private fun withReason(
@@ -144,7 +139,7 @@
             configurationController, keyguardStateController, unlockedScreenOffAnimationController,
             udfpsDisplayMode, secureSettings, REQUEST_ID, reason,
             controllerCallback, onTouch, activityLaunchAnimator, featureFlags,
-            primaryBouncerInteractor, alternateBouncerInteractor, isDebuggable
+            primaryBouncerInteractor, alternateBouncerInteractor, isDebuggable, udfpsUtils
         )
         block()
     }
@@ -159,37 +154,6 @@
     }
 
     @Test
-    fun showUdfpsOverlay_settings() = withReason(REASON_AUTH_SETTINGS) { showUdfpsOverlay() }
-
-    @Test
-    fun showUdfpsOverlay_locate() = withReason(REASON_ENROLL_FIND_SENSOR) {
-        showUdfpsOverlay(isEnrollUseCase = true)
-    }
-
-    @Test
-    fun showUdfpsOverlay_locate_withEnrollmentUiRemoved() {
-        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 1)
-        withReason(REASON_ENROLL_FIND_SENSOR, isDebuggable = true) {
-            showUdfpsOverlay(isEnrollUseCase = false)
-        }
-        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 0)
-    }
-
-    @Test
-    fun showUdfpsOverlay_enroll() = withReason(REASON_ENROLL_ENROLLING) {
-        showUdfpsOverlay(isEnrollUseCase = true)
-    }
-
-    @Test
-    fun showUdfpsOverlay_enroll_withEnrollmentUiRemoved() {
-        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 1)
-        withReason(REASON_ENROLL_ENROLLING, isDebuggable = true) {
-            showUdfpsOverlay(isEnrollUseCase = false)
-        }
-        Settings.Global.putInt(mContext.contentResolver, SETTING_REMOVE_ENROLLMENT_UI, 0)
-    }
-
-    @Test
     fun showUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { showUdfpsOverlay() }
 
     private fun withRotation(@Rotation rotation: Int, block: () -> Unit) {
@@ -278,7 +242,7 @@
         }
     }
 
-    private fun showUdfpsOverlay(isEnrollUseCase: Boolean = false) {
+    private fun showUdfpsOverlay() {
         val didShow = controllerOverlay.show(udfpsController, overlayParams)
 
         verify(windowManager).addView(eq(controllerOverlay.overlayView), any())
@@ -290,12 +254,6 @@
         assertThat(controllerOverlay.isShowing).isTrue()
         assertThat(controllerOverlay.isHiding).isFalse()
         assertThat(controllerOverlay.overlayView).isNotNull()
-        if (isEnrollUseCase) {
-            verify(udfpsEnrollView).updateSensorLocation(eq(overlayParams.sensorBounds))
-            assertThat(controllerOverlay.enrollHelper).isNotNull()
-        } else {
-            assertThat(controllerOverlay.enrollHelper).isNull()
-        }
     }
 
     @Test
@@ -308,12 +266,6 @@
     fun hideUdfpsOverlay_settings() = withReason(REASON_AUTH_SETTINGS) { hideUdfpsOverlay() }
 
     @Test
-    fun hideUdfpsOverlay_locate() = withReason(REASON_ENROLL_FIND_SENSOR) { hideUdfpsOverlay() }
-
-    @Test
-    fun hideUdfpsOverlay_enroll() = withReason(REASON_ENROLL_ENROLLING) { hideUdfpsOverlay() }
-
-    @Test
     fun hideUdfpsOverlay_other() = withReason(REASON_AUTH_OTHER) { hideUdfpsOverlay() }
 
     private fun hideUdfpsOverlay() {
@@ -343,44 +295,6 @@
     }
 
     @Test
-    fun forwardEnrollProgressEvents() = withReason(REASON_ENROLL_ENROLLING) {
-        controllerOverlay.show(udfpsController, overlayParams)
-
-        with(EnrollListener(controllerOverlay)) {
-            controllerOverlay.onEnrollmentProgress(/* remaining */20)
-            controllerOverlay.onAcquiredGood()
-            assertThat(progress).isTrue()
-            assertThat(help).isFalse()
-            assertThat(acquired).isFalse()
-        }
-    }
-
-    @Test
-    fun forwardEnrollHelpEvents() = withReason(REASON_ENROLL_ENROLLING) {
-        controllerOverlay.show(udfpsController, overlayParams)
-
-        with(EnrollListener(controllerOverlay)) {
-            controllerOverlay.onEnrollmentHelp()
-            assertThat(progress).isFalse()
-            assertThat(help).isTrue()
-            assertThat(acquired).isFalse()
-        }
-    }
-
-    @Test
-    fun forwardEnrollAcquiredEvents() = withReason(REASON_ENROLL_ENROLLING) {
-        controllerOverlay.show(udfpsController, overlayParams)
-
-        with(EnrollListener(controllerOverlay)) {
-            controllerOverlay.onEnrollmentProgress(/* remaining */ 1)
-            controllerOverlay.onAcquiredGood()
-            assertThat(progress).isTrue()
-            assertThat(help).isFalse()
-            assertThat(acquired).isTrue()
-        }
-    }
-
-    @Test
     fun cancels() = withReason(REASON_AUTH_BP) {
         controllerOverlay.cancel()
         verify(controllerCallback).onUserCanceled()
@@ -400,131 +314,4 @@
         assertThat(controllerOverlay.matchesRequestId(REQUEST_ID)).isTrue()
         assertThat(controllerOverlay.matchesRequestId(REQUEST_ID + 1)).isFalse()
     }
-
-    @Test
-    fun testTouchOutsideAreaNoRotation() = withReason(REASON_ENROLL_ENROLLING) {
-        val touchHints =
-            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
-        val rotation = Surface.ROTATION_0
-        // touch at 0 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, 0.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[0])
-        // touch at 90 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, -1.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[1])
-        // touch at 180 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                -1.0f /* x */, 0.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[2])
-        // touch at 270 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, 1.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[3])
-    }
-
-    fun testTouchOutsideAreaNoRotation90Degrees() = withReason(REASON_ENROLL_ENROLLING) {
-        val touchHints =
-            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
-        val rotation = Surface.ROTATION_90
-        // touch at 0 degrees -> 90 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, 0.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[1])
-        // touch at 90 degrees -> 180 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, -1.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[2])
-        // touch at 180 degrees -> 270 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                -1.0f /* x */, 0.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[3])
-        // touch at 270 degrees -> 0 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, 1.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[0])
-    }
-
-    fun testTouchOutsideAreaNoRotation270Degrees() = withReason(REASON_ENROLL_ENROLLING) {
-        val touchHints =
-            context.resources.getStringArray(R.array.udfps_accessibility_touch_hints)
-        val rotation = Surface.ROTATION_270
-        // touch at 0 degrees -> 270 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, 0.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[3])
-        // touch at 90 degrees -> 0 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, -1.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[0])
-        // touch at 180 degrees -> 90 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                -1.0f /* x */, 0.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[1])
-        // touch at 270 degrees -> 180 degrees
-        assertThat(
-            controllerOverlay.onTouchOutsideOfSensorAreaImpl(
-                0.0f /* x */, 1.0f /* y */,
-                0.0f /* sensorX */, 0.0f /* sensorY */, rotation
-            )
-        ).isEqualTo(touchHints[2])
-    }
-}
-
-private class EnrollListener(
-    overlay: UdfpsControllerOverlay,
-    var progress: Boolean = false,
-    var help: Boolean = false,
-    var acquired: Boolean = false
-) : UdfpsEnrollHelper.Listener {
-
-    init {
-        overlay.enrollHelper!!.setListener(this)
-    }
-
-    override fun onEnrollmentProgress(remaining: Int, totalSteps: Int) {
-        progress = true
-    }
-
-    override fun onEnrollmentHelp(remaining: Int, totalSteps: Int) {
-        help = true
-    }
-
-    override fun onLastStepAcquired() {
-        acquired = true
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index dd7082a..05266f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -71,6 +71,8 @@
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.settingslib.udfps.UdfpsOverlayParams;
+import com.android.settingslib.udfps.UdfpsUtils;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -187,8 +189,6 @@
     @Mock
     private UdfpsView mUdfpsView;
     @Mock
-    private UdfpsEnrollView mEnrollView;
-    @Mock
     private UdfpsBpView mBpView;
     @Mock
     private UdfpsFpmEmptyView mFpmEmptyView;
@@ -230,22 +230,21 @@
     private ScreenLifecycle.Observer mScreenObserver;
     private FingerprintSensorPropertiesInternal mOpticalProps;
     private FingerprintSensorPropertiesInternal mUltrasonicProps;
+    private UdfpsUtils mUdfpsUtils;
 
     @Before
     public void setUp() {
         Execution execution = new FakeExecution();
+        mUdfpsUtils = new UdfpsUtils();
 
         when(mLayoutInflater.inflate(R.layout.udfps_view, null, false))
                 .thenReturn(mUdfpsView);
-        when(mLayoutInflater.inflate(R.layout.udfps_enroll_view, null))
-                .thenReturn(mEnrollView); // for showOverlay REASON_ENROLL_ENROLLING
         when(mLayoutInflater.inflate(R.layout.udfps_keyguard_view, null))
                 .thenReturn(mKeyguardView); // for showOverlay REASON_AUTH_FPM_KEYGUARD
         when(mLayoutInflater.inflate(R.layout.udfps_bp_view, null))
                 .thenReturn(mBpView);
         when(mLayoutInflater.inflate(R.layout.udfps_fpm_empty_view, null))
                 .thenReturn(mFpmEmptyView);
-        when(mEnrollView.getContext()).thenReturn(mContext);
         when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
         when(mSessionTracker.getSessionId(anyInt())).thenReturn(
                 (new InstanceIdSequence(1 << 20)).newInstanceId());
@@ -305,7 +304,7 @@
                 mUnlockedScreenOffAnimationController, mSystemUIDialogManager, mLatencyTracker,
                 mActivityLaunchAnimator, alternateTouchProvider, mBiometricExecutor,
                 mPrimaryBouncerInteractor, mSinglePointerTouchProcessor, mSessionTracker,
-                mAlternateBouncerInteractor, mSecureSettings);
+                mAlternateBouncerInteractor, mSecureSettings, mUdfpsUtils);
         verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
         mOverlayController = mOverlayCaptor.getValue();
         verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsEnrollViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsEnrollViewTest.java
deleted file mode 100644
index 60a0258..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsEnrollViewTest.java
+++ /dev/null
@@ -1,50 +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.biometrics;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class UdfpsEnrollViewTest extends SysuiTestCase {
-
-    private static String ENROLL_PROGRESS_COLOR_LIGHT = "#699FF3";
-    private static String ENROLL_PROGRESS_COLOR_DARK = "#7DA7F1";
-
-    @Test
-    public void fingerprintUdfpsEnroll_usesCorrectThemeCheckmarkFillColor() {
-        final Configuration config = mContext.getResources().getConfiguration();
-        final boolean isDarkThemeOn = (config.uiMode & Configuration.UI_MODE_NIGHT_MASK)
-                == Configuration.UI_MODE_NIGHT_YES;
-        final int currentColor = mContext.getColor(R.color.udfps_enroll_progress);
-
-        assertThat(currentColor).isEqualTo(Color.parseColor(isDarkThemeOn
-                ? ENROLL_PROGRESS_COLOR_DARK : ENROLL_PROGRESS_COLOR_LIGHT));
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 44fa4eb..07b4a64 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -25,6 +25,7 @@
 import android.view.LayoutInflater
 import android.view.Surface
 import androidx.test.filters.SmallTest
+import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
index 8e20303..ec2c1bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
@@ -23,8 +23,8 @@
 import android.view.Surface
 import android.view.Surface.Rotation
 import androidx.test.filters.SmallTest
+import com.android.settingslib.udfps.UdfpsOverlayParams
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.UdfpsOverlayParams
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -607,12 +607,16 @@
                     pointerCoords = pointerCoords
                 )
 
+            val expectedTouchDataPointer =
+                currentPointers.find { it.id == expectedPointerOnSensorId }
+                    ?: currentPointers.find { it.id == previousPointerOnSensorId }
+                        ?: currentPointers[0]
             val expectedTouchData =
-                if (expectedPointerOnSensorId != INVALID_POINTER_ID) {
+                if (motionEventAction != MotionEvent.ACTION_CANCEL) {
                     NORMALIZED_TOUCH_DATA.copy(
-                        pointerId = expectedPointerOnSensorId,
-                        x = ROTATION_0_INPUTS.getNativeX(isWithinSensor = true),
-                        y = ROTATION_0_INPUTS.getNativeY(isWithinSensor = true)
+                        pointerId = expectedTouchDataPointer.id,
+                        x = ROTATION_0_INPUTS.getNativeX(expectedTouchDataPointer.onSensor),
+                        y = ROTATION_0_INPUTS.getNativeY(expectedTouchDataPointer.onSensor)
                     )
                 } else {
                     NormalizedTouchData()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
new file mode 100644
index 0000000..d552c9d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.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.common.coroutine
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** atest SystemUITests:CoroutineResultTest */
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class CoroutineResultTest : SysuiTestCase() {
+
+    @Test
+    fun suspendRunCatching_shouldReturnSuccess() = runTest {
+        val actual = suspendRunCatching { "Placeholder" }
+        assertThat(actual.isSuccess).isTrue()
+        assertThat(actual.getOrNull()).isEqualTo("Placeholder")
+    }
+
+    @Test
+    fun suspendRunCatching_whenExceptionThrow_shouldResumeWithException() = runTest {
+        val actual = suspendRunCatching { throw Exception() }
+        assertThat(actual.isFailure).isTrue()
+        assertThat(actual.exceptionOrNull()).isInstanceOf(Exception::class.java)
+    }
+
+    @Test(expected = CancellationException::class)
+    fun suspendRunCatching_whenCancelled_shouldResumeWithException() = runTest {
+        suspendRunCatching { cancel() }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt
new file mode 100644
index 0000000..1e4753e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt
@@ -0,0 +1,24 @@
+package com.android.systemui.coroutines
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class FlowTest : SysuiTestCase() {
+
+    @Test
+    fun collectLastValue() = runTest {
+        val flow = flowOf(0, 1, 2)
+        val lastValue by collectLastValue(flow)
+        assertThat(lastValue).isEqualTo(2)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java
index 9f4a7c8..b9db9c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationTypesUpdaterTest.java
@@ -33,6 +33,7 @@
 import com.android.settingslib.dream.DreamBackend;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.shared.condition.Monitor;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -66,13 +67,16 @@
 
     private ComplicationTypesUpdater mController;
 
+    @Mock
+    private Monitor mMonitor;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mDreamBackend.getEnabledComplications()).thenReturn(new HashSet<>());
 
         mController = new ComplicationTypesUpdater(mDreamBackend, mExecutor,
-                mSecureSettings, mDreamOverlayStateController);
+                mSecureSettings, mDreamOverlayStateController, mMonitor);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java
index ec448f9..52aaea1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamClockTimeComplicationTest.java
@@ -30,6 +30,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.shared.condition.Monitor;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -69,6 +70,9 @@
     @Mock
     private ComplicationLayoutParams mLayoutParams;
 
+    @Mock
+    private Monitor mMonitor;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -83,7 +87,8 @@
         final DreamClockTimeComplication.Registrant registrant =
                 new DreamClockTimeComplication.Registrant(
                         mDreamOverlayStateController,
-                        mComplication);
+                        mComplication,
+                        mMonitor);
         registrant.start();
         verify(mDreamOverlayStateController).addComplication(eq(mComplication));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
index a4cf15c..fc1d38b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
@@ -46,6 +46,7 @@
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent;
 import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.shared.condition.Monitor;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -101,6 +102,9 @@
     @Captor
     private ArgumentCaptor<DreamOverlayStateController.Callback> mStateCallbackCaptor;
 
+    @Mock
+    private Monitor mMonitor;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -126,7 +130,7 @@
     public void complicationAvailability_serviceNotAvailable_noFavorites_doNotAddComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(false);
@@ -139,7 +143,7 @@
     public void complicationAvailability_serviceAvailable_noFavorites_doNotAddComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(false);
@@ -152,7 +156,7 @@
     public void complicationAvailability_serviceAvailable_noFavorites_panel_addComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(false);
@@ -165,7 +169,7 @@
     public void complicationAvailability_serviceNotAvailable_haveFavorites_doNotAddComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(true);
@@ -178,7 +182,7 @@
     public void complicationAvailability_serviceAvailable_haveFavorites_addComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(true);
@@ -191,7 +195,7 @@
     public void complicationAvailability_checkAvailabilityWhenDreamOverlayBecomesActive() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setServiceAvailable(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
index c8b2b25..77ca958 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
@@ -33,6 +33,8 @@
 import com.android.systemui.dreams.DreamOverlayStateController;
 import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
+import com.android.systemui.shared.condition.Condition;
+import com.android.systemui.shared.condition.Monitor;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,6 +45,8 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -60,6 +64,11 @@
     @Mock
     private View mBcSmartspaceView;
 
+    @Mock
+    private Monitor mMonitor;
+
+    private final Set<Condition> mPreconditions = new HashSet<>();
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -79,7 +88,8 @@
         return new SmartSpaceComplication.Registrant(
                 mDreamOverlayStateController,
                 mComplication,
-                mSmartspaceController);
+                mSmartspaceController,
+                mMonitor);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt
index ed16721..686782f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP
 import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE
+import com.android.systemui.util.mockito.any
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentCaptor
@@ -48,22 +49,22 @@
     @Test
     fun testRestart_ImmediateWhenAsleep() {
         whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_ASLEEP)
-        restarter.restartSystemUI()
-        verify(systemExitRestarter).restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
+        verify(systemExitRestarter).restartSystemUI(any())
     }
 
     @Test
     fun testRestart_WaitsForSceenOff() {
         whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_AWAKE)
 
-        restarter.restartSystemUI()
-        verify(systemExitRestarter, never()).restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
+        verify(systemExitRestarter, never()).restartSystemUI(any())
 
         val captor = ArgumentCaptor.forClass(WakefulnessLifecycle.Observer::class.java)
         verify(wakefulnessLifecycle).addObserver(captor.capture())
 
         captor.value.onFinishedGoingToSleep()
 
-        verify(systemExitRestarter).restartSystemUI()
+        verify(systemExitRestarter).restartSystemUI(any())
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
index d8bbd04..2bcd75b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.settings.GlobalSettings
-import com.android.systemui.util.settings.SecureSettings
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert
 import org.junit.Before
@@ -63,8 +62,6 @@
     @Mock
     private lateinit var globalSettings: GlobalSettings
     @Mock
-    private lateinit var secureSettings: SecureSettings
-    @Mock
     private lateinit var systemProperties: SystemPropertiesHelper
     @Mock
     private lateinit var resources: Resources
@@ -92,7 +89,6 @@
             flagManager,
             mockContext,
             globalSettings,
-            secureSettings,
             systemProperties,
             resources,
             serverFlagReader,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt
index 7d807e2..6060afe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -63,7 +64,7 @@
         whenever(batteryController.isPluggedIn).thenReturn(true)
 
         assertThat(executor.numPending()).isEqualTo(0)
-        restarter.restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
         assertThat(executor.numPending()).isEqualTo(1)
     }
 
@@ -72,11 +73,11 @@
         whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_ASLEEP)
         whenever(batteryController.isPluggedIn).thenReturn(true)
 
-        restarter.restartSystemUI()
-        verify(systemExitRestarter, never()).restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
+        verify(systemExitRestarter, never()).restartSystemUI("Restart for test")
         executor.advanceClockToLast()
         executor.runAllReady()
-        verify(systemExitRestarter).restartSystemUI()
+        verify(systemExitRestarter).restartSystemUI(any())
     }
 
     @Test
@@ -85,7 +86,7 @@
         whenever(batteryController.isPluggedIn).thenReturn(true)
 
         assertThat(executor.numPending()).isEqualTo(0)
-        restarter.restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
         assertThat(executor.numPending()).isEqualTo(0)
     }
 
@@ -95,7 +96,7 @@
         whenever(batteryController.isPluggedIn).thenReturn(false)
 
         assertThat(executor.numPending()).isEqualTo(0)
-        restarter.restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
         assertThat(executor.numPending()).isEqualTo(0)
     }
 
@@ -105,8 +106,8 @@
         whenever(batteryController.isPluggedIn).thenReturn(true)
 
         assertThat(executor.numPending()).isEqualTo(0)
-        restarter.restartSystemUI()
-        restarter.restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
+        restarter.restartSystemUI("Restart for test")
         assertThat(executor.numPending()).isEqualTo(1)
     }
 
@@ -115,7 +116,7 @@
         whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_AWAKE)
         whenever(batteryController.isPluggedIn).thenReturn(true)
         assertThat(executor.numPending()).isEqualTo(0)
-        restarter.restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
 
         val captor = ArgumentCaptor.forClass(WakefulnessLifecycle.Observer::class.java)
         verify(wakefulnessLifecycle).addObserver(captor.capture())
@@ -131,7 +132,7 @@
         whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_ASLEEP)
         whenever(batteryController.isPluggedIn).thenReturn(false)
         assertThat(executor.numPending()).isEqualTo(0)
-        restarter.restartSystemUI()
+        restarter.restartSystemUI("Restart for test")
 
         val captor =
             ArgumentCaptor.forClass(BatteryController.BatteryStateChangeCallback::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
index 1633912..4ebf974 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
@@ -45,7 +45,7 @@
     fun setup() {
         MockitoAnnotations.initMocks(this)
 
-        serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor)
+        serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor, false)
     }
 
     @Test
@@ -56,6 +56,6 @@
         deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
         executor.runAllReady()
 
-        verify(changeListener).onChange()
+        verify(changeListener).onChange(flag)
     }
 }
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 fb54d6d..4415033 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -157,25 +157,28 @@
                 dumpManager = mock(),
                 userHandle = UserHandle.SYSTEM,
             )
+        val featureFlags =
+            FakeFeatureFlags().apply {
+                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
+                set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true)
+                set(Flags.REVAMPED_WALLPAPER_UI, true)
+                set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true)
+                set(Flags.FACE_AUTH_REFACTOR, true)
+            }
         underTest.interactor =
             KeyguardQuickAffordanceInteractor(
                 keyguardInteractor =
                     KeyguardInteractor(
                         repository = FakeKeyguardRepository(),
                         commandQueue = commandQueue,
+                        featureFlags = featureFlags,
                     ),
                 registry = mock(),
                 lockPatternUtils = lockPatternUtils,
                 keyguardStateController = keyguardStateController,
                 userTracker = userTracker,
                 activityStarter = activityStarter,
-                featureFlags =
-                    FakeFeatureFlags().apply {
-                        set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, true)
-                        set(Flags.LOCKSCREEN_CUSTOM_CLOCKS, true)
-                        set(Flags.REVAMPED_WALLPAPER_UI, true)
-                        set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true)
-                    },
+                featureFlags = featureFlags,
                 repository = { quickAffordanceRepository },
                 launchAnimator = launchAnimator,
             )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
index 2290676..c3b0e5226 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewControllerTest.java
@@ -38,6 +38,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
@@ -66,6 +67,8 @@
     private KeyguardIndicationTextView mView;
     @Mock
     private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private KeyguardLogger mLogger;
     @Captor
     private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
 
@@ -77,7 +80,7 @@
         MockitoAnnotations.initMocks(this);
         when(mView.getTextColors()).thenReturn(ColorStateList.valueOf(Color.WHITE));
         mController = new KeyguardIndicationRotateTextViewController(mView, mExecutor,
-                mStatusBarStateController);
+                mStatusBarStateController, mLogger);
         mController.onViewAttached();
 
         verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
index 58cdec4..db18ba6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
@@ -20,6 +20,7 @@
 import android.app.StatusBarManager
 import android.content.Context
 import android.content.pm.PackageManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.camera.CameraGestureHelper
@@ -31,14 +32,13 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class CameraQuickAffordanceConfigTest : SysuiTestCase() {
 
     @Mock private lateinit var cameraGestureHelper: CameraGestureHelper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index 15b85de..64839e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -22,6 +22,7 @@
 import android.provider.Settings.Global.ZEN_MODE_OFF
 import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
 import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.notification.EnableZenModeDialog
 import com.android.systemui.R
@@ -51,7 +52,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
@@ -60,7 +60,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() {
 
     @Mock private lateinit var zenModeController: ZenModeController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
index 9fa7db1..31391ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
@@ -18,6 +18,7 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.common.shared.model.Icon
@@ -35,13 +36,12 @@
 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)
+@RunWith(AndroidJUnit4::class)
 class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() {
 
     @Mock private lateinit var context: Context
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index 659c1e5..2c1c04c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.data.quickaffordance
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -34,13 +35,12 @@
 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.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
 
     @Mock private lateinit var component: ControlsComponent
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index 3b0169d..3bae7f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import android.content.res.Resources
 import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -40,7 +41,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Mock
@@ -48,7 +48,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() {
 
     @Mock private lateinit var sharedPrefs: FakeSharedPreferences
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index 3d65713..1259b47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -20,6 +20,7 @@
 import android.content.Intent
 import android.content.SharedPreferences
 import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -40,7 +41,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Mock
@@ -51,7 +51,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
 
     @Mock private lateinit var userFileManager: UserFileManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
index b21cec9..c08ef42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
@@ -19,6 +19,7 @@
 
 import android.content.pm.UserInfo
 import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
@@ -37,13 +38,12 @@
 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)
+@RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
 
     @Mock private lateinit var userHandle: UserHandle
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
index 34f3ed8..facc747 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
@@ -21,6 +21,7 @@
 import android.media.AudioManager
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.Observer
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
@@ -47,7 +48,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
@@ -55,8 +55,8 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
-class MuteQuickAffordanceCoreStartableTest : SysuiTestCase()  {
+@RunWith(AndroidJUnit4::class)
+class MuteQuickAffordanceCoreStartableTest : SysuiTestCase() {
 
     @Mock
     private lateinit var featureFlags: FeatureFlags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index 9d2ddff..1adf808 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -18,6 +18,7 @@
 package com.android.systemui.keyguard.data.quickaffordance
 
 import android.content.Intent
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
@@ -33,13 +34,12 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
 
     @Mock private lateinit var controller: QRCodeScannerController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index 8f56b95..752963f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
@@ -20,6 +20,7 @@
 import android.graphics.drawable.Drawable
 import android.service.quickaccesswallet.GetWalletCardsResponse
 import android.service.quickaccesswallet.QuickAccessWalletClient
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -41,14 +42,13 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
 
     @Mock private lateinit var walletController: QuickAccessWalletController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
index 805dcec..5bd86bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.data.quickaffordance
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.SysuiTestCase
@@ -32,7 +33,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
@@ -40,7 +40,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
 
     @Mock private lateinit var activityIntentHelper: ActivityIntentHelper
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 ddd1049..21ad5e2 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
@@ -18,8 +18,12 @@
 package com.android.systemui.keyguard.data.repository
 
 import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE
+import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT
 import android.content.Intent
 import android.content.pm.UserInfo
+import android.hardware.biometrics.BiometricManager
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
@@ -29,8 +33,14 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.data.repository.BiometricType.FACE
+import com.android.systemui.keyguard.data.repository.BiometricType.REAR_FINGERPRINT
+import com.android.systemui.keyguard.data.repository.BiometricType.SIDE_FINGERPRINT
+import com.android.systemui.keyguard.data.repository.BiometricType.UNDER_DISPLAY_FINGERPRINT
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.StandardTestDispatcher
@@ -41,9 +51,14 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.isNull
+import org.mockito.Captor
 import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -56,6 +71,12 @@
     @Mock private lateinit var authController: AuthController
     @Mock private lateinit var lockPatternUtils: LockPatternUtils
     @Mock private lateinit var devicePolicyManager: DevicePolicyManager
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var biometricManager: BiometricManager
+    @Captor private lateinit var authControllerCallback: ArgumentCaptor<AuthController.Callback>
+    @Captor
+    private lateinit var biometricManagerCallback:
+        ArgumentCaptor<IBiometricEnabledOnKeyguardCallback.Stub>
     private lateinit var userRepository: FakeUserRepository
 
     private lateinit var testDispatcher: TestDispatcher
@@ -72,7 +93,7 @@
     }
 
     private suspend fun createBiometricSettingsRepository() {
-        userRepository.setUserInfos(listOf(PRIMARY_USER))
+        userRepository.setUserInfos(listOf(PRIMARY_USER, ANOTHER_USER))
         userRepository.setSelectedUserInfo(PRIMARY_USER)
         underTest =
             BiometricSettingsRepositoryImpl(
@@ -85,33 +106,30 @@
                 scope = testScope.backgroundScope,
                 backgroundDispatcher = testDispatcher,
                 looper = testableLooper!!.looper,
+                dumpManager = dumpManager,
+                biometricManager = biometricManager,
             )
+        testScope.runCurrent()
     }
 
     @Test
     fun fingerprintEnrollmentChange() =
         testScope.runTest {
             createBiometricSettingsRepository()
-            val fingerprintEnabledByDevicePolicy = collectLastValue(underTest.isFingerprintEnrolled)
+            val fingerprintEnrolled = collectLastValue(underTest.isFingerprintEnrolled)
             runCurrent()
 
-            val captor = argumentCaptor<AuthController.Callback>()
-            verify(authController).addCallback(captor.capture())
+            verify(authController).addCallback(authControllerCallback.capture())
             whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(true)
-            captor.value.onEnrollmentsChanged(
-                BiometricType.UNDER_DISPLAY_FINGERPRINT,
-                PRIMARY_USER_ID,
-                true
-            )
-            assertThat(fingerprintEnabledByDevicePolicy()).isTrue()
+            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, true)
+            assertThat(fingerprintEnrolled()).isTrue()
 
             whenever(authController.isFingerprintEnrolled(anyInt())).thenReturn(false)
-            captor.value.onEnrollmentsChanged(
-                BiometricType.UNDER_DISPLAY_FINGERPRINT,
-                PRIMARY_USER_ID,
-                false
-            )
-            assertThat(fingerprintEnabledByDevicePolicy()).isFalse()
+            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, ANOTHER_USER_ID, false)
+            assertThat(fingerprintEnrolled()).isTrue()
+
+            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, false)
+            assertThat(fingerprintEnrolled()).isFalse()
         }
 
     @Test
@@ -124,15 +142,14 @@
             val captor = argumentCaptor<LockPatternUtils.StrongAuthTracker>()
             verify(lockPatternUtils).registerStrongAuthTracker(captor.capture())
 
-            captor.value
-                .getStub()
-                .onStrongAuthRequiredChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
+            captor.value.stub.onStrongAuthRequiredChanged(STRONG_AUTH_NOT_REQUIRED, PRIMARY_USER_ID)
             testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper
             assertThat(strongBiometricAllowed()).isTrue()
 
-            captor.value
-                .getStub()
-                .onStrongAuthRequiredChanged(STRONG_AUTH_REQUIRED_AFTER_BOOT, PRIMARY_USER_ID)
+            captor.value.stub.onStrongAuthRequiredChanged(
+                STRONG_AUTH_REQUIRED_AFTER_BOOT,
+                PRIMARY_USER_ID
+            )
             testableLooper?.processAllMessages() // StrongAuthTracker uses the TestableLooper
             assertThat(strongBiometricAllowed()).isFalse()
         }
@@ -146,7 +163,7 @@
             runCurrent()
 
             whenever(devicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt()))
-                .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT)
+                .thenReturn(KEYGUARD_DISABLE_FINGERPRINT)
             broadcastDPMStateChange()
             assertThat(fingerprintEnabledByDevicePolicy()).isFalse()
 
@@ -155,6 +172,137 @@
             assertThat(fingerprintEnabledByDevicePolicy()).isTrue()
         }
 
+    @Test
+    fun faceEnrollmentChangeIsPropagatedForTheCurrentUser() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+            runCurrent()
+            clearInvocations(authController)
+
+            whenever(authController.isFaceAuthEnrolled(PRIMARY_USER_ID)).thenReturn(false)
+            val faceEnrolled = collectLastValue(underTest.isFaceEnrolled)
+
+            assertThat(faceEnrolled()).isFalse()
+            verify(authController).addCallback(authControllerCallback.capture())
+            enrollmentChange(REAR_FINGERPRINT, PRIMARY_USER_ID, true)
+
+            assertThat(faceEnrolled()).isFalse()
+
+            enrollmentChange(SIDE_FINGERPRINT, PRIMARY_USER_ID, true)
+
+            assertThat(faceEnrolled()).isFalse()
+
+            enrollmentChange(UNDER_DISPLAY_FINGERPRINT, PRIMARY_USER_ID, true)
+
+            assertThat(faceEnrolled()).isFalse()
+
+            enrollmentChange(FACE, ANOTHER_USER_ID, true)
+
+            assertThat(faceEnrolled()).isFalse()
+
+            enrollmentChange(FACE, PRIMARY_USER_ID, true)
+
+            assertThat(faceEnrolled()).isTrue()
+        }
+
+    @Test
+    fun faceEnrollmentStatusOfNewUserUponUserSwitch() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+            runCurrent()
+            clearInvocations(authController)
+
+            whenever(authController.isFaceAuthEnrolled(PRIMARY_USER_ID)).thenReturn(false)
+            whenever(authController.isFaceAuthEnrolled(ANOTHER_USER_ID)).thenReturn(true)
+            val faceEnrolled = collectLastValue(underTest.isFaceEnrolled)
+
+            assertThat(faceEnrolled()).isFalse()
+        }
+
+    @Test
+    fun faceEnrollmentChangesArePropagatedAfterUserSwitch() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+
+            userRepository.setSelectedUserInfo(ANOTHER_USER)
+            runCurrent()
+            clearInvocations(authController)
+
+            val faceEnrolled = collectLastValue(underTest.isFaceEnrolled)
+            runCurrent()
+
+            verify(authController).addCallback(authControllerCallback.capture())
+
+            enrollmentChange(FACE, ANOTHER_USER_ID, true)
+
+            assertThat(faceEnrolled()).isTrue()
+        }
+
+    @Test
+    fun devicePolicyControlsFaceAuthenticationEnabledState() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+            verify(biometricManager)
+                .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture())
+
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(isNull(), eq(PRIMARY_USER_ID)))
+                .thenReturn(KEYGUARD_DISABLE_FINGERPRINT or KEYGUARD_DISABLE_FACE)
+
+            val isFaceAuthEnabled = collectLastValue(underTest.isFaceAuthenticationEnabled)
+            runCurrent()
+
+            broadcastDPMStateChange()
+
+            assertThat(isFaceAuthEnabled()).isFalse()
+
+            biometricManagerCallback.value.onChanged(true, PRIMARY_USER_ID)
+            runCurrent()
+            assertThat(isFaceAuthEnabled()).isFalse()
+
+            whenever(devicePolicyManager.getKeyguardDisabledFeatures(isNull(), eq(PRIMARY_USER_ID)))
+                .thenReturn(KEYGUARD_DISABLE_FINGERPRINT)
+            broadcastDPMStateChange()
+
+            assertThat(isFaceAuthEnabled()).isTrue()
+        }
+
+    @Test
+    fun biometricManagerControlsFaceAuthenticationEnabledStatus() =
+        testScope.runTest {
+            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()
+
+            biometricManagerCallback.value.onChanged(false, PRIMARY_USER_ID)
+
+            assertThat(isFaceAuthEnabled()).isFalse()
+        }
+
+    @Test
+    fun biometricManagerCallbackIsRegisteredOnlyOnce() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+
+            collectLastValue(underTest.isFaceAuthenticationEnabled)()
+            collectLastValue(underTest.isFaceAuthenticationEnabled)()
+            collectLastValue(underTest.isFaceAuthenticationEnabled)()
+
+            verify(biometricManager, times(1)).registerEnabledOnKeyguardCallback(any())
+        }
+
+    private fun enrollmentChange(biometricType: BiometricType, userId: Int, enabled: Boolean) {
+        authControllerCallback.value.onEnrollmentsChanged(biometricType, userId, enabled)
+    }
+
     private fun broadcastDPMStateChange() {
         fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
             receiver.onReceive(
@@ -172,5 +320,13 @@
                 /* name= */ "primary user",
                 /* flags= */ UserInfo.FLAG_PRIMARY
             )
+
+        private const val ANOTHER_USER_ID = 1
+        private val ANOTHER_USER =
+            UserInfo(
+                /* id= */ ANOTHER_USER_ID,
+                /* name= */ "another user",
+                /* flags= */ UserInfo.FLAG_PRIMARY
+            )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
index 9203f05..0519a44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
@@ -22,6 +22,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -44,6 +45,7 @@
 @RunWith(JUnit4::class)
 class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() {
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock private lateinit var dumpManager: DumpManager
     @Captor private lateinit var callbackCaptor: ArgumentCaptor<KeyguardUpdateMonitorCallback>
 
     private lateinit var testScope: TestScope
@@ -59,6 +61,7 @@
             DeviceEntryFingerprintAuthRepositoryImpl(
                 keyguardUpdateMonitor,
                 testScope.backgroundScope,
+                dumpManager,
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
index 03cb1db..2eabda3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.data.repository
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.ViewMediatorCallback
 import com.android.systemui.SysuiTestCase
@@ -27,14 +28,13 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardBouncerRepositoryTest : SysuiTestCase() {
 
     @Mock private lateinit var systemClock: SystemClock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 6099f01..86e8c9a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -19,9 +19,11 @@
 
 import android.content.pm.UserInfo
 import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
 import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceProviderClientFactory
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
@@ -39,23 +41,19 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.yield
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: KeyguardQuickAffordanceRepository
@@ -65,12 +63,14 @@
     private lateinit var userTracker: FakeUserTracker
     private lateinit var client1: FakeCustomizationProviderClient
     private lateinit var client2: FakeCustomizationProviderClient
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
         config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
         config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
-        val scope = CoroutineScope(IMMEDIATE)
+        val testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
         userTracker = FakeUserTracker()
         val localUserSelectionManager =
             KeyguardQuickAffordanceLocalUserSelectionManager(
@@ -93,7 +93,7 @@
         client2 = FakeCustomizationProviderClient()
         val remoteUserSelectionManager =
             KeyguardQuickAffordanceRemoteUserSelectionManager(
-                scope = scope,
+                scope = testScope.backgroundScope,
                 userTracker = userTracker,
                 clientFactory =
                     FakeKeyguardQuickAffordanceProviderClientFactory(
@@ -116,14 +116,14 @@
         underTest =
             KeyguardQuickAffordanceRepository(
                 appContext = context,
-                scope = scope,
+                scope = testScope.backgroundScope,
                 localUserSelectionManager = localUserSelectionManager,
                 remoteUserSelectionManager = remoteUserSelectionManager,
                 userTracker = userTracker,
                 legacySettingSyncer =
                     KeyguardQuickAffordanceLegacySettingSyncer(
-                        scope = scope,
-                        backgroundDispatcher = IMMEDIATE,
+                        scope = testScope.backgroundScope,
+                        backgroundDispatcher = testDispatcher,
                         secureSettings = FakeSettings(),
                         selectionsManager = localUserSelectionManager,
                     ),
@@ -135,15 +135,14 @@
 
     @Test
     fun setSelections() =
-        runBlocking(IMMEDIATE) {
-            var configsBySlotId: Map<String, List<KeyguardQuickAffordanceConfig>>? = null
-            val job = underTest.selections.onEach { configsBySlotId = it }.launchIn(this)
+        testScope.runTest {
+            val configsBySlotId = collectLastValue(underTest.selections)
             val slotId1 = "slot1"
             val slotId2 = "slot2"
 
             underTest.setSelections(slotId1, listOf(config1.key))
             assertSelections(
-                configsBySlotId,
+                configsBySlotId(),
                 mapOf(
                     slotId1 to listOf(config1),
                 ),
@@ -151,7 +150,7 @@
 
             underTest.setSelections(slotId2, listOf(config2.key))
             assertSelections(
-                configsBySlotId,
+                configsBySlotId(),
                 mapOf(
                     slotId1 to listOf(config1),
                     slotId2 to listOf(config2),
@@ -161,19 +160,17 @@
             underTest.setSelections(slotId1, emptyList())
             underTest.setSelections(slotId2, listOf(config1.key))
             assertSelections(
-                configsBySlotId,
+                configsBySlotId(),
                 mapOf(
                     slotId1 to emptyList(),
                     slotId2 to listOf(config1),
                 ),
             )
-
-            job.cancel()
         }
 
     @Test
     fun getAffordancePickerRepresentations() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             assertThat(underTest.getAffordancePickerRepresentations())
                 .isEqualTo(
                     listOf(
@@ -226,7 +223,7 @@
 
     @Test
     fun `selections for secondary user`() =
-        runBlocking(IMMEDIATE) {
+        testScope.runTest {
             userTracker.set(
                 userInfos =
                     listOf(
@@ -252,12 +249,10 @@
                 slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
                 affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
             )
-            val observed = mutableListOf<Map<String, List<KeyguardQuickAffordanceConfig>>>()
-            val job = underTest.selections.onEach { observed.add(it) }.launchIn(this)
-            yield()
+            val observed = collectLastValue(underTest.selections)
 
             assertSelections(
-                observed = observed.last(),
+                observed = observed(),
                 expected =
                     mapOf(
                         KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
@@ -266,8 +261,6 @@
                             ),
                     )
             )
-
-            job.cancel()
         }
 
     private fun assertSelections(
@@ -283,7 +276,6 @@
     }
 
     companion object {
-        private val IMMEDIATE = Dispatchers.Main.immediate
         private const val SECONDARY_USER_1 = UserHandle.MIN_SECONDARY_USER_ID + 1
         private const val SECONDARY_USER_2 = UserHandle.MIN_SECONDARY_USER_ID + 2
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index f997d18..8bb6a85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Point
 import android.hardware.biometrics.BiometricSourceType
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
@@ -54,13 +55,12 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardRepositoryImplTest : SysuiTestCase() {
 
     @Mock private lateinit var statusBarStateController: StatusBarStateController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 32cec09..ae227b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -20,6 +20,7 @@
 import android.util.Log
 import android.util.Log.TerribleFailure
 import android.util.Log.TerribleFailureHandler
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Interpolators
@@ -43,10 +44,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardTransitionRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: KeyguardTransitionRepository
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 4b06905..a181137 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
@@ -18,6 +18,7 @@
 
 import android.app.trust.TrustManager
 import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.logging.TrustRepositoryLogger
 import com.android.systemui.SysuiTestCase
@@ -33,7 +34,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
@@ -43,7 +43,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class TrustRepositoryTest : SysuiTestCase() {
     @Mock private lateinit var trustManager: TrustManager
     @Captor private lateinit var listenerCaptor: ArgumentCaptor<TrustManager.TrustListener>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
index 8caf60f..7ded354 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.ViewMediatorCallback
@@ -36,14 +37,13 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.mock
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class AlternateBouncerInteractorTest : SysuiTestCase() {
     private lateinit var underTest: AlternateBouncerInteractor
     private lateinit var bouncerRepository: KeyguardBouncerRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index 68d13d3..7d4861b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -18,30 +18,35 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.app.StatusBarManager
+import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
+import com.android.systemui.settings.DisplayTracker
 import com.android.systemui.statusbar.CommandQueue
-import com.android.systemui.statusbar.CommandQueue.Callbacks
-import com.android.systemui.util.mockito.argumentCaptor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.onCompletion
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.mockito.Mock
+import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardInteractorTest : SysuiTestCase() {
-    @Mock private lateinit var commandQueue: CommandQueue
+    private lateinit var commandQueue: FakeCommandQueue
+    private lateinit var featureFlags: FakeFeatureFlags
+    private lateinit var testScope: TestScope
 
     private lateinit var underTest: KeyguardInteractor
     private lateinit var repository: FakeKeyguardRepository
@@ -49,38 +54,134 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-
+        featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
+        commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java))
+        testScope = TestScope()
         repository = FakeKeyguardRepository()
-        underTest = KeyguardInteractor(repository, commandQueue)
+        underTest = KeyguardInteractor(repository, commandQueue, featureFlags)
     }
 
     @Test
-    fun onCameraLaunchDetected() = runTest {
-        val flow = underTest.onCameraLaunchDetected
-        var cameraLaunchSource = collectLastValue(flow)
-        runCurrent()
+    fun onCameraLaunchDetected() =
+        testScope.runTest {
+            val flow = underTest.onCameraLaunchDetected
+            var cameraLaunchSource = collectLastValue(flow)
+            runCurrent()
 
-        val captor = argumentCaptor<CommandQueue.Callbacks>()
-        verify(commandQueue).addCallback(captor.capture())
+            commandQueue.doForEachCallback {
+                it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
+            }
+            assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
 
-        captor.value.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)
-        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE)
+            commandQueue.doForEachCallback {
+                it.onCameraLaunchGestureDetected(
+                    StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
+                )
+            }
+            assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
 
-        captor.value.onCameraLaunchGestureDetected(
-            StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
-        )
-        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP)
+            commandQueue.doForEachCallback {
+                it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)
+            }
+            assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
 
-        captor.value.onCameraLaunchGestureDetected(
-            StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER
-        )
-        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER)
+            commandQueue.doForEachCallback {
+                it.onCameraLaunchGestureDetected(
+                    StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
+                )
+            }
+            assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
 
-        captor.value.onCameraLaunchGestureDetected(
-            StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE
-        )
-        assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE)
+            flow.onCompletion { assertThat(commandQueue.callbackCount()).isEqualTo(0) }
+        }
 
-        flow.onCompletion { verify(commandQueue).removeCallback(captor.value) }
+    @Test
+    fun testKeyguardGuardVisibilityStopsSecureCamera() =
+        testScope.runTest {
+            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
+            runCurrent()
+
+            commandQueue.doForEachCallback {
+                it.onCameraLaunchGestureDetected(
+                    StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
+                )
+            }
+
+            assertThat(secureCameraActive()).isTrue()
+
+            // Keyguard is showing but occluded
+            repository.setKeyguardShowing(true)
+            repository.setKeyguardOccluded(true)
+            assertThat(secureCameraActive()).isTrue()
+
+            // Keyguard is showing and not occluded
+            repository.setKeyguardOccluded(false)
+            assertThat(secureCameraActive()).isFalse()
+        }
+
+    @Test
+    fun testBouncerShowingResetsSecureCameraState() =
+        testScope.runTest {
+            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
+            runCurrent()
+
+            commandQueue.doForEachCallback {
+                it.onCameraLaunchGestureDetected(
+                    StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP
+                )
+            }
+            assertThat(secureCameraActive()).isTrue()
+
+            // Keyguard is showing and not occluded
+            repository.setKeyguardShowing(true)
+            repository.setKeyguardOccluded(true)
+            assertThat(secureCameraActive()).isTrue()
+
+            repository.setBouncerShowing(true)
+            assertThat(secureCameraActive()).isFalse()
+        }
+
+    @Test
+    fun keyguardVisibilityIsDefinedAsKeyguardShowingButNotOccluded() = runTest {
+        var isVisible = collectLastValue(underTest.isKeyguardVisible)
+        repository.setKeyguardShowing(true)
+        repository.setKeyguardOccluded(false)
+
+        assertThat(isVisible()).isTrue()
+
+        repository.setKeyguardOccluded(true)
+        assertThat(isVisible()).isFalse()
+
+        repository.setKeyguardShowing(false)
+        repository.setKeyguardOccluded(true)
+        assertThat(isVisible()).isFalse()
     }
+
+    @Test
+    fun secureCameraIsNotActiveWhenNoCameraLaunchEventHasBeenFiredYet() =
+        testScope.runTest {
+            val secureCameraActive = collectLastValue(underTest.isSecureCameraActive)
+            runCurrent()
+
+            assertThat(secureCameraActive()).isFalse()
+        }
+}
+
+class FakeCommandQueue(val context: Context, val displayTracker: DisplayTracker) :
+    CommandQueue(context, displayTracker) {
+    private val callbacks = mutableListOf<Callbacks>()
+
+    override fun addCallback(callback: Callbacks) {
+        callbacks.add(callback)
+    }
+
+    override fun removeCallback(callback: Callbacks) {
+        callbacks.remove(callback)
+    }
+
+    fun doForEachCallback(func: (callback: Callbacks) -> Unit) {
+        callbacks.forEach { func(it) }
+    }
+
+    fun callbackCount(): Int = callbacks.size
 }
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 9d60b16..51988ef 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
@@ -18,6 +18,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.content.Intent
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
@@ -39,7 +40,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.Mock
 import org.mockito.Mockito.never
@@ -48,7 +48,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardLongPressInteractorTest : SysuiTestCase() {
 
     @Mock private lateinit var activityStarter: ActivityStarter
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 43287b0..240af7b 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
@@ -286,12 +286,18 @@
                 dumpManager = mock(),
                 userHandle = UserHandle.SYSTEM,
             )
+        val featureFlags =
+            FakeFeatureFlags().apply {
+                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
+                set(Flags.FACE_AUTH_REFACTOR, true)
+            }
         underTest =
             KeyguardQuickAffordanceInteractor(
                 keyguardInteractor =
                     KeyguardInteractor(
                         repository = FakeKeyguardRepository(),
-                        commandQueue = commandQueue
+                        commandQueue = commandQueue,
+                        featureFlags = featureFlags,
                     ),
                 registry =
                     FakeKeyguardQuickAffordanceRegistry(
@@ -311,10 +317,7 @@
                 keyguardStateController = keyguardStateController,
                 userTracker = userTracker,
                 activityStarter = activityStarter,
-                featureFlags =
-                    FakeFeatureFlags().apply {
-                        set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
-                    },
+                featureFlags = featureFlags,
                 repository = { quickAffordanceRepository },
                 launchAnimator = launchAnimator,
             )
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 b75a15d..ec70857 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
@@ -18,6 +18,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.R
@@ -60,7 +61,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Mock
@@ -68,7 +68,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
 
     @Mock private lateinit var lockPatternUtils: LockPatternUtils
@@ -150,12 +150,17 @@
         featureFlags =
             FakeFeatureFlags().apply {
                 set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
+                set(Flags.FACE_AUTH_REFACTOR, true)
             }
 
         underTest =
             KeyguardQuickAffordanceInteractor(
                 keyguardInteractor =
-                    KeyguardInteractor(repository = repository, commandQueue = commandQueue),
+                    KeyguardInteractor(
+                        repository = repository,
+                        commandQueue = commandQueue,
+                        featureFlags = featureFlags
+                    ),
                 registry =
                     FakeKeyguardQuickAffordanceRegistry(
                         mapOf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 6333b24..3d13d80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -29,17 +30,17 @@
 import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
+@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardTransitionInteractorTest : SysuiTestCase() {
 
     private lateinit var underTest: KeyguardTransitionInteractor
@@ -53,7 +54,7 @@
 
     @Test
     fun `transition collectors receives only appropriate events`() =
-        runBlocking(IMMEDIATE) {
+        runTest(UnconfinedTestDispatcher()) {
             var lockscreenToAodSteps = mutableListOf<TransitionStep>()
             val job1 =
                 underTest.lockscreenToAodTransition
@@ -87,10 +88,9 @@
 
     @Test
     fun dozeAmountTransitionTest() =
-        runBlocking(IMMEDIATE) {
+        runTest(UnconfinedTestDispatcher()) {
             var dozeAmountSteps = mutableListOf<TransitionStep>()
-            val job =
-                underTest.dozeAmountTransition.onEach { dozeAmountSteps.add(it) }.launchIn(this)
+            val job = underTest.dozeAmountTransition.onEach { dozeAmountSteps.add(it) }.launchIn(this)
 
             val steps = mutableListOf<TransitionStep>()
 
@@ -119,10 +119,9 @@
 
     @Test
     fun keyguardStateTests() =
-        runBlocking(IMMEDIATE) {
+        runTest(UnconfinedTestDispatcher()) {
             var finishedSteps = mutableListOf<KeyguardState>()
-            val job =
-                underTest.finishedKeyguardState.onEach { finishedSteps.add(it) }.launchIn(this)
+            val job = underTest.finishedKeyguardState.onEach { finishedSteps.add(it) }.launchIn(this)
 
             val steps = mutableListOf<TransitionStep>()
 
@@ -143,12 +142,10 @@
 
     @Test
     fun finishedKeyguardTransitionStepTests() =
-        runBlocking(IMMEDIATE) {
+        runTest(UnconfinedTestDispatcher()) {
             var finishedSteps = mutableListOf<TransitionStep>()
             val job =
-                underTest.finishedKeyguardTransitionStep
-                    .onEach { finishedSteps.add(it) }
-                    .launchIn(this)
+                underTest.finishedKeyguardTransitionStep.onEach { finishedSteps.add(it) }.launchIn(this)
 
             val steps = mutableListOf<TransitionStep>()
 
@@ -169,12 +166,10 @@
 
     @Test
     fun startedKeyguardTransitionStepTests() =
-        runBlocking(IMMEDIATE) {
+        runTest(UnconfinedTestDispatcher()) {
             var startedSteps = mutableListOf<TransitionStep>()
             val job =
-                underTest.startedKeyguardTransitionStep
-                    .onEach { startedSteps.add(it) }
-                    .launchIn(this)
+                underTest.startedKeyguardTransitionStep.onEach { startedSteps.add(it) }.launchIn(this)
 
             val steps = mutableListOf<TransitionStep>()
 
@@ -192,8 +187,4 @@
 
             job.cancel()
         }
-
-    companion object {
-        private val IMMEDIATE = Dispatchers.Main.immediate
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 702f3763..46e4679 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -21,6 +21,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Interpolators
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl
@@ -92,10 +94,12 @@
         transitionRepository = KeyguardTransitionRepositoryImpl()
         runner = KeyguardTransitionRunner(transitionRepository)
 
+        val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
         fromLockscreenTransitionInteractor =
             FromLockscreenTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardInteractor =
+                    KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
                 shadeRepository = shadeRepository,
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -105,7 +109,8 @@
         fromDreamingTransitionInteractor =
             FromDreamingTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardInteractor =
+                    KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
             )
@@ -114,7 +119,8 @@
         fromAodTransitionInteractor =
             FromAodTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardInteractor =
+                    KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
             )
@@ -123,7 +129,8 @@
         fromGoneTransitionInteractor =
             FromGoneTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardInteractor =
+                    KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
             )
@@ -132,7 +139,8 @@
         fromDozingTransitionInteractor =
             FromDozingTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardInteractor =
+                    KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
             )
@@ -141,7 +149,8 @@
         fromOccludedTransitionInteractor =
             FromOccludedTransitionInteractor(
                 scope = testScope,
-                keyguardInteractor = KeyguardInteractor(keyguardRepository, commandQueue),
+                keyguardInteractor =
+                    KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
                 keyguardTransitionRepository = mockTransitionRepository,
                 keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
             )
@@ -149,7 +158,7 @@
     }
 
     @Test
-    fun `DREAMING to LOCKSCREEN`() =
+    fun `DREAMING to LOCKSCREEN - dreaming state changes first`() =
         testScope.runTest {
             // GIVEN a device is dreaming and occluded
             keyguardRepository.setDreamingWithOverlay(true)
@@ -179,9 +188,59 @@
             )
             // AND dreaming has stopped
             keyguardRepository.setDreamingWithOverlay(false)
+            advanceUntilIdle()
+            // AND then occluded has stopped
+            keyguardRepository.setKeyguardOccluded(false)
+            advanceUntilIdle()
+
+            val info =
+                withArgCaptor<TransitionInfo> {
+                    verify(mockTransitionRepository).startTransition(capture())
+                }
+            // THEN a transition to BOUNCER should occur
+            assertThat(info.ownerName).isEqualTo("FromDreamingTransitionInteractor")
+            assertThat(info.from).isEqualTo(KeyguardState.DREAMING)
+            assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
+            assertThat(info.animator).isNotNull()
+
+            coroutineContext.cancelChildren()
+        }
+
+    @Test
+    fun `DREAMING to LOCKSCREEN - occluded state changes first`() =
+        testScope.runTest {
+            // GIVEN a device is dreaming and occluded
+            keyguardRepository.setDreamingWithOverlay(true)
+            keyguardRepository.setKeyguardOccluded(true)
+            runCurrent()
+
+            // GIVEN a prior transition has run to DREAMING
+            runner.startTransition(
+                testScope,
+                TransitionInfo(
+                    ownerName = "",
+                    from = KeyguardState.LOCKSCREEN,
+                    to = KeyguardState.DREAMING,
+                    animator =
+                        ValueAnimator().apply {
+                            duration = 10
+                            interpolator = Interpolators.LINEAR
+                        },
+                )
+            )
+            runCurrent()
+            reset(mockTransitionRepository)
+
+            // WHEN doze is complete
+            keyguardRepository.setDozeTransitionModel(
+                DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
+            )
             // AND occluded has stopped
             keyguardRepository.setKeyguardOccluded(false)
             advanceUntilIdle()
+            // AND then dreaming has stopped
+            keyguardRepository.setDreamingWithOverlay(false)
+            advanceUntilIdle()
 
             val info =
                 withArgCaptor<TransitionInfo> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
index 3166214..6236616 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -33,11 +34,10 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class LightRevealScrimInteractorTest : SysuiTestCase() {
     private val fakeKeyguardTransitionRepository = FakeKeyguardTransitionRepository()
     private val fakeLightRevealScrimRepository = FakeLightRevealScrimRepository()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
index fbfeca9..f86ac79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
@@ -17,18 +17,18 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class PrimaryBouncerCallbackInteractorTest : SysuiTestCase() {
     private val mPrimaryBouncerCallbackInteractor = PrimaryBouncerCallbackInteractor()
     @Mock
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 ea7bc91..75b74b0 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
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import android.os.Looper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -35,12 +36,11 @@
 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
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
     private lateinit var repository: FakeKeyguardBouncerRepository
     @Mock private lateinit var bouncerView: BouncerView
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
index 06e397d..706154e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -33,10 +34,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: DreamingToLockscreenTransitionViewModel
     private lateinit var repository: FakeKeyguardTransitionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
index 14c3b50..b15ce10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: GoneToDreamingTransitionViewModel
     private lateinit var repository: FakeKeyguardTransitionRepository
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 4b04b7b..03a347e 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
@@ -125,9 +125,18 @@
                 ),
             )
         repository = FakeKeyguardRepository()
+        val featureFlags =
+            FakeFeatureFlags().apply {
+                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
+                set(Flags.FACE_AUTH_REFACTOR, true)
+            }
 
         val keyguardInteractor =
-            KeyguardInteractor(repository = repository, commandQueue = commandQueue)
+            KeyguardInteractor(
+                repository = repository,
+                commandQueue = commandQueue,
+                featureFlags = featureFlags,
+            )
         whenever(userTracker.userHandle).thenReturn(mock())
         whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
             .thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
@@ -191,10 +200,7 @@
                         keyguardStateController = keyguardStateController,
                         userTracker = userTracker,
                         activityStarter = activityStarter,
-                        featureFlags =
-                            FakeFeatureFlags().apply {
-                                set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
-                            },
+                        featureFlags = featureFlags,
                         repository = { quickAffordanceRepository },
                         launchAnimator = launchAnimator,
                     ),
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 3727134..586af62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -16,28 +16,29 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.BouncerView
 import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
+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
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
+@kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardBouncerViewModelTest : SysuiTestCase() {
     lateinit var underTest: KeyguardBouncerViewModel
     @Mock lateinit var bouncerView: BouncerView
@@ -51,7 +52,7 @@
 
     @Test
     fun setMessage() =
-        runBlocking(Dispatchers.Main.immediate) {
+        runTest {
             val flow = MutableStateFlow<BouncerShowMessageModel?>(null)
             var message: BouncerShowMessageModel? = null
             Mockito.`when`(bouncerInteractor.showMessage)
@@ -62,6 +63,8 @@
             flow.value = BouncerShowMessageModel(message = "abc", colorStateList = null)
 
             val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this)
+            // Run the tasks that are pending at this point of virtual time.
+            runCurrent()
             assertThat(message?.message).isEqualTo("abc")
             job.cancel()
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
index ed31dc3..d94c108 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: LockscreenToDreamingTransitionViewModel
     private lateinit var repository: FakeKeyguardTransitionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index 458b315..12ec24d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: LockscreenToOccludedTransitionViewModel
     private lateinit var repository: FakeKeyguardTransitionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
index a36214e..0c4e845 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
     private lateinit var underTest: OccludedToLockscreenTransitionViewModel
     private lateinit var repository: FakeKeyguardTransitionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
index 3b5e6b9..d1744c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
@@ -276,6 +276,52 @@
         }
 
     @Test
+    fun intNullable_logsNull() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+            val flow = flow {
+                for (int in listOf(null, 6, null, 8)) {
+                    systemClock.advanceTime(100L)
+                    emit(int)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = 1234,
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) + SEPARATOR + FULL_NAME + SEPARATOR + "1234"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) + SEPARATOR + FULL_NAME + SEPARATOR + "null"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) + SEPARATOR + FULL_NAME + SEPARATOR + "6"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) + SEPARATOR + FULL_NAME + SEPARATOR + "null"
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(500L) + SEPARATOR + FULL_NAME + SEPARATOR + "8"
+                )
+
+            job.cancel()
+        }
+
+    @Test
     fun int_logsUpdates() =
         testScope.runTest {
             systemClock.setCurrentTimeMillis(100L)
@@ -1030,6 +1076,246 @@
             job.cancel()
         }
 
+    // ---- Flow<List<T>> tests ----
+
+    @Test
+    fun list_doesNotLogWhenNotCollected() {
+        val flow = flowOf(listOf(5), listOf(6), listOf(7))
+
+        flow.logDiffsForTable(
+            tableLogBuffer,
+            COLUMN_PREFIX,
+            COLUMN_NAME,
+            initialValue = listOf(1234),
+        )
+
+        val logs = dumpLog()
+        assertThat(logs).doesNotContain(COLUMN_PREFIX)
+        assertThat(logs).doesNotContain(COLUMN_NAME)
+        assertThat(logs).doesNotContain("1234")
+    }
+
+    @Test
+    fun list_logsInitialWhenCollected() =
+        testScope.runTest {
+            val flow = flowOf(listOf(5), listOf(6), listOf(7))
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = listOf(1234),
+                )
+
+            systemClock.setCurrentTimeMillis(3000L)
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(3000L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf(1234).toString()
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun list_logsUpdates() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+
+            val listItems =
+                listOf(listOf("val1", "val2"), listOf("val3"), listOf("val4", "val5", "val6"))
+            val flow = flow {
+                for (list in listItems) {
+                    systemClock.advanceTime(100L)
+                    emit(list)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = listOf("val0", "val00"),
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf("val0", "val00").toString()
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf("val1", "val2").toString()
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf("val3").toString()
+                )
+            assertThat(logs)
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(400L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf("val4", "val5", "val6").toString()
+                )
+
+            job.cancel()
+        }
+
+    @Test
+    fun list_doesNotLogIfSameValue() =
+        testScope.runTest {
+            systemClock.setCurrentTimeMillis(100L)
+
+            val listItems =
+                listOf(
+                    listOf("val0", "val00"),
+                    listOf("val1"),
+                    listOf("val1"),
+                    listOf("val1", "val2"),
+                )
+            val flow = flow {
+                for (bool in listItems) {
+                    systemClock.advanceTime(100L)
+                    emit(bool)
+                }
+            }
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = listOf("val0", "val00"),
+                )
+
+            val job = launch { flowWithLogging.collect() }
+
+            val logs = dumpLog()
+
+            val expected1 =
+                TABLE_LOG_DATE_FORMAT.format(100L) +
+                    SEPARATOR +
+                    FULL_NAME +
+                    SEPARATOR +
+                    listOf("val0", "val00").toString()
+            val expected3 =
+                TABLE_LOG_DATE_FORMAT.format(300L) +
+                    SEPARATOR +
+                    FULL_NAME +
+                    SEPARATOR +
+                    listOf("val1").toString()
+            val expected5 =
+                TABLE_LOG_DATE_FORMAT.format(500L) +
+                    SEPARATOR +
+                    FULL_NAME +
+                    SEPARATOR +
+                    listOf("val1", "val2").toString()
+            assertThat(logs).contains(expected1)
+            assertThat(logs).contains(expected3)
+            assertThat(logs).contains(expected5)
+
+            val unexpected2 =
+                TABLE_LOG_DATE_FORMAT.format(200L) +
+                    SEPARATOR +
+                    FULL_NAME +
+                    SEPARATOR +
+                    listOf("val0", "val00")
+            val unexpected4 =
+                TABLE_LOG_DATE_FORMAT.format(400L) +
+                    SEPARATOR +
+                    FULL_NAME +
+                    SEPARATOR +
+                    listOf("val1")
+            assertThat(logs).doesNotContain(unexpected2)
+            assertThat(logs).doesNotContain(unexpected4)
+            job.cancel()
+        }
+
+    @Test
+    fun list_worksForStateFlows() =
+        testScope.runTest {
+            val flow = MutableStateFlow(listOf(1111))
+
+            val flowWithLogging =
+                flow.logDiffsForTable(
+                    tableLogBuffer,
+                    COLUMN_PREFIX,
+                    COLUMN_NAME,
+                    initialValue = listOf(1111),
+                )
+
+            systemClock.setCurrentTimeMillis(50L)
+            val job = launch { flowWithLogging.collect() }
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(50L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf(1111).toString()
+                )
+
+            systemClock.setCurrentTimeMillis(100L)
+            flow.emit(listOf(2222, 3333))
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(100L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf(2222, 3333).toString()
+                )
+
+            systemClock.setCurrentTimeMillis(200L)
+            flow.emit(listOf(3333, 4444))
+            assertThat(dumpLog())
+                .contains(
+                    TABLE_LOG_DATE_FORMAT.format(200L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf(3333, 4444).toString()
+                )
+
+            // Doesn't log duplicates
+            systemClock.setCurrentTimeMillis(300L)
+            flow.emit(listOf(3333, 4444))
+            assertThat(dumpLog())
+                .doesNotContain(
+                    TABLE_LOG_DATE_FORMAT.format(300L) +
+                        SEPARATOR +
+                        FULL_NAME +
+                        SEPARATOR +
+                        listOf(3333, 4444).toString()
+                )
+
+            job.cancel()
+        }
+
     private fun dumpLog(): String {
         val outputWriter = StringWriter()
         tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt
index 432764a..c7f3fa0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt
@@ -36,6 +36,17 @@
     }
 
     @Test
+    fun setString_null() {
+        val underTest = TableChange()
+
+        underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName")
+        underTest.set(null as String?)
+
+        assertThat(underTest.hasData()).isTrue()
+        assertThat(underTest.getVal()).isEqualTo("null")
+    }
+
+    @Test
     fun setBoolean_isBoolean() {
         val underTest = TableChange()
 
@@ -58,6 +69,17 @@
     }
 
     @Test
+    fun setInt_null() {
+        val underTest = TableChange()
+
+        underTest.reset(timestamp = 100, columnPrefix = "", columnName = "fakeName")
+        underTest.set(null as Int?)
+
+        assertThat(underTest.hasData()).isTrue()
+        assertThat(underTest.getVal()).isEqualTo("null")
+    }
+
+    @Test
     fun setThenReset_isEmpty() {
         val underTest = TableChange()
 
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 44e2fbd..9f12329 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
@@ -40,6 +40,7 @@
 import androidx.media.utils.MediaConstants
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.InstanceIdSequenceFake
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
@@ -51,6 +52,7 @@
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaDataProvider
 import com.android.systemui.media.controls.resume.MediaResumeListener
+import com.android.systemui.media.controls.resume.ResumeMediaBrowser
 import com.android.systemui.media.controls.util.MediaControllerFactory
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
@@ -125,6 +127,7 @@
     @Mock lateinit var pendingIntent: PendingIntent
     @Mock lateinit var activityStarter: ActivityStarter
     @Mock lateinit var smartspaceManager: SmartspaceManager
+    @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
     @Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
     @Mock private lateinit var mediaRecommendationItem: SmartspaceAction
@@ -186,6 +189,7 @@
                 mediaFlags = mediaFlags,
                 logger = logger,
                 smartspaceManager = smartspaceManager,
+                keyguardUpdateMonitor = keyguardUpdateMonitor
             )
         verify(tunerService)
             .addTunable(capture(tunableCaptor), eq(Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION))
@@ -241,6 +245,7 @@
         whenever(mediaFlags.isRetainingPlayersEnabled()).thenReturn(false)
         whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
         whenever(logger.getNewInstanceId()).thenReturn(instanceIdSequence.newInstanceId())
+        whenever(keyguardUpdateMonitor.isUserInLockdown(any())).thenReturn(false)
     }
 
     @After
@@ -642,6 +647,59 @@
     }
 
     @Test
+    fun testOnNotificationRemoved_withResumption_tooManyPlayers() {
+        // Given the maximum number of resume controls already
+        val desc =
+            MediaDescription.Builder().run {
+                setTitle(SESSION_TITLE)
+                build()
+            }
+        for (i in 0..ResumeMediaBrowser.MAX_RESUMPTION_CONTROLS) {
+            addResumeControlAndLoad(desc, "$i:$PACKAGE_NAME")
+            clock.advanceTime(1000)
+        }
+
+        // And an active, resumable notification
+        whenever(controller.metadata).thenReturn(metadataBuilder.build())
+        addNotificationAndLoad()
+        val data = mediaDataCaptor.value
+        assertThat(data.resumption).isFalse()
+        mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+        // When the notification is removed
+        mediaDataManager.onNotificationRemoved(KEY)
+
+        // Then it is converted to resumption
+        verify(listener)
+            .onMediaDataLoaded(
+                eq(PACKAGE_NAME),
+                eq(KEY),
+                capture(mediaDataCaptor),
+                eq(true),
+                eq(0),
+                eq(false)
+            )
+        assertThat(mediaDataCaptor.value.resumption).isTrue()
+        assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+
+        // And the oldest resume control was removed
+        verify(listener).onMediaDataRemoved(eq("0:$PACKAGE_NAME"))
+    }
+
+    fun testOnNotificationRemoved_lockDownMode() {
+        whenever(keyguardUpdateMonitor.isUserInLockdown(any())).thenReturn(true)
+
+        addNotificationAndLoad()
+        val data = mediaDataCaptor.value
+        mediaDataManager.onNotificationRemoved(KEY)
+
+        verify(listener, never()).onMediaDataRemoved(eq(KEY))
+        verify(logger, never())
+            .logActiveConvertedToResume(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
+        verify(logger).logMediaRemoved(anyInt(), eq(PACKAGE_NAME), eq(data.instanceId))
+    }
+
+    @Test
     fun testAddResumptionControls() {
         // WHEN resumption controls are added
         val desc =
@@ -769,6 +827,24 @@
     }
 
     @Test
+    fun testAddResumptionControls_hasNoExtras() {
+        whenever(mediaFlags.isResumeProgressEnabled()).thenReturn(true)
+
+        // WHEN resumption controls are added that do not have any extras
+        val desc =
+            MediaDescription.Builder().run {
+                setTitle(SESSION_TITLE)
+                build()
+            }
+        addResumeControlAndLoad(desc)
+
+        // Resume progress is null
+        val data = mediaDataCaptor.value
+        assertThat(data.resumption).isTrue()
+        assertThat(data.resumeProgress).isEqualTo(null)
+    }
+
+    @Test
     fun testResumptionDisabled_dismissesResumeControls() {
         // WHEN there are resume controls and resumption is switched off
         val desc =
@@ -1846,7 +1922,10 @@
     }
 
     /** Helper function to add a resumption control and capture the resulting MediaData */
-    private fun addResumeControlAndLoad(desc: MediaDescription) {
+    private fun addResumeControlAndLoad(
+        desc: MediaDescription,
+        packageName: String = PACKAGE_NAME
+    ) {
         mediaDataManager.addResumptionControls(
             USER_ID,
             desc,
@@ -1854,14 +1933,14 @@
             session.sessionToken,
             APP_NAME,
             pendingIntent,
-            PACKAGE_NAME
+            packageName
         )
         assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
         assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
 
         verify(listener)
             .onMediaDataLoaded(
-                eq(PACKAGE_NAME),
+                eq(packageName),
                 eq(null),
                 capture(mediaDataCaptor),
                 eq(true),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index e201b6b..997198e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -21,12 +21,20 @@
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.util.MathUtils.abs
+import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.media.controls.MediaTestUtils
 import com.android.systemui.media.controls.models.player.MediaData
 import com.android.systemui.media.controls.models.recommendation.SmartspaceMediaData
@@ -49,6 +57,9 @@
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
@@ -90,11 +101,15 @@
     @Mock lateinit var mediaCarousel: MediaScrollView
     @Mock lateinit var pageIndicator: PageIndicator
     @Mock lateinit var mediaFlags: MediaFlags
+    @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+    @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+    private lateinit var transitionRepository: FakeKeyguardTransitionRepository
     @Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
     @Captor
     lateinit var configListener: ArgumentCaptor<ConfigurationController.ConfigurationListener>
     @Captor lateinit var newConfig: ArgumentCaptor<Configuration>
     @Captor lateinit var visualStabilityCallback: ArgumentCaptor<OnReorderingAllowedListener>
+    @Captor lateinit var keyguardCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback>
 
     private val clock = FakeSystemClock()
     private lateinit var mediaCarouselController: MediaCarouselController
@@ -102,6 +117,7 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        transitionRepository = FakeKeyguardTransitionRepository()
         mediaCarouselController =
             MediaCarouselController(
                 context,
@@ -119,11 +135,14 @@
                 logger,
                 debugLogger,
                 mediaFlags,
+                keyguardUpdateMonitor,
+                KeyguardTransitionInteractor(repository = transitionRepository),
             )
         verify(configurationController).addCallback(capture(configListener))
         verify(mediaDataManager).addListener(capture(listener))
         verify(visualStabilityProvider)
             .addPersistentReorderingAllowedListener(capture(visualStabilityCallback))
+        verify(keyguardUpdateMonitor).registerCallback(capture(keyguardCallback))
         whenever(mediaControlPanelFactory.get()).thenReturn(panel)
         whenever(panel.mediaViewController).thenReturn(mediaViewController)
         whenever(mediaDataManager.smartspaceMediaData).thenReturn(smartspaceMediaData)
@@ -740,4 +759,41 @@
         assertTrue(MediaPlayerData.visiblePlayerKeys().elementAt(0).isSsMediaRec)
         assertFalse(MediaPlayerData.visiblePlayerKeys().elementAt(0).data.active)
     }
+
+    @Test
+    fun testOnLockDownMode_hideMediaCarousel() {
+        whenever(keyguardUpdateMonitor.isUserInLockdown(context.userId)).thenReturn(true)
+        mediaCarouselController.mediaCarousel = mediaCarousel
+
+        keyguardCallback.value.onStrongAuthStateChanged(context.userId)
+
+        verify(mediaCarousel).visibility = View.GONE
+    }
+
+    @Test
+    fun testLockDownModeOff_showMediaCarousel() {
+        whenever(keyguardUpdateMonitor.isUserInLockdown(context.userId)).thenReturn(false)
+        whenever(keyguardUpdateMonitor.isUserUnlocked(context.userId)).thenReturn(true)
+        mediaCarouselController.mediaCarousel = mediaCarousel
+
+        keyguardCallback.value.onStrongAuthStateChanged(context.userId)
+
+        verify(mediaCarousel).visibility = View.VISIBLE
+    }
+
+    @ExperimentalCoroutinesApi
+    @Test
+    fun testKeyguardGone_showMediaCarousel() =
+        runTest(UnconfinedTestDispatcher()) {
+            mediaCarouselController.mediaCarousel = mediaCarousel
+
+            val job = mediaCarouselController.listenForAnyStateToGoneKeyguardTransition(this)
+            transitionRepository.sendTransitionStep(
+                TransitionStep(to = KeyguardState.GONE, transitionState = TransitionState.FINISHED)
+            )
+
+            verify(mediaCarousel).visibility = View.VISIBLE
+
+            job.cancel()
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
index 2f7eac2..af91cdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
@@ -33,6 +33,7 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.floatThat
 import org.mockito.Mock
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -139,14 +140,12 @@
         whenever(controlWidgetState.y).thenReturn(150F)
         whenever(controlWidgetState.height).thenReturn(20)
         // in current beizer, when the progress reach 0.38, the result will be 0.5
-        mediaViewController.squishViewState(mockViewState, 119F / 200F)
-        verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
-        mediaViewController.squishViewState(mockViewState, 150F / 200F)
-        verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
         mediaViewController.squishViewState(mockViewState, 181.4F / 200F)
         verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
+        verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
         mediaViewController.squishViewState(mockViewState, 200F / 200F)
         verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
+        verify(detailWidgetState, times(2)).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
     }
 
     @Test
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 f40e3a6..56e060d 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
@@ -16,6 +16,10 @@
 
 package com.android.systemui.media.dialog;
 
+import static android.media.RouteListingPreference.Item.SELECTION_BEHAVIOR_GO_TO_APP;
+import static android.media.RouteListingPreference.Item.SELECTION_BEHAVIOR_NONE;
+import static android.media.RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED;
+import static android.media.RouteListingPreference.Item.SUBTEXT_CUSTOM;
 import static android.media.RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -62,6 +66,7 @@
     private static final String TEST_DEVICE_ID_1 = "test_device_id_1";
     private static final String TEST_DEVICE_ID_2 = "test_device_id_2";
     private static final String TEST_SESSION_NAME = "test_session_name";
+    private static final String TEST_CUSTOM_SUBTEXT = "custom subtext";
 
     private static final int TEST_MAX_VOLUME = 20;
     private static final int TEST_CURRENT_VOLUME = 10;
@@ -431,12 +436,46 @@
     }
 
     @Test
-    public void subStatusSupported_onBindViewHolder_bindFailedStateDevice_verifyView() {
+    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);
+        when(mMediaDevice1.getSubtext()).thenReturn(SUBTEXT_CUSTOM);
+        when(mMediaDevice1.getSubtextString()).thenReturn(TEST_CUSTOM_SUBTEXT);
+        when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
+        when(mMediaDevice1.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mEndClickIcon.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mStatusIcon.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mSubTitleText.getText().toString()).isEqualTo(TEST_CUSTOM_SUBTEXT);
+        assertThat(mViewHolder.mTwoLineTitleText.getText().toString()).isEqualTo(
+                TEST_DEVICE_NAME_1);
+        assertThat(mViewHolder.mContainerLayout.hasOnClickListeners()).isFalse();
+    }
+
+    @Test
+    public void subStatusSupported_onBindViewHolder_bindDeviceRequirePremium_verifyView() {
         String deviceStatus = (String) mContext.getText(
                 R.string.media_output_status_require_premium);
         when(mMediaOutputController.isSubStatusSupported()).thenReturn(true);
-        when(mMediaDevice2.hasDisabledReason()).thenReturn(true);
-        when(mMediaDevice2.getDisableReason()).thenReturn(SUBTEXT_SUBSCRIPTION_REQUIRED);
+        when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
+        when(mMediaDevice2.hasSubtext()).thenReturn(true);
+        when(mMediaDevice2.getSubtext()).thenReturn(SUBTEXT_SUBSCRIPTION_REQUIRED);
+        when(mMediaDevice2.getSubtextString()).thenReturn(deviceStatus);
+        when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
 
         assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
@@ -444,9 +483,64 @@
         assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
         assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mStatusIcon.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mViewHolder.mSubTitleText.getText()).isEqualTo(deviceStatus);
         assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.hasOnClickListeners()).isTrue();
+    }
+
+    @Test
+    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);
+        when(mMediaDevice2.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_NONE);
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 1);
+
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mStatusIcon.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mSubTitleText.getText().toString()).isEqualTo(deviceStatus);
+        assertThat(mViewHolder.mTwoLineTitleText.getText().toString()).isEqualTo(
+                TEST_DEVICE_NAME_2);
+        assertThat(mViewHolder.mContainerLayout.hasOnClickListeners()).isFalse();
+    }
+
+    @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);
+        when(mMediaDevice1.hasOngoingSession()).thenReturn(true);
+        when(mMediaDevice1.getSelectionBehavior()).thenReturn(SELECTION_BEHAVIOR_GO_TO_APP);
+        mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+                .onCreateViewHolder(new LinearLayout(mContext), 0);
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mStatusIcon.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mSubTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTwoLineTitleText.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mSubTitleText.getText().toString()).isEqualTo(TEST_CUSTOM_SUBTEXT);
+        assertThat(mViewHolder.mTwoLineTitleText.getText().toString()).isEqualTo(
+                TEST_DEVICE_NAME_1);
+        assertThat(mViewHolder.mContainerLayout.hasOnClickListeners()).isTrue();
     }
 
     @Test
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 7c36e46..0bdcaf4 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
@@ -240,7 +240,6 @@
         verify(mMediaController, never()).unregisterCallback(any());
     }
 
-
     @Test
     public void stop_nearbyMediaDevicesManagerNotNull_unregistersNearbyDevicesCallback() {
         mMediaOutputController.start(mCb);
@@ -253,7 +252,7 @@
 
     @Test
     public void tryToLaunchMediaApplication_nullIntent_skip() {
-        mMediaOutputController.tryToLaunchMediaApplication();
+        mMediaOutputController.tryToLaunchMediaApplication(mDialogLaunchView);
 
         verify(mCb, never()).dismissDialog();
     }
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 31866a8..9ecc63c 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
@@ -36,6 +36,7 @@
 import android.os.PowerExemptionManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.util.FeatureFlagUtils;
 import android.view.View;
 
 import androidx.test.filters.SmallTest;
@@ -171,6 +172,8 @@
                 mLocalBluetoothLeBroadcast);
         when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
         when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+        FeatureFlagUtils.setEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
         when(mMediaDevice.isBLEDevice()).thenReturn(false);
 
         assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.GONE);
@@ -184,6 +187,62 @@
     }
 
     @Test
+    public void isBroadcastSupported_flagOnAndConnectBleDevice_returnsTrue() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        FeatureFlagUtils.setEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
+        when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
+        assertThat(mMediaOutputDialog.isBroadcastSupported()).isTrue();
+    }
+
+    @Test
+    public void isBroadcastSupported_flagOnAndNoBleDevice_returnsFalse() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        FeatureFlagUtils.setEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
+        when(mMediaDevice.isBLEDevice()).thenReturn(false);
+
+        assertThat(mMediaOutputDialog.isBroadcastSupported()).isFalse();
+    }
+
+    @Test
+    public void isBroadcastSupported_notSupportBroadcastAndflagOn_returnsFalse() {
+        FeatureFlagUtils.setEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
+
+        assertThat(mMediaOutputDialog.isBroadcastSupported()).isFalse();
+    }
+
+    @Test
+    public void isBroadcastSupported_flagOffAndConnectToBleDevice_returnsTrue() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        FeatureFlagUtils.setEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, false);
+        when(mMediaDevice.isBLEDevice()).thenReturn(true);
+
+        assertThat(mMediaOutputDialog.isBroadcastSupported()).isTrue();
+    }
+
+    @Test
+    public void isBroadcastSupported_flagOffAndNoBleDevice_returnsTrue() {
+        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+                mLocalBluetoothLeBroadcast);
+        when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+        FeatureFlagUtils.setEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, false);
+        when(mMediaDevice.isBLEDevice()).thenReturn(false);
+
+        assertThat(mMediaOutputDialog.isBroadcastSupported()).isTrue();
+    }
+
+    @Test
     public void getBroadcastIconVisibility_isBroadcasting_returnVisible() {
         when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
                 mLocalBluetoothLeBroadcast);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
index 8055b98..4fc9ca7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -65,7 +65,13 @@
 
     @Test
     fun getIconInfoFromPackageName_nullPackageName_returnsDefault() {
-        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null) {}
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(
+                context,
+                appPackageName = null,
+                isReceiver = false,
+            ) {
+            }
 
         assertThat(iconInfo.isAppIcon).isFalse()
         assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -74,10 +80,32 @@
     }
 
     @Test
+    fun getIconInfoFromPackageName_nullPackageName_isReceiver_returnsDefault() {
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(
+                context,
+                appPackageName = null,
+                isReceiver = true,
+            ) {
+            }
+
+        assertThat(iconInfo.isAppIcon).isFalse()
+        assertThat(iconInfo.contentDescription.loadContentDescription(context))
+            .isEqualTo(
+                context.getString(R.string.media_transfer_receiver_content_description_unknown_app)
+            )
+        assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
+    }
+
+    @Test
     fun getIconInfoFromPackageName_nullPackageName_exceptionFnNotTriggered() {
         var exceptionTriggered = false
 
-        MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null) {
+        MediaTttUtils.getIconInfoFromPackageName(
+            context,
+            appPackageName = null,
+            isReceiver = false,
+        ) {
             exceptionTriggered = true
         }
 
@@ -86,7 +114,13 @@
 
     @Test
     fun getIconInfoFromPackageName_invalidPackageName_returnsDefault() {
-        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, "fakePackageName") {}
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(
+                context,
+                appPackageName = "fakePackageName",
+                isReceiver = false,
+            ) {
+            }
 
         assertThat(iconInfo.isAppIcon).isFalse()
         assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -95,19 +129,58 @@
     }
 
     @Test
+    fun getIconInfoFromPackageName_invalidPackageName_isReceiver_returnsDefault() {
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(
+                context,
+                appPackageName = "fakePackageName",
+                isReceiver = true,
+            ) {
+            }
+
+        assertThat(iconInfo.isAppIcon).isFalse()
+        assertThat(iconInfo.contentDescription.loadContentDescription(context))
+            .isEqualTo(
+                context.getString(R.string.media_transfer_receiver_content_description_unknown_app)
+            )
+        assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
+    }
+
+    @Test
     fun getIconInfoFromPackageName_invalidPackageName_exceptionFnTriggered() {
         var exceptionTriggered = false
 
-        MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = "fakePackageName") {
-            exceptionTriggered = true
-        }
+        MediaTttUtils.getIconInfoFromPackageName(
+            context,
+            appPackageName = "fakePackageName",
+            isReceiver = false
+        ) { exceptionTriggered = true }
+
+        assertThat(exceptionTriggered).isTrue()
+    }
+
+    @Test
+    fun getIconInfoFromPackageName_invalidPackageName_isReceiver_exceptionFnTriggered() {
+        var exceptionTriggered = false
+
+        MediaTttUtils.getIconInfoFromPackageName(
+            context,
+            appPackageName = "fakePackageName",
+            isReceiver = true
+        ) { exceptionTriggered = true }
 
         assertThat(exceptionTriggered).isTrue()
     }
 
     @Test
     fun getIconInfoFromPackageName_validPackageName_returnsAppInfo() {
-        val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME) {}
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(
+                context,
+                PACKAGE_NAME,
+                isReceiver = false,
+            ) {
+            }
 
         assertThat(iconInfo.isAppIcon).isTrue()
         assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
@@ -115,10 +188,42 @@
     }
 
     @Test
+    fun getIconInfoFromPackageName_validPackageName_isReceiver_returnsAppInfo() {
+        val iconInfo =
+            MediaTttUtils.getIconInfoFromPackageName(
+                context,
+                PACKAGE_NAME,
+                isReceiver = true,
+            ) {
+            }
+
+        assertThat(iconInfo.isAppIcon).isTrue()
+        assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
+        assertThat(iconInfo.contentDescription.loadContentDescription(context))
+            .isEqualTo(
+                context.getString(
+                    R.string.media_transfer_receiver_content_description_with_app_name,
+                    APP_NAME
+                )
+            )
+    }
+
+    @Test
     fun getIconInfoFromPackageName_validPackageName_exceptionFnNotTriggered() {
         var exceptionTriggered = false
 
-        MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME) {
+        MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, isReceiver = false) {
+            exceptionTriggered = true
+        }
+
+        assertThat(exceptionTriggered).isFalse()
+    }
+
+    @Test
+    fun getIconInfoFromPackageName_validPackageName_isReceiver_exceptionFnNotTriggered() {
+        var exceptionTriggered = false
+
+        MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, isReceiver = true) {
             exceptionTriggered = true
         }
 
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 dba2da7..19dd2f0 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
@@ -354,7 +354,11 @@
 
         val view = getChipView()
         assertThat(view.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
-        assertThat(view.getAppIconView().contentDescription).isEqualTo(APP_NAME)
+        assertThat(view.getAppIconView().contentDescription)
+            .isEqualTo(context.getString(
+                R.string.media_transfer_receiver_content_description_with_app_name,
+                APP_NAME,
+            ))
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
index 1042ea7..4977775 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
@@ -24,6 +24,8 @@
     private val taskListProvider = TestRecentTaskListProvider()
     private val scope = CoroutineScope(Dispatchers.Unconfined)
     private val appSelectorComponentName = ComponentName("com.test", "AppSelector")
+    private val callerPackageName = "com.test.caller"
+    private val callerComponentName = ComponentName(callerPackageName, "Caller")
 
     private val hostUserHandle = UserHandle.of(123)
     private val otherUserHandle = UserHandle.of(456)
@@ -31,14 +33,16 @@
     private val view: MediaProjectionAppSelectorView = mock()
     private val featureFlags: FeatureFlags = mock()
 
-    private val controller = MediaProjectionAppSelectorController(
-        taskListProvider,
-        view,
-        featureFlags,
-        hostUserHandle,
-        scope,
-        appSelectorComponentName
-    )
+    private val controller =
+        MediaProjectionAppSelectorController(
+            taskListProvider,
+            view,
+            featureFlags,
+            hostUserHandle,
+            scope,
+            appSelectorComponentName,
+            callerPackageName
+        )
 
     @Test
     fun initNoRecentTasks_bindsEmptyList() {
@@ -51,104 +55,87 @@
 
     @Test
     fun initOneRecentTask_bindsList() {
-        taskListProvider.tasks = listOf(
-            createRecentTask(taskId = 1)
-        )
+        taskListProvider.tasks = listOf(createRecentTask(taskId = 1))
 
         controller.init()
 
-        verify(view).bind(
-            listOf(
-                createRecentTask(taskId = 1)
-            )
-        )
+        verify(view).bind(listOf(createRecentTask(taskId = 1)))
     }
 
     @Test
     fun initMultipleRecentTasksWithoutAppSelectorTask_bindsListInTheSameOrder() {
-        val tasks = listOf(
-            createRecentTask(taskId = 1),
-            createRecentTask(taskId = 2),
-            createRecentTask(taskId = 3),
-        )
-        taskListProvider.tasks = tasks
-
-        controller.init()
-
-        verify(view).bind(
+        val tasks =
             listOf(
                 createRecentTask(taskId = 1),
                 createRecentTask(taskId = 2),
                 createRecentTask(taskId = 3),
             )
-        )
-    }
-
-    @Test
-    fun initRecentTasksWithAppSelectorTasks_bindsAppSelectorTasksAtTheEnd() {
-        val tasks = listOf(
-            createRecentTask(taskId = 1),
-            createRecentTask(taskId = 2, topActivityComponent = appSelectorComponentName),
-            createRecentTask(taskId = 3),
-            createRecentTask(taskId = 4, topActivityComponent = appSelectorComponentName),
-            createRecentTask(taskId = 5),
-        )
         taskListProvider.tasks = tasks
 
         controller.init()
 
-        verify(view).bind(
+        verify(view)
+            .bind(
+                listOf(
+                    createRecentTask(taskId = 1),
+                    createRecentTask(taskId = 2),
+                    createRecentTask(taskId = 3),
+                )
+            )
+    }
+
+    @Test
+    fun initRecentTasksWithAppSelectorTasks_removeAppSelector() {
+        val tasks =
             listOf(
                 createRecentTask(taskId = 1),
-                createRecentTask(taskId = 3),
-                createRecentTask(taskId = 5),
                 createRecentTask(taskId = 2, topActivityComponent = appSelectorComponentName),
-                createRecentTask(taskId = 4, topActivityComponent = appSelectorComponentName),
+                createRecentTask(taskId = 3),
+                createRecentTask(taskId = 4),
             )
-        )
+        taskListProvider.tasks = tasks
+
+        controller.init()
+
+        verify(view)
+            .bind(
+                listOf(
+                    createRecentTask(taskId = 1),
+                    createRecentTask(taskId = 3),
+                    createRecentTask(taskId = 4),
+                )
+            )
+    }
+
+    @Test
+    fun initRecentTasksWithAppSelectorTasks_bindsCallerTasksAtTheEnd() {
+        val tasks =
+            listOf(
+                createRecentTask(taskId = 1),
+                createRecentTask(taskId = 2, topActivityComponent = callerComponentName),
+                createRecentTask(taskId = 3),
+                createRecentTask(taskId = 4),
+            )
+        taskListProvider.tasks = tasks
+
+        controller.init()
+
+        verify(view)
+            .bind(
+                listOf(
+                    createRecentTask(taskId = 1),
+                    createRecentTask(taskId = 3),
+                    createRecentTask(taskId = 4),
+                    createRecentTask(taskId = 2, topActivityComponent = callerComponentName),
+                )
+            )
     }
 
     @Test
     fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesDisabled_bindsOnlyTasksWithHostProfile() {
         givenEnterprisePoliciesFeatureFlag(enabled = false)
 
-        val tasks = listOf(
-            createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
-            createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
-            createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
-            createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
-            createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
-        )
-        taskListProvider.tasks = tasks
-
-        controller.init()
-
-        verify(view).bind(
-            listOf(
-                createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
-                createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
-                createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
-            )
-        )
-    }
-
-    @Test
-    fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesEnabled_bindsAllTasks() {
-        givenEnterprisePoliciesFeatureFlag(enabled = true)
-
-        val tasks = listOf(
-            createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
-            createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
-            createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
-            createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
-            createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
-        )
-        taskListProvider.tasks = tasks
-
-        controller.init()
-
-        // TODO(b/233348916) should filter depending on the policies
-        verify(view).bind(
+        val tasks =
             listOf(
                 createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
                 createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
@@ -156,7 +143,47 @@
                 createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
                 createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
             )
-        )
+        taskListProvider.tasks = tasks
+
+        controller.init()
+
+        verify(view)
+            .bind(
+                listOf(
+                    createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+                    createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+                    createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+                )
+            )
+    }
+
+    @Test
+    fun initRecentTasksWithAppSelectorTasks_enterprisePoliciesEnabled_bindsAllTasks() {
+        givenEnterprisePoliciesFeatureFlag(enabled = true)
+
+        val tasks =
+            listOf(
+                createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+                createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
+                createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+                createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
+                createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+            )
+        taskListProvider.tasks = tasks
+
+        controller.init()
+
+        // TODO(b/233348916) should filter depending on the policies
+        verify(view)
+            .bind(
+                listOf(
+                    createRecentTask(taskId = 1, userId = hostUserHandle.identifier),
+                    createRecentTask(taskId = 2, userId = otherUserHandle.identifier),
+                    createRecentTask(taskId = 3, userId = hostUserHandle.identifier),
+                    createRecentTask(taskId = 4, userId = otherUserHandle.identifier),
+                    createRecentTask(taskId = 5, userId = hostUserHandle.identifier),
+                )
+            )
     }
 
     private fun givenEnterprisePoliciesFeatureFlag(enabled: Boolean) {
@@ -183,6 +210,5 @@
         var tasks: List<RecentTask> = emptyList()
 
         override suspend fun loadRecentTasks(): List<RecentTask> = tasks
-
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
new file mode 100644
index 0000000..bc31a0e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.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.navigationbar.gestural
+
+import android.os.Handler
+import android.os.Looper
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_UP
+import android.view.ViewConfiguration
+import android.view.WindowManager
+import androidx.test.filters.SmallTest
+import com.android.internal.util.LatencyTracker
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.NavigationEdgeBackPlugin
+import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BackPanelControllerTest : SysuiTestCase() {
+    companion object {
+        private const val START_X: Float = 0f
+    }
+    private lateinit var mBackPanelController: BackPanelController
+    private lateinit var testableLooper: TestableLooper
+    private var triggerThreshold: Float = 0.0f
+    private val touchSlop = ViewConfiguration.get(context).scaledEdgeSlop
+    @Mock private lateinit var vibratorHelper: VibratorHelper
+    @Mock private lateinit var windowManager: WindowManager
+    @Mock private lateinit var configurationController: ConfigurationController
+    @Mock private lateinit var latencyTracker: LatencyTracker
+    @Mock private lateinit var layoutParams: WindowManager.LayoutParams
+    @Mock private lateinit var backCallback: NavigationEdgeBackPlugin.BackCallback
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        mBackPanelController =
+            BackPanelController(
+                context,
+                windowManager,
+                ViewConfiguration.get(context),
+                Handler.createAsync(Looper.myLooper()),
+                vibratorHelper,
+                configurationController,
+                latencyTracker
+            )
+        mBackPanelController.setLayoutParams(layoutParams)
+        mBackPanelController.setBackCallback(backCallback)
+        mBackPanelController.setIsLeftPanel(true)
+        testableLooper = TestableLooper.get(this)
+        triggerThreshold = mBackPanelController.params.staticTriggerThreshold
+    }
+
+    @Test
+    fun handlesActionDown() {
+        startTouch()
+
+        assertThat(mBackPanelController.currentState)
+            .isEqualTo(BackPanelController.GestureState.GONE)
+    }
+
+    @Test
+    fun staysHiddenBeforeSlopCrossed() {
+        startTouch()
+        // Move just enough to not cross the touch slop
+        continueTouch(START_X + touchSlop - 1)
+
+        assertThat(mBackPanelController.currentState)
+            .isEqualTo(BackPanelController.GestureState.GONE)
+    }
+
+    @Test
+    fun handlesBackCommitted() {
+        startTouch()
+        // Move once to cross the touch slop
+        continueTouch(START_X + touchSlop.toFloat() + 1)
+        // Move again to cross the back trigger threshold
+        continueTouch(START_X + touchSlop + triggerThreshold + 1)
+
+        assertThat(mBackPanelController.currentState)
+            .isEqualTo(BackPanelController.GestureState.ACTIVE)
+        verify(backCallback).setTriggerBack(true)
+        testableLooper.moveTimeForward(100)
+        testableLooper.processAllMessages()
+        verify(vibratorHelper).vibrate(VIBRATE_ACTIVATED_EFFECT)
+
+        finishTouchActionUp(START_X + touchSlop + triggerThreshold + 1)
+        assertThat(mBackPanelController.currentState)
+            .isEqualTo(BackPanelController.GestureState.FLUNG)
+        verify(backCallback).triggerBack()
+    }
+
+    @Test
+    fun handlesBackCancelled() {
+        startTouch()
+        continueTouch(START_X + touchSlop.toFloat() + 1)
+        continueTouch(
+            START_X + touchSlop + triggerThreshold -
+                mBackPanelController.params.deactivationSwipeTriggerThreshold
+        )
+        clearInvocations(backCallback)
+        Thread.sleep(MIN_DURATION_ACTIVE_ANIMATION)
+        // Move in the opposite direction to cross the deactivation threshold and cancel back
+        continueTouch(START_X)
+
+        assertThat(mBackPanelController.currentState)
+            .isEqualTo(BackPanelController.GestureState.INACTIVE)
+        verify(backCallback).setTriggerBack(false)
+        verify(vibratorHelper).vibrate(VIBRATE_DEACTIVATED_EFFECT)
+
+        finishTouchActionUp(START_X)
+        verify(backCallback).cancelBack()
+    }
+
+    private fun startTouch() {
+        mBackPanelController.onMotionEvent(createMotionEvent(ACTION_DOWN, START_X, 0f))
+    }
+
+    private fun continueTouch(x: Float) {
+        mBackPanelController.onMotionEvent(createMotionEvent(ACTION_MOVE, x, 0f))
+    }
+
+    private fun finishTouchActionUp(x: Float) {
+        mBackPanelController.onMotionEvent(createMotionEvent(ACTION_UP, x, 0f))
+    }
+
+    private fun createMotionEvent(action: Int, x: Float, y: Float): MotionEvent {
+        return MotionEvent.obtain(0L, 0L, action, x, y, 0)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
index bc67df6..5f206b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
@@ -13,8 +13,9 @@
 
 @RunWith(Parameterized::class)
 @SmallTest
-internal class FloatingRotationButtonPositionCalculatorTest(private val testCase: TestCase)
-    : SysuiTestCase() {
+internal class FloatingRotationButtonPositionCalculatorTest(
+        private val testCase: TestCase,
+) : SysuiTestCase() {
 
     @Test
     fun calculatePosition() {
@@ -34,11 +35,18 @@
         val expectedPosition: Position
     ) {
         override fun toString(): String =
-            "when calculator = $calculator, " +
-                "rotation = $rotation, " +
-                "taskbarVisible = $taskbarVisible, " +
-                "taskbarStashed = $taskbarStashed - " +
-                "expected $expectedPosition"
+                buildString {
+                    append("when calculator = ")
+                    append(when (calculator) {
+                        posLeftCalculator -> "LEFT"
+                        posRightCalculator -> "RIGHT"
+                        else -> error("Unknown calculator: $calculator")
+                    })
+                    append(", rotation = $rotation")
+                    append(", taskbarVisible = $taskbarVisible")
+                    append(", taskbarStashed = $taskbarStashed")
+                    append(" - expected $expectedPosition")
+                }
     }
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/MotionEventsHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/MotionEventsHandlerTest.java
deleted file mode 100644
index 509d5f0..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/MotionEventsHandlerTest.java
+++ /dev/null
@@ -1,145 +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.navigationbar.gestural;
-
-import static android.view.InputDevice.SOURCE_TOUCHPAD;
-import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
-import static android.view.MotionEvent.AXIS_GESTURE_X_OFFSET;
-import static android.view.MotionEvent.AXIS_GESTURE_Y_OFFSET;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.MotionEvent;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.flags.FakeFeatureFlags;
-import com.android.systemui.flags.Flags;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for {@link MotionEventsHandler}.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class MotionEventsHandlerTest extends SysuiTestCase {
-
-    private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
-    private static int SCALE = 100;
-
-    private MotionEventsHandler mMotionEventsHandler;
-
-    @Before
-    public void setUp() {
-        mFeatureFlags.set(Flags.TRACKPAD_GESTURE_BACK, true);
-        mMotionEventsHandler = new MotionEventsHandler(mFeatureFlags, SCALE);
-    }
-
-    @Test
-    public void onTouchEvent_touchScreen_hasCorrectDisplacements() {
-        MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 100, 100, 0);
-        // TODO: change to use classification after gesture library is ported.
-        down.setSource(SOURCE_TOUCHSCREEN);
-        MotionEvent move1 = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 150, 125, 0);
-        move1.setSource(SOURCE_TOUCHSCREEN);
-        MotionEvent move2 = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 200, 150, 0);
-        move2.setSource(SOURCE_TOUCHSCREEN);
-        MotionEvent up = MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, 250, 175, 0);
-        up.setSource(SOURCE_TOUCHSCREEN);
-
-        mMotionEventsHandler.onMotionEvent(down);
-        mMotionEventsHandler.onMotionEvent(move1);
-        assertThat(mMotionEventsHandler.getDisplacementX(move1)).isEqualTo(50);
-        assertThat(mMotionEventsHandler.getDisplacementY(move1)).isEqualTo(25);
-        mMotionEventsHandler.onMotionEvent(move2);
-        assertThat(mMotionEventsHandler.getDisplacementX(move2)).isEqualTo(100);
-        assertThat(mMotionEventsHandler.getDisplacementY(move2)).isEqualTo(50);
-        mMotionEventsHandler.onMotionEvent(up);
-        assertThat(mMotionEventsHandler.getDisplacementX(up)).isEqualTo(150);
-        assertThat(mMotionEventsHandler.getDisplacementY(up)).isEqualTo(75);
-    }
-
-    @Test
-    public void onTouchEvent_trackpad_hasCorrectDisplacements() {
-        MotionEvent.PointerCoords[] downPointerCoords = new MotionEvent.PointerCoords[1];
-        downPointerCoords[0] = new MotionEvent.PointerCoords();
-        downPointerCoords[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.1f);
-        downPointerCoords[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.1f);
-        MotionEvent.PointerProperties[] downPointerProperties =
-                new MotionEvent.PointerProperties[1];
-        downPointerProperties[0] = new MotionEvent.PointerProperties();
-        downPointerProperties[0].id = 1;
-        downPointerProperties[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
-        MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 1,
-                downPointerProperties, downPointerCoords, 0, 0, 1.0f, 1.0f, 0, 0,
-                SOURCE_TOUCHPAD, 0);
-
-        MotionEvent.PointerCoords[] movePointerCoords1 = new MotionEvent.PointerCoords[1];
-        movePointerCoords1[0] = new MotionEvent.PointerCoords();
-        movePointerCoords1[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.2f);
-        movePointerCoords1[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.1f);
-        MotionEvent.PointerProperties[] movePointerProperties1 =
-                new MotionEvent.PointerProperties[1];
-        movePointerProperties1[0] = new MotionEvent.PointerProperties();
-        movePointerProperties1[0].id = 1;
-        movePointerProperties1[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
-        MotionEvent move1 = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 1,
-                movePointerProperties1, movePointerCoords1, 0, 0, 1.0f, 1.0f, 0, 0, SOURCE_TOUCHPAD,
-                0);
-
-        MotionEvent.PointerCoords[] movePointerCoords2 = new MotionEvent.PointerCoords[1];
-        movePointerCoords2[0] = new MotionEvent.PointerCoords();
-        movePointerCoords2[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.1f);
-        movePointerCoords2[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.4f);
-        MotionEvent.PointerProperties[] movePointerProperties2 =
-                new MotionEvent.PointerProperties[1];
-        movePointerProperties2[0] = new MotionEvent.PointerProperties();
-        movePointerProperties2[0].id = 1;
-        movePointerProperties2[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
-        MotionEvent move2 = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 1,
-                movePointerProperties2, movePointerCoords2, 0, 0, 1.0f, 1.0f, 0, 0, SOURCE_TOUCHPAD,
-                0);
-
-        MotionEvent.PointerCoords[] upPointerCoords = new MotionEvent.PointerCoords[1];
-        upPointerCoords[0] = new MotionEvent.PointerCoords();
-        upPointerCoords[0].setAxisValue(AXIS_GESTURE_X_OFFSET, 0.1f);
-        upPointerCoords[0].setAxisValue(AXIS_GESTURE_Y_OFFSET, 0.1f);
-        MotionEvent.PointerProperties[] upPointerProperties2 =
-                new MotionEvent.PointerProperties[1];
-        upPointerProperties2[0] = new MotionEvent.PointerProperties();
-        upPointerProperties2[0].id = 1;
-        upPointerProperties2[0].toolType = MotionEvent.TOOL_TYPE_FINGER;
-        MotionEvent up = MotionEvent.obtain(0, 2, MotionEvent.ACTION_UP, 1,
-                upPointerProperties2, upPointerCoords, 0, 0, 1.0f, 1.0f, 0, 0, SOURCE_TOUCHPAD, 0);
-
-        mMotionEventsHandler.onMotionEvent(down);
-        mMotionEventsHandler.onMotionEvent(move1);
-        assertThat(mMotionEventsHandler.getDisplacementX(move1)).isEqualTo(20f);
-        assertThat(mMotionEventsHandler.getDisplacementY(move1)).isEqualTo(10f);
-        mMotionEventsHandler.onMotionEvent(move2);
-        assertThat(mMotionEventsHandler.getDisplacementX(move2)).isEqualTo(30f);
-        assertThat(mMotionEventsHandler.getDisplacementY(move2)).isEqualTo(50f);
-        mMotionEventsHandler.onMotionEvent(up);
-        assertThat(mMotionEventsHandler.getDisplacementX(up)).isEqualTo(40f);
-        assertThat(mMotionEventsHandler.getDisplacementY(up)).isEqualTo(60f);
-    }
-}
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 8440455..39c4e06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -23,10 +23,14 @@
 import android.os.UserManager
 import android.test.suitebuilder.annotation.SmallTest
 import androidx.test.runner.AndroidJUnit4
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE
+import com.android.systemui.notetask.NoteTaskController.Companion.INTENT_EXTRA_USE_STYLUS_MODE
+import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
+import com.android.systemui.notetask.NoteTaskInfoResolver.NoteTaskInfo
 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
 import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.android.wm.shell.bubbles.Bubbles
@@ -36,8 +40,8 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
 
 /**
@@ -50,24 +54,23 @@
 @RunWith(AndroidJUnit4::class)
 internal class NoteTaskControllerTest : SysuiTestCase() {
 
-    private val notesIntent = Intent(ACTION_CREATE_NOTE)
-
     @Mock lateinit var context: Context
     @Mock lateinit var packageManager: PackageManager
-    @Mock lateinit var noteTaskIntentResolver: NoteTaskIntentResolver
+    @Mock lateinit var resolver: NoteTaskInfoResolver
     @Mock lateinit var bubbles: Bubbles
     @Mock lateinit var optionalBubbles: Optional<Bubbles>
     @Mock lateinit var keyguardManager: KeyguardManager
     @Mock lateinit var optionalKeyguardManager: Optional<KeyguardManager>
     @Mock lateinit var optionalUserManager: Optional<UserManager>
     @Mock lateinit var userManager: UserManager
+    @Mock lateinit var uiEventLogger: UiEventLogger
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
         whenever(context.packageManager).thenReturn(packageManager)
-        whenever(noteTaskIntentResolver.resolveIntent()).thenReturn(notesIntent)
+        whenever(resolver.resolveInfo()).thenReturn(NoteTaskInfo(NOTES_PACKAGE_NAME, NOTES_UID))
         whenever(optionalBubbles.orElse(null)).thenReturn(bubbles)
         whenever(optionalKeyguardManager.orElse(null)).thenReturn(keyguardManager)
         whenever(optionalUserManager.orElse(null)).thenReturn(userManager)
@@ -77,101 +80,182 @@
     private fun createNoteTaskController(isEnabled: Boolean = true): NoteTaskController {
         return NoteTaskController(
             context = context,
-            intentResolver = noteTaskIntentResolver,
+            resolver = resolver,
             optionalBubbles = optionalBubbles,
             optionalKeyguardManager = optionalKeyguardManager,
             optionalUserManager = optionalUserManager,
             isEnabled = isEnabled,
+            uiEventLogger = uiEventLogger,
         )
     }
 
     // region showNoteTask
     @Test
-    fun showNoteTask_keyguardIsLocked_shouldStartActivity() {
+    fun showNoteTask_keyguardIsLocked_shouldStartActivityAndLogUiEvent() {
         whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE,
+            )
 
-        verify(context).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        val intentCaptor = argumentCaptor<Intent>()
+        verify(context).startActivity(capture(intentCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
+            assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
+            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
+            assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        }
+        verifyZeroInteractions(bubbles)
+        verify(uiEventLogger)
+            .log(
+                ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE,
+                NOTES_UID,
+                NOTES_PACKAGE_NAME
+            )
     }
 
     @Test
-    fun showNoteTask_keyguardIsUnlocked_shouldStartBubbles() {
+    fun showNoteTask_keyguardIsUnlocked_shouldStartBubblesAndLogUiEvent() {
         whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON,
+            )
 
-        verify(bubbles).showOrHideAppBubble(notesIntent)
-        verify(context, never()).startActivity(notesIntent)
+        verifyZeroInteractions(context)
+        val intentCaptor = argumentCaptor<Intent>()
+        verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
+            assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
+            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
+            assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        }
+        verify(uiEventLogger)
+            .log(
+                ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON,
+                NOTES_UID,
+                NOTES_PACKAGE_NAME
+            )
     }
 
     @Test
-    fun showNoteTask_isInMultiWindowMode_shouldStartActivity() {
+    fun showNoteTask_keyguardIsUnlocked_uiEventIsNull_shouldStartBubblesWithoutLoggingUiEvent() {
         whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = true)
+        createNoteTaskController().showNoteTask(isInMultiWindowMode = false, uiEvent = null)
 
-        verify(context).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context)
+        val intentCaptor = argumentCaptor<Intent>()
+        verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
+            assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
+            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
+            assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        }
+        verifyZeroInteractions(uiEventLogger)
+    }
+
+    @Test
+    fun showNoteTask_isInMultiWindowMode_shouldStartActivityAndLogUiEvent() {
+        whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
+
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = true,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT,
+            )
+
+        val intentCaptor = argumentCaptor<Intent>()
+        verify(context).startActivity(capture(intentCaptor))
+        intentCaptor.value.let { intent ->
+            assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
+            assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
+            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
+            assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue()
+        }
+        verifyZeroInteractions(bubbles)
+        verify(uiEventLogger)
+            .log(ShowNoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT, NOTES_UID, NOTES_PACKAGE_NAME)
     }
 
     @Test
     fun showNoteTask_bubblesIsNull_shouldDoNothing() {
         whenever(optionalBubbles.orElse(null)).thenReturn(null)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
+            )
 
-        verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context, bubbles, uiEventLogger)
     }
 
     @Test
     fun showNoteTask_keyguardManagerIsNull_shouldDoNothing() {
         whenever(optionalKeyguardManager.orElse(null)).thenReturn(null)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON,
+            )
 
-        verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context, bubbles, uiEventLogger)
     }
 
     @Test
     fun showNoteTask_userManagerIsNull_shouldDoNothing() {
         whenever(optionalUserManager.orElse(null)).thenReturn(null)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON,
+            )
 
-        verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context, bubbles, uiEventLogger)
     }
 
     @Test
     fun showNoteTask_intentResolverReturnsNull_shouldDoNothing() {
-        whenever(noteTaskIntentResolver.resolveIntent()).thenReturn(null)
+        whenever(resolver.resolveInfo()).thenReturn(null)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON,
+            )
 
-        verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context, bubbles, uiEventLogger)
     }
 
     @Test
     fun showNoteTask_flagDisabled_shouldDoNothing() {
-        createNoteTaskController(isEnabled = false).showNoteTask()
+        createNoteTaskController(isEnabled = false)
+            .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON)
 
-        verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context, bubbles, uiEventLogger)
     }
 
     @Test
     fun showNoteTask_userIsLocked_shouldDoNothing() {
         whenever(userManager.isUserUnlocked).thenReturn(false)
 
-        createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
+        createNoteTaskController()
+            .showNoteTask(
+                isInMultiWindowMode = false,
+                uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON,
+            )
 
-        verify(context, never()).startActivity(notesIntent)
-        verify(bubbles, never()).showOrHideAppBubble(notesIntent)
+        verifyZeroInteractions(context, bubbles, uiEventLogger)
     }
     // endregion
 
@@ -206,4 +290,9 @@
         assertThat(argument.value.flattenToString()).isEqualTo(expected.flattenToString())
     }
     // endregion
+
+    private companion object {
+        const val NOTES_PACKAGE_NAME = "com.android.note.app"
+        const val NOTES_UID = 123456
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInfoResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInfoResolverTest.kt
new file mode 100644
index 0000000..d6495d8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInfoResolverTest.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.notetask
+
+import android.app.role.RoleManager
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.test.suitebuilder.annotation.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.MockitoAnnotations
+
+/**
+ * Tests for [NoteTaskInfoResolver].
+ *
+ * Build/Install/Run:
+ * - atest SystemUITests:NoteTaskInfoResolverTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+internal class NoteTaskInfoResolverTest : SysuiTestCase() {
+
+    @Mock lateinit var packageManager: PackageManager
+    @Mock lateinit var roleManager: RoleManager
+
+    private lateinit var underTest: NoteTaskInfoResolver
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        underTest = NoteTaskInfoResolver(context, roleManager, packageManager)
+    }
+
+    @Test
+    fun resolveInfo_shouldReturnInfo() {
+        val packageName = "com.android.note.app"
+        val uid = 123456
+        whenever(roleManager.getRoleHoldersAsUser(NoteTaskInfoResolver.ROLE_NOTES, context.user))
+            .then { listOf(packageName) }
+        whenever(
+                packageManager.getApplicationInfoAsUser(
+                    eq(packageName),
+                    any<PackageManager.ApplicationInfoFlags>(),
+                    eq(context.user)
+                )
+            )
+            .thenReturn(ApplicationInfo().apply { this.uid = uid })
+
+        val actual = underTest.resolveInfo()
+
+        requireNotNull(actual) { "Note task info must not be null" }
+        assertThat(actual.packageName).isEqualTo(packageName)
+        assertThat(actual.uid).isEqualTo(uid)
+    }
+
+    @Test
+    fun resolveInfo_packageManagerThrowsException_shouldReturnInfoWithZeroUid() {
+        val packageName = "com.android.note.app"
+        whenever(roleManager.getRoleHoldersAsUser(NoteTaskInfoResolver.ROLE_NOTES, context.user))
+            .then { listOf(packageName) }
+        whenever(
+                packageManager.getApplicationInfoAsUser(
+                    eq(packageName),
+                    any<PackageManager.ApplicationInfoFlags>(),
+                    eq(context.user)
+                )
+            )
+            .thenThrow(PackageManager.NameNotFoundException(packageName))
+
+        val actual = underTest.resolveInfo()
+
+        requireNotNull(actual) { "Note task info must not be null" }
+        assertThat(actual.packageName).isEqualTo(packageName)
+        assertThat(actual.uid).isEqualTo(0)
+    }
+
+    @Test
+    fun resolveInfo_noRoleHolderIsSet_shouldReturnNull() {
+        whenever(roleManager.getRoleHoldersAsUser(eq(NoteTaskInfoResolver.ROLE_NOTES), any()))
+            .then { listOf<String>() }
+
+        val actual = underTest.resolveInfo()
+
+        assertThat(actual).isNull()
+    }
+}
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 010ac5b..53720ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt
@@ -15,11 +15,14 @@
  */
 package com.android.systemui.notetask
 
+import android.app.KeyguardManager
 import android.test.suitebuilder.annotation.SmallTest
 import android.view.KeyEvent
 import androidx.test.runner.AndroidJUnit4
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.wm.shell.bubbles.Bubbles
 import java.util.Optional
@@ -30,6 +33,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
 
 /**
@@ -55,12 +59,16 @@
         whenever(optionalBubbles.orElse(null)).thenReturn(bubbles)
     }
 
-    private fun createNoteTaskInitializer(isEnabled: Boolean = true): NoteTaskInitializer {
+    private fun createNoteTaskInitializer(
+        isEnabled: Boolean = true,
+        optionalKeyguardManager: Optional<KeyguardManager> = Optional.empty(),
+    ): NoteTaskInitializer {
         return NoteTaskInitializer(
             optionalBubbles = optionalBubbles,
             noteTaskController = noteTaskController,
             commandQueue = commandQueue,
             isEnabled = isEnabled,
+            optionalKeyguardManager = optionalKeyguardManager,
         )
     }
 
@@ -105,19 +113,44 @@
 
     // region handleSystemKey
     @Test
-    fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() {
-        createNoteTaskInitializer()
+    fun handleSystemKey_receiveValidSystemKey_keyguardNotLocked_shouldShowNoteTaskWithUnlocked() {
+        val keyguardManager =
+            mock<KeyguardManager>() { whenever(isKeyguardLocked).thenReturn(false) }
+        createNoteTaskInitializer(optionalKeyguardManager = Optional.of(keyguardManager))
             .callbacks
             .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT)
 
-        verify(noteTaskController).showNoteTask()
+        verify(noteTaskController)
+            .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON)
+    }
+
+    @Test
+    fun handleSystemKey_receiveValidSystemKey_keyguardLocked_shouldShowNoteTaskWithLocked() {
+        val keyguardManager =
+            mock<KeyguardManager>() { whenever(isKeyguardLocked).thenReturn(true) }
+        createNoteTaskInitializer(optionalKeyguardManager = Optional.of(keyguardManager))
+            .callbacks
+            .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT)
+
+        verify(noteTaskController)
+            .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED)
+    }
+
+    @Test
+    fun handleSystemKey_receiveValidSystemKey_nullKeyguardManager_shouldShowNoteTaskWithUnlocked() {
+        createNoteTaskInitializer(optionalKeyguardManager = Optional.empty())
+            .callbacks
+            .handleSystemKey(NoteTaskController.NOTE_TASK_KEY_EVENT)
+
+        verify(noteTaskController)
+            .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON)
     }
 
     @Test
     fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() {
         createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent.KEYCODE_UNKNOWN)
 
-        verify(noteTaskController, never()).showNoteTask()
+        verifyZeroInteractions(noteTaskController)
     }
     // endregion
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt
deleted file mode 100644
index 18be92b..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskIntentResolverTest.kt
+++ /dev/null
@@ -1,83 +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.notetask
-
-import android.app.role.RoleManager
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.test.suitebuilder.annotation.SmallTest
-import androidx.test.runner.AndroidJUnit4
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.notetask.NoteTaskIntentResolver.Companion.ACTION_CREATE_NOTE
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.any
-import org.mockito.MockitoAnnotations
-
-/**
- * Tests for [NoteTaskIntentResolver].
- *
- * Build/Install/Run:
- * - atest SystemUITests:NoteTaskIntentResolverTest
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-internal class NoteTaskIntentResolverTest : SysuiTestCase() {
-
-    @Mock lateinit var packageManager: PackageManager
-    @Mock lateinit var roleManager: RoleManager
-
-    private lateinit var underTest: NoteTaskIntentResolver
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        underTest = NoteTaskIntentResolver(context, roleManager)
-    }
-
-    @Test
-    fun resolveIntent_shouldReturnIntentInStylusMode() {
-        val packageName = "com.android.note.app"
-        whenever(roleManager.getRoleHoldersAsUser(NoteTaskIntentResolver.ROLE_NOTES, context.user))
-            .then { listOf(packageName) }
-
-        val actual = underTest.resolveIntent()
-
-        requireNotNull(actual) { "Intent must not be null" }
-        assertThat(actual.action).isEqualTo(ACTION_CREATE_NOTE)
-        assertThat(actual.`package`).isEqualTo(packageName)
-        val expectedExtra = actual.getExtra(NoteTaskIntentResolver.INTENT_EXTRA_USE_STYLUS_MODE)
-        assertThat(expectedExtra).isEqualTo(true)
-        val expectedFlag = actual.flags and Intent.FLAG_ACTIVITY_NEW_TASK
-        assertThat(expectedFlag).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
-    }
-
-    @Test
-    fun resolveIntent_noRoleHolderIsSet_shouldReturnNull() {
-        whenever(roleManager.getRoleHoldersAsUser(eq(NoteTaskIntentResolver.ROLE_NOTES), any()))
-            .then { listOf<String>() }
-
-        val actual = underTest.resolveIntent()
-
-        assertThat(actual).isNull()
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
index a1d42a0..cdc683f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.LockScreenState
 import com.android.systemui.notetask.NoteTaskController
-import com.android.systemui.util.mockito.whenever
+import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
@@ -53,7 +53,6 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        whenever(noteTaskController.showNoteTask()).then {}
     }
 
     private fun createUnderTest(isEnabled: Boolean) =
@@ -96,6 +95,7 @@
 
         underTest.onTriggered(expandable = null)
 
-        verify(noteTaskController).showNoteTask()
+        verify(noteTaskController)
+            .showNoteTask(uiEvent = ShowNoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java
new file mode 100644
index 0000000..2293fc5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/process/condition/UserProcessConditionTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.process.condition;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.process.ProcessWrapper;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shared.condition.Condition;
+import com.android.systemui.shared.condition.Monitor;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class UserProcessConditionTest extends SysuiTestCase {
+    @Mock
+    UserTracker mUserTracker;
+
+    @Mock
+    ProcessWrapper mProcessWrapper;
+
+    @Mock
+    Monitor.Callback mCallback;
+
+    private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    /**
+     * Verifies condition reports false when tracker reports a different user id than the
+     * identifier from the process handle.
+     */
+    @Test
+    public void testConditionFailsWithDifferentIds() {
+
+        final Condition condition = new UserProcessCondition(mProcessWrapper, mUserTracker);
+        when(mProcessWrapper.getUserHandleIdentifier()).thenReturn(0);
+        when(mUserTracker.getUserId()).thenReturn(1);
+
+        final Monitor monitor = new Monitor(mExecutor);
+
+        monitor.addSubscription(new Monitor.Subscription.Builder(mCallback)
+                .addCondition(condition)
+                .build());
+
+        mExecutor.runAllReady();
+
+        verify(mCallback).onConditionsChanged(false);
+    }
+
+    /**
+     * Verifies condition reports false when tracker reports a different user id than the
+     * identifier from the process handle.
+     */
+    @Test
+    public void testConditionSucceedsWithSameIds() {
+
+        final Condition condition = new UserProcessCondition(mProcessWrapper, mUserTracker);
+        when(mProcessWrapper.getUserHandleIdentifier()).thenReturn(0);
+        when(mUserTracker.getUserId()).thenReturn(0);
+
+        final Monitor monitor = new Monitor(mExecutor);
+
+        monitor.addSubscription(new Monitor.Subscription.Builder(mCallback)
+                .addCondition(condition)
+                .build());
+
+        mExecutor.runAllReady();
+
+        verify(mCallback).onConditionsChanged(true);
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
index a13bece..15545a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DreamTileTest.java
@@ -29,9 +29,9 @@
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.dreams.IDreamManager;
 import android.service.quicksettings.Tile;
@@ -123,7 +123,7 @@
 
         // Should not be available if component is not set
         mSecureSettings.putInt(Settings.Secure.SCREENSAVER_ENABLED, 1);
-        when(mDreamManager.getDreamComponents()).thenReturn(null);
+        when(mDreamManager.getDreamComponentsForUser(mUserTracker.getUserId())).thenReturn(null);
 
         mTestableLooper.processAllMessages();
         assertEquals(Tile.STATE_UNAVAILABLE, mTile.getState().state);
@@ -134,9 +134,8 @@
     public void testInactiveWhenDreaming() throws RemoteException {
         setScreensaverEnabled(true);
 
-        when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
-                COLORS_DREAM_COMPONENT_NAME
-        });
+        when(mDreamManager.getDreamComponentsForUser(mUserTracker.getUserId()))
+             .thenReturn(new ComponentName[]{COLORS_DREAM_COMPONENT_NAME});
         when(mDreamManager.isDreaming()).thenReturn(false);
 
         mTile.refreshState();
@@ -148,9 +147,8 @@
     public void testActive() throws RemoteException {
         setScreensaverEnabled(true);
 
-        when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
-                COLORS_DREAM_COMPONENT_NAME
-        });
+        when(mDreamManager.getDreamComponentsForUser(mUserTracker.getUserId()))
+             .thenReturn(new ComponentName[]{COLORS_DREAM_COMPONENT_NAME});
         when(mDreamManager.isDreaming()).thenReturn(true);
 
         mTile.refreshState();
@@ -162,9 +160,8 @@
     public void testClick() throws RemoteException {
         // Set the AOSP dream enabled as the base setup.
         setScreensaverEnabled(true);
-        when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
-                COLORS_DREAM_COMPONENT_NAME
-        });
+        when(mDreamManager.getDreamComponentsForUser(mUserTracker.getUserId()))
+             .thenReturn(new ComponentName[]{COLORS_DREAM_COMPONENT_NAME});
         when(mDreamManager.isDreaming()).thenReturn(false);
 
         mTile.refreshState();
@@ -203,21 +200,21 @@
 
         DreamTile supportedTileAllUsers = constructTileForTest(true, false);
 
-        UserHandle systemUserHandle = mock(UserHandle.class);
-        when(systemUserHandle.isSystem()).thenReturn(true);
+        UserInfo mainUserInfo = mock(UserInfo.class);
+        when(mainUserInfo.isMain()).thenReturn(true);
 
-        UserHandle nonSystemUserHandle = mock(UserHandle.class);
-        when(nonSystemUserHandle.isSystem()).thenReturn(false);
+        UserInfo nonMainUserInfo = mock(UserInfo.class);
+        when(nonMainUserInfo.isMain()).thenReturn(false);
 
-        when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle);
+        when(mUserTracker.getUserInfo()).thenReturn(mainUserInfo);
         assertTrue(supportedTileAllUsers.isAvailable());
-        when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle);
+        when(mUserTracker.getUserInfo()).thenReturn(nonMainUserInfo);
         assertTrue(supportedTileAllUsers.isAvailable());
 
         DreamTile supportedTileOnlySystemUser = constructTileForTest(true, true);
-        when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle);
+        when(mUserTracker.getUserInfo()).thenReturn(mainUserInfo);
         assertTrue(supportedTileOnlySystemUser.isAvailable());
-        when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle);
+        when(mUserTracker.getUserInfo()).thenReturn(nonMainUserInfo);
         assertFalse(supportedTileOnlySystemUser.isAvailable());
     }
 
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 62404cb..84cc977 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
@@ -941,6 +941,26 @@
         }
     }
 
+    @Test
+    public void getMobileNetworkSummary_withCarrierNetworkChange() {
+        Resources res = mock(Resources.class);
+        doReturn("Carrier network changing").when(res).getString(anyInt());
+        when(SubscriptionManager.getResourcesForSubId(any(), eq(SUB_ID))).thenReturn(res);
+        InternetDialogController spyController = spy(mInternetDialogController);
+        Map<Integer, TelephonyDisplayInfo> mSubIdTelephonyDisplayInfoMap =
+                spyController.mSubIdTelephonyDisplayInfoMap;
+        TelephonyDisplayInfo info = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
+
+        mSubIdTelephonyDisplayInfoMap.put(SUB_ID, info);
+        doReturn(true).when(spyController).isMobileDataEnabled();
+        doReturn(true).when(spyController).activeNetworkIsCellular();
+        spyController.mCarrierNetworkChangeMode = true;
+        String dds = spyController.getMobileNetworkSummary(SUB_ID);
+
+        assertThat(dds).contains(mContext.getString(R.string.carrier_network_change_mode));
+    }
+
     private String getResourcesString(String name) {
         return mContext.getResources().getString(getResourcesId(name));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java
index ea0e454..9acd47e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayDialogControllerTest.java
@@ -16,14 +16,13 @@
 
 package com.android.systemui.reardisplay;
 
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
 
 import android.hardware.devicestate.DeviceStateManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.view.View;
+import android.widget.TextView;
 
 import androidx.test.filters.SmallTest;
 
@@ -37,8 +36,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 
-import java.util.concurrent.Executor;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -63,9 +60,11 @@
 
         controller.showRearDisplayDialog(CLOSED_BASE_STATE);
         assertTrue(controller.mRearDisplayEducationDialog.isShowing());
-        View deviceOpenedWarningTextView = controller.mRearDisplayEducationDialog.findViewById(
-                R.id.rear_display_warning_text_view);
-        assertNull(deviceOpenedWarningTextView);
+        TextView deviceClosedTitleTextView = controller.mRearDisplayEducationDialog.findViewById(
+                R.id.rear_display_title_text_view);
+        assertEquals(deviceClosedTitleTextView.getText().toString(),
+                getContext().getResources().getString(
+                        R.string.rear_display_folded_bottom_sheet_title));
     }
 
     @Test
@@ -79,9 +78,11 @@
         controller.showRearDisplayDialog(OPEN_BASE_STATE);
 
         assertTrue(controller.mRearDisplayEducationDialog.isShowing());
-        View deviceOpenedWarningTextView = controller.mRearDisplayEducationDialog.findViewById(
-                R.id.rear_display_warning_text_view);
-        assertNotNull(deviceOpenedWarningTextView);
+        TextView deviceClosedTitleTextView = controller.mRearDisplayEducationDialog.findViewById(
+                R.id.rear_display_title_text_view);
+        assertEquals(deviceClosedTitleTextView.getText().toString(),
+                getContext().getResources().getString(
+                        R.string.rear_display_unfolded_bottom_sheet_title));
     }
 
     /**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
index 8127ccc..6e6833d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
@@ -16,13 +16,15 @@
 
 package com.android.systemui.screenrecord;
 
+import static com.google.common.truth.Truth.assertThat;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.app.Dialog;
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.os.Looper;
@@ -31,7 +33,13 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
+import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver;
+import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialog;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -61,8 +69,15 @@
     @Mock
     private UserContextProvider mUserContextProvider;
     @Mock
+    private ScreenCaptureDevicePolicyResolver mDevicePolicyResolver;
+    @Mock
+    private DialogLaunchAnimator mDialogLaunchAnimator;
+    @Mock
+    private ActivityStarter mActivityStarter;
+    @Mock
     private UserTracker mUserTracker;
 
+    private FakeFeatureFlags mFeatureFlags;
     private RecordingController mController;
 
     private static final int USER_ID = 10;
@@ -70,8 +85,9 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mController = new RecordingController(mMainExecutor, mBroadcastDispatcher,
-                mUserContextProvider, mUserTracker);
+        mFeatureFlags = new FakeFeatureFlags();
+        mController = new RecordingController(mMainExecutor, mBroadcastDispatcher, mContext,
+                mFeatureFlags, mUserContextProvider, () -> mDevicePolicyResolver, mUserTracker);
         mController.addCallback(mCallback);
     }
 
@@ -190,4 +206,67 @@
         verify(mCallback).onRecordingEnd();
         assertFalse(mController.isRecording());
     }
+
+    @Test
+    public void testPoliciesFlagDisabled_screenCapturingNotAllowed_returnsNullDevicePolicyDialog() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING, true);
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, false);
+        when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(true);
+
+        Dialog dialog = mController.createScreenRecordDialog(mContext, mFeatureFlags,
+                mDialogLaunchAnimator, mActivityStarter, /* onStartRecordingClicked= */ null);
+
+        assertThat(dialog).isInstanceOf(ScreenRecordPermissionDialog.class);
+    }
+
+    @Test
+    public void testPartialScreenSharingDisabled_returnsLegacyDialog() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING, false);
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, false);
+
+        Dialog dialog = mController.createScreenRecordDialog(mContext, mFeatureFlags,
+                mDialogLaunchAnimator, mActivityStarter, /* onStartRecordingClicked= */ null);
+
+        assertThat(dialog).isInstanceOf(ScreenRecordDialog.class);
+    }
+
+    @Test
+    public void testPoliciesFlagEnabled_screenCapturingNotAllowed_returnsDevicePolicyDialog() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING, true);
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, true);
+        when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(true);
+
+        Dialog dialog = mController.createScreenRecordDialog(mContext, mFeatureFlags,
+                mDialogLaunchAnimator, mActivityStarter, /* onStartRecordingClicked= */ null);
+
+        assertThat(dialog).isInstanceOf(ScreenCaptureDisabledDialog.class);
+    }
+
+    @Test
+    public void testPoliciesFlagEnabled_screenCapturingAllowed_returnsNullDevicePolicyDialog() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING, true);
+        mFeatureFlags.set(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES, true);
+        when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false);
+
+        Dialog dialog = mController.createScreenRecordDialog(mContext, mFeatureFlags,
+                mDialogLaunchAnimator, mActivityStarter, /* onStartRecordingClicked= */ null);
+
+        assertThat(dialog).isInstanceOf(ScreenRecordPermissionDialog.class);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
index 0aa3621..5b094c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.screenrecord
 
+import android.os.UserHandle
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
@@ -59,6 +60,7 @@
         dialog =
             ScreenRecordPermissionDialog(
                 context,
+                UserHandle.of(0),
                 controller,
                 starter,
                 dialogLaunchAnimator,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
index 1fa2ace..c40c287 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
@@ -38,7 +38,7 @@
 import com.android.internal.util.ScreenshotRequest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags.SCREENSHOT_METADATA
+import com.android.systemui.flags.Flags.SCREENSHOT_METADATA_REFACTOR
 import com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_CAPTURE_FAILED
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_KEY_OTHER
@@ -126,7 +126,7 @@
 
         // Flipped in selected test cases
         flags.set(SCREENSHOT_WORK_PROFILE_POLICY, false)
-        flags.set(SCREENSHOT_METADATA, false)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, false)
 
         service.attach(
             mContext,
@@ -183,7 +183,7 @@
 
     @Test
     fun takeScreenshotFullscreen_screenshotDataEnabled() {
-        flags.set(SCREENSHOT_METADATA, true)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, true)
 
         val request =
             ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER)
@@ -260,7 +260,7 @@
 
     @Test
     fun takeScreenshotFullscreen_userLocked() {
-        flags.set(SCREENSHOT_METADATA, true)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, true)
 
         whenever(userManager.isUserUnlocked).thenReturn(false)
 
@@ -302,7 +302,7 @@
 
     @Test
     fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers() {
-        flags.set(SCREENSHOT_METADATA, true)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, true)
 
         whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL)))
             .thenReturn(true)
@@ -353,7 +353,7 @@
 
     @Test
     fun takeScreenshotFullscreen_userLocked_metadataDisabled() {
-        flags.set(SCREENSHOT_METADATA, false)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, false)
         whenever(userManager.isUserUnlocked).thenReturn(false)
 
         val request =
@@ -394,7 +394,7 @@
 
     @Test
     fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers_metadataDisabled() {
-        flags.set(SCREENSHOT_METADATA, false)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, false)
 
         whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL)))
             .thenReturn(true)
@@ -445,7 +445,7 @@
 
     @Test
     fun takeScreenshot_workProfile_nullBitmap_metadataDisabled() {
-        flags.set(SCREENSHOT_METADATA, false)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, false)
 
         val request =
             ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER)
@@ -487,7 +487,7 @@
     }
     @Test
     fun takeScreenshot_workProfile_nullBitmap() {
-        flags.set(SCREENSHOT_METADATA, true)
+        flags.set(SCREENSHOT_METADATA_REFACTOR, true)
 
         val request =
             ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
new file mode 100644
index 0000000..6e8f5fe
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot.appclips;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.graphics.ColorSpace;
+import android.hardware.HardwareBuffer;
+import android.os.RemoteException;
+import android.view.Display;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
+import android.window.ScreenCapture.ScreenshotSync;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+@RunWith(AndroidJUnit4.class)
+public final class AppClipsScreenshotHelperServiceTest extends SysuiTestCase {
+
+    private static final Intent FAKE_INTENT = new Intent();
+    private static final int DEFAULT_DISPLAY = Display.DEFAULT_DISPLAY;
+    private static final HardwareBuffer FAKE_HARDWARE_BUFFER =
+            HardwareBuffer.create(1, 1, HardwareBuffer.RGBA_8888, 1,
+                    HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
+    private static final ColorSpace FAKE_COLOR_SPACE = ColorSpace.get(ColorSpace.Named.SRGB);
+    private static final ScreenshotHardwareBufferInternal EXPECTED_SCREENSHOT_BUFFER =
+            new ScreenshotHardwareBufferInternal(
+                    new ScreenshotHardwareBuffer(FAKE_HARDWARE_BUFFER, FAKE_COLOR_SPACE, false,
+                            false));
+
+    @Mock private Optional<Bubbles> mBubblesOptional;
+    @Mock private Bubbles mBubbles;
+    @Mock private ScreenshotHardwareBuffer mScreenshotHardwareBuffer;
+    @Mock private ScreenshotSync mScreenshotSync;
+
+    private AppClipsScreenshotHelperService mAppClipsScreenshotHelperService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mAppClipsScreenshotHelperService = new AppClipsScreenshotHelperService(mBubblesOptional);
+    }
+
+    @Test
+    public void emptyBubbles_shouldReturnNull() throws RemoteException {
+        when(mBubblesOptional.isEmpty()).thenReturn(true);
+
+        assertThat(getInterface().takeScreenshot(DEFAULT_DISPLAY)).isNull();
+    }
+
+    @Test
+    public void bubblesPresent_screenshotFailed_ShouldReturnNull() throws RemoteException {
+        when(mBubblesOptional.isEmpty()).thenReturn(false);
+        when(mBubblesOptional.get()).thenReturn(mBubbles);
+        when(mBubbles.getScreenshotExcludingBubble(DEFAULT_DISPLAY)).thenReturn(mScreenshotSync);
+        when(mScreenshotSync.get()).thenReturn(null);
+
+        assertThat(getInterface().takeScreenshot(DEFAULT_DISPLAY)).isNull();
+    }
+
+    @Test
+    public void bubblesPresent_screenshotSuccess_shouldReturnScreenshot() throws RemoteException {
+        when(mBubblesOptional.isEmpty()).thenReturn(false);
+        when(mBubblesOptional.get()).thenReturn(mBubbles);
+        when(mBubbles.getScreenshotExcludingBubble(DEFAULT_DISPLAY)).thenReturn(mScreenshotSync);
+        when(mScreenshotSync.get()).thenReturn(mScreenshotHardwareBuffer);
+        when(mScreenshotHardwareBuffer.getHardwareBuffer()).thenReturn(FAKE_HARDWARE_BUFFER);
+        when(mScreenshotHardwareBuffer.getColorSpace()).thenReturn(FAKE_COLOR_SPACE);
+
+        assertThat(getInterface().takeScreenshot(DEFAULT_DISPLAY)).isEqualTo(
+                EXPECTED_SCREENSHOT_BUFFER);
+    }
+
+    private IAppClipsScreenshotHelperService getInterface() {
+        return IAppClipsScreenshotHelperService.Stub.asInterface(
+                mAppClipsScreenshotHelperService.onBind(FAKE_INTENT));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
new file mode 100644
index 0000000..b55fe36
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsServiceTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot.appclips;
+
+import static com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.statusbar.IAppClipsService;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dagger.qualifiers.Application;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+@RunWith(AndroidJUnit4.class)
+public final class AppClipsServiceTest extends SysuiTestCase {
+
+    private static final Intent FAKE_INTENT = new Intent();
+    private static final int FAKE_TASK_ID = 42;
+    private static final String EMPTY = "";
+
+    @Mock @Application private Context mMockContext;
+    @Mock private FeatureFlags mFeatureFlags;
+    @Mock private Optional<Bubbles> mOptionalBubbles;
+    @Mock private Bubbles mBubbles;
+    @Mock private DevicePolicyManager mDevicePolicyManager;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void flagOff_shouldReturnFalse() throws RemoteException {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(false);
+
+        assertThat(getInterfaceWithRealContext()
+                .canLaunchCaptureContentActivityForNote(FAKE_TASK_ID)).isFalse();
+    }
+
+    @Test
+    public void emptyBubbles_shouldReturnFalse() throws RemoteException {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(true);
+
+        assertThat(getInterfaceWithRealContext()
+                .canLaunchCaptureContentActivityForNote(FAKE_TASK_ID)).isFalse();
+    }
+
+    @Test
+    public void taskIdNotAppBubble_shouldReturnFalse() throws RemoteException {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(false);
+
+        assertThat(getInterfaceWithRealContext()
+                .canLaunchCaptureContentActivityForNote(FAKE_TASK_ID)).isFalse();
+    }
+
+    @Test
+    public void dpmScreenshotBlocked_shouldReturnFalse() throws RemoteException {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
+        when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(true);
+
+        assertThat(getInterfaceWithRealContext()
+                .canLaunchCaptureContentActivityForNote(FAKE_TASK_ID)).isFalse();
+    }
+
+    @Test
+    public void configComponentNameNotValid_shouldReturnFalse() throws RemoteException {
+        when(mMockContext.getString(anyInt())).thenReturn(EMPTY);
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
+        when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(false);
+
+        assertThat(getInterfaceWithMockContext()
+                .canLaunchCaptureContentActivityForNote(FAKE_TASK_ID)).isFalse();
+    }
+
+    @Test
+    public void allPrerequisitesSatisfy_shouldReturnTrue() throws RemoteException {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(eq((FAKE_TASK_ID)))).thenReturn(true);
+        when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(false);
+
+        assertThat(getInterfaceWithRealContext()
+                .canLaunchCaptureContentActivityForNote(FAKE_TASK_ID)).isTrue();
+    }
+
+    private IAppClipsService getInterfaceWithRealContext() {
+        AppClipsService appClipsService = new AppClipsService(getContext(), mFeatureFlags,
+                mOptionalBubbles, mDevicePolicyManager);
+        return getInterfaceFromService(appClipsService);
+    }
+
+    private IAppClipsService getInterfaceWithMockContext() {
+        AppClipsService appClipsService = new AppClipsService(mMockContext, mFeatureFlags,
+                mOptionalBubbles, mDevicePolicyManager);
+        return getInterfaceFromService(appClipsService);
+    }
+
+    private static IAppClipsService getInterfaceFromService(AppClipsService appClipsService) {
+        IBinder iBinder = appClipsService.onBind(FAKE_INTENT);
+        return IAppClipsService.Stub.asInterface(iBinder);
+    }
+}
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
new file mode 100644
index 0000000..295d127
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot.appclips;
+
+import static android.app.Instrumentation.ActivityResult;
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN;
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED;
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS;
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED;
+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 com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS;
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.ACTION_FINISH_FROM_TRAMPOLINE;
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
+import static com.android.systemui.screenshot.AppClipsTrampolineActivity.PERMISSION_SELF;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.intercepting.SingleActivityFactory;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.notetask.NoteTaskController;
+import com.android.systemui.screenshot.AppClipsTrampolineActivity;
+import com.android.wm.shell.bubbles.Bubbles;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+@RunWith(AndroidTestingRunner.class)
+public final class AppClipsTrampolineActivityTest extends SysuiTestCase {
+
+    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 TIME_OUT = 5000;
+
+    @Mock
+    private DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    private FeatureFlags mFeatureFlags;
+    @Mock
+    private Optional<Bubbles> mOptionalBubbles;
+    @Mock
+    private Bubbles mBubbles;
+    @Mock
+    private NoteTaskController mNoteTaskController;
+    @Main
+    private Handler mMainHandler;
+
+    // Using the deprecated ActivityTestRule and SingleActivityFactory to help with injecting mocks
+    // and getting result from activity both of which are difficult to do in newer APIs.
+    private final SingleActivityFactory<AppClipsTrampolineActivityTestable> mFactory =
+            new SingleActivityFactory<>(AppClipsTrampolineActivityTestable.class) {
+                @Override
+                protected AppClipsTrampolineActivityTestable create(Intent unUsed) {
+                    return new AppClipsTrampolineActivityTestable(mDevicePolicyManager,
+                            mFeatureFlags, mOptionalBubbles, mNoteTaskController, mMainHandler);
+                }
+            };
+
+    @Rule
+    public final ActivityTestRule<AppClipsTrampolineActivityTestable> mActivityRule =
+            new ActivityTestRule<>(mFactory, false, false);
+
+    private Context mContext;
+    private Intent mActivityIntent;
+    private ComponentName mExpectedComponentName;
+    private Intent mKillAppClipsActivityBroadcast;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = getContext();
+        mMainHandler = mContext.getMainThreadHandler();
+
+        mActivityIntent = new Intent(mContext, AppClipsTrampolineActivityTestable.class);
+        mExpectedComponentName = ComponentName.unflattenFromString(
+                mContext.getString(
+                        R.string.config_screenshotAppClipsActivityComponent));
+        mKillAppClipsActivityBroadcast = new Intent(ACTION_FINISH_FROM_TRAMPOLINE)
+                .setComponent(mExpectedComponentName)
+                .setPackage(mExpectedComponentName.getPackageName());
+    }
+
+    @After
+    public void tearDown() {
+        mContext.sendBroadcast(mKillAppClipsActivityBroadcast, PERMISSION_SELF);
+        mActivityRule.finishActivity();
+    }
+
+    @Test
+    public void configComponentName_shouldResolve() {
+        // Verify component name is setup - has package and class name.
+        assertThat(mExpectedComponentName).isNotNull();
+        assertThat(mExpectedComponentName.getPackageName()).isNotEmpty();
+        assertThat(mExpectedComponentName.getClassName()).isNotEmpty();
+
+        // Verify an intent when launched with above component resolves to the same component to
+        // confirm that component from above is available in framework.
+        Intent appClipsActivityIntent = new Intent();
+        appClipsActivityIntent.setComponent(mExpectedComponentName);
+        ResolveInfo resolveInfo = getContext().getPackageManager().resolveActivity(
+                appClipsActivityIntent, PackageManager.ResolveInfoFlags.of(0));
+        ActivityInfo activityInfo = resolveInfo.activityInfo;
+
+        assertThat(activityInfo.packageName).isEqualTo(
+                mExpectedComponentName.getPackageName());
+        assertThat(activityInfo.name).isEqualTo(mExpectedComponentName.getClassName());
+    }
+
+    @Test
+    public void flagOff_shouldFinishWithResultCancel() {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(false);
+
+        mActivityRule.launchActivity(mActivityIntent);
+
+        assertThat(mActivityRule.getActivityResult().getResultCode())
+                .isEqualTo(Activity.RESULT_CANCELED);
+    }
+
+    @Test
+    public void bubblesEmpty_shouldFinishWithFailed() {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(true);
+
+        mActivityRule.launchActivity(mActivityIntent);
+
+        ActivityResult actualResult = mActivityRule.getActivityResult();
+        assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
+        assertThat(getStatusCodeExtra(actualResult.getResultData()))
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+    }
+
+    @Test
+    public void taskIdNotAppBubble_shouldFinishWithWindowModeUnsupported() {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(anyInt())).thenReturn(false);
+
+        mActivityRule.launchActivity(mActivityIntent);
+
+        ActivityResult actualResult = mActivityRule.getActivityResult();
+        assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
+        assertThat(getStatusCodeExtra(actualResult.getResultData()))
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPPORTED);
+    }
+
+    @Test
+    public void dpmScreenshotBlocked_shouldFinishWithBlockedByAdmin() {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(anyInt())).thenReturn(true);
+        when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(true);
+
+        mActivityRule.launchActivity(mActivityIntent);
+
+        ActivityResult actualResult = mActivityRule.getActivityResult();
+        assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
+        assertThat(getStatusCodeExtra(actualResult.getResultData()))
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN);
+    }
+
+    @Test
+    public void startAppClipsActivity_userCanceled_shouldReturnUserCanceled() {
+        mockToSatisfyAllPrerequisites();
+
+        AppClipsTrampolineActivityTestable activity = mActivityRule.launchActivity(mActivityIntent);
+        waitForIdleSync();
+
+        Bundle bundle = new Bundle();
+        bundle.putInt(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE,
+                CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED);
+        activity.getResultReceiverForTest().send(Activity.RESULT_OK, bundle);
+        waitForIdleSync();
+
+        ActivityResult actualResult = mActivityRule.getActivityResult();
+        assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
+        assertThat(getStatusCodeExtra(actualResult.getResultData()))
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_USER_CANCELED);
+    }
+
+    @Test
+    public void startAppClipsActivity_shouldReturnSuccess() {
+        mockToSatisfyAllPrerequisites();
+
+        AppClipsTrampolineActivityTestable activity = mActivityRule.launchActivity(mActivityIntent);
+        waitForIdleSync();
+
+        Bundle bundle = new Bundle();
+        bundle.putParcelable(EXTRA_SCREENSHOT_URI, TEST_URI);
+        bundle.putInt(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
+        activity.getResultReceiverForTest().send(Activity.RESULT_OK, bundle);
+        waitForIdleSync();
+
+        ActivityResult actualResult = mActivityRule.getActivityResult();
+        assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
+        assertThat(getStatusCodeExtra(actualResult.getResultData()))
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
+        assertThat(actualResult.getResultData().getData()).isEqualTo(TEST_URI);
+    }
+
+    private void mockToSatisfyAllPrerequisites() {
+        when(mFeatureFlags.isEnabled(SCREENSHOT_APP_CLIPS)).thenReturn(true);
+        when(mOptionalBubbles.isEmpty()).thenReturn(false);
+        when(mOptionalBubbles.get()).thenReturn(mBubbles);
+        when(mBubbles.isAppBubbleTaskId(anyInt())).thenReturn(true);
+        when(mDevicePolicyManager.getScreenCaptureDisabled(eq(null))).thenReturn(false);
+    }
+
+    public static final class AppClipsTrampolineActivityTestable extends
+            AppClipsTrampolineActivity {
+
+        public AppClipsTrampolineActivityTestable(DevicePolicyManager devicePolicyManager,
+                FeatureFlags flags,
+                Optional<Bubbles> optionalBubbles,
+                NoteTaskController noteTaskController,
+                @Main Handler mainHandler) {
+            super(devicePolicyManager, flags, optionalBubbles, noteTaskController, mainHandler);
+        }
+    }
+
+    private static int getStatusCodeExtra(Intent intent) {
+        return intent.getIntExtra(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, -100);
+    }
+}
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
new file mode 100644
index 0000000..d5af7ce1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
@@ -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.systemui.screenshot;
+
+import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.net.Uri;
+import android.os.UserHandle;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.screenshot.appclips.AppClipsCrossProcessHelper;
+
+import com.google.common.util.concurrent.Futures;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.time.ZonedDateTime;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidJUnit4.class)
+public final class AppClipsViewModelTest extends SysuiTestCase {
+
+    private static final Bitmap FAKE_BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
+    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");
+
+    @Mock private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
+    @Mock private ImageExporter mImageExporter;
+
+    private com.android.systemui.screenshot.AppClipsViewModel mViewModel;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mViewModel = new AppClipsViewModel.Factory(mAppClipsCrossProcessHelper, mImageExporter,
+                getContext().getMainExecutor(), directExecutor()).create(AppClipsViewModel.class);
+    }
+
+    @Test
+    public void performScreenshot_fails_shouldUpdateErrorWithFailed() {
+        when(mAppClipsCrossProcessHelper.takeScreenshot()).thenReturn(null);
+
+        mViewModel.performScreenshot();
+        waitForIdleSync();
+
+        verify(mAppClipsCrossProcessHelper).takeScreenshot();
+        assertThat(mViewModel.getErrorLiveData().getValue())
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+        assertThat(mViewModel.getResultLiveData().getValue()).isNull();
+    }
+
+    @Test
+    public void performScreenshot_succeeds_shouldUpdateScreenshotWithBitmap() {
+        when(mAppClipsCrossProcessHelper.takeScreenshot()).thenReturn(FAKE_BITMAP);
+
+        mViewModel.performScreenshot();
+        waitForIdleSync();
+
+        verify(mAppClipsCrossProcessHelper).takeScreenshot();
+        assertThat(mViewModel.getErrorLiveData().getValue()).isNull();
+        assertThat(mViewModel.getScreenshot().getValue()).isEqualTo(FAKE_BITMAP);
+    }
+
+    @Test
+    public void saveScreenshot_throwsError_shouldUpdateErrorWithFailed() {
+        when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), any(
+                ZonedDateTime.class), any(UserHandle.class))).thenReturn(
+                Futures.immediateFailedFuture(new ExecutionException(new Throwable())));
+
+        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT);
+        waitForIdleSync();
+
+        assertThat(mViewModel.getErrorLiveData().getValue())
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+        assertThat(mViewModel.getResultLiveData().getValue()).isNull();
+    }
+
+    @Test
+    public void saveScreenshot_failsSilently_shouldUpdateErrorWithFailed() {
+        when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), any(
+                ZonedDateTime.class), any(UserHandle.class))).thenReturn(
+                Futures.immediateFuture(new ImageExporter.Result()));
+
+        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT);
+        waitForIdleSync();
+
+        assertThat(mViewModel.getErrorLiveData().getValue())
+                .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_FAILED);
+        assertThat(mViewModel.getResultLiveData().getValue()).isNull();
+    }
+
+    @Test
+    public void saveScreenshot_succeeds_shouldUpdateResultWithUri() {
+        ImageExporter.Result result = new ImageExporter.Result();
+        result.uri = FAKE_URI;
+        when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), any(
+                ZonedDateTime.class), any(UserHandle.class))).thenReturn(
+                Futures.immediateFuture(result));
+
+        mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT);
+        waitForIdleSync();
+
+        assertThat(mViewModel.getErrorLiveData().getValue()).isNull();
+        assertThat(mViewModel.getResultLiveData().getValue()).isEqualTo(FAKE_URI);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 78bebb9..d01edcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -18,8 +18,6 @@
 import android.content.ContentResolver
 import android.content.Context
 import android.graphics.drawable.Drawable
-import android.os.Handler
-import android.os.UserHandle
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -34,6 +32,9 @@
 import com.android.systemui.util.mockito.eq
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.fail
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
 import org.json.JSONException
 import org.junit.Before
 import org.junit.Rule
@@ -49,19 +50,19 @@
 class ClockRegistryTest : SysuiTestCase() {
 
     @JvmField @Rule val mockito = MockitoJUnit.rule()
+    private lateinit var dispatcher: CoroutineDispatcher
+    private lateinit var scope: TestScope
+
     @Mock private lateinit var mockContext: Context
     @Mock private lateinit var mockPluginManager: PluginManager
     @Mock private lateinit var mockClock: ClockController
     @Mock private lateinit var mockDefaultClock: ClockController
     @Mock private lateinit var mockThumbnail: Drawable
-    @Mock private lateinit var mockHandler: Handler
     @Mock private lateinit var mockContentResolver: ContentResolver
     private lateinit var fakeDefaultProvider: FakeClockPlugin
     private lateinit var pluginListener: PluginListener<ClockProviderPlugin>
     private lateinit var registry: ClockRegistry
 
-    private var settingValue: ClockSettings? = null
-
     companion object {
         private fun failFactory(): ClockController {
             fail("Unexpected call to createClock")
@@ -99,6 +100,9 @@
 
     @Before
     fun setUp() {
+        dispatcher = StandardTestDispatcher()
+        scope = TestScope(dispatcher)
+
         fakeDefaultProvider = FakeClockPlugin()
             .addClock(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME, { mockDefaultClock }, { mockThumbnail })
         whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
@@ -107,15 +111,22 @@
         registry = object : ClockRegistry(
             mockContext,
             mockPluginManager,
-            mockHandler,
+            scope = scope.backgroundScope,
+            mainDispatcher = dispatcher,
+            bgDispatcher = dispatcher,
             isEnabled = true,
-            userHandle = UserHandle.USER_ALL,
-            defaultClockProvider = fakeDefaultProvider
+            handleAllUsers = true,
+            defaultClockProvider = fakeDefaultProvider,
         ) {
-            override var settings: ClockSettings?
-                get() = settingValue
-                set(value) { settingValue = value }
+            override fun querySettings() { }
+            override fun applySettings(value: ClockSettings?) {
+                settings = value
+            }
+            // Unit Test does not validate threading
+            override fun assertMainThread() {}
+            override fun assertNotMainThread() {}
         }
+        registry.registerListeners()
 
         verify(mockPluginManager)
             .addPluginListener(captor.capture(), eq(ClockProviderPlugin::class.java), eq(true))
@@ -187,16 +198,16 @@
             .addClock("clock_1", "clock 1")
             .addClock("clock_2", "clock 2")
 
-        settingValue = ClockSettings("clock_3", null, null)
         val plugin2 = FakeClockPlugin()
             .addClock("clock_3", "clock 3", { mockClock })
             .addClock("clock_4", "clock 4")
 
+        registry.applySettings(ClockSettings("clock_3", null))
         pluginListener.onPluginConnected(plugin1, mockContext)
         pluginListener.onPluginConnected(plugin2, mockContext)
 
         val clock = registry.createCurrentClock()
-        assertEquals(clock, mockClock)
+        assertEquals(mockClock, clock)
     }
 
     @Test
@@ -205,11 +216,11 @@
             .addClock("clock_1", "clock 1")
             .addClock("clock_2", "clock 2")
 
-        settingValue = ClockSettings("clock_3", null, null)
         val plugin2 = FakeClockPlugin()
             .addClock("clock_3", "clock 3")
             .addClock("clock_4", "clock 4")
 
+        registry.applySettings(ClockSettings("clock_3", null))
         pluginListener.onPluginConnected(plugin1, mockContext)
         pluginListener.onPluginConnected(plugin2, mockContext)
         pluginListener.onPluginDisconnected(plugin2)
@@ -224,11 +235,11 @@
             .addClock("clock_1", "clock 1")
             .addClock("clock_2", "clock 2")
 
-        settingValue = ClockSettings("clock_3", null, null)
         val plugin2 = FakeClockPlugin()
             .addClock("clock_3", "clock 3", { mockClock })
             .addClock("clock_4", "clock 4")
 
+        registry.applySettings(ClockSettings("clock_3", null))
         pluginListener.onPluginConnected(plugin1, mockContext)
         pluginListener.onPluginConnected(plugin2, mockContext)
 
@@ -244,7 +255,7 @@
 
     @Test
     fun jsonDeserialization_gotExpectedObject() {
-        val expected = ClockSettings("ID", null, 500)
+        val expected = ClockSettings("ID", null).apply { _applied_timestamp = 500 }
         val actual = ClockSettings.deserialize("""{
             "clockId":"ID",
             "_applied_timestamp":500
@@ -254,14 +265,14 @@
 
     @Test
     fun jsonDeserialization_noTimestamp_gotExpectedObject() {
-        val expected = ClockSettings("ID", null, null)
+        val expected = ClockSettings("ID", null)
         val actual = ClockSettings.deserialize("{\"clockId\":\"ID\"}")
         assertEquals(expected, actual)
     }
 
     @Test
     fun jsonDeserialization_nullTimestamp_gotExpectedObject() {
-        val expected = ClockSettings("ID", null, null)
+        val expected = ClockSettings("ID", null)
         val actual = ClockSettings.deserialize("""{
             "clockId":"ID",
             "_applied_timestamp":null
@@ -271,7 +282,7 @@
 
     @Test(expected = JSONException::class)
     fun jsonDeserialization_noId_threwException() {
-        val expected = ClockSettings("ID", null, 500)
+        val expected = ClockSettings(null, null).apply { _applied_timestamp = 500 }
         val actual = ClockSettings.deserialize("{\"_applied_timestamp\":500}")
         assertEquals(expected, actual)
     }
@@ -279,14 +290,15 @@
     @Test
     fun jsonSerialization_gotExpectedString() {
         val expected = "{\"clockId\":\"ID\",\"_applied_timestamp\":500}"
-        val actual = ClockSettings.serialize(ClockSettings("ID", null, 500))
+        val actual = ClockSettings.serialize(ClockSettings("ID", null)
+            .apply { _applied_timestamp = 500 })
         assertEquals(expected, actual)
     }
 
     @Test
     fun jsonSerialization_noTimestamp_gotExpectedString() {
         val expected = "{\"clockId\":\"ID\"}"
-        val actual = ClockSettings.serialize(ClockSettings("ID", null, null))
+        val actual = ClockSettings.serialize(ClockSettings("ID", null))
         assertEquals(expected, actual)
     }
 }
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 7693fee..9eccbb6 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
@@ -471,4 +471,142 @@
         mExecutor.runAllReady();
         verify(callback).onConditionsChanged(true);
     }
+
+    /**
+     * Ensures that the result of a condition being true leads to its nested condition being
+     * activated.
+     */
+    @Test
+    public void testNestedCondition() {
+        mCondition1.fakeUpdateCondition(false);
+        final Monitor.Callback callback =
+                mock(Monitor.Callback.class);
+
+        mCondition2.fakeUpdateCondition(false);
+
+        // Create a nested condition
+        mConditionMonitor.addSubscription(new Monitor.Subscription.Builder(
+                new Monitor.Subscription.Builder(callback)
+                        .addCondition(mCondition2)
+                        .build())
+                .addCondition(mCondition1)
+                .build());
+
+        mExecutor.runAllReady();
+
+        // Ensure the nested condition callback is not called at all.
+        verify(callback, never()).onActiveChanged(anyBoolean());
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+
+        // Update the inner condition to true and ensure that the nested condition is not triggered.
+        mCondition2.fakeUpdateCondition(true);
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+        mCondition2.fakeUpdateCondition(false);
+
+        // Set outer condition and make sure the inner condition becomes active and reports that
+        // conditions aren't met
+        mCondition1.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+
+        verify(callback).onActiveChanged(eq(true));
+        verify(callback).onConditionsChanged(eq(false));
+
+        Mockito.clearInvocations(callback);
+
+        // Update the inner condition and make sure the callback is updated.
+        mCondition2.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+
+        verify(callback).onConditionsChanged(true);
+
+        Mockito.clearInvocations(callback);
+        // Invalidate outer condition and make sure callback is informed, but the last state is
+        // not affected.
+        mCondition1.fakeUpdateCondition(false);
+        mExecutor.runAllReady();
+
+        verify(callback).onActiveChanged(eq(false));
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+    }
+
+    /**
+     * Ensures a subscription is predicated on its precondition.
+     */
+    @Test
+    public void testPrecondition() {
+        mCondition1.fakeUpdateCondition(false);
+        final Monitor.Callback callback =
+                mock(Monitor.Callback.class);
+
+        mCondition2.fakeUpdateCondition(false);
+
+        // Create a nested condition
+        mConditionMonitor.addSubscription(new Monitor.Subscription.Builder(callback)
+                .addPrecondition(mCondition1)
+                .addCondition(mCondition2)
+                .build());
+
+        mExecutor.runAllReady();
+
+        // Ensure the nested condition callback is not called at all.
+        verify(callback, never()).onActiveChanged(anyBoolean());
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+
+        // Update the condition to true and ensure that the nested condition is not triggered.
+        mCondition2.fakeUpdateCondition(true);
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+        mCondition2.fakeUpdateCondition(false);
+
+        // Set precondition and make sure the inner condition becomes active and reports that
+        // conditions aren't met
+        mCondition1.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+
+        verify(callback).onActiveChanged(eq(true));
+        verify(callback).onConditionsChanged(eq(false));
+
+        Mockito.clearInvocations(callback);
+
+        // Update the condition and make sure the callback is updated.
+        mCondition2.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+
+        verify(callback).onConditionsChanged(true);
+
+        Mockito.clearInvocations(callback);
+        // Invalidate precondition and make sure callback is informed, but the last state is
+        // not affected.
+        mCondition1.fakeUpdateCondition(false);
+        mExecutor.runAllReady();
+
+        verify(callback).onActiveChanged(eq(false));
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+    }
+
+    /**
+     * Ensure preconditions are applied to every subscription added to a monitor.
+     */
+    @Test
+    public void testPreconditionMonitor() {
+        final Monitor.Callback callback =
+                mock(Monitor.Callback.class);
+
+        mCondition2.fakeUpdateCondition(true);
+        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1)));
+
+        monitor.addSubscription(new Monitor.Subscription.Builder(callback)
+                .addCondition(mCondition2)
+                .build());
+
+        mExecutor.runAllReady();
+
+        verify(callback, never()).onActiveChanged(anyBoolean());
+        verify(callback, never()).onConditionsChanged(anyBoolean());
+
+        mCondition1.fakeUpdateCondition(true);
+        mExecutor.runAllReady();
+
+        verify(callback).onActiveChanged(eq(true));
+        verify(callback).onConditionsChanged(eq(true));
+    }
 }
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 b1ca1c0..f581154 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -18,8 +18,6 @@
 import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
 import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
 
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -158,7 +156,7 @@
 
     @Test
     public void testShowTransient() {
-        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+        int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars();
         mCommandQueue.showTransient(DEFAULT_DISPLAY, types, true /* isGestureOnSystemBar */);
         waitForIdleSync();
         verify(mCallbacks).showTransient(eq(DEFAULT_DISPLAY), eq(types), eq(true));
@@ -166,7 +164,7 @@
 
     @Test
     public void testShowTransientForSecondaryDisplay() {
-        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+        int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars();
         mCommandQueue.showTransient(SECONDARY_DISPLAY, types, true /* isGestureOnSystemBar */);
         waitForIdleSync();
         verify(mCallbacks).showTransient(eq(SECONDARY_DISPLAY), eq(types), eq(true));
@@ -174,7 +172,7 @@
 
     @Test
     public void testAbortTransient() {
-        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+        int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars();
         mCommandQueue.abortTransient(DEFAULT_DISPLAY, types);
         waitForIdleSync();
         verify(mCallbacks).abortTransient(eq(DEFAULT_DISPLAY), eq(types));
@@ -182,7 +180,7 @@
 
     @Test
     public void testAbortTransientForSecondaryDisplay() {
-        int[] types = new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR};
+        int types = WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars();
         mCommandQueue.abortTransient(SECONDARY_DISPLAY, types);
         waitForIdleSync();
         verify(mCallbacks).abortTransient(eq(SECONDARY_DISPLAY), eq(types));
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 0806a62..3b4cc7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -23,6 +23,7 @@
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT;
 
+import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
@@ -631,6 +632,109 @@
     }
 
     @Test
+    public void onBiometricHelp_coEx_faceUnavailable() {
+        createController();
+
+        // GIVEN unlocking with fingerprint is possible
+        when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(anyInt()))
+                .thenReturn(true);
+
+        String message = "A message";
+        mController.setVisible(true);
+
+        // WHEN there's a face unavailable message
+        mController.getKeyguardCallback().onBiometricHelp(
+                BIOMETRIC_HELP_FACE_NOT_AVAILABLE,
+                message,
+                BiometricSourceType.FACE);
+
+        // THEN show sequential messages such as: 'face unlock unavailable' and
+        // 'try fingerprint instead'
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                message);
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_suggest_fingerprint));
+    }
+
+    @Test
+    public void onBiometricHelp_coEx_fpFailure_faceAlreadyUnlocked() {
+        createController();
+
+        // GIVEN face has already unlocked the device
+        when(mKeyguardUpdateMonitor.getUserUnlockedWithFace(anyInt())).thenReturn(true);
+
+        String message = "A message";
+        mController.setVisible(true);
+
+        // WHEN there's a fingerprint not recognized message
+        mController.getKeyguardCallback().onBiometricHelp(
+                BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                message,
+                BiometricSourceType.FINGERPRINT);
+
+        // THEN show sequential messages such as: 'Unlocked by face' and
+        // 'Swipe up to open'
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                mContext.getString(R.string.keyguard_face_successful_unlock));
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_unlock));
+    }
+
+    @Test
+    public void onBiometricHelp_coEx_fpFailure_trustAgentAlreadyUnlocked() {
+        createController();
+
+        // GIVEN trust agent has already unlocked the device
+        when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
+
+        String message = "A message";
+        mController.setVisible(true);
+
+        // WHEN there's a fingerprint not recognized message
+        mController.getKeyguardCallback().onBiometricHelp(
+                BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                message,
+                BiometricSourceType.FINGERPRINT);
+
+        // THEN show sequential messages such as: 'Kept unlocked by TrustAgent' and
+        // 'Swipe up to open'
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE,
+                mContext.getString(R.string.keyguard_indication_trust_unlocked));
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_unlock));
+    }
+
+    @Test
+    public void onBiometricHelp_coEx_fpFailure_trustAgentUnlocked_emptyTrustGrantedMessage() {
+        createController();
+
+        // GIVEN trust agent has already unlocked the device & trust granted message is empty
+        when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
+        mController.showTrustGrantedMessage(false, "");
+
+        String message = "A message";
+        mController.setVisible(true);
+
+        // WHEN there's a fingerprint not recognized message
+        mController.getKeyguardCallback().onBiometricHelp(
+                BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+                message,
+                BiometricSourceType.FINGERPRINT);
+
+        // THEN show action to unlock (ie: 'Swipe up to open')
+        verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
+        verifyIndicationMessage(
+                INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
+                mContext.getString(R.string.keyguard_unlock));
+    }
+
+    @Test
     public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() {
         createController();
         String message = mContext.getString(R.string.keyguard_unlock);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
index 0a576de..d6225c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
@@ -32,7 +32,9 @@
 import android.view.View
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.plugins.ActivityStarter
@@ -104,6 +106,9 @@
     private lateinit var keyguardBypassController: KeyguardBypassController
 
     @Mock
+    private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+
+    @Mock
     private lateinit var deviceProvisionedController: DeviceProvisionedController
 
     @Mock
@@ -125,6 +130,9 @@
     private lateinit var configPlugin: BcSmartspaceConfigPlugin
 
     @Mock
+    private lateinit var dumpManager: DumpManager
+
+    @Mock
     private lateinit var controllerListener: SmartspaceTargetListener
 
     @Captor
@@ -223,6 +231,8 @@
                 statusBarStateController,
                 deviceProvisionedController,
                 keyguardBypassController,
+                keyguardUpdateMonitor,
+                dumpManager,
                 execution,
                 executor,
                 bgExecutor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 94e3e6c..005c80a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -92,6 +92,7 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLogger;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -167,7 +168,8 @@
                 mMainHandler,
                 mBgExecutor,
                 mEulogizer,
-                mock(DumpManager.class));
+                mock(DumpManager.class),
+                mock(NotificationDismissibilityProvider.class));
         mCollection.attach(mGroupCoalescer);
         mCollection.addCollectionListener(mCollectionListener);
         mCollection.setBuildListener(mBuildListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
index 9b3626b..4708350 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
@@ -120,13 +120,31 @@
     private fun createRanking(key: String) = Ranking().apply {
         populate(
                 key,
-                0,
-                false,
-                0,
-                0,
-                NotificationManager.IMPORTANCE_DEFAULT,
-                null, null,
-                null, null, null, true, 0, false, -1, false, null, null, false, false,
-                false, null, 0, false, 0)
+                /* rank = */ 0,
+                /* matchesInterruptionFilter = */ false,
+                /* visibilityOverride = */ 0,
+                /* suppressedVisualEffects = */ 0,
+                /* importance = */ NotificationManager.IMPORTANCE_DEFAULT,
+                /* explanation = */ null,
+                /* overrideGroupKey = */ null,
+                /* channel = */ null,
+                /* overridePeople = */ null,
+                /* snoozeCriteria = */ null,
+                /* showBadge = */ true,
+                /* userSentiment = */ 0,
+                /* hidden = */ false,
+                /* lastAudiblyAlertedMs = */ -1,
+                /* noisy = */ false,
+                /* smartActions = */ null,
+                /* smartReplies = */ null,
+                /* canBubble = */ false,
+                /* isTextChanged = */ false,
+                /* isConversation = */ false,
+                /* shortcutInfo = */ null,
+                /* rankingAdjustment = */ 0,
+                /* isBubble = */ false,
+                /* proposedImportance = */ 0,
+                /* sensitiveContent = */ false
+        )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java
index 701cf95..af52459 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DeviceProvisionedCoordinatorTest.java
@@ -117,10 +117,6 @@
         extras.putBoolean(SHOW_WHEN_UNPROVISIONED_FLAG, true);
         mNotification.extras = extras;
 
-        // GIVEN notification has the permission to display during setup
-        when(mIPackageManager.checkUidPermission(SETUP_NOTIF_PERMISSION, NOTIF_UID))
-                .thenReturn(PackageManager.PERMISSION_GRANTED);
-
         // THEN don't filter out the notification
         assertFalse(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0));
     }
@@ -130,15 +126,10 @@
         // GIVEN device is unprovisioned
         when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(false);
 
-        // GIVEN notification has a flag to allow the notification during setup
+        // GIVEN notification does not have the flag to allow the notification during setup
         Bundle extras = new Bundle();
-        extras.putBoolean(SHOW_WHEN_UNPROVISIONED_FLAG, true);
         mNotification.extras = extras;
 
-        // GIVEN notification does NOT have permission to display during setup
-        when(mIPackageManager.checkUidPermission(SETUP_NOTIF_PERMISSION, NOTIF_UID))
-                .thenReturn(PackageManager.PERMISSION_DENIED);
-
         // THEN filter out the notification
         assertTrue(mDeviceProvisionedFilter.shouldFilterOut(mEntry, 0));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
new file mode 100644
index 0000000..55a79da
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DismissibilityCoordinatorTest.kt
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator
+
+import android.app.Notification
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProviderImpl
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.withArgCaptor
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DismissibilityCoordinatorTest : SysuiTestCase() {
+
+    private lateinit var coordinator: DismissibilityCoordinator
+    private lateinit var dismissibilityProvider: NotificationDismissibilityProviderImpl
+    private lateinit var onBeforeRenderListListener: OnBeforeRenderListListener
+    private val keyguardStateController: KeyguardStateController = mock()
+    private val pipeline: NotifPipeline = mock()
+    private val flagResolver: SystemUiSystemPropertiesFlags.FlagResolver = mock()
+    private val dumpManager: DumpManager = mock()
+
+    @Before
+    fun setUp() {
+        setTestFlagResolver(flagResolver)
+        whenever(flagResolver.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)).thenReturn(true)
+
+        dismissibilityProvider = NotificationDismissibilityProviderImpl(dumpManager)
+        coordinator = DismissibilityCoordinator(keyguardStateController, dismissibilityProvider)
+        coordinator.attach(pipeline)
+        onBeforeRenderListListener = withArgCaptor {
+            Mockito.verify(pipeline).addOnBeforeRenderListListener(capture())
+        }
+    }
+
+    @Test
+    fun testNotif() {
+        val entry = NotificationEntryBuilder().setTag("entry").build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertTrue(
+            "Notifs without any flags should be dismissible",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testProviderCleared() {
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+        onBeforeRenderListListener.onBeforeRenderList(emptyList()) // provider should be updated
+
+        assertTrue(dismissibilityProvider.nonDismissableEntryKeys.isEmpty())
+    }
+
+    @Test
+    fun testNonDismissableEntry() {
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertFalse(
+            "Non-dismiss Notifs should NOT be dismissible",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testOngoingNotifWhenPhoneIsLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(false)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertFalse(
+            "Ongoing Notifs should NOT be dismissible when the device is locked",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testOngoingNotifWhenPhoneIsUnLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertTrue(
+            "Ongoing Notifs should be dismissible when the device is unlocked",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testOngoingNondismissNotifWhenPhoneIsUnLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertFalse(
+            "Non-dismiss Notifs should NOT be dismissible",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testMultipleEntries() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+        val noFlagEntry = NotificationEntryBuilder().setTag("noFlagEntry").build()
+        val ongoingEntry =
+            NotificationEntryBuilder()
+                .setTag("ongoingEntry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+        val nonDismissEntry =
+            NotificationEntryBuilder()
+                .setTag("nonDismissEntry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(
+            listOf(noFlagEntry, ongoingEntry, nonDismissEntry)
+        )
+
+        assertTrue(
+            "Notifs without any flags should be dismissible",
+            dismissibilityProvider.isDismissable(noFlagEntry)
+        )
+        assertTrue(
+            "Ongoing Notifs should be dismissible when the device is unlocked",
+            dismissibilityProvider.isDismissable(ongoingEntry)
+        )
+
+        assertFalse(
+            "Non-dismiss Notifs should NOT be dismissible",
+            dismissibilityProvider.isDismissable(nonDismissEntry)
+        )
+    }
+
+    @Test
+    fun testNonDismissableEntryInGroup() {
+        val summary = NotificationEntryBuilder().setTag("summary").build()
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+        val group = GroupEntryBuilder().setSummary(summary).addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertFalse("Child should be non-dismissible", dismissibilityProvider.isDismissable(entry))
+        assertFalse(
+            "Summary should be non-dismissible",
+            dismissibilityProvider.isDismissable(summary)
+        )
+    }
+
+    @Test
+    fun testOngoingEntryInGroupWhenPhoneIsLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(false)
+        val summary = NotificationEntryBuilder().setTag("summary").build()
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+        val group = GroupEntryBuilder().setSummary(summary).addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertFalse("Child should be non-dismissible", dismissibilityProvider.isDismissable(entry))
+        assertFalse(
+            "Summary should be non-dismissible",
+            dismissibilityProvider.isDismissable(summary)
+        )
+    }
+
+    @Test
+    fun testOngoingEntryInGroupWhenPhoneIsUnLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+        val summary = NotificationEntryBuilder().setTag("summary").build()
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+        val group = GroupEntryBuilder().setSummary(summary).addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertTrue("Child should be dismissible", dismissibilityProvider.isDismissable(entry))
+        assertTrue("Summary should be dismissible", dismissibilityProvider.isDismissable(summary))
+    }
+
+    @Test
+    fun testNonDismissableEntryInGroupWithoutSummary() {
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+        val group = GroupEntryBuilder().addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertFalse("Child should be non-dismissible", dismissibilityProvider.isDismissable(entry))
+    }
+
+    @Test
+    fun testOngoingEntryInGroupWithoutSummaryWhenPhoneIsLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(false)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+        val group = GroupEntryBuilder().addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertFalse("Child should be non-dismissible", dismissibilityProvider.isDismissable(entry))
+    }
+
+    @Test
+    fun testOngoingEntryInGroupWithoutSummaryWhenPhoneIsUnLocked() {
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+        val group = GroupEntryBuilder().addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertTrue("Child should be dismissible", dismissibilityProvider.isDismissable(entry))
+    }
+
+    @Test
+    fun testNonDismissableSummary() {
+        val summary =
+            NotificationEntryBuilder()
+                .setTag("summary")
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+        val entry = NotificationEntryBuilder().setTag("entry").build()
+        val group = GroupEntryBuilder().setSummary(summary).addChild(entry).build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(group))
+
+        assertTrue("Child should be dismissible", dismissibilityProvider.isDismissable(entry))
+        assertFalse(
+            "Summary should be non-dismissible",
+            dismissibilityProvider.isDismissable(summary)
+        )
+    }
+
+    @Test
+    fun testFeatureToggleOffNonDismissibleEntry() {
+        whenever(flagResolver.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)).thenReturn(false)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertTrue(
+            "FLAG_NO_DISMISS should be ignored, if the feature is off",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testFeatureToggleOffOngoingNotifWhenPhoneIsLocked() {
+        whenever(flagResolver.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)).thenReturn(false)
+        whenever(keyguardStateController.isUnlocked).thenReturn(false)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertFalse(
+            "Ongoing Notifs should NOT be dismissible, if the feature is off",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+
+    @Test
+    fun testFeatureToggleOffOngoingNotifWhenPhoneIsUnLocked() {
+        whenever(flagResolver.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)).thenReturn(false)
+        whenever(keyguardStateController.isUnlocked).thenReturn(true)
+        val entry =
+            NotificationEntryBuilder()
+                .setTag("entry")
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .build()
+
+        onBeforeRenderListListener.onBeforeRenderList(listOf(entry))
+
+        assertFalse(
+            "Ongoing Notifs should NOT be dismissible, if the feature is off",
+            dismissibilityProvider.isDismissable(entry)
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index 2686238..49da848 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -38,6 +38,8 @@
 import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.withArgCaptor
@@ -63,6 +65,7 @@
 @RunWith(AndroidTestingRunner::class)
 class KeyguardCoordinatorTest : SysuiTestCase() {
 
+    private val headsUpManager: HeadsUpManager = mock()
     private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
     private val keyguardRepository = FakeKeyguardRepository()
     private val notifPipelineFlags: NotifPipelineFlags = mock()
@@ -90,8 +93,9 @@
     fun unseenFilterSuppressesSeenNotifWhileKeyguardShowing() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
-        // GIVEN: Keyguard is not showing, and a notification is present
+        // GIVEN: Keyguard is not showing, shade is expanded, and a notification is present
         keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
@@ -113,11 +117,44 @@
     }
 
     @Test
+    fun unseenFilter_headsUpMarkedAsSeen() {
+        whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
+
+        // GIVEN: Keyguard is not showing, shade is not expanded
+        keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(false)
+        runKeyguardCoordinatorTest {
+            // WHEN: A notification is posted
+            val fakeEntry = NotificationEntryBuilder().build()
+            collectionListener.onEntryAdded(fakeEntry)
+
+            // WHEN: That notification is heads up
+            onHeadsUpChangedListener.onHeadsUpStateChanged(fakeEntry, /* isHeadsUp= */ true)
+            testScheduler.runCurrent()
+
+            // WHEN: The keyguard is now showing
+            keyguardRepository.setKeyguardShowing(true)
+            testScheduler.runCurrent()
+
+            // THEN: The notification is recognized as "seen" and is filtered out.
+            assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
+
+            // WHEN: The keyguard goes away
+            keyguardRepository.setKeyguardShowing(false)
+            testScheduler.runCurrent()
+
+            // THEN: The notification is shown regardless
+            assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
+        }
+    }
+
+    @Test
     fun unseenFilterDoesNotSuppressSeenOngoingNotifWhileKeyguardShowing() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
-        // GIVEN: Keyguard is not showing, and an ongoing notification is present
+        // GIVEN: Keyguard is not showing, shade is expanded, and an ongoing notification is present
         keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
             val fakeEntry = NotificationEntryBuilder()
                 .setNotification(Notification.Builder(mContext).setOngoing(true).build())
@@ -137,8 +174,9 @@
     fun unseenFilterDoesNotSuppressSeenMediaNotifWhileKeyguardShowing() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
-        // GIVEN: Keyguard is not showing, and a media notification is present
+        // GIVEN: Keyguard is not showing, shade is expanded, and a media notification is present
         keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
             val fakeEntry = NotificationEntryBuilder().build().apply {
                 row = mock<ExpandableNotificationRow>().apply {
@@ -160,8 +198,9 @@
     fun unseenFilterUpdatesSeenProviderWhenSuppressing() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
-        // GIVEN: Keyguard is not showing, and a notification is present
+        // GIVEN: Keyguard is not showing, shade is expanded, and a notification is present
         keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
@@ -185,8 +224,9 @@
     fun unseenFilterInvalidatesWhenSettingChanges() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
-        // GIVEN: Keyguard is not showing
+        // GIVEN: Keyguard is not showing, and shade is expanded
         keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
             // GIVEN: A notification is present
             val fakeEntry = NotificationEntryBuilder().build()
@@ -237,8 +277,9 @@
     fun unseenFilterSeenGroupSummaryWithUnseenChild() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
-        // GIVEN: Keyguard is not showing, and a notification is present
+        // GIVEN: Keyguard is not showing, shade is expanded, and a notification is present
         keyguardRepository.setKeyguardShowing(false)
+        whenever(statusBarStateController.isExpanded).thenReturn(true)
         runKeyguardCoordinatorTest {
             // WHEN: A new notification is posted
             val fakeSummary = NotificationEntryBuilder().build()
@@ -276,11 +317,11 @@
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
 
-            // WHEN: Keyguard is no longer showing for 5 seconds
+            // WHEN: Keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
-            testScheduler.runCurrent()
-            testScheduler.advanceTimeBy(5.seconds.inWholeMilliseconds)
-            testScheduler.runCurrent()
+
+            // When: Shade is expanded
+            statusBarStateListener.onExpandedChanged(true)
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
@@ -292,7 +333,7 @@
     }
 
     @Test
-    fun unseenNotificationIsNotMarkedAsSeenIfTimeThresholdNotMet() {
+    fun unseenNotificationIsNotMarkedAsSeenIfShadeNotExpanded() {
         whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
 
         // GIVEN: Keyguard is showing, unseen notification is present
@@ -301,10 +342,8 @@
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
 
-            // WHEN: Keyguard is no longer showing for <5 seconds
+            // WHEN: Keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
-            testScheduler.runCurrent()
-            testScheduler.advanceTimeBy(1.seconds.inWholeMilliseconds)
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
@@ -327,6 +366,7 @@
         val keyguardCoordinator =
             KeyguardCoordinator(
                 testDispatcher,
+                headsUpManager,
                 keyguardNotifVisibilityProvider,
                 keyguardRepository,
                 notifPipelineFlags,
@@ -364,12 +404,21 @@
         val unseenFilter: NotifFilter
             get() = keyguardCoordinator.unseenNotifFilter
 
-        // TODO(254647461): Remove lazy once Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD is enabled and
-        //  removed
+        // TODO(254647461): Remove lazy from these properties once
+        //    Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD is enabled and removed
+
         val collectionListener: NotifCollectionListener by lazy {
             withArgCaptor { verify(notifPipeline).addCollectionListener(capture()) }
         }
 
+        val onHeadsUpChangedListener: OnHeadsUpChangedListener by lazy {
+            withArgCaptor { verify(headsUpManager).addListener(capture()) }
+        }
+
+        val statusBarStateListener: StatusBarStateController.StateListener by lazy {
+            withArgCaptor { verify(statusBarStateController).addCallback(capture()) }
+        }
+
         var showOnlyUnseenNotifsOnKeyguardSetting: Boolean
             get() =
                 fakeSettings.getIntForUser(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
index 33b94e3..bd03903 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryLoggerTest.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import java.lang.RuntimeException
 import kotlinx.coroutines.Dispatchers
 import org.junit.Before
 import org.junit.Test
@@ -113,6 +114,24 @@
         assertThat(data).hasSize(2)
     }
 
+    @Test
+    fun onPullAtom_throwsInterruptedException_failsGracefully() {
+        val pipeline: NotifPipeline = mock()
+        whenever(pipeline.allNotifs).thenAnswer { throw InterruptedException("Timeout") }
+        val logger = NotificationMemoryLogger(pipeline, statsManager, immediate, bgExecutor)
+        assertThat(logger.onPullAtom(SysUiStatsLog.NOTIFICATION_MEMORY_USE, mutableListOf()))
+            .isEqualTo(StatsManager.PULL_SKIP)
+    }
+
+    @Test
+    fun onPullAtom_throwsRuntimeException_failsGracefully() {
+        val pipeline: NotifPipeline = mock()
+        whenever(pipeline.allNotifs).thenThrow(RuntimeException("Something broke!"))
+        val logger = NotificationMemoryLogger(pipeline, statsManager, immediate, bgExecutor)
+        assertThat(logger.onPullAtom(SysUiStatsLog.NOTIFICATION_MEMORY_USE, mutableListOf()))
+            .isEqualTo(StatsManager.PULL_SKIP)
+    }
+
     private fun createLoggerWithNotifications(
         notifications: List<Notification>
     ): NotificationMemoryLogger {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index 2d23f3c..5b6c8c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.NotificationMediaManager
 import com.android.systemui.statusbar.SmartReplyController
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
 import com.android.systemui.statusbar.notification.logging.NotificationLogger
@@ -88,6 +89,7 @@
     private val peopleNotificationIdentifier: PeopleNotificationIdentifier = mock()
     private val bubblesManager: BubblesManager = mock()
     private val dragController: ExpandableNotificationRowDragController = mock()
+    private val dismissibilityProvider: NotificationDismissibilityProvider = mock()
     private lateinit var controller: ExpandableNotificationRowController
 
     @Before
@@ -124,7 +126,8 @@
                 featureFlags,
                 peopleNotificationIdentifier,
                 Optional.of(bubblesManager),
-                dragController
+                dragController,
+                dismissibilityProvider
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 9e23d54..110926c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -16,12 +16,9 @@
 
 package com.android.systemui.statusbar.notification.row;
 
-import static android.app.Notification.FLAG_NO_CLEAR;
-import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 
 import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
-import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -478,26 +475,24 @@
     }
 
     @Test
-    public void testCanDismissNoClear() throws Exception {
+    public void testCanDismiss() throws Exception {
         ExpandableNotificationRow row =
                 mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
-        modifySbn(row.getEntry())
-                .setFlag(mContext, FLAG_NO_CLEAR, true)
-                .build();
+        when(mNotificationTestHelper.getDismissibilityProvider().isDismissable(row.getEntry()))
+                .thenReturn(true);
         row.performDismiss(false);
-        verify(mNotificationTestHelper.mOnUserInteractionCallback)
+        verify(mNotificationTestHelper.getOnUserInteractionCallback())
                 .registerFutureDismissal(any(), anyInt());
     }
 
     @Test
-    public void testCannotDismissOngoing() throws Exception {
+    public void testCannotDismiss() throws Exception {
         ExpandableNotificationRow row =
                 mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
-        modifySbn(row.getEntry())
-                .setFlag(mContext, FLAG_ONGOING_EVENT, true)
-                .build();
+        when(mNotificationTestHelper.getDismissibilityProvider().isDismissable(row.getEntry()))
+                .thenReturn(false);
         row.performDismiss(false);
-        verify(mNotificationTestHelper.mOnUserInteractionCallback, never())
+        verify(mNotificationTestHelper.getOnUserInteractionCallback(), never())
                 .registerFutureDismissal(any(), anyInt());
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 5394d88..3face35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
@@ -42,6 +43,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
+import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.RemoteViews;
@@ -332,6 +334,38 @@
                 eq(FLAG_CONTENT_VIEW_HEADS_UP));
     }
 
+    @Test
+    public void testNotificationViewHeightTooSmallFailsValidation() {
+        View view = mock(View.class);
+        when(view.getHeight())
+                .thenReturn((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10,
+                        mContext.getResources().getDisplayMetrics()));
+        String result = NotificationContentInflater.isValidView(view, mRow.getEntry(),
+                mContext.getResources());
+        assertNotNull(result);
+    }
+
+    @Test
+    public void testNotificationViewPassesValidation() {
+        View view = mock(View.class);
+        when(view.getHeight())
+                .thenReturn((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 17,
+                        mContext.getResources().getDisplayMetrics()));
+        String result = NotificationContentInflater.isValidView(view, mRow.getEntry(),
+                mContext.getResources());
+        assertNull(result);
+    }
+
+    @Test
+    public void testInvalidNotificationDoesNotInvokeCallback() throws Exception {
+        mRow.getPrivateLayout().removeAllViews();
+        mRow.getEntry().getSbn().getNotification().contentView =
+                new RemoteViews(mContext.getPackageName(), R.layout.invalid_notification_height);
+        inflateAndWait(true, mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+        assertEquals(0, mRow.getPrivateLayout().getChildCount());
+        verify(mRow, times(0)).onNotificationUpdated();
+    }
+
     private static void inflateAndWait(NotificationContentInflater inflater,
             @InflationFlag int contentToInflate,
             ExpandableNotificationRow row)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index aca9c56..f92678f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -65,6 +65,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.icon.IconBuilder;
@@ -121,7 +122,8 @@
     private final IconManager mIconManager;
     private final StatusBarStateController mStatusBarStateController;
     private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
-    public final OnUserInteractionCallback mOnUserInteractionCallback;
+    private final OnUserInteractionCallback mOnUserInteractionCallback;
+    private final NotificationDismissibilityProvider mDismissibilityProvider;
     public final Runnable mFutureDismissalRunnable;
     private @InflationFlag int mDefaultInflationFlags;
     private FeatureFlags mFeatureFlags;
@@ -171,6 +173,7 @@
         mBindPipelineEntryListener = collectionListenerCaptor.getValue();
         mPeopleNotificationIdentifier = mock(PeopleNotificationIdentifier.class);
         mOnUserInteractionCallback = mock(OnUserInteractionCallback.class);
+        mDismissibilityProvider = mock(NotificationDismissibilityProvider.class);
         mFutureDismissalRunnable = mock(Runnable.class);
         when(mOnUserInteractionCallback.registerFutureDismissal(any(), anyInt()))
                 .thenReturn(mFutureDismissalRunnable);
@@ -189,6 +192,14 @@
         return mMockLogger;
     }
 
+    public OnUserInteractionCallback getOnUserInteractionCallback() {
+        return mOnUserInteractionCallback;
+    }
+
+    public NotificationDismissibilityProvider getDismissibilityProvider() {
+        return mDismissibilityProvider;
+    }
+
     /**
      * Creates a generic row with rounded border.
      *
@@ -545,6 +556,7 @@
                 mOnUserInteractionCallback,
                 Optional.of(mock(BubblesManager.class)),
                 mock(NotificationGutsManager.class),
+                mDismissibilityProvider,
                 mock(MetricsLogger.class),
                 mock(SmartReplyConstants.class),
                 mock(SmartReplyController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 9f6f082..5b8305d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -63,6 +63,7 @@
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl;
 import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
@@ -195,7 +196,8 @@
                 mNotificationStackSizeCalculator,
                 mFeatureFlags,
                 mNotificationTargetsHelper,
-                mSecureSettings
+                mSecureSettings,
+                mock(NotificationDismissibilityProvider.class)
         );
 
         when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 8cfcc07..f568547 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
+import static com.android.systemui.statusbar.phone.AutoTileManager.DEVICE_CONTROLS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -50,6 +51,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.qs.AutoAddTracker;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
@@ -70,6 +72,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.Mockito;
@@ -77,6 +80,7 @@
 import org.mockito.Spy;
 import org.mockito.stubbing.Answer;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -543,6 +547,61 @@
     }
 
     @Test
+    public void testAddControlsTileIfNotPresent() {
+        String spec = DEVICE_CONTROLS;
+        when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false);
+        when(mQsTileHost.getTiles()).thenReturn(new ArrayList<>());
+
+        mAutoTileManager.init();
+        ArgumentCaptor<DeviceControlsController.Callback> captor =
+                ArgumentCaptor.forClass(DeviceControlsController.Callback.class);
+
+        verify(mDeviceControlsController).setCallback(captor.capture());
+
+        captor.getValue().onControlsUpdate(3);
+        verify(mQsTileHost).addTile(spec, 3);
+        verify(mAutoAddTracker).setTileAdded(spec);
+    }
+
+    @Test
+    public void testDontAddControlsTileIfPresent() {
+        String spec = DEVICE_CONTROLS;
+        when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(false);
+        when(mQsTileHost.getTiles()).thenReturn(new ArrayList<>());
+
+        mAutoTileManager.init();
+        ArgumentCaptor<DeviceControlsController.Callback> captor =
+                ArgumentCaptor.forClass(DeviceControlsController.Callback.class);
+
+        verify(mDeviceControlsController).setCallback(captor.capture());
+
+        captor.getValue().removeControlsAutoTracker();
+        verify(mQsTileHost, never()).addTile(spec, 3);
+        verify(mAutoAddTracker, never()).setTileAdded(spec);
+        verify(mAutoAddTracker).setTileRemoved(spec);
+    }
+
+    @Test
+    public void testRemoveControlsTileFromTrackerWhenRequested() {
+        String spec = "controls";
+        when(mAutoAddTracker.isAdded(eq(spec))).thenReturn(true);
+        QSTile mockTile = mock(QSTile.class);
+        when(mockTile.getTileSpec()).thenReturn(spec);
+        when(mQsTileHost.getTiles()).thenReturn(List.of(mockTile));
+
+        mAutoTileManager.init();
+        ArgumentCaptor<DeviceControlsController.Callback> captor =
+                ArgumentCaptor.forClass(DeviceControlsController.Callback.class);
+
+        verify(mDeviceControlsController).setCallback(captor.capture());
+
+        captor.getValue().onControlsUpdate(3);
+        verify(mQsTileHost, never()).addTile(spec, 3);
+        verify(mAutoAddTracker, never()).setTileAdded(spec);
+    }
+
+
+    @Test
     public void testEmptyArray_doesNotCrash() {
         mContext.getOrCreateTestableResources().addOverride(
                 R.array.config_quickSettingsAutoAdd, new String[0]);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index ed3f710..7e69efa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -264,6 +264,19 @@
     }
 
     @Test
+    public void notifPositionAlignedWithClockAndBurnInOffsetInSplitShadeMode() {
+        setSplitShadeTopMargin(100); // this makes clock to be at 100
+        givenAOD();
+        mIsSplitShade = true;
+        givenMaxBurnInOffset(100);
+        givenHighestBurnInOffset(); // this makes clock to be at 200
+        // WHEN the position algorithm is run
+        positionClock();
+        // THEN the notif padding adjusts for burn-in offset: clock position - burn-in offset
+        assertThat(mClockPosition.stackScrollerPadding).isEqualTo(100);
+    }
+
+    @Test
     public void clockPositionedDependingOnMarginInSplitShade() {
         setSplitShadeTopMargin(400);
         givenLockScreen();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
index 6fb6893..8aaa57f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -23,6 +23,8 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.testing.AndroidTestingRunner;
@@ -33,7 +35,10 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.StatusBarMobileView;
 import com.android.systemui.statusbar.StatusBarWifiView;
@@ -46,6 +51,8 @@
 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags;
 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter;
 import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.tuner.TunerService;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
@@ -87,6 +94,61 @@
         testCallOnAdd_forManager(manager);
     }
 
+    @Test
+    public void testRemoveIcon_ignoredForNewPipeline() {
+        IconManager manager = mock(IconManager.class);
+
+        // GIVEN the new pipeline is on
+        StatusBarPipelineFlags flags = mock(StatusBarPipelineFlags.class);
+        when(flags.isIconControlledByFlags("test_icon")).thenReturn(true);
+
+        StatusBarIconController iconController = new StatusBarIconControllerImpl(
+                mContext,
+                mock(CommandQueue.class),
+                mock(DemoModeController.class),
+                mock(ConfigurationController.class),
+                mock(TunerService.class),
+                mock(DumpManager.class),
+                mock(StatusBarIconList.class),
+                flags
+        );
+
+        iconController.addIconGroup(manager);
+
+        // WHEN a request to remove a new icon is sent
+        iconController.removeIcon("test_icon", 0);
+
+        // THEN it is not removed for those icons
+        verify(manager, never()).onRemoveIcon(anyInt());
+    }
+
+    @Test
+    public void testRemoveAllIconsForSlot_ignoredForNewPipeline() {
+        IconManager manager = mock(IconManager.class);
+
+        // GIVEN the new pipeline is on
+        StatusBarPipelineFlags flags = mock(StatusBarPipelineFlags.class);
+        when(flags.isIconControlledByFlags("test_icon")).thenReturn(true);
+
+        StatusBarIconController iconController = new StatusBarIconControllerImpl(
+                mContext,
+                mock(CommandQueue.class),
+                mock(DemoModeController.class),
+                mock(ConfigurationController.class),
+                mock(TunerService.class),
+                mock(DumpManager.class),
+                mock(StatusBarIconList.class),
+                flags
+        );
+
+        iconController.addIconGroup(manager);
+
+        // WHEN a request to remove a new icon is sent
+        iconController.removeAllIconsForSlot("test_icon");
+
+        // THEN it is not removed for those icons
+        verify(manager, never()).onRemoveIcon(anyInt());
+    }
 
     private <T extends IconManager & TestableIconManager> void testCallOnAdd_forManager(T manager) {
         StatusBarIconHolder holder = holderForType(TYPE_ICON);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
index 4506e41..6c0f6c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
@@ -19,8 +19,10 @@
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.BroadcastReceiver;
 import android.content.Intent;
@@ -32,6 +34,8 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,12 +50,15 @@
 public class SystemUIDialogTest extends SysuiTestCase {
 
     @Mock
+    private FeatureFlags mFeatureFlags;
+    @Mock
     private BroadcastDispatcher mBroadcastDispatcher;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
+        mDependency.injectTestDependency(FeatureFlags.class, mFeatureFlags);
         mDependency.injectTestDependency(BroadcastDispatcher.class, mBroadcastDispatcher);
     }
 
@@ -86,4 +93,20 @@
         verify(mBroadcastDispatcher, never()).unregisterReceiver(any());
         assertFalse(dialog.isShowing());
     }
+
+    @Test
+    public void usePredictiveBackAnimFlag() {
+        when(mFeatureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_QS_DIALOG_ANIM))
+                .thenReturn(true);
+        final SystemUIDialog dialog = new SystemUIDialog(mContext);
+
+        dialog.show();
+
+        assertTrue(dialog.isShowing());
+        verify(mFeatureFlags, atLeast(1))
+                .isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_QS_DIALOG_ANIM);
+
+        dialog.dismiss();
+        assertFalse(dialog.isShowing());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModelTest.kt
index f822ba0..45189cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/MobileConnectionModelTest.kt
@@ -19,7 +19,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableRowLogger
-import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_ACTIVITY_DIRECTION
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_ACTIVITY_DIRECTION_IN
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_ACTIVITY_DIRECTION_OUT
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_CARRIER_NETWORK_CHANGE
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_CDMA_LEVEL
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_CONNECTION_STATE
@@ -54,7 +55,19 @@
         assertThat(logger.changes)
             .contains(Pair(COL_CONNECTION_STATE, connection.dataConnectionState.toString()))
         assertThat(logger.changes)
-            .contains(Pair(COL_ACTIVITY_DIRECTION, connection.dataActivityDirection.toString()))
+            .contains(
+                Pair(
+                    COL_ACTIVITY_DIRECTION_IN,
+                    connection.dataActivityDirection.hasActivityIn.toString(),
+                )
+            )
+        assertThat(logger.changes)
+            .contains(
+                Pair(
+                    COL_ACTIVITY_DIRECTION_OUT,
+                    connection.dataActivityDirection.hasActivityOut.toString(),
+                )
+            )
         assertThat(logger.changes)
             .contains(
                 Pair(COL_CARRIER_NETWORK_CHANGE, connection.carrierNetworkChangeActive.toString())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt
new file mode 100644
index 0000000..63cb30c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.model
+
+import android.os.PersistableBundle
+import android.telephony.CarrierConfigManager
+import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL
+import android.telephony.CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import org.junit.Before
+import org.junit.Test
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+class SystemUiCarrierConfigTest : SysuiTestCase() {
+
+    lateinit var underTest: SystemUiCarrierConfig
+
+    @Before
+    fun setUp() {
+        underTest = SystemUiCarrierConfig(SUB_1_ID, createTestConfig())
+    }
+
+    @Test
+    fun `process new config - reflected by isUsingDefault`() {
+        // Starts out using the defaults
+        assertThat(underTest.isUsingDefault).isTrue()
+
+        // ANY new config means we're no longer tracking defaults
+        underTest.processNewCarrierConfig(createTestConfig())
+
+        assertThat(underTest.isUsingDefault).isFalse()
+    }
+
+    @Test
+    fun `process new config - updates all flows`() {
+        assertThat(underTest.shouldInflateSignalStrength.value).isFalse()
+        assertThat(underTest.showOperatorNameInStatusBar.value).isFalse()
+
+        underTest.processNewCarrierConfig(
+            configWithOverrides(
+                KEY_INFLATE_SIGNAL_STRENGTH_BOOL to true,
+                KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL to true,
+            )
+        )
+
+        assertThat(underTest.shouldInflateSignalStrength.value).isTrue()
+        assertThat(underTest.showOperatorNameInStatusBar.value).isTrue()
+    }
+
+    @Test
+    fun `process new config - defaults to false for config overrides`() {
+        // This case is only apparent when:
+        //   1. The default is true
+        //   2. The override config has no value for a given key
+        // In this case (per the old code) we would use the default value of false, despite there
+        // being no override key present in the override config
+
+        underTest =
+            SystemUiCarrierConfig(
+                SUB_1_ID,
+                configWithOverrides(
+                    KEY_INFLATE_SIGNAL_STRENGTH_BOOL to true,
+                    KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL to true,
+                )
+            )
+
+        assertThat(underTest.isUsingDefault).isTrue()
+        assertThat(underTest.shouldInflateSignalStrength.value).isTrue()
+        assertThat(underTest.showOperatorNameInStatusBar.value).isTrue()
+
+        // Process a new config with no keys
+        underTest.processNewCarrierConfig(PersistableBundle())
+
+        assertThat(underTest.isUsingDefault).isFalse()
+        assertThat(underTest.shouldInflateSignalStrength.value).isFalse()
+        assertThat(underTest.showOperatorNameInStatusBar.value).isFalse()
+    }
+
+    companion object {
+        private const val SUB_1_ID = 1
+
+        /**
+         * In order to keep us from having to update every place that might want to create a config,
+         * make sure to add new keys here
+         */
+        fun createTestConfig() =
+            PersistableBundle().also {
+                it.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
+                it.putBoolean(CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL, false)
+            }
+
+        /** Override the default config with the given (key, value) pair */
+        fun configWithOverride(key: String, override: Boolean): PersistableBundle =
+            createTestConfig().also { it.putBoolean(key, override) }
+
+        /** Override any number of configs from the default */
+        fun configWithOverrides(vararg overrides: Pair<String, Boolean>) =
+            createTestConfig().also { config ->
+                overrides.forEach { (key, value) -> config.putBoolean(key, value) }
+            }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
new file mode 100644
index 0000000..521c67f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.data.repository
+
+import android.content.Intent
+import android.os.PersistableBundle
+import android.telephony.CarrierConfigManager
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.MockitoSession
+import org.mockito.quality.Strictness
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+class CarrierConfigRepositoryTest : SysuiTestCase() {
+    private val testDispatcher = UnconfinedTestDispatcher()
+    private val testScope = TestScope(testDispatcher)
+
+    private lateinit var underTest: CarrierConfigRepository
+    private lateinit var mockitoSession: MockitoSession
+    private lateinit var carrierConfigCoreStartable: CarrierConfigCoreStartable
+
+    @Mock private lateinit var logger: ConnectivityPipelineLogger
+    @Mock private lateinit var carrierConfigManager: CarrierConfigManager
+    @Mock private lateinit var dumpManager: DumpManager
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mockitoSession =
+            mockitoSession()
+                .initMocks(this)
+                .mockStatic(CarrierConfigManager::class.java)
+                .strictness(Strictness.LENIENT)
+                .startMocking()
+
+        whenever(CarrierConfigManager.getDefaultConfig()).thenReturn(DEFAULT_CONFIG)
+
+        whenever(carrierConfigManager.getConfigForSubId(anyInt())).thenAnswer { invocation ->
+            when (invocation.getArgument(0) as Int) {
+                1 -> CONFIG_1
+                2 -> CONFIG_2
+                else -> null
+            }
+        }
+
+        underTest =
+            CarrierConfigRepository(
+                fakeBroadcastDispatcher,
+                carrierConfigManager,
+                dumpManager,
+                logger,
+                testScope.backgroundScope,
+            )
+
+        carrierConfigCoreStartable =
+            CarrierConfigCoreStartable(underTest, testScope.backgroundScope)
+    }
+
+    @After
+    fun tearDown() {
+        mockitoSession.finishMocking()
+    }
+
+    @Test
+    fun `carrier config stream produces int-bundle pairs`() =
+        testScope.runTest {
+            var latest: Pair<Int, PersistableBundle>? = null
+            val job = underTest.carrierConfigStream.onEach { latest = it }.launchIn(this)
+
+            sendConfig(SUB_ID_1)
+            assertThat(latest).isEqualTo(Pair(SUB_ID_1, CONFIG_1))
+
+            sendConfig(SUB_ID_2)
+            assertThat(latest).isEqualTo(Pair(SUB_ID_2, CONFIG_2))
+
+            job.cancel()
+        }
+
+    @Test
+    fun `carrier config stream ignores invalid subscriptions`() =
+        testScope.runTest {
+            var latest: Pair<Int, PersistableBundle>? = null
+            val job = underTest.carrierConfigStream.onEach { latest = it }.launchIn(this)
+
+            sendConfig(INVALID_SUBSCRIPTION_ID)
+
+            assertThat(latest).isNull()
+
+            job.cancel()
+        }
+
+    @Test
+    fun `getOrCreateConfig - uses default config if no override`() {
+        val config = underTest.getOrCreateConfigForSubId(123)
+        assertThat(config.isUsingDefault).isTrue()
+    }
+
+    @Test
+    fun `getOrCreateConfig - uses override if exists`() {
+        val config = underTest.getOrCreateConfigForSubId(SUB_ID_1)
+        assertThat(config.isUsingDefault).isFalse()
+    }
+
+    @Test
+    fun `config - updates while config stream is collected`() =
+        testScope.runTest {
+            CONFIG_1.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
+
+            carrierConfigCoreStartable.start()
+
+            val config = underTest.getOrCreateConfigForSubId(SUB_ID_1)
+            assertThat(config.shouldInflateSignalStrength.value).isFalse()
+
+            CONFIG_1.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true)
+            sendConfig(SUB_ID_1)
+
+            assertThat(config.shouldInflateSignalStrength.value).isTrue()
+        }
+
+    private fun sendConfig(subId: Int) {
+        fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+            receiver.onReceive(
+                context,
+                Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
+                    .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, subId)
+            )
+        }
+    }
+
+    companion object {
+        private const val SUB_ID_1 = 1
+        private const val SUB_ID_2 = 2
+
+        private val DEFAULT_CONFIG = createTestConfig()
+        private val CONFIG_1 = createTestConfig()
+        private val CONFIG_2 = createTestConfig()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
index 0add905e..f483e42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
@@ -55,8 +55,12 @@
     private val _subscriptions = MutableStateFlow<List<SubscriptionModel>>(listOf())
     override val subscriptions = _subscriptions
 
-    private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
+    private val _activeMobileDataSubscriptionId = MutableStateFlow<Int?>(null)
     override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId
+
+    private val _activeMobileRepository = MutableStateFlow<MobileConnectionRepository?>(null)
+    override val activeMobileDataRepository = _activeMobileRepository
+
     override val activeSubChangedInGroupEvent: MutableSharedFlow<Unit> = MutableSharedFlow()
 
     private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
@@ -66,14 +70,12 @@
     override val defaultMobileNetworkConnectivity = _mobileConnectivity
 
     private val subIdRepos = mutableMapOf<Int, MobileConnectionRepository>()
+
     override fun getRepoForSubId(subId: Int): MobileConnectionRepository {
         return subIdRepos[subId]
             ?: FakeMobileConnectionRepository(subId, tableLogBuffer).also { subIdRepos[subId] = it }
     }
 
-    private val _globalMobileDataSettingChangedEvent = MutableStateFlow(Unit)
-    override val globalMobileDataSettingChangedEvent = _globalMobileDataSettingChangedEvent
-
     override val defaultDataSubRatConfig = MutableStateFlow(MobileMappings.Config())
 
     private val _defaultMobileIconMapping = MutableStateFlow(TEST_MAPPING)
@@ -94,12 +96,15 @@
         _mobileConnectivity.value = model
     }
 
-    suspend fun triggerGlobalMobileDataSettingChangedEvent() {
-        _globalMobileDataSettingChangedEvent.emit(Unit)
-    }
-
     fun setActiveMobileDataSubscriptionId(subId: Int) {
-        _activeMobileDataSubscriptionId.value = subId
+        // Simulate the filtering that the repo does
+        if (subId == INVALID_SUBSCRIPTION_ID) {
+            _activeMobileDataSubscriptionId.value = null
+            _activeMobileRepository.value = null
+        } else {
+            _activeMobileDataSubscriptionId.value = subId
+            _activeMobileRepository.value = getRepoForSubId(subId)
+        }
     }
 
     fun setMobileConnectionRepositoryMap(connections: Map<Int, MobileConnectionRepository>) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 0859d14..4da2104 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.demomode.DemoMode
 import com.android.systemui.demomode.DemoModeController
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.DemoMobileConnectionsRepository
@@ -40,7 +41,6 @@
 import com.android.systemui.util.mockito.kotlinArgumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.FakeSettings
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
@@ -82,10 +82,10 @@
     @Mock private lateinit var subscriptionManager: SubscriptionManager
     @Mock private lateinit var telephonyManager: TelephonyManager
     @Mock private lateinit var logger: ConnectivityPipelineLogger
+    @Mock private lateinit var summaryLogger: TableLogBuffer
     @Mock private lateinit var demoModeController: DemoModeController
     @Mock private lateinit var dumpManager: DumpManager
 
-    private val globalSettings = FakeSettings()
     private val fakeNetworkEventsFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
     private val mobileMappings = FakeMobileMappingsProxy()
 
@@ -116,9 +116,9 @@
                 subscriptionManager,
                 telephonyManager,
                 logger,
+                summaryLogger,
                 mobileMappings,
                 fakeBroadcastDispatcher,
-                globalSettings,
                 context,
                 IMMEDIATE,
                 scope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 6989b514..00ce412 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -138,7 +138,8 @@
                 assertThat(connectionInfo.carrierNetworkChangeActive)
                     .isEqualTo(model.carrierNetworkChange)
                 assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
-                assertThat(conn.networkName.value).isEqualTo(NetworkNameModel.Derived(model.name))
+                assertThat(conn.networkName.value)
+                    .isEqualTo(NetworkNameModel.IntentDerived(model.name))
 
                 // TODO(b/261029387): check these once we start handling them
                 assertThat(connectionInfo.isEmergencyOnly).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index f12d113..f60d92b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -539,7 +539,8 @@
                 assertThat(connectionInfo.carrierNetworkChangeActive)
                     .isEqualTo(model.carrierNetworkChange)
                 assertThat(connectionInfo.isRoaming).isEqualTo(model.roaming)
-                assertThat(conn.networkName.value).isEqualTo(NetworkNameModel.Derived(model.name))
+                assertThat(conn.networkName.value)
+                    .isEqualTo(NetworkNameModel.IntentDerived(model.name))
 
                 // TODO(b/261029387) check these once we start handling them
                 assertThat(connectionInfo.isEmergencyOnly).isFalse()
@@ -594,9 +595,11 @@
     subId: Int = 1,
     level: Int = 1,
     numberOfLevels: Int = 4,
+    activity: Int = DATA_ACTIVITY_NONE,
 ): FakeWifiEventModel.CarrierMerged =
     FakeWifiEventModel.CarrierMerged(
         subscriptionId = subId,
         level = level,
         numberOfLevels = numberOfLevels,
+        activity = activity,
     )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
index ea90150..abb4561 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/CarrierMergedConnectionRepositoryTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
 
+import android.telephony.TelephonyManager
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -27,6 +28,7 @@
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
 import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
+import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
@@ -49,6 +51,7 @@
 
     private lateinit var wifiRepository: FakeWifiRepository
     @Mock private lateinit var logger: TableLogBuffer
+    @Mock private lateinit var telephonyManager: TelephonyManager
 
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
@@ -56,13 +59,16 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID)
+        whenever(telephonyManager.simOperatorName).thenReturn("")
+
         wifiRepository = FakeWifiRepository()
 
         underTest =
             CarrierMergedConnectionRepository(
                 SUB_ID,
                 logger,
-                NetworkNameModel.Default("name"),
+                telephonyManager,
                 testScope.backgroundScope,
                 wifiRepository,
             )
@@ -135,6 +141,44 @@
         }
 
     @Test
+    fun connectionInfo_activity_comesFromWifiActivity() =
+        testScope.runTest {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            wifiRepository.setIsWifiEnabled(true)
+            wifiRepository.setIsWifiDefault(true)
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID,
+                    level = 3,
+                )
+            )
+            wifiRepository.setWifiActivity(
+                DataActivityModel(
+                    hasActivityIn = true,
+                    hasActivityOut = false,
+                )
+            )
+
+            assertThat(latest!!.dataActivityDirection.hasActivityIn).isTrue()
+            assertThat(latest!!.dataActivityDirection.hasActivityOut).isFalse()
+
+            wifiRepository.setWifiActivity(
+                DataActivityModel(
+                    hasActivityIn = false,
+                    hasActivityOut = true,
+                )
+            )
+
+            assertThat(latest!!.dataActivityDirection.hasActivityIn).isFalse()
+            assertThat(latest!!.dataActivityDirection.hasActivityOut).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
     fun connectionInfo_carrierMergedWifi_wrongSubId_isDefault() =
         testScope.runTest {
             var latest: MobileConnectionModel? = null
@@ -244,6 +288,43 @@
             job.cancel()
         }
 
+    @Test
+    fun networkName_usesSimOperatorNameAsInitial() =
+        testScope.runTest {
+            whenever(telephonyManager.simOperatorName).thenReturn("Test SIM name")
+
+            var latest: NetworkNameModel? = null
+            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
+
+            job.cancel()
+        }
+
+    @Test
+    fun networkName_updatesOnNetworkUpdate() =
+        testScope.runTest {
+            whenever(telephonyManager.simOperatorName).thenReturn("Test SIM name")
+
+            var latest: NetworkNameModel? = null
+            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("Test SIM name"))
+
+            whenever(telephonyManager.simOperatorName).thenReturn("New SIM name")
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId = NET_ID,
+                    subscriptionId = SUB_ID,
+                    level = 3,
+                )
+            )
+
+            assertThat(latest).isEqualTo(NetworkNameModel.SimDerived("New SIM name"))
+
+            job.cancel()
+        }
+
     private companion object {
         const val SUB_ID = 123
         const val NET_ID = 456
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
index c02a4df..c02ca01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
@@ -16,24 +16,33 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
 
+import android.telephony.ServiceState
+import android.telephony.SignalStrength
+import android.telephony.TelephonyCallback
+import android.telephony.TelephonyManager
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_EMERGENCY
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_OPERATOR
+import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel.Companion.COL_PRIMARY_LEVEL
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.getTelephonyCallbackForType
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import java.io.PrintWriter
+import java.io.StringWriter
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.test.TestScope
@@ -55,24 +64,18 @@
 class FullMobileConnectionRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: FullMobileConnectionRepository
 
+    private val systemClock = FakeSystemClock()
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
-    private val mobileMappings = FakeMobileMappingsProxy()
-    private val tableLogBuffer = mock<TableLogBuffer>()
+    private val tableLogBuffer = TableLogBuffer(maxSize = 100, name = "TestName", systemClock)
     private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>()
     private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>()
 
-    private lateinit var connectionsRepo: FakeMobileConnectionsRepository
-    private val globalMobileDataSettingChangedEvent: Flow<Unit>
-        get() = connectionsRepo.globalMobileDataSettingChangedEvent
-
     private lateinit var mobileRepo: FakeMobileConnectionRepository
     private lateinit var carrierMergedRepo: FakeMobileConnectionRepository
 
     @Before
     fun setUp() {
-        connectionsRepo = FakeMobileConnectionsRepository(mobileMappings, tableLogBuffer)
-
         mobileRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
         carrierMergedRepo = FakeMobileConnectionRepository(SUB_ID, tableLogBuffer)
 
@@ -82,12 +85,10 @@
                     any(),
                     eq(DEFAULT_NAME),
                     eq(SEP),
-                    eq(globalMobileDataSettingChangedEvent),
                 )
             )
             .thenReturn(mobileRepo)
-        whenever(carrierMergedFactory.build(eq(SUB_ID), any(), eq(DEFAULT_NAME)))
-            .thenReturn(carrierMergedRepo)
+        whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(carrierMergedRepo)
     }
 
     @Test
@@ -109,7 +110,6 @@
                     tableLogBuffer,
                     DEFAULT_NAME,
                     SEP,
-                    globalMobileDataSettingChangedEvent
                 )
         }
 
@@ -126,7 +126,7 @@
 
             assertThat(underTest.activeRepo.value).isEqualTo(mobileRepo)
             assertThat(underTest.connectionInfo.value).isEqualTo(mobileConnectionInfo)
-            verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer, DEFAULT_NAME)
+            verify(carrierMergedFactory, never()).build(SUB_ID, tableLogBuffer)
         }
 
     @Test
@@ -310,7 +310,6 @@
                     startingIsCarrierMerged = false,
                     DEFAULT_NAME,
                     SEP,
-                    globalMobileDataSettingChangedEvent,
                 )
 
             val connection1Repeat =
@@ -319,7 +318,6 @@
                     startingIsCarrierMerged = false,
                     DEFAULT_NAME,
                     SEP,
-                    globalMobileDataSettingChangedEvent,
                 )
 
             assertThat(connection1.tableLogBuffer)
@@ -345,7 +343,6 @@
                     startingIsCarrierMerged = false,
                     DEFAULT_NAME,
                     SEP,
-                    globalMobileDataSettingChangedEvent,
                 )
 
             // WHEN a connection with the same sub ID but carrierMerged = true is created
@@ -355,7 +352,6 @@
                     startingIsCarrierMerged = true,
                     DEFAULT_NAME,
                     SEP,
-                    globalMobileDataSettingChangedEvent,
                 )
 
             // THEN the same table is re-used
@@ -363,8 +359,219 @@
                 .isSameInstanceAs(connection1Repeat.tableLogBuffer)
         }
 
-    // TODO(b/238425913): Verify that the logging switches correctly (once the carrier merged repo
-    //   implements logging).
+    @Test
+    fun connectionInfo_logging_notCarrierMerged_getsUpdates() =
+        testScope.runTest {
+            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+            val telephonyManager =
+                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
+            createRealMobileRepo(telephonyManager)
+            createRealCarrierMergedRepo(telephonyManager, FakeWifiRepository())
+
+            initializeRepo(startingIsCarrierMerged = false)
+
+            val job = underTest.connectionInfo.launchIn(this)
+
+            // WHEN we set up some mobile connection info
+            val serviceState = ServiceState()
+            serviceState.setOperatorName("longName", "OpTypical", "1")
+            serviceState.isEmergencyOnly = false
+            getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager)
+                .onServiceStateChanged(serviceState)
+
+            // THEN it's logged to the buffer
+            assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpTypical")
+            assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}false")
+
+            // WHEN we update mobile connection info
+            val serviceState2 = ServiceState()
+            serviceState2.setOperatorName("longName", "OpDiff", "1")
+            serviceState2.isEmergencyOnly = true
+            getTelephonyCallbackForType<TelephonyCallback.ServiceStateListener>(telephonyManager)
+                .onServiceStateChanged(serviceState2)
+
+            // THEN the updates are logged
+            assertThat(dumpBuffer()).contains("$COL_OPERATOR${BUFFER_SEPARATOR}OpDiff")
+            assertThat(dumpBuffer()).contains("$COL_EMERGENCY${BUFFER_SEPARATOR}true")
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_logging_carrierMerged_getsUpdates() =
+        testScope.runTest {
+            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+            val telephonyManager =
+                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
+            createRealMobileRepo(telephonyManager)
+            val wifiRepository = FakeWifiRepository()
+            createRealCarrierMergedRepo(telephonyManager, wifiRepository)
+
+            initializeRepo(startingIsCarrierMerged = true)
+
+            val job = underTest.connectionInfo.launchIn(this)
+
+            // WHEN we set up carrier merged info
+            val networkId = 2
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId,
+                    SUB_ID,
+                    level = 3,
+                )
+            )
+
+            // THEN the carrier merged info is logged
+            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
+
+            // WHEN we update the info
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId,
+                    SUB_ID,
+                    level = 1,
+                )
+            )
+
+            // THEN the updates are logged
+            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_logging_updatesWhenCarrierMergedUpdates() =
+        testScope.runTest {
+            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+            val telephonyManager =
+                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
+            createRealMobileRepo(telephonyManager)
+
+            val wifiRepository = FakeWifiRepository()
+            createRealCarrierMergedRepo(telephonyManager, wifiRepository)
+
+            initializeRepo(startingIsCarrierMerged = false)
+
+            val job = underTest.connectionInfo.launchIn(this)
+
+            // WHEN we set up some mobile connection info
+            val signalStrength = mock<SignalStrength>()
+            whenever(signalStrength.level).thenReturn(1)
+
+            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
+                .onSignalStrengthsChanged(signalStrength)
+
+            // THEN it's logged to the buffer
+            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
+
+            // WHEN isCarrierMerged is set to true
+            val networkId = 2
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId,
+                    SUB_ID,
+                    level = 3,
+                )
+            )
+            underTest.setIsCarrierMerged(true)
+
+            // THEN the carrier merged info is logged
+            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
+
+            // WHEN the carrier merge network is updated
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId,
+                    SUB_ID,
+                    level = 4,
+                )
+            )
+
+            // THEN the new level is logged
+            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
+
+            // WHEN isCarrierMerged is set to false
+            underTest.setIsCarrierMerged(false)
+
+            // THEN the typical info is logged
+            // Note: Since our first logs also had the typical info, we need to search the log
+            // contents for after our carrier merged level log.
+            val fullBuffer = dumpBuffer()
+            val carrierMergedContentIndex = fullBuffer.indexOf("${BUFFER_SEPARATOR}4")
+            val bufferAfterCarrierMerged = fullBuffer.substring(carrierMergedContentIndex)
+            assertThat(bufferAfterCarrierMerged).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}1")
+
+            // WHEN the normal network is updated
+            val newMobileInfo =
+                MobileConnectionModel(
+                    operatorAlphaShort = "Mobile Operator 2",
+                    primaryLevel = 0,
+                )
+            mobileRepo.setConnectionInfo(newMobileInfo)
+
+            // THEN the new level is logged
+            assertThat(dumpBuffer()).contains("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}0")
+
+            job.cancel()
+        }
+
+    @Test
+    fun connectionInfo_logging_doesNotLogUpdatesForNotActiveRepo() =
+        testScope.runTest {
+            // SETUP: Use real repositories to verify the diffing still works. (See b/267501739.)
+            val telephonyManager =
+                mock<TelephonyManager>().apply { whenever(this.simOperatorName).thenReturn("") }
+            createRealMobileRepo(telephonyManager)
+
+            val wifiRepository = FakeWifiRepository()
+            createRealCarrierMergedRepo(telephonyManager, wifiRepository)
+
+            // WHEN isCarrierMerged = false
+            initializeRepo(startingIsCarrierMerged = false)
+
+            val job = underTest.connectionInfo.launchIn(this)
+
+            val signalStrength = mock<SignalStrength>()
+            whenever(signalStrength.level).thenReturn(1)
+            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
+                .onSignalStrengthsChanged(signalStrength)
+
+            // THEN updates to the carrier merged level aren't logged
+            val networkId = 2
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId,
+                    SUB_ID,
+                    level = 4,
+                )
+            )
+            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}4")
+
+            wifiRepository.setWifiNetwork(
+                WifiNetworkModel.CarrierMerged(
+                    networkId,
+                    SUB_ID,
+                    level = 3,
+                )
+            )
+            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}3")
+
+            // WHEN isCarrierMerged is set to true
+            underTest.setIsCarrierMerged(true)
+
+            // THEN updates to the normal level aren't logged
+            whenever(signalStrength.level).thenReturn(5)
+            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
+                .onSignalStrengthsChanged(signalStrength)
+            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}5")
+
+            whenever(signalStrength.level).thenReturn(6)
+            getTelephonyCallbackForType<TelephonyCallback.SignalStrengthsListener>(telephonyManager)
+                .onSignalStrengthsChanged(signalStrength)
+            assertThat(dumpBuffer()).doesNotContain("$COL_PRIMARY_LEVEL${BUFFER_SEPARATOR}6")
+
+            job.cancel()
+        }
 
     private fun initializeRepo(startingIsCarrierMerged: Boolean) {
         underTest =
@@ -374,16 +581,74 @@
                 tableLogBuffer,
                 DEFAULT_NAME,
                 SEP,
-                globalMobileDataSettingChangedEvent,
                 testScope.backgroundScope,
                 mobileFactory,
                 carrierMergedFactory,
             )
     }
 
+    private fun createRealMobileRepo(
+        telephonyManager: TelephonyManager,
+    ): MobileConnectionRepositoryImpl {
+        whenever(telephonyManager.subscriptionId).thenReturn(SUB_ID)
+
+        val realRepo =
+            MobileConnectionRepositoryImpl(
+                context,
+                SUB_ID,
+                defaultNetworkName = NetworkNameModel.Default("default"),
+                networkNameSeparator = SEP,
+                telephonyManager,
+                systemUiCarrierConfig = mock(),
+                fakeBroadcastDispatcher,
+                mobileMappingsProxy = mock(),
+                testDispatcher,
+                logger = mock(),
+                tableLogBuffer,
+                testScope.backgroundScope,
+            )
+        whenever(
+                mobileFactory.build(
+                    eq(SUB_ID),
+                    any(),
+                    eq(DEFAULT_NAME),
+                    eq(SEP),
+                )
+            )
+            .thenReturn(realRepo)
+
+        return realRepo
+    }
+
+    private fun createRealCarrierMergedRepo(
+        telephonyManager: TelephonyManager,
+        wifiRepository: FakeWifiRepository,
+    ): CarrierMergedConnectionRepository {
+        wifiRepository.setIsWifiEnabled(true)
+        wifiRepository.setIsWifiDefault(true)
+        val realRepo =
+            CarrierMergedConnectionRepository(
+                SUB_ID,
+                tableLogBuffer,
+                telephonyManager,
+                testScope.backgroundScope,
+                wifiRepository,
+            )
+        whenever(carrierMergedFactory.build(eq(SUB_ID), any())).thenReturn(realRepo)
+
+        return realRepo
+    }
+
+    private fun dumpBuffer(): String {
+        val outputWriter = StringWriter()
+        tableLogBuffer.dump(PrintWriter(outputWriter), arrayOf())
+        return outputWriter.toString()
+    }
+
     private companion object {
         const val SUB_ID = 42
         private val DEFAULT_NAME = NetworkNameModel.Default("default name")
         private const val SEP = "-"
+        private const val BUFFER_SEPARATOR = "|"
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index d6b8c0d..a294088a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -17,15 +17,13 @@
 package com.android.systemui.statusbar.pipeline.mobile.data.repository.prod
 
 import android.content.Intent
-import android.os.UserHandle
-import android.provider.Settings
+import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL
 import android.telephony.CellSignalStrengthCdma
 import android.telephony.NetworkRegistrationInfo
 import android.telephony.ServiceState
 import android.telephony.ServiceState.STATE_IN_SERVICE
 import android.telephony.ServiceState.STATE_OUT_OF_SERVICE
 import android.telephony.SignalStrength
-import android.telephony.SubscriptionInfo
 import android.telephony.TelephonyCallback
 import android.telephony.TelephonyCallback.DataActivityListener
 import android.telephony.TelephonyCallback.ServiceStateListener
@@ -41,6 +39,8 @@
 import android.telephony.TelephonyManager.DATA_CONNECTING
 import android.telephony.TelephonyManager.DATA_DISCONNECTED
 import android.telephony.TelephonyManager.DATA_DISCONNECTING
+import android.telephony.TelephonyManager.DATA_HANDOVER_IN_PROGRESS
+import android.telephony.TelephonyManager.DATA_SUSPENDED
 import android.telephony.TelephonyManager.DATA_UNKNOWN
 import android.telephony.TelephonyManager.ERI_OFF
 import android.telephony.TelephonyManager.ERI_ON
@@ -59,6 +59,9 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.OverrideNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.configWithOverride
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
 import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
@@ -67,10 +70,8 @@
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -83,7 +84,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.mockito.Mock
-import org.mockito.Mockito
 import org.mockito.MockitoAnnotations
 
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@@ -99,12 +99,15 @@
 
     private val scope = CoroutineScope(IMMEDIATE)
     private val mobileMappings = FakeMobileMappingsProxy()
-    private val globalSettings = FakeSettings()
+    private val systemUiCarrierConfig =
+        SystemUiCarrierConfig(
+            SUB_1_ID,
+            createTestConfig(),
+        )
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        globalSettings.userId = UserHandle.USER_ALL
         whenever(telephonyManager.subscriptionId).thenReturn(SUB_1_ID)
 
         connectionsRepo = FakeMobileConnectionsRepository(mobileMappings, tableLogger)
@@ -116,9 +119,8 @@
                 DEFAULT_NAME,
                 SEP,
                 telephonyManager,
-                globalSettings,
+                systemUiCarrierConfig,
                 fakeBroadcastDispatcher,
-                connectionsRepo.globalMobileDataSettingChangedEvent,
                 mobileMappings,
                 IMMEDIATE,
                 logger,
@@ -255,6 +257,37 @@
         }
 
     @Test
+    fun testFlowForSubId_dataConnectionState_suspended() =
+        runBlocking(IMMEDIATE) {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            val callback =
+                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+            callback.onDataConnectionStateChanged(DATA_SUSPENDED, 200 /* unused */)
+
+            assertThat(latest?.dataConnectionState).isEqualTo(DataConnectionState.Suspended)
+
+            job.cancel()
+        }
+
+    @Test
+    fun testFlowForSubId_dataConnectionState_handoverInProgress() =
+        runBlocking(IMMEDIATE) {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            val callback =
+                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+            callback.onDataConnectionStateChanged(DATA_HANDOVER_IN_PROGRESS, 200 /* unused */)
+
+            assertThat(latest?.dataConnectionState)
+                .isEqualTo(DataConnectionState.HandoverInProgress)
+
+            job.cancel()
+        }
+
+    @Test
     fun testFlowForSubId_dataConnectionState_unknown() =
         runBlocking(IMMEDIATE) {
             var latest: MobileConnectionModel? = null
@@ -270,6 +303,21 @@
         }
 
     @Test
+    fun testFlowForSubId_dataConnectionState_invalid() =
+        runBlocking(IMMEDIATE) {
+            var latest: MobileConnectionModel? = null
+            val job = underTest.connectionInfo.onEach { latest = it }.launchIn(this)
+
+            val callback =
+                getTelephonyCallbackForType<TelephonyCallback.DataConnectionStateListener>()
+            callback.onDataConnectionStateChanged(45, 200 /* unused */)
+
+            assertThat(latest?.dataConnectionState).isEqualTo(DataConnectionState.Invalid)
+
+            job.cancel()
+        }
+
+    @Test
     fun testFlowForSubId_dataActivity() =
         runBlocking(IMMEDIATE) {
             var latest: MobileConnectionModel? = null
@@ -352,52 +400,26 @@
     @Test
     fun dataEnabled_initial_false() =
         runBlocking(IMMEDIATE) {
-            whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true)
-
-            assertThat(underTest.dataEnabled.value).isFalse()
-        }
-
-    @Test
-    fun dataEnabled_isEnabled_true() =
-        runBlocking(IMMEDIATE) {
-            whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true)
-            val job = underTest.dataEnabled.launchIn(this)
-
-            assertThat(underTest.dataEnabled.value).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
-    fun dataEnabled_isDisabled() =
-        runBlocking(IMMEDIATE) {
             whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
-            val job = underTest.dataEnabled.launchIn(this)
 
             assertThat(underTest.dataEnabled.value).isFalse()
-
-            job.cancel()
         }
 
     @Test
-    fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() =
+    fun `is data enabled - tracks telephony callback`() =
         runBlocking(IMMEDIATE) {
-            val subIdSettingName = "${Settings.Global.MOBILE_DATA}$SUB_1_ID"
-
             var latest: Boolean? = null
             val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
 
-            // We don't read the setting directly, we query telephony when changes happen
             whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
-            globalSettings.putInt(subIdSettingName, 0)
-            assertThat(latest).isFalse()
+            assertThat(underTest.dataEnabled.value).isFalse()
 
-            whenever(telephonyManager.isDataConnectionAllowed).thenReturn(true)
-            globalSettings.putInt(subIdSettingName, 1)
+            val callback = getTelephonyCallbackForType<TelephonyCallback.DataEnabledListener>()
+
+            callback.onDataEnabledChanged(true, 1)
             assertThat(latest).isTrue()
 
-            whenever(telephonyManager.isDataConnectionAllowed).thenReturn(false)
-            globalSettings.putInt(subIdSettingName, 0)
+            callback.onDataEnabledChanged(false, 1)
             assertThat(latest).isFalse()
 
             job.cancel()
@@ -418,8 +440,6 @@
     fun `roaming - cdma - queries telephony manager`() =
         runBlocking(IMMEDIATE) {
             var latest: Boolean? = null
-            // Start the telephony collection job so that cdmaRoaming starts updating
-            val telephonyJob = underTest.connectionInfo.launchIn(this)
             val job = underTest.cdmaRoaming.onEach { latest = it }.launchIn(this)
 
             val cb = getTelephonyCallbackForType<ServiceStateListener>()
@@ -439,7 +459,6 @@
 
             assertThat(latest).isTrue()
 
-            telephonyJob.cancel()
             job.cancel()
         }
 
@@ -536,16 +555,51 @@
         }
 
     @Test
-    fun `network name - broadcast not for this sub id - returns default`() =
+    fun `network name - broadcast not for this sub id - keeps old value`() =
         runBlocking(IMMEDIATE) {
             var latest: NetworkNameModel? = null
             val job = underTest.networkName.onEach { latest = it }.launchIn(this)
 
-            val intent = spnIntent(subId = 101)
-
+            val intent = spnIntent()
             fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
                 receiver.onReceive(context, intent)
             }
+            assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
+
+            // WHEN an intent with a different subId is sent
+            val wrongSubIntent = spnIntent(subId = 101)
+
+            fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+                receiver.onReceive(context, wrongSubIntent)
+            }
+
+            // THEN the previous intent's name is still used
+            assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
+
+            job.cancel()
+        }
+
+    @Test
+    fun `network name - broadcast has no data - updates to default`() =
+        runBlocking(IMMEDIATE) {
+            var latest: NetworkNameModel? = null
+            val job = underTest.networkName.onEach { latest = it }.launchIn(this)
+
+            val intent = spnIntent()
+            fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+                receiver.onReceive(context, intent)
+            }
+            assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
+
+            val intentWithoutInfo =
+                spnIntent(
+                    showSpn = false,
+                    showPlmn = false,
+                )
+
+            fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
+                receiver.onReceive(context, intentWithoutInfo)
+            }
 
             assertThat(latest).isEqualTo(DEFAULT_NAME)
 
@@ -553,7 +607,7 @@
         }
 
     @Test
-    fun `network name - operatorAlphaShort - tracked`() =
+    fun `operatorAlphaShort - tracked`() =
         runBlocking(IMMEDIATE) {
             var latest: String? = null
 
@@ -625,16 +679,31 @@
             job.cancel()
         }
 
-    private fun getTelephonyCallbacks(): List<TelephonyCallback> {
-        val callbackCaptor = argumentCaptor<TelephonyCallback>()
-        Mockito.verify(telephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
-        return callbackCaptor.allValues
-    }
+    @Test
+    fun `number of levels - uses carrier config`() =
+        runBlocking(IMMEDIATE) {
+            var latest: Int? = null
+            val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
+
+            systemUiCarrierConfig.processNewCarrierConfig(
+                configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, true)
+            )
+
+            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS + 1)
+
+            systemUiCarrierConfig.processNewCarrierConfig(
+                configWithOverride(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false)
+            )
+
+            assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
+
+            job.cancel()
+        }
 
     private inline fun <reified T> getTelephonyCallbackForType(): T {
-        val cbs = getTelephonyCallbacks().filterIsInstance<T>()
-        assertThat(cbs.size).isEqualTo(1)
-        return cbs[0]
+        return MobileTelephonyHelpers.getTelephonyCallbackForType(telephonyManager)
     }
 
     /** Convenience constructor for SignalStrength */
@@ -668,8 +737,6 @@
     companion object {
         private val IMMEDIATE = Dispatchers.Main.immediate
         private const val SUB_1_ID = 1
-        private val SUB_1 =
-            mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
 
         private val DEFAULT_NAME = NetworkNameModel.Default("default name")
         private const val SEP = "-"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index db8172a..673e559 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -23,10 +23,10 @@
 import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
 import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
 import android.os.ParcelUuid
-import android.provider.Settings
 import android.telephony.CarrierConfigManager
 import android.telephony.SubscriptionInfo
 import android.telephony.SubscriptionManager
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.TelephonyCallback
 import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
 import android.telephony.TelephonyManager
@@ -39,6 +39,8 @@
 import com.android.systemui.log.table.TableLogBufferFactory
 import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectivityModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
@@ -49,13 +51,13 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.runBlocking
@@ -80,20 +82,22 @@
     private lateinit var carrierMergedFactory: CarrierMergedConnectionRepository.Factory
     private lateinit var fullConnectionFactory: FullMobileConnectionRepository.Factory
     private lateinit var wifiRepository: FakeWifiRepository
+    private lateinit var carrierConfigRepository: CarrierConfigRepository
     @Mock private lateinit var connectivityManager: ConnectivityManager
     @Mock private lateinit var subscriptionManager: SubscriptionManager
     @Mock private lateinit var telephonyManager: TelephonyManager
     @Mock private lateinit var logger: ConnectivityPipelineLogger
+    @Mock private lateinit var summaryLogger: TableLogBuffer
     @Mock private lateinit var logBufferFactory: TableLogBufferFactory
 
     private val mobileMappings = FakeMobileMappingsProxy()
 
     private val scope = CoroutineScope(IMMEDIATE)
-    private val globalSettings = FakeSettings()
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        whenever(telephonyManager.simOperatorName).thenReturn("")
 
         // Set up so the individual connection repositories
         whenever(telephonyManager.createForSubscriptionId(anyInt())).thenAnswer { invocation ->
@@ -119,19 +123,29 @@
 
         wifiRepository = FakeWifiRepository()
 
+        carrierConfigRepository =
+            CarrierConfigRepository(
+                fakeBroadcastDispatcher,
+                mock(),
+                mock(),
+                logger,
+                scope,
+            )
+
         connectionFactory =
             MobileConnectionRepositoryImpl.Factory(
                 fakeBroadcastDispatcher,
                 context = context,
                 telephonyManager = telephonyManager,
                 bgDispatcher = IMMEDIATE,
-                globalSettings = globalSettings,
                 logger = logger,
                 mobileMappingsProxy = mobileMappings,
                 scope = scope,
+                carrierConfigRepository = carrierConfigRepository,
             )
         carrierMergedFactory =
             CarrierMergedConnectionRepository.Factory(
+                telephonyManager,
                 scope,
                 wifiRepository,
             )
@@ -149,9 +163,9 @@
                 subscriptionManager,
                 telephonyManager,
                 logger,
+                summaryLogger,
                 mobileMappings,
                 fakeBroadcastDispatcher,
-                globalSettings,
                 context,
                 IMMEDIATE,
                 scope,
@@ -245,10 +259,9 @@
         }
 
     @Test
-    fun testActiveDataSubscriptionId_initialValueIsInvalidId() =
+    fun testActiveDataSubscriptionId_initialValueIsNull() =
         runBlocking(IMMEDIATE) {
-            assertThat(underTest.activeMobileDataSubscriptionId.value)
-                .isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+            assertThat(underTest.activeMobileDataSubscriptionId.value).isEqualTo(null)
         }
 
     @Test
@@ -267,6 +280,140 @@
         }
 
     @Test
+    fun activeSubId_nullIfInvalidSubIdIsReceived() =
+        runBlocking(IMMEDIATE) {
+            var latest: Int? = null
+
+            val job = underTest.activeMobileDataSubscriptionId.onEach { latest = it }.launchIn(this)
+
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+            assertThat(latest).isNotNull()
+
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
+
+            assertThat(latest).isNull()
+
+            job.cancel()
+        }
+
+    @Test
+    fun activeRepo_initiallyNull() {
+        assertThat(underTest.activeMobileDataRepository.value).isNull()
+    }
+
+    @Test
+    fun activeRepo_updatesWithActiveDataId() =
+        runBlocking(IMMEDIATE) {
+            var latest: MobileConnectionRepository? = null
+            val job = underTest.activeMobileDataRepository.onEach { latest = it }.launchIn(this)
+
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+            assertThat(latest?.subId).isEqualTo(SUB_2_ID)
+
+            job.cancel()
+        }
+
+    @Test
+    fun activeRepo_nullIfActiveDataSubIdBecomesInvalid() =
+        runBlocking(IMMEDIATE) {
+            var latest: MobileConnectionRepository? = null
+            val job = underTest.activeMobileDataRepository.onEach { latest = it }.launchIn(this)
+
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+            assertThat(latest).isNotNull()
+
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
+
+            assertThat(latest).isNull()
+
+            job.cancel()
+        }
+
+    @Test
+    /** Regression test for b/268146648. */
+    fun activeSubIdIsSetBeforeSubscriptionsAreUpdated_doesNotThrow() =
+        runBlocking(IMMEDIATE) {
+            var activeRepo: MobileConnectionRepository? = null
+            var subscriptions: List<SubscriptionModel>? = null
+
+            val activeRepoJob =
+                underTest.activeMobileDataRepository.onEach { activeRepo = it }.launchIn(this)
+            val subscriptionsJob =
+                underTest.subscriptions.onEach { subscriptions = it }.launchIn(this)
+
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+            assertThat(subscriptions).isEmpty()
+            assertThat(activeRepo).isNotNull()
+
+            activeRepoJob.cancel()
+            subscriptionsJob.cancel()
+        }
+
+    @Test
+    fun getRepoForSubId_activeDataSubIdIsRequestedBeforeSubscriptionsUpdate() =
+        runBlocking(IMMEDIATE) {
+            var latest: MobileConnectionRepository? = null
+            var subscriptions: List<SubscriptionModel>? = null
+            val activeSubIdJob =
+                underTest.activeMobileDataSubscriptionId
+                    .filterNotNull()
+                    .onEach { latest = underTest.getRepoForSubId(it) }
+                    .launchIn(this)
+            val subscriptionsJob =
+                underTest.subscriptions.onEach { subscriptions = it }.launchIn(this)
+
+            // Active data subscription id is sent, but no subscription change has been posted yet
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+            // Subscriptions list is empty
+            assertThat(subscriptions).isEmpty()
+            // getRepoForSubId does not throw
+            assertThat(latest).isNotNull()
+
+            activeSubIdJob.cancel()
+            subscriptionsJob.cancel()
+        }
+
+    @Test
+    fun activeDataSentBeforeSubscriptionList_subscriptionReusesActiveDataRepo() =
+        runBlocking(IMMEDIATE) {
+            var activeRepo: MobileConnectionRepository? = null
+            val job = underTest.activeMobileDataRepository.onEach { activeRepo = it }.launchIn(this)
+            val subscriptionsJob = underTest.subscriptions.launchIn(this)
+
+            // GIVEN active repo is updated before the subscription list updates
+            getTelephonyCallbackForType<ActiveDataSubscriptionIdListener>()
+                .onActiveDataSubscriptionIdChanged(SUB_2_ID)
+
+            assertThat(activeRepo).isNotNull()
+
+            // GIVEN the subscription list is then updated which includes the active data sub id
+            whenever(subscriptionManager.completeActiveSubscriptionInfoList)
+                .thenReturn(listOf(SUB_2))
+            getSubscriptionCallback().onSubscriptionsChanged()
+
+            // WHEN requesting a connection repository for the subscription
+            val newRepo = underTest.getRepoForSubId(SUB_2_ID)
+
+            // THEN the newly request repo has been cached and reused
+            assertThat(activeRepo).isSameInstanceAs(newRepo)
+
+            job.cancel()
+            subscriptionsJob.cancel()
+        }
+
+    @Test
     fun testConnectionRepository_validSubId_isCached() =
         runBlocking(IMMEDIATE) {
             val job = underTest.subscriptions.launchIn(this)
@@ -466,7 +613,7 @@
         }
 
     @Test
-    fun `connection repository - log buffer contains sub id in its name`() =
+    fun connectionRepository_logBufferContainsSubIdInItsName() =
         runBlocking(IMMEDIATE) {
             val job = underTest.subscriptions.launchIn(this)
 
@@ -544,24 +691,6 @@
         }
 
     @Test
-    fun globalMobileDataSettingsChangedEvent_producesOnSettingChange() =
-        runBlocking(IMMEDIATE) {
-            var produced = false
-            val job =
-                underTest.globalMobileDataSettingChangedEvent
-                    .onEach { produced = true }
-                    .launchIn(this)
-
-            assertThat(produced).isFalse()
-
-            globalSettings.putInt(Settings.Global.MOBILE_DATA, 0)
-
-            assertThat(produced).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
     fun mobileConnectivity_isConnected_isNotValidated() =
         runBlocking(IMMEDIATE) {
             val caps = createCapabilities(connected = true, validated = false)
@@ -627,9 +756,9 @@
                     subscriptionManager,
                     telephonyManager,
                     logger,
+                    summaryLogger,
                     mobileMappings,
                     fakeBroadcastDispatcher,
-                    globalSettings,
                     context,
                     IMMEDIATE,
                     scope,
@@ -700,7 +829,7 @@
         }
 
     @Test
-    fun `active data change - in same group - emits unit`() =
+    fun activeDataChange_inSameGroup_emitsUnit() =
         runBlocking(IMMEDIATE) {
             var latest: Unit? = null
             val job = underTest.activeSubChangedInGroupEvent.onEach { latest = it }.launchIn(this)
@@ -716,7 +845,7 @@
         }
 
     @Test
-    fun `active data change - not in same group - does not emit`() =
+    fun activeDataChange_notInSameGroup_doesNotEmit() =
         runBlocking(IMMEDIATE) {
             var latest: Unit? = null
             val job = underTest.activeSubChangedInGroupEvent.onEach { latest = it }.launchIn(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
new file mode 100644
index 0000000..621f793
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.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.statusbar.pipeline.mobile.data.repository.prod
+
+import android.telephony.TelephonyCallback
+import android.telephony.TelephonyManager
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.google.common.truth.Truth.assertThat
+import org.mockito.Mockito.verify
+
+/** Helper methods for telephony-related callbacks for mobile tests. */
+object MobileTelephonyHelpers {
+    fun getTelephonyCallbacks(mockTelephonyManager: TelephonyManager): List<TelephonyCallback> {
+        val callbackCaptor = argumentCaptor<TelephonyCallback>()
+        verify(mockTelephonyManager).registerTelephonyCallback(any(), callbackCaptor.capture())
+        return callbackCaptor.allValues
+    }
+
+    inline fun <reified T> getTelephonyCallbackForType(mockTelephonyManager: TelephonyManager): T {
+        val cbs = getTelephonyCallbacks(mockTelephonyManager).filterIsInstance<T>()
+        assertThat(cbs.size).isEqualTo(1)
+        return cbs[0]
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
index 7aeaa48..b645e66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconInteractor.kt
@@ -45,7 +45,7 @@
     private val _iconGroup = MutableStateFlow<SignalIcon.MobileIconGroup>(TelephonyIcons.THREE_G)
     override val networkTypeIconGroup = _iconGroup
 
-    override val networkName = MutableStateFlow(NetworkNameModel.Derived("demo mode"))
+    override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived("demo mode"))
 
     private val _isEmergencyOnly = MutableStateFlow(false)
     override val isEmergencyOnly = _isEmergencyOnly
@@ -71,6 +71,8 @@
     private val _numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
     override val numberOfLevels = _numberOfLevels
 
+    override val isForceHidden = MutableStateFlow(false)
+
     fun setIconGroup(group: SignalIcon.MobileIconGroup) {
         _iconGroup.value = group
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
index 172755c..2699316 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/FakeMobileIconsInteractor.kt
@@ -73,6 +73,8 @@
     private val _isUserSetup = MutableStateFlow(true)
     override val isUserSetup = _isUserSetup
 
+    override val isForceHidden = MutableStateFlow(false)
+
     /** Always returns a new fake interactor */
     override fun createMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor {
         return FakeMobileIconInteractor(tableLogBuffer)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index c42aba5..fa072fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -66,6 +66,7 @@
                 mobileIconsInteractor.defaultMobileIconGroup,
                 mobileIconsInteractor.defaultDataSubId,
                 mobileIconsInteractor.isDefaultConnectionFailed,
+                mobileIconsInteractor.isForceHidden,
                 connectionRepository,
             )
     }
@@ -530,7 +531,7 @@
             )
             yield()
 
-            assertThat(latest).isEqualTo(NetworkNameModel.Derived(testOperatorName))
+            assertThat(latest).isEqualTo(NetworkNameModel.IntentDerived(testOperatorName))
 
             // Default network name, operator name is null, uses the default
             connectionRepository.setConnectionInfo(MobileConnectionModel(operatorAlphaShort = null))
@@ -550,6 +551,21 @@
             job.cancel()
         }
 
+    @Test
+    fun isForceHidden_matchesParent() =
+        runBlocking(IMMEDIATE) {
+            var latest: Boolean? = null
+            val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this)
+
+            mobileIconsInteractor.isForceHidden.value = true
+            assertThat(latest).isTrue()
+
+            mobileIconsInteractor.isForceHidden.value = false
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
     companion object {
         private val IMMEDIATE = Dispatchers.Main.immediate
 
@@ -559,6 +575,6 @@
         private const val SUB_1_ID = 1
 
         private val DEFAULT_NAME = NetworkNameModel.Default("test default name")
-        private val DERIVED_NAME = NetworkNameModel.Derived("test derived name")
+        private val DERIVED_NAME = NetworkNameModel.IntentDerived("test derived name")
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index bd24922..f8a9783 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
+import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.android.systemui.util.CarrierConfigTracker
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -50,6 +52,7 @@
 @SmallTest
 class MobileIconsInteractorTest : SysuiTestCase() {
     private lateinit var underTest: MobileIconsInteractor
+    private lateinit var connectivityRepository: FakeConnectivityRepository
     private lateinit var connectionsRepository: FakeMobileConnectionsRepository
     private val userSetupRepository = FakeUserSetupRepository()
     private val mobileMappingsProxy = FakeMobileMappingsProxy()
@@ -63,6 +66,8 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
+        connectivityRepository = FakeConnectivityRepository()
+
         connectionsRepository = FakeMobileConnectionsRepository(mobileMappingsProxy, tableLogBuffer)
         connectionsRepository.setMobileConnectionRepositoryMap(
             mapOf(
@@ -79,6 +84,8 @@
                 connectionsRepository,
                 carrierConfigTracker,
                 logger = mock(),
+                tableLogger = mock(),
+                connectivityRepository,
                 userSetupRepository,
                 testScope.backgroundScope,
             )
@@ -609,6 +616,32 @@
             job.cancel()
         }
 
+    @Test
+    fun isForceHidden_repoHasMobileHidden_true() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this)
+
+            connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
+
+            assertThat(latest).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
+    fun isForceHidden_repoDoesNotHaveMobileHidden_false() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this)
+
+            connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.WIFI))
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
     companion object {
         private val tableLogBuffer =
             TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
index a2c1209..e68a397 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/view/ModernStatusBarMobileViewTest.kt
@@ -29,12 +29,14 @@
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.StatusBarIconView
 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModel
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.QsMobileIconViewModel
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -58,31 +60,37 @@
 
     @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
     @Mock private lateinit var tableLogBuffer: TableLogBuffer
-    @Mock private lateinit var logger: ConnectivityPipelineLogger
     @Mock private lateinit var constants: ConnectivityConstants
+    private lateinit var interactor: FakeMobileIconInteractor
+    private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
+    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
 
+    private lateinit var viewModelCommon: MobileIconViewModel
     private lateinit var viewModel: LocationBasedMobileViewModel
 
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        // This line was necessary to make the onDarkChanged and setStaticDrawableColor tests pass.
+        // But, it maybe *shouldn't* be necessary.
+        whenever(constants.hasDataCapabilities).thenReturn(true)
+
         testableLooper = TestableLooper.get(this)
 
-        val interactor = FakeMobileIconInteractor(tableLogBuffer)
-
-        val viewModelCommon =
-            MobileIconViewModel(
-                subscriptionId = 1,
-                interactor,
-                logger,
-                constants,
-                testScope.backgroundScope,
+        airplaneModeRepository = FakeAirplaneModeRepository()
+        airplaneModeInteractor =
+            AirplaneModeInteractor(
+                airplaneModeRepository,
+                FakeConnectivityRepository(),
             )
-        viewModel = QsMobileIconViewModel(viewModelCommon, statusBarPipelineFlags)
+
+        interactor = FakeMobileIconInteractor(tableLogBuffer)
+        createViewModel()
     }
 
     // Note: The following tests are more like integration tests, since they stand up a full
-    // [WifiViewModel] and test the interactions between the view, view-binder, and view-model.
+    // [MobileIconViewModel] and test the interactions between the view, view-binder, and
+    // view-model.
 
     @Test
     fun setVisibleState_icon_iconShownDotHidden() {
@@ -130,7 +138,25 @@
     }
 
     @Test
-    fun isIconVisible_alwaysTrue() {
+    fun isIconVisible_noData_outputsFalse() {
+        whenever(constants.hasDataCapabilities).thenReturn(false)
+        createViewModel()
+
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.isIconVisible).isFalse()
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun isIconVisible_hasData_outputsTrue() {
+        whenever(constants.hasDataCapabilities).thenReturn(true)
+        createViewModel()
+
         val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
 
         ViewUtils.attachView(view)
@@ -142,6 +168,34 @@
     }
 
     @Test
+    fun isIconVisible_notAirplaneMode_outputsTrue() {
+        airplaneModeRepository.setIsAirplaneMode(false)
+
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.isIconVisible).isTrue()
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
+    fun isIconVisible_airplaneMode_outputsTrue() {
+        airplaneModeRepository.setIsAirplaneMode(true)
+
+        val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
+
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+
+        assertThat(view.isIconVisible).isFalse()
+
+        ViewUtils.detachView(view)
+    }
+
+    @Test
     fun onDarkChanged_iconHasNewColor() {
         whenever(statusBarPipelineFlags.useDebugColoring()).thenReturn(false)
         val view = ModernStatusBarMobileView.constructAndBind(context, SLOT_NAME, viewModel)
@@ -184,6 +238,18 @@
     private fun View.getDotView(): View {
         return this.requireViewById(R.id.status_bar_dot)
     }
+
+    private fun createViewModel() {
+        viewModelCommon =
+            MobileIconViewModel(
+                subscriptionId = 1,
+                interactor,
+                airplaneModeInteractor,
+                constants,
+                testScope.backgroundScope,
+            )
+        viewModel = QsMobileIconViewModel(viewModelCommon, statusBarPipelineFlags)
+    }
 }
 
 private const val SLOT_NAME = "TestSlotName"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
index c960a06..f983030 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelTest.kt
@@ -21,10 +21,13 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconViewModelTest.Companion.defaultSignal
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.launchIn
@@ -46,8 +49,8 @@
     private lateinit var qsIcon: QsMobileIconViewModel
     private lateinit var keyguardIcon: KeyguardMobileIconViewModel
     private lateinit var interactor: FakeMobileIconInteractor
+    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
     @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
-    @Mock private lateinit var logger: ConnectivityPipelineLogger
     @Mock private lateinit var constants: ConnectivityConstants
     @Mock private lateinit var tableLogBuffer: TableLogBuffer
 
@@ -57,6 +60,11 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        airplaneModeInteractor =
+            AirplaneModeInteractor(
+                FakeAirplaneModeRepository(),
+                FakeConnectivityRepository(),
+            )
         interactor = FakeMobileIconInteractor(tableLogBuffer)
         interactor.apply {
             setLevel(1)
@@ -68,7 +76,13 @@
             isDataConnected.value = true
         }
         commonImpl =
-            MobileIconViewModel(SUB_1_ID, interactor, logger, constants, testScope.backgroundScope)
+            MobileIconViewModel(
+                SUB_1_ID,
+                interactor,
+                airplaneModeInteractor,
+                constants,
+                testScope.backgroundScope,
+            )
 
         homeIcon = HomeMobileIconViewModel(commonImpl, statusBarPipelineFlags)
         qsIcon = QsMobileIconViewModel(commonImpl, statusBarPipelineFlags)
@@ -78,14 +92,14 @@
     @Test
     fun `location based view models receive same icon id when common impl updates`() =
         testScope.runTest {
-            var latestHome: Int? = null
-            val homeJob = homeIcon.iconId.onEach { latestHome = it }.launchIn(this)
+            var latestHome: SignalIconModel? = null
+            val homeJob = homeIcon.icon.onEach { latestHome = it }.launchIn(this)
 
-            var latestQs: Int? = null
-            val qsJob = qsIcon.iconId.onEach { latestQs = it }.launchIn(this)
+            var latestQs: SignalIconModel? = null
+            val qsJob = qsIcon.icon.onEach { latestQs = it }.launchIn(this)
 
-            var latestKeyguard: Int? = null
-            val keyguardJob = keyguardIcon.iconId.onEach { latestKeyguard = it }.launchIn(this)
+            var latestKeyguard: SignalIconModel? = null
+            val keyguardJob = keyguardIcon.icon.onEach { latestKeyguard = it }.launchIn(this)
 
             var expected = defaultSignal(level = 1)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
index b91a4df..bec276a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelTest.kt
@@ -19,16 +19,18 @@
 import androidx.test.filters.SmallTest
 import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH
 import com.android.settingslib.AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH_NONE
-import com.android.settingslib.graph.SignalDrawable
 import com.android.settingslib.mobile.TelephonyIcons.THREE_G
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconInteractor
+import com.android.systemui.statusbar.pipeline.mobile.ui.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
+import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -49,7 +51,8 @@
 class MobileIconViewModelTest : SysuiTestCase() {
     private lateinit var underTest: MobileIconViewModel
     private lateinit var interactor: FakeMobileIconInteractor
-    @Mock private lateinit var logger: ConnectivityPipelineLogger
+    private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
+    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
     @Mock private lateinit var constants: ConnectivityConstants
     @Mock private lateinit var tableLogBuffer: TableLogBuffer
 
@@ -59,6 +62,15 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        whenever(constants.hasDataCapabilities).thenReturn(true)
+
+        airplaneModeRepository = FakeAirplaneModeRepository()
+        airplaneModeInteractor =
+            AirplaneModeInteractor(
+                airplaneModeRepository,
+                FakeConnectivityRepository(),
+            )
+
         interactor = FakeMobileIconInteractor(tableLogBuffer)
         interactor.apply {
             setLevel(1)
@@ -69,15 +81,94 @@
             setNumberOfLevels(4)
             isDataConnected.value = true
         }
-        underTest =
-            MobileIconViewModel(SUB_1_ID, interactor, logger, constants, testScope.backgroundScope)
+        createAndSetViewModel()
     }
 
     @Test
+    fun isVisible_notDataCapable_alwaysFalse() =
+        testScope.runTest {
+            // Create a new view model here so the constants are properly read
+            whenever(constants.hasDataCapabilities).thenReturn(false)
+            createAndSetViewModel()
+
+            var latest: Boolean? = null
+            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun isVisible_notAirplane_notForceHidden_true() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+
+            airplaneModeRepository.setIsAirplaneMode(false)
+            interactor.isForceHidden.value = false
+
+            assertThat(latest).isTrue()
+
+            job.cancel()
+        }
+
+    @Test
+    fun isVisible_airplane_false() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+
+            airplaneModeRepository.setIsAirplaneMode(true)
+            interactor.isForceHidden.value = false
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun isVisible_forceHidden_false() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+
+            airplaneModeRepository.setIsAirplaneMode(false)
+            interactor.isForceHidden.value = true
+
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
+    fun isVisible_respondsToUpdates() =
+        testScope.runTest {
+            var latest: Boolean? = null
+            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+
+            airplaneModeRepository.setIsAirplaneMode(false)
+            interactor.isForceHidden.value = false
+
+            assertThat(latest).isTrue()
+
+            airplaneModeRepository.setIsAirplaneMode(true)
+            assertThat(latest).isFalse()
+
+            airplaneModeRepository.setIsAirplaneMode(false)
+            assertThat(latest).isTrue()
+
+            interactor.isForceHidden.value = true
+            assertThat(latest).isFalse()
+
+            job.cancel()
+        }
+
+    @Test
     fun iconId_correctLevel_notCutout() =
         testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.iconId.onEach { latest = it }.launchIn(this)
+            var latest: SignalIconModel? = null
+            val job = underTest.icon.onEach { latest = it }.launchIn(this)
             val expected = defaultSignal()
 
             assertThat(latest).isEqualTo(expected)
@@ -90,8 +181,8 @@
         testScope.runTest {
             interactor.setIsDefaultDataEnabled(false)
 
-            var latest: Int? = null
-            val job = underTest.iconId.onEach { latest = it }.launchIn(this)
+            var latest: SignalIconModel? = null
+            val job = underTest.icon.onEach { latest = it }.launchIn(this)
             val expected = defaultSignal(level = 1, connected = false)
 
             assertThat(latest).isEqualTo(expected)
@@ -102,8 +193,8 @@
     @Test
     fun `icon - uses empty state - when not in service`() =
         testScope.runTest {
-            var latest: Int? = null
-            val job = underTest.iconId.onEach { latest = it }.launchIn(this)
+            var latest: SignalIconModel? = null
+            val job = underTest.icon.onEach { latest = it }.launchIn(this)
 
             interactor.isInService.value = false
 
@@ -364,14 +455,7 @@
         testScope.runTest {
             // Create a new view model here so the constants are properly read
             whenever(constants.shouldShowActivityConfig).thenReturn(false)
-            underTest =
-                MobileIconViewModel(
-                    SUB_1_ID,
-                    interactor,
-                    logger,
-                    constants,
-                    testScope.backgroundScope,
-                )
+            createAndSetViewModel()
 
             var inVisible: Boolean? = null
             val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
@@ -403,14 +487,7 @@
         testScope.runTest {
             // Create a new view model here so the constants are properly read
             whenever(constants.shouldShowActivityConfig).thenReturn(true)
-            underTest =
-                MobileIconViewModel(
-                    SUB_1_ID,
-                    interactor,
-                    logger,
-                    constants,
-                    testScope.backgroundScope,
-                )
+            createAndSetViewModel()
 
             var inVisible: Boolean? = null
             val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
@@ -459,6 +536,16 @@
             containerJob.cancel()
         }
 
+    private fun createAndSetViewModel() {
+        underTest = MobileIconViewModel(
+            SUB_1_ID,
+            interactor,
+            airplaneModeInteractor,
+            constants,
+            testScope.backgroundScope,
+        )
+    }
+
     companion object {
         private const val SUB_1_ID = 1
 
@@ -466,10 +553,11 @@
         fun defaultSignal(
             level: Int = 1,
             connected: Boolean = true,
-        ): Int {
-            return SignalDrawable.getState(level, /* numLevels */ 4, !connected)
+        ): SignalIconModel {
+            return SignalIconModel(level, numberOfLevels = 4, showExclamationMark = !connected)
         }
 
-        fun emptySignal(): Int = SignalDrawable.getEmptyState(4)
+        fun emptySignal(): SignalIconModel =
+            SignalIconModel(level = 0, numberOfLevels = 4, showExclamationMark = true)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
index 58b50c7..d9268a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
@@ -20,11 +20,14 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -46,6 +49,7 @@
     private lateinit var underTest: MobileIconsViewModel
     private val interactor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
 
+    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
     @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
     @Mock private lateinit var logger: ConnectivityPipelineLogger
     @Mock private lateinit var constants: ConnectivityConstants
@@ -57,6 +61,12 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
+        airplaneModeInteractor =
+            AirplaneModeInteractor(
+                FakeAirplaneModeRepository(),
+                FakeConnectivityRepository(),
+            )
+
         val subscriptionIdsFlow =
             interactor.filteredSubscriptions
                 .map { subs -> subs.map { it.subscriptionId } }
@@ -66,6 +76,7 @@
             MobileIconsViewModel(
                 subscriptionIdsFlow,
                 interactor,
+                airplaneModeInteractor,
                 logger,
                 constants,
                 testScope.backgroundScope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
index 64a93cf..6557754 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
@@ -38,6 +38,7 @@
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_SEEDING_COMPLETED
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.QS_DEFAULT_POSITION
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.QS_PRIORITY_POSITION
+import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.settings.SecureSettings
 
 import java.util.Optional
@@ -102,6 +103,8 @@
         `when`(controlsComponent.getControlsListingController())
                 .thenReturn(Optional.of(controlsListingController))
 
+        `when`(controlsComponent.isEnabled()).thenReturn(true)
+
         controller = DeviceControlsControllerImpl(
             mContext,
             controlsComponent,
@@ -168,4 +171,15 @@
         seedCallback.value.accept(SeedResponse(TEST_PKG, true))
         verify(callback).onControlsUpdate(QS_DEFAULT_POSITION)
     }
+
+    @Test
+    fun testControlsDisabledRemoveFromAutoTracker() {
+        `when`(controlsComponent.isEnabled()).thenReturn(false)
+        val callback: DeviceControlsController.Callback = mock()
+
+        controller.setCallback(callback)
+
+        verify(callback).removeControlsAutoTracker()
+        verify(callback, never()).onControlsUpdate(anyInt())
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
index a08e002..56203d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
@@ -23,6 +23,7 @@
 import android.testing.AndroidTestingRunner
 import android.view.InputDevice
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -53,8 +54,11 @@
     @Mock lateinit var bluetoothAdapter: BluetoothAdapter
     @Mock lateinit var bluetoothDevice: BluetoothDevice
     @Mock lateinit var handler: Handler
+
     @Mock lateinit var featureFlags: FeatureFlags
 
+    @Mock lateinit var uiEventLogger: UiEventLogger
+
     @Mock lateinit var stylusCallback: StylusManager.StylusCallback
 
     @Mock lateinit var otherStylusCallback: StylusManager.StylusCallback
@@ -75,7 +79,15 @@
         }
 
         stylusManager =
-            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+            StylusManager(
+                mContext,
+                inputManager,
+                bluetoothAdapter,
+                handler,
+                EXECUTOR,
+                featureFlags,
+                uiEventLogger
+            )
 
         whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
         whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
@@ -104,7 +116,15 @@
     @Test
     fun startListener_hasNotStarted_registersInputDeviceListener() {
         stylusManager =
-            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+            StylusManager(
+                mContext,
+                inputManager,
+                bluetoothAdapter,
+                handler,
+                EXECUTOR,
+                featureFlags,
+                uiEventLogger
+            )
 
         stylusManager.startListener()
 
@@ -121,7 +141,15 @@
     @Test
     fun onInputDeviceAdded_hasNotStarted_doesNothing() {
         stylusManager =
-            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+            StylusManager(
+                mContext,
+                inputManager,
+                bluetoothAdapter,
+                handler,
+                EXECUTOR,
+                featureFlags,
+                uiEventLogger
+            )
 
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
 
@@ -203,7 +231,15 @@
     @Test
     fun onInputDeviceChanged_hasNotStarted_doesNothing() {
         stylusManager =
-            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+            StylusManager(
+                mContext,
+                inputManager,
+                bluetoothAdapter,
+                handler,
+                EXECUTOR,
+                featureFlags,
+                uiEventLogger
+            )
 
         stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
 
@@ -268,7 +304,15 @@
     @Test
     fun onInputDeviceRemoved_hasNotStarted_doesNothing() {
         stylusManager =
-            StylusManager(mContext, inputManager, bluetoothAdapter, handler, EXECUTOR, featureFlags)
+            StylusManager(
+                mContext,
+                inputManager,
+                bluetoothAdapter,
+                handler,
+                EXECUTOR,
+                featureFlags,
+                uiEventLogger
+            )
         stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
 
         stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
@@ -337,6 +381,13 @@
     }
 
     @Test
+    fun onStylusBluetoothConnected_logsEvent() {
+        stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+        verify(uiEventLogger, times(1)).log(StylusUiEvent.BLUETOOTH_STYLUS_CONNECTED)
+    }
+
+    @Test
     fun onStylusBluetoothDisconnected_unregistersMetadataListener() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
 
@@ -346,6 +397,15 @@
     }
 
     @Test
+    fun onStylusBluetoothDisconnected_logsEvent() {
+        stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+        stylusManager.onInputDeviceRemoved(BT_STYLUS_DEVICE_ID)
+
+        verify(uiEventLogger, times(1)).log(StylusUiEvent.BLUETOOTH_STYLUS_DISCONNECTED)
+    }
+
+    @Test
     fun onMetadataChanged_multipleRegisteredBatteryCallbacks_executesAll() {
         stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
         stylusManager.registerBatteryCallback(otherStylusBatteryCallback)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index e1668e8..d51c514 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.stylus
 
+import android.app.ActivityManager
 import android.app.Notification
 import android.content.BroadcastReceiver
 import android.content.Context
@@ -27,6 +28,7 @@
 import android.view.InputDevice
 import androidx.core.app.NotificationManagerCompat
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
@@ -54,15 +56,23 @@
 @SmallTest
 class StylusUsiPowerUiTest : SysuiTestCase() {
     @Mock lateinit var notificationManager: NotificationManagerCompat
+
     @Mock lateinit var inputManager: InputManager
+
     @Mock lateinit var handler: Handler
+
     @Mock lateinit var btStylusDevice: InputDevice
+
+    @Mock lateinit var uiEventLogger: UiEventLogger
+
     @Captor lateinit var notificationCaptor: ArgumentCaptor<Notification>
 
     private lateinit var stylusUsiPowerUi: StylusUsiPowerUI
     private lateinit var broadcastReceiver: BroadcastReceiver
     private lateinit var contextSpy: Context
 
+    private val uid = ActivityManager.getCurrentUser()
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -80,7 +90,8 @@
         whenever(btStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
         whenever(btStylusDevice.bluetoothAddress).thenReturn("SO:ME:AD:DR:ES")
 
-        stylusUsiPowerUi = StylusUsiPowerUI(contextSpy, notificationManager, inputManager, handler)
+        stylusUsiPowerUi =
+            StylusUsiPowerUI(contextSpy, notificationManager, inputManager, handler, uiEventLogger)
         broadcastReceiver = stylusUsiPowerUi.receiver
     }
 
@@ -197,6 +208,19 @@
     }
 
     @Test
+    fun updateBatteryState_showsNotification_logsNotificationShown() {
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
+
+        verify(uiEventLogger, times(1))
+            .logWithPosition(
+                StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_SHOWN,
+                uid,
+                contextSpy.packageName,
+                10
+            )
+    }
+
+    @Test
     fun broadcastReceiver_clicked_hasInputDeviceId_startsUsiDetailsActivity() {
         val intent = Intent(StylusUsiPowerUI.ACTION_CLICKED_LOW_BATTERY)
         val activityIntentCaptor = argumentCaptor<Intent>()
@@ -219,4 +243,32 @@
 
         verify(contextSpy, never()).startActivity(any())
     }
+
+    @Test
+    fun broadcastReceiver_clicked_logsNotificationClicked() {
+        val intent = Intent(StylusUsiPowerUI.ACTION_CLICKED_LOW_BATTERY)
+        broadcastReceiver.onReceive(contextSpy, intent)
+
+        verify(uiEventLogger, times(1))
+            .logWithPosition(
+                StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_CLICKED,
+                uid,
+                contextSpy.packageName,
+                100
+            )
+    }
+
+    @Test
+    fun broadcastReceiver_dismissed_logsNotificationDismissed() {
+        val intent = Intent(StylusUsiPowerUI.ACTION_DISMISSED_LOW_BATTERY)
+        broadcastReceiver.onReceive(contextSpy, intent)
+
+        verify(uiEventLogger, times(1))
+            .logWithPosition(
+                StylusUiEvent.STYLUS_LOW_BATTERY_NOTIFICATION_DISMISSED,
+                uid,
+                contextSpy.packageName,
+                100
+            )
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
index 756397a..74ed7fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
@@ -42,13 +42,35 @@
                 pixelDensity = 2f,
                 color = Color.RED,
                 opacity = 30,
-                shouldFillRipple = true,
+                baseRingFadeParams =
+                    RippleShader.FadeParams(
+                        fadeInStart = 0f,
+                        fadeInEnd = 0.3f,
+                        fadeOutStart = 0.5f,
+                        fadeOutEnd = 1f
+                    ),
+                sparkleRingFadeParams =
+                    RippleShader.FadeParams(
+                        fadeInStart = 0.1f,
+                        fadeInEnd = 0.2f,
+                        fadeOutStart = 0.7f,
+                        fadeOutEnd = 0.9f
+                    ),
+                centerFillFadeParams =
+                    RippleShader.FadeParams(
+                        fadeInStart = 0f,
+                        fadeInEnd = 0.1f,
+                        fadeOutStart = 0.2f,
+                        fadeOutEnd = 0.3f
+                    ),
                 sparkleStrength = 0.3f
             )
         val rippleAnimation = RippleAnimation(config)
 
         with(rippleAnimation.rippleShader) {
-            assertThat(rippleFill).isEqualTo(config.shouldFillRipple)
+            assertThat(baseRingFadeParams).isEqualTo(config.baseRingFadeParams)
+            assertThat(sparkleRingFadeParams).isEqualTo(config.sparkleRingFadeParams)
+            assertThat(centerFillFadeParams).isEqualTo(config.centerFillFadeParams)
             assertThat(pixelDensity).isEqualTo(config.pixelDensity)
             assertThat(color).isEqualTo(ColorUtils.setAlphaComponent(config.color, config.opacity))
             assertThat(sparkleStrength).isEqualTo(config.sparkleStrength)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
index 3032ff1f..83439f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayApplierTest.java
@@ -17,6 +17,7 @@
 
 import static com.android.systemui.theme.ThemeOverlayApplier.ANDROID_PACKAGE;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ACCENT_COLOR;
+import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_DYNAMIC_COLOR;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_FONT;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_ANDROID;
 import static com.android.systemui.theme.ThemeOverlayApplier.OVERLAY_CATEGORY_ICON_LAUNCHER;
@@ -113,6 +114,8 @@
         };
         when(mOverlayManager.getOverlayInfosForTarget(ANDROID_PACKAGE, UserHandle.SYSTEM))
                 .thenReturn(Lists.newArrayList(
+                        createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_DYNAMIC_COLOR,
+                                ANDROID_PACKAGE, OVERLAY_CATEGORY_DYNAMIC_COLOR, false),
                         createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, false),
                         createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE,
@@ -123,6 +126,8 @@
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_SHAPE, false),
                         createOverlayInfo(TEST_DISABLED_PREFIX + OVERLAY_CATEGORY_ICON_ANDROID,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_ICON_ANDROID, false),
+                        createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_DYNAMIC_COLOR,
+                                ANDROID_PACKAGE, OVERLAY_CATEGORY_DYNAMIC_COLOR, true),
                         createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_ACCENT_COLOR,
                                 ANDROID_PACKAGE, OVERLAY_CATEGORY_ACCENT_COLOR, true),
                         createOverlayInfo(TEST_ENABLED_PREFIX + OVERLAY_CATEGORY_SYSTEM_PALETTE,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index 1710709..f9b5767 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -47,8 +47,9 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
+import android.view.accessibility.AccessibilityManager;
 
-import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -57,7 +58,6 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.monet.Style;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -115,6 +115,8 @@
     private Resources mResources;
     @Mock
     private WakefulnessLifecycle mWakefulnessLifecycle;
+    @Mock
+    private AccessibilityManager mAccessibilityManager;
     @Captor
     private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiver;
     @Captor
@@ -127,13 +129,13 @@
     private ArgumentCaptor<UserTracker.Callback> mUserTrackerCallback;
     @Captor
     private ArgumentCaptor<ContentObserver> mSettingsObserver;
-    private Style mCurrentStyle;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
         when(mFeatureFlags.isEnabled(Flags.MONET)).thenReturn(true);
         when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
+        when(mAccessibilityManager.getUiContrast()).thenReturn(0.5f);
         when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
         when(mResources.getColor(eq(android.R.color.system_accent1_500), any()))
                 .thenReturn(Color.RED);
@@ -148,15 +150,19 @@
         mThemeOverlayController = new ThemeOverlayController(mContext,
                 mBroadcastDispatcher, mBgHandler, mMainExecutor, mBgExecutor, mThemeOverlayApplier,
                 mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
-                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
-            @Nullable
-            @Override
-            protected FabricatedOverlay getOverlay(int color, int type, Style style) {
+                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
+                mAccessibilityManager) {
+            @VisibleForTesting
+            protected boolean isNightMode() {
+                return false;
+            }
+
+            @VisibleForTesting
+            protected FabricatedOverlay newFabricatedOverlay(String name) {
                 FabricatedOverlay overlay = mock(FabricatedOverlay.class);
                 when(overlay.getIdentifier())
-                        .thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
-                mCurrentStyle = style;
-                mColorScheme = new ColorScheme(color, false /* nightMode */, style);
+                        .thenReturn(new OverlayIdentifier(
+                                Integer.toHexString(mColorScheme.getSeed() | 0xff000000)));
                 return overlay;
             }
         };
@@ -416,7 +422,7 @@
 
             mSettingsObserver.getValue().onChange(true, null, 0, mUserTracker.getUserId());
 
-            assertThat(mCurrentStyle).isEqualTo(style);
+            assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(style);
         }
     }
 
@@ -432,7 +438,7 @@
 
         mSettingsObserver.getValue().onChange(true, null, 0, mUserTracker.getUserId());
 
-        assertThat(mCurrentStyle).isEqualTo(Style.TONAL_SPOT);
+        assertThat(mThemeOverlayController.mThemeStyle).isEqualTo(Style.TONAL_SPOT);
     }
 
     @Test
@@ -726,17 +732,20 @@
         mThemeOverlayController = new ThemeOverlayController(mContext,
                 mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
                 mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
-                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
-            @Nullable
-            @Override
-            protected FabricatedOverlay getOverlay(int color, int type, Style style) {
+                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
+                mAccessibilityManager) {
+            @VisibleForTesting
+            protected boolean isNightMode() {
+                return false;
+            }
+
+            @VisibleForTesting
+            protected FabricatedOverlay newFabricatedOverlay(String name) {
                 FabricatedOverlay overlay = mock(FabricatedOverlay.class);
                 when(overlay.getIdentifier())
                         .thenReturn(new OverlayIdentifier("com.thebest.livewallpaperapp.ever"));
-                mColorScheme = new ColorScheme(color, false /* nightMode */, style);
                 return overlay;
             }
-
         };
         mThemeOverlayController.start();
 
@@ -763,14 +772,19 @@
         mThemeOverlayController = new ThemeOverlayController(mContext,
                 mBroadcastDispatcher, mBgHandler, executor, executor, mThemeOverlayApplier,
                 mSecureSettings, mWallpaperManager, mUserManager, mDeviceProvisionedController,
-                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle) {
-            @Nullable
-            @Override
-            protected FabricatedOverlay getOverlay(int color, int type, Style style) {
+                mUserTracker, mDumpManager, mFeatureFlags, mResources, mWakefulnessLifecycle,
+                mAccessibilityManager) {
+            @VisibleForTesting
+            protected boolean isNightMode() {
+                return false;
+            }
+
+            @VisibleForTesting
+            protected FabricatedOverlay newFabricatedOverlay(String name) {
                 FabricatedOverlay overlay = mock(FabricatedOverlay.class);
                 when(overlay.getIdentifier())
-                        .thenReturn(new OverlayIdentifier(Integer.toHexString(color | 0xff000000)));
-                mColorScheme = new ColorScheme(color, false /* nightMode */, style);
+                        .thenReturn(new OverlayIdentifier(
+                                Integer.toHexString(mColorScheme.getSeed() | 0xff000000)));
                 return overlay;
             }
         };
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index f4226bc..3d75967 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -25,6 +25,8 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -105,8 +107,13 @@
             }
 
         keyguardRepository = FakeKeyguardRepository()
+        val featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
         val keyguardInteractor =
-            KeyguardInteractor(repository = keyguardRepository, commandQueue = commandQueue)
+            KeyguardInteractor(
+                repository = keyguardRepository,
+                commandQueue = commandQueue,
+                featureFlags = featureFlags
+            )
 
         // Needs to be run on the main thread
         runBlocking(IMMEDIATE) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
index abbdab0..5288608 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -20,17 +20,13 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
-import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
+import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
-import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
+import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
+import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
 import com.android.systemui.unfold.util.TestFoldStateProvider
-import com.android.systemui.util.leak.ReferenceTestUtils.waitForCondition
-import com.google.common.truth.Truth.assertThat
-import com.google.common.truth.Truth.assertWithMessage
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,9 +41,7 @@
 
     @Before
     fun setUp() {
-        progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(
-            foldStateProvider
-        )
+        progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
         progressProvider.addCallback(listener)
     }
 
@@ -79,9 +73,7 @@
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
         )
 
-        with(listener.ensureTransitionFinished()) {
-            assertHasSingleFinishingEvent()
-        }
+        with(listener.ensureTransitionFinished()) { assertHasSingleFinishingEvent() }
     }
 
     @Test
@@ -150,106 +142,12 @@
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) },
         )
 
-        with(listener.ensureTransitionFinished()) {
-            assertHasFoldAnimationAtTheEnd()
-        }
-    }
-
-    private class TestUnfoldProgressListener : TransitionProgressListener {
-
-        private val recordings: MutableList<UnfoldTransitionRecording> = arrayListOf()
-        private var currentRecording: UnfoldTransitionRecording? = null
-
-        override fun onTransitionStarted() {
-            assertWithMessage("Trying to start a transition when it is already in progress")
-                .that(currentRecording).isNull()
-
-            currentRecording = UnfoldTransitionRecording()
-        }
-
-        override fun onTransitionProgress(progress: Float) {
-            assertWithMessage("Received transition progress event when it's not started")
-                .that(currentRecording).isNotNull()
-            currentRecording!!.addProgress(progress)
-        }
-
-        override fun onTransitionFinishing() {
-            assertWithMessage("Received transition finishing event when it's not started")
-                    .that(currentRecording).isNotNull()
-            currentRecording!!.onFinishing()
-        }
-
-        override fun onTransitionFinished() {
-            assertWithMessage("Received transition finish event when it's not started")
-                .that(currentRecording).isNotNull()
-            recordings += currentRecording!!
-            currentRecording = null
-        }
-
-        fun ensureTransitionFinished(): UnfoldTransitionRecording {
-            waitForCondition { recordings.size == 1 }
-            return recordings.first()
-        }
-
-        class UnfoldTransitionRecording {
-            private val progressHistory: MutableList<Float> = arrayListOf()
-            private var finishingInvocations: Int = 0
-
-            fun addProgress(progress: Float) {
-                assertThat(progress).isAtMost(1.0f)
-                assertThat(progress).isAtLeast(0.0f)
-
-                progressHistory += progress
-            }
-
-            fun onFinishing() {
-                finishingInvocations++
-            }
-
-            fun assertIncreasingProgress() {
-                assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
-                assertThat(progressHistory).isInOrder()
-            }
-
-            fun assertDecreasingProgress() {
-                assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
-                assertThat(progressHistory).isInOrder(Comparator.reverseOrder<Float>())
-            }
-
-            fun assertFinishedWithUnfold() {
-                assertThat(progressHistory).isNotEmpty()
-                assertThat(progressHistory.last()).isEqualTo(1.0f)
-            }
-
-            fun assertFinishedWithFold() {
-                assertThat(progressHistory).isNotEmpty()
-                assertThat(progressHistory.last()).isEqualTo(0.0f)
-            }
-
-            fun assertHasFoldAnimationAtTheEnd() {
-                // Check that there are at least a few decreasing events at the end
-                assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
-                assertThat(progressHistory.takeLast(MIN_ANIMATION_EVENTS))
-                    .isInOrder(Comparator.reverseOrder<Float>())
-                assertThat(progressHistory.last()).isEqualTo(0.0f)
-            }
-
-            fun assertHasSingleFinishingEvent() {
-                assertWithMessage("onTransitionFinishing callback should be invoked exactly " +
-                        "one time").that(finishingInvocations).isEqualTo(1)
-            }
-        }
-
-        private companion object {
-            private const val MIN_ANIMATION_EVENTS = 5
-        }
+        with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() }
     }
 
     private fun runOnMainThreadWithInterval(vararg blocks: () -> Unit, intervalMillis: Long = 60) {
         blocks.forEach {
-            InstrumentationRegistry.getInstrumentation().runOnMainSync {
-                it()
-            }
+            InstrumentationRegistry.getInstrumentation().runOnMainSync { it() }
             Thread.sleep(intervalMillis)
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt
new file mode 100644
index 0000000..0e7e039
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold.progress
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class RemoteUnfoldTransitionReceiverTest : SysuiTestCase() {
+
+    private val progressProvider = RemoteUnfoldTransitionReceiver { it.run() }
+    private val listener = TestUnfoldProgressListener()
+
+    @Before
+    fun setUp() {
+        progressProvider.addCallback(listener)
+    }
+
+    @Test
+    fun onTransitionStarted_propagated() {
+        progressProvider.onTransitionStarted()
+
+        listener.assertStarted()
+    }
+
+    @Test
+    fun onTransitionProgress_propagated() {
+        progressProvider.onTransitionStarted()
+
+        progressProvider.onTransitionProgress(0.5f)
+
+        listener.assertLastProgress(0.5f)
+    }
+
+    @Test
+    fun onTransitionEnded_propagated() {
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+
+        progressProvider.onTransitionFinished()
+
+        listener.ensureTransitionFinished()
+    }
+
+    @Test
+    fun onTransitionStarted_afterCallbackRemoved_notPropagated() {
+        progressProvider.removeCallback(listener)
+
+        progressProvider.onTransitionStarted()
+
+        listener.assertNotStarted()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
new file mode 100644
index 0000000..f653207
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.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.unfold.progress
+
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.util.leak.ReferenceTestUtils.waitForCondition
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+
+/** Listener usable by tests with some handy assertions. */
+class TestUnfoldProgressListener : UnfoldTransitionProgressProvider.TransitionProgressListener {
+
+    private val recordings: MutableList<UnfoldTransitionRecording> = arrayListOf()
+    private var currentRecording: UnfoldTransitionRecording? = null
+
+    override fun onTransitionStarted() {
+        assertWithMessage("Trying to start a transition when it is already in progress")
+            .that(currentRecording)
+            .isNull()
+
+        currentRecording = UnfoldTransitionRecording()
+    }
+
+    override fun onTransitionProgress(progress: Float) {
+        assertWithMessage("Received transition progress event when it's not started")
+            .that(currentRecording)
+            .isNotNull()
+        currentRecording!!.addProgress(progress)
+    }
+
+    override fun onTransitionFinishing() {
+        assertWithMessage("Received transition finishing event when it's not started")
+            .that(currentRecording)
+            .isNotNull()
+        currentRecording!!.onFinishing()
+    }
+
+    override fun onTransitionFinished() {
+        assertWithMessage("Received transition finish event when it's not started")
+            .that(currentRecording)
+            .isNotNull()
+        recordings += currentRecording!!
+        currentRecording = null
+    }
+
+    fun ensureTransitionFinished(): UnfoldTransitionRecording {
+        waitForCondition { recordings.size == 1 }
+        return recordings.first()
+    }
+
+    fun assertStarted() {
+        assertWithMessage("Transition didn't start").that(currentRecording).isNotNull()
+    }
+
+    fun assertNotStarted() {
+        assertWithMessage("Transition started").that(currentRecording).isNull()
+    }
+
+    fun assertLastProgress(progress: Float) {
+        currentRecording?.assertLastProgress(progress) ?: error("unfold not in progress.")
+    }
+
+    class UnfoldTransitionRecording {
+        private val progressHistory: MutableList<Float> = arrayListOf()
+        private var finishingInvocations: Int = 0
+
+        fun addProgress(progress: Float) {
+            assertThat(progress).isAtMost(1.0f)
+            assertThat(progress).isAtLeast(0.0f)
+
+            progressHistory += progress
+        }
+
+        fun onFinishing() {
+            finishingInvocations++
+        }
+
+        fun assertIncreasingProgress() {
+            assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
+            assertThat(progressHistory).isInOrder()
+        }
+
+        fun assertDecreasingProgress() {
+            assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
+            assertThat(progressHistory).isInOrder(Comparator.reverseOrder<Float>())
+        }
+
+        fun assertFinishedWithUnfold() {
+            assertThat(progressHistory).isNotEmpty()
+            assertThat(progressHistory.last()).isEqualTo(1.0f)
+        }
+
+        fun assertFinishedWithFold() {
+            assertThat(progressHistory).isNotEmpty()
+            assertThat(progressHistory.last()).isEqualTo(0.0f)
+        }
+
+        fun assertHasFoldAnimationAtTheEnd() {
+            // Check that there are at least a few decreasing events at the end
+            assertThat(progressHistory.size).isGreaterThan(MIN_ANIMATION_EVENTS)
+            assertThat(progressHistory.takeLast(MIN_ANIMATION_EVENTS))
+                .isInOrder(Comparator.reverseOrder<Float>())
+            assertThat(progressHistory.last()).isEqualTo(0.0f)
+        }
+
+        fun assertHasSingleFinishingEvent() {
+            assertWithMessage(
+                    "onTransitionFinishing callback should be invoked exactly " + "one time"
+                )
+                .that(finishingInvocations)
+                .isEqualTo(1)
+        }
+
+        fun assertLastProgress(progress: Float) {
+            assertThat(progressHistory.last()).isEqualTo(progress)
+        }
+    }
+
+    private companion object {
+        private const val MIN_ANIMATION_EVENTS = 5
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
index ccf378a..9312643 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
@@ -128,6 +128,11 @@
 
     @Test
     fun refreshUsers() = runSelfCancelingTest {
+        val mainUserId = 10
+        val mainUser = mock(UserHandle::class.java)
+        whenever(manager.mainUser).thenReturn(mainUser)
+        whenever(mainUser.identifier).thenReturn(mainUserId)
+
         underTest = create(this)
         val initialExpectedValue =
             setUpUsers(
@@ -166,6 +171,7 @@
         assertThat(selectedUserInfo).isEqualTo(thirdExpectedValue[1])
         assertThat(selectedUserInfo?.isGuest).isTrue()
         assertThat(underTest.lastSelectedNonGuestUserId).isEqualTo(selectedNonGuestUserId)
+        assertThat(underTest.mainUserId).isEqualTo(mainUserId)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
index fb781e8..cc23485 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
@@ -204,10 +204,12 @@
         }
 
     @Test
-    fun `exit - last non-guest was removed - returns to system`() =
+    fun `exit - last non-guest was removed - returns to main user`() =
         runBlocking(IMMEDIATE) {
             val removedUserId = 310
+            val mainUserId = 10
             repository.lastSelectedNonGuestUserId = removedUserId
+            repository.mainUserId = mainUserId
             repository.setSelectedUserInfo(GUEST_USER_INFO)
 
             underTest.exit(
@@ -221,7 +223,7 @@
 
             verify(manager, never()).markGuestForDeletion(anyInt())
             verify(manager, never()).removeUser(anyInt())
-            verify(switchUser).invoke(UserHandle.USER_SYSTEM)
+            verify(switchUser).invoke(mainUserId)
         }
 
     @Test
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 7380ca4..3538d9b 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
@@ -119,8 +119,11 @@
             SUPERVISED_USER_CREATION_APP_PACKAGE,
         )
 
-        featureFlags = FakeFeatureFlags()
-        featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+        featureFlags =
+            FakeFeatureFlags().apply {
+                set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+                set(Flags.FACE_AUTH_REFACTOR, true)
+            }
         userRepository = FakeUserRepository()
         keyguardRepository = FakeKeyguardRepository()
         telephonyRepository = FakeTelephonyRepository()
@@ -141,6 +144,7 @@
                     KeyguardInteractor(
                         repository = keyguardRepository,
                         commandQueue = commandQueue,
+                        featureFlags = featureFlags,
                     ),
                 manager = manager,
                 applicationScope = testScope.backgroundScope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 46f38ed..8f0375f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -82,7 +82,6 @@
 
     private val userRepository = FakeUserRepository()
     private val keyguardRepository = FakeKeyguardRepository()
-    private val featureFlags = FakeFeatureFlags()
     private lateinit var guestUserInteractor: GuestUserInteractor
     private lateinit var refreshUsersScheduler: RefreshUsersScheduler
 
@@ -233,6 +232,11 @@
         }
 
     private fun viewModel(): StatusBarUserChipViewModel {
+        val featureFlags =
+            FakeFeatureFlags().apply {
+                set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+                set(Flags.FACE_AUTH_REFACTOR, true)
+            }
         return StatusBarUserChipViewModel(
             context = context,
             interactor =
@@ -244,9 +248,9 @@
                         KeyguardInteractor(
                             repository = keyguardRepository,
                             commandQueue = commandQueue,
+                            featureFlags = featureFlags,
                         ),
-                    featureFlags =
-                        FakeFeatureFlags().apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) },
+                    featureFlags = featureFlags,
                     manager = manager,
                     applicationScope = testScope.backgroundScope,
                     telephonyInteractor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 1d57d0b..71a112c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -134,6 +134,11 @@
                 resetOrExitSessionReceiver = resetOrExitSessionReceiver,
             )
 
+        val featureFlags =
+            FakeFeatureFlags().apply {
+                set(Flags.FULL_SCREEN_USER_SWITCHER, false)
+                set(Flags.FACE_AUTH_REFACTOR, true)
+            }
         underTest =
             UserSwitcherViewModel.Factory(
                     userInteractor =
@@ -145,11 +150,9 @@
                                 KeyguardInteractor(
                                     repository = keyguardRepository,
                                     commandQueue = commandQueue,
+                                    featureFlags = featureFlags
                                 ),
-                            featureFlags =
-                                FakeFeatureFlags().apply {
-                                    set(Flags.FULL_SCREEN_USER_SWITCHER, false)
-                                },
+                            featureFlags = featureFlags,
                             manager = manager,
                             applicationScope = testScope.backgroundScope,
                             telephonyInteractor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java
new file mode 100644
index 0000000..5ef62c1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/condition/ConditionalCoreStartableTest.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.condition;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.shared.condition.Condition;
+import com.android.systemui.shared.condition.Monitor;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ConditionalCoreStartableTest extends SysuiTestCase {
+    public static class FakeConditionalCoreStartable extends ConditionalCoreStartable {
+        interface Callback {
+            void onStart();
+            void bootCompleted();
+        }
+
+        private final Callback mCallback;
+
+        public FakeConditionalCoreStartable(Monitor monitor, Set<Condition> conditions,
+                Callback callback) {
+            super(monitor, conditions);
+            mCallback = callback;
+        }
+
+        @Override
+        protected void onStart() {
+            mCallback.onStart();
+        }
+
+        @Override
+        protected void bootCompleted() {
+            mCallback.bootCompleted();
+        }
+    }
+
+
+    final Set<Condition> mConditions = new HashSet<>();
+
+    @Mock
+    Condition mCondition;
+
+    @Mock
+    Monitor mMonitor;
+
+    @Mock
+    FakeConditionalCoreStartable.Callback mCallback;
+
+    @Mock
+    Monitor.Subscription.Token mSubscriptionToken;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mConditions.clear();
+    }
+
+    /**
+     * Verifies that {@link ConditionalCoreStartable#onStart()} is predicated on conditions being
+     * met.
+     */
+    @Test
+    public void testOnStartCallback() {
+        final CoreStartable coreStartable =
+                new FakeConditionalCoreStartable(mMonitor,
+                        new HashSet<>(Arrays.asList(mCondition)),
+                        mCallback);
+
+        when(mMonitor.addSubscription(any())).thenReturn(mSubscriptionToken);
+        coreStartable.start();
+
+        final ArgumentCaptor<Monitor.Subscription> subscriptionCaptor = ArgumentCaptor.forClass(
+                Monitor.Subscription.class);
+        verify(mMonitor).addSubscription(subscriptionCaptor.capture());
+
+        final Monitor.Subscription subscription = subscriptionCaptor.getValue();
+
+        assertThat(subscription.getConditions()).containsExactly(mCondition);
+
+        verify(mCallback, never()).onStart();
+
+        subscription.getCallback().onConditionsChanged(true);
+
+        verify(mCallback).onStart();
+        verify(mMonitor).removeSubscription(mSubscriptionToken);
+    }
+
+
+    /**
+     * Verifies that {@link ConditionalCoreStartable#bootCompleted()} ()} is predicated on
+     * conditions being met.
+     */
+    @Test
+    public void testBootCompleted() {
+        final CoreStartable coreStartable =
+                new FakeConditionalCoreStartable(mMonitor,
+                        new HashSet<>(Arrays.asList(mCondition)),
+                        mCallback);
+
+        when(mMonitor.addSubscription(any())).thenReturn(mSubscriptionToken);
+        coreStartable.onBootCompleted();
+
+        final ArgumentCaptor<Monitor.Subscription> subscriptionCaptor = ArgumentCaptor.forClass(
+                Monitor.Subscription.class);
+        verify(mMonitor).addSubscription(subscriptionCaptor.capture());
+
+        final Monitor.Subscription subscription = subscriptionCaptor.getValue();
+
+        assertThat(subscription.getConditions()).containsExactly(mCondition);
+
+        verify(mCallback, never()).bootCompleted();
+
+        subscription.getCallback().onConditionsChanged(true);
+
+        verify(mCallback).bootCompleted();
+        verify(mMonitor).removeSubscription(mSubscriptionToken);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 9d518ac..185d408 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -74,6 +74,7 @@
 import android.testing.TestableLooper;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.view.IWindowManager;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
@@ -81,6 +82,8 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.SysuiTestCase;
@@ -281,6 +284,8 @@
     private UserManager mUserManager;
     @Mock
     private ShadeWindowLogger mShadeWindowLogger;
+    @Mock
+    private SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver;
 
     private TestableBubblePositioner mPositioner;
 
@@ -293,6 +298,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        setTestFlagResolver(mFlagResolver);
 
         mTestableLooper = TestableLooper.get(this);
 
@@ -392,7 +398,8 @@
                 syncExecutor,
                 mock(Handler.class),
                 mTaskViewTransitions,
-                mock(SyncTransactionQueue.class));
+                mock(SyncTransactionQueue.class),
+                mock(IWindowManager.class));
         mBubbleController.setExpandListener(mBubbleExpandListener);
         spyOn(mBubbleController);
 
@@ -1505,7 +1512,7 @@
 
     @Test
     public void testUpdateBubble_skipsDndSuppressListNotifs() {
-        mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(),
+        mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), true, /* isDismissable */
                 mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */,
                 mRow.shouldSuppressPeek());
         mBubbleEntry.getBubbleMetadata().setFlags(
@@ -1532,7 +1539,7 @@
 
         // Send ranking update that the notif is suppressed from the list.
         HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey = new HashMap<>();
-        mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), mRow.isDismissable(),
+        mBubbleEntry = new BubbleEntry(mRow.getSbn(), mRow.getRanking(), true /* isDismissable */,
                 mRow.shouldSuppressNotificationDot(), true /* DndSuppressNotifFromList */,
                 mRow.shouldSuppressPeek());
         Pair<BubbleEntry, Boolean> pair = new Pair(mBubbleEntry, true);
@@ -1697,7 +1704,65 @@
         assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
     }
 
-    /** Creates a bubble using the userId and package. */
+    @Test
+    public void testCreateBubbleFromOngoingNotification_OngoingDismissalEnabled() {
+        when(mFlagResolver.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)).thenReturn(true);
+        NotificationEntry notif = new NotificationEntryBuilder()
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .setCanBubble(true)
+                .build();
+
+        BubbleEntry bubble = BubblesManager.notifToBubbleEntry(notif);
+
+        assertTrue("Ongoing Notifis should be dismissable", bubble.isDismissable());
+    }
+
+
+    @Test
+    public void testCreateBubbleFromNoDismissNotification_OngoingDismissalEnabled() {
+        when(mFlagResolver.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)).thenReturn(true);
+        NotificationEntry notif = new NotificationEntryBuilder()
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .setCanBubble(true)
+                .build();
+
+        BubbleEntry bubble = BubblesManager.notifToBubbleEntry(notif);
+
+        assertFalse("FLAG_NO_DISMISS Notifs should be non-dismissable", bubble.isDismissable());
+    }
+
+    @Test
+    public void testCreateBubbleFromOngoingNotification_OngoingDismissalDisabled() {
+        NotificationEntry notif = new NotificationEntryBuilder()
+                .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
+                .setCanBubble(true)
+                .build();
+
+        BubbleEntry bubble = BubblesManager.notifToBubbleEntry(notif);
+
+        assertFalse(
+                "Ongoing Notifis should be dismissable, if the feature is off",
+                bubble.isDismissable()
+        );
+    }
+
+
+    @Test
+    public void testCreateBubbleFromNoDismissNotification_OngoingDismissalDisabled() {
+        NotificationEntry notif = new NotificationEntryBuilder()
+                .setFlag(mContext, Notification.FLAG_NO_DISMISS, true)
+                .setCanBubble(true)
+                .build();
+
+        BubbleEntry bubble = BubblesManager.notifToBubbleEntry(notif);
+
+        assertTrue(
+                "FLAG_NO_DISMISS should be ignored, if the feature is off",
+                bubble.isDismissable()
+        );
+    }
+
+        /** Creates a bubble using the userId and package. */
     private Bubble createBubble(int userId, String pkg) {
         final UserHandle userHandle = new UserHandle(userId);
         NotificationEntry workEntry = new NotificationEntryBuilder()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 6357a09..3179285 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -20,6 +20,7 @@
 import android.content.pm.LauncherApps;
 import android.os.Handler;
 import android.os.UserManager;
+import android.view.IWindowManager;
 import android.view.WindowManager;
 
 import com.android.internal.statusbar.IStatusBarService;
@@ -72,13 +73,14 @@
             ShellExecutor shellMainExecutor,
             Handler shellMainHandler,
             TaskViewTransitions taskViewTransitions,
-            SyncTransactionQueue syncQueue) {
+            SyncTransactionQueue syncQueue,
+            IWindowManager wmService) {
         super(context, shellInit, shellCommandHandler, shellController, data, Runnable::run,
                 floatingContentCoordinator, dataRepository, statusBarService, windowManager,
                 windowManagerShellWrapper, userManager, launcherApps, bubbleLogger,
                 taskStackListener, shellTaskOrganizer, positioner, displayController,
                 oneHandedOptional, dragAndDropController, shellMainExecutor, shellMainHandler,
-                new SyncExecutor(), taskViewTransitions, syncQueue);
+                new SyncExecutor(), taskViewTransitions, syncQueue, wmService);
         setInflateSynchronously(true);
         onInit();
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index 1bab997..c236bc9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -34,6 +34,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.uiautomator.UiDevice;
 
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.systemui.animation.DialogLaunchAnimator;
@@ -144,6 +145,7 @@
         disallowTestableLooperAsMainThread();
         mContext.cleanUpReceivers(this.getClass().getSimpleName());
         mFakeBroadcastDispatcher.cleanUpReceivers(this.getClass().getSimpleName());
+        setTestFlagResolver(null);
     }
 
     @AfterClass
@@ -206,6 +208,10 @@
         }
     }
 
+    protected void setTestFlagResolver(SystemUiSystemPropertiesFlags.FlagResolver flagResolver) {
+        SystemUiSystemPropertiesFlags.TEST_RESOLVER = flagResolver;
+    }
+
     public static void waitForIdleSync(Handler h) {
         validateThread(h.getLooper());
         Idler idler = new Idler(null);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt
index b7a8d2e..9b4f496 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/coroutines/Flow.kt
@@ -18,6 +18,8 @@
 
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.Flow
@@ -25,16 +27,35 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 
-/** Collect [flow] in a new [Job] and return a getter for the last collected value. */
+/**
+ * Collect [flow] in a new [Job] and return a getter for the last collected value.
+ * ```
+ * fun myTest() = runTest {
+ *   // ...
+ *   val actual by collectLastValue(underTest.flow)
+ *   assertThat(actual).isEqualTo(expected)
+ * }
+ * ```
+ */
 fun <T> TestScope.collectLastValue(
     flow: Flow<T>,
     context: CoroutineContext = EmptyCoroutineContext,
     start: CoroutineStart = CoroutineStart.DEFAULT,
-): () -> T? {
+): FlowValue<T?> {
     var lastValue: T? = null
     backgroundScope.launch(context, start) { flow.collect { lastValue = it } }
-    return {
+    return FlowValueImpl {
         runCurrent()
         lastValue
     }
 }
+
+/** @see collectLastValue */
+interface FlowValue<T> : ReadOnlyProperty<Any?, T?> {
+    operator fun invoke(): T?
+}
+
+private class FlowValueImpl<T>(private val block: () -> T?) : FlowValue<T> {
+    override operator fun invoke(): T? = block()
+    override fun getValue(thisRef: Any?, property: KProperty<*>): T? = invoke()
+}
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 044679d..01dac36 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,6 +17,7 @@
 
 package com.android.systemui.keyguard.data.repository
 
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -26,6 +27,14 @@
     private val _isFingerprintEnrolled = MutableStateFlow<Boolean>(false)
     override val isFingerprintEnrolled: StateFlow<Boolean> = _isFingerprintEnrolled.asStateFlow()
 
+    private val _isFaceEnrolled = MutableStateFlow(false)
+    override val isFaceEnrolled: Flow<Boolean>
+        get() = _isFaceEnrolled
+
+    private val _isFaceAuthEnabled = MutableStateFlow(false)
+    override val isFaceAuthenticationEnabled: Flow<Boolean>
+        get() = _isFaceAuthEnabled
+
     private val _isStrongBiometricAllowed = MutableStateFlow(false)
     override val isStrongBiometricAllowed = _isStrongBiometricAllowed.asStateFlow()
 
@@ -44,4 +53,12 @@
     fun setFingerprintEnabledByDevicePolicy(isFingerprintEnabledByDevicePolicy: Boolean) {
         _isFingerprintEnabledByDevicePolicy.value = isFingerprintEnabledByDevicePolicy
     }
+
+    fun setFaceEnrolled(isFaceEnrolled: Boolean) {
+        _isFaceEnrolled.value = isFaceEnrolled
+    }
+
+    fun setIsFaceAuthEnabled(enabled: Boolean) {
+        _isFaceAuthEnabled.value = enabled
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java
index 7bcad45..6cd6594 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/RankingBuilder.java
@@ -60,6 +60,7 @@
     private int mRankingAdjustment = 0;
     private boolean mIsBubble = false;
     private int mProposedImportance = IMPORTANCE_UNSPECIFIED;
+    private boolean mSensitiveContent = false;
 
     public RankingBuilder() {
     }
@@ -90,6 +91,7 @@
         mRankingAdjustment = ranking.getRankingAdjustment();
         mIsBubble = ranking.isBubble();
         mProposedImportance = ranking.getProposedImportance();
+        mSensitiveContent = ranking.hasSensitiveContent();
     }
 
     public Ranking build() {
@@ -119,7 +121,8 @@
                 mShortcutInfo,
                 mRankingAdjustment,
                 mIsBubble,
-                mProposedImportance);
+                mProposedImportance,
+                mSensitiveContent);
         return ranking;
     }
 
@@ -224,6 +227,11 @@
         return this;
     }
 
+    public RankingBuilder setSensitiveContent(boolean sensitiveContent) {
+        mSensitiveContent = sensitiveContent;
+        return this;
+    }
+
     public RankingBuilder setUserSentiment(int userSentiment) {
         mUserSentiment = userSentiment;
         return this;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
index 1a8e244..53bb340 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
@@ -28,6 +28,10 @@
 import kotlinx.coroutines.yield
 
 class FakeUserRepository : UserRepository {
+    companion object {
+        // User id to represent a non system (human) user id. We presume this is the main user.
+        private const val MAIN_USER_ID = 10
+    }
 
     private val _userSwitcherSettings = MutableStateFlow(UserSwitcherSettingsModel())
     override val userSwitcherSettings: Flow<UserSwitcherSettingsModel> =
@@ -43,7 +47,8 @@
     override val userSwitchingInProgress: Flow<Boolean>
         get() = _userSwitchingInProgress
 
-    override var lastSelectedNonGuestUserId: Int = UserHandle.USER_SYSTEM
+    override var mainUserId: Int = MAIN_USER_ID
+    override var lastSelectedNonGuestUserId: Int = mainUserId
 
     private var _isGuestUserAutoCreated: Boolean = false
     override val isGuestUserAutoCreated: Boolean
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
new file mode 100644
index 0000000..b395d9c
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldRemoteModule.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold
+
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver
+import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
+import dagger.Module
+import dagger.Provides
+import java.util.Optional
+import javax.inject.Provider
+import javax.inject.Singleton
+
+/** Binds classes needed to provide unfold transition progresses to another process. */
+@Module
+class UnfoldRemoteModule {
+    @Provides
+    @Singleton
+    fun provideTransitionProvider(
+        config: UnfoldTransitionConfig,
+        traceListener: ATraceLoggerTransitionProgressListener,
+        remoteReceiverProvider: Provider<RemoteUnfoldTransitionReceiver>,
+    ): Optional<RemoteUnfoldTransitionReceiver> {
+        if (!config.isEnabled) {
+            return Optional.empty()
+        }
+        val remoteReceiver = remoteReceiverProvider.get()
+        remoteReceiver.addCallback(traceListener)
+        return Optional.of(remoteReceiver)
+    }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
index cfb959e..068347c 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.dagger.UnfoldMain
 import com.android.systemui.unfold.dagger.UnfoldSingleThreadBg
+import com.android.systemui.unfold.progress.RemoteUnfoldTransitionReceiver
 import com.android.systemui.unfold.updates.FoldProvider
 import com.android.systemui.unfold.updates.RotationChangeProvider
 import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
@@ -68,3 +69,38 @@
     val unfoldTransitionProvider: Optional<UnfoldTransitionProgressProvider>
     val rotationChangeProvider: RotationChangeProvider
 }
+
+/**
+ * Generates a [RemoteTransitionProgress] usable to receive unfold transition progress from another
+ * process.
+ */
+@Singleton
+@Component(modules = [UnfoldRemoteModule::class])
+interface RemoteUnfoldSharedComponent {
+
+    @Component.Factory
+    interface Factory {
+        fun create(
+            @BindsInstance context: Context,
+            @BindsInstance config: UnfoldTransitionConfig,
+            @BindsInstance @UnfoldMain executor: Executor,
+            @BindsInstance @UnfoldSingleThreadBg singleThreadBgExecutor: Executor,
+            @BindsInstance windowManager: IWindowManager,
+            @BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
+        ): RemoteUnfoldSharedComponent
+    }
+
+    val remoteTransitionProgress: Optional<RemoteUnfoldTransitionReceiver>
+    val rotationChangeProvider: RotationChangeProvider
+}
+
+/**
+ * Usable to receive and propagate unfold transition progresses
+ *
+ * All unfold events received by [remoteReceiver] will be propagated to [localProvider].
+ * [remoteReceiver] is meant to receive events from a remote process (E.g. from a binder service).
+ */
+data class RemoteTransitionProgress(
+    val localProvider: UnfoldTransitionProgressProvider,
+    val remoteReceiver: UnfoldTransitionProgressProvider.TransitionProgressListener
+)
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
index 31616fa..5ffc094 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
 import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
+import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder
 import com.android.systemui.unfold.updates.DeviceFoldStateProvider
 import com.android.systemui.unfold.updates.FoldStateProvider
 import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
@@ -102,4 +103,16 @@
             EmptyHingeAngleProvider
         }
     }
+
+    @Provides
+    @Singleton
+    fun provideProgressForwarder(
+            config: UnfoldTransitionConfig,
+            progressForwarder: Provider<UnfoldTransitionProgressForwarder>
+    ): Optional<UnfoldTransitionProgressForwarder> {
+        if (!config.isEnabled) {
+            return Optional.empty()
+        }
+        return Optional.of(progressForwarder.get())
+    }
 }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index aa93c629..8eb79df 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -63,3 +63,26 @@
                         tracingTagPrefix,
                         windowManager,
                 )
+
+/**
+ * Factory for [RemoteUnfoldSharedComponent].
+ *
+ * Wraps [DaggerRemoteUnfoldSharedComponent] (that is autogenerated), for better discoverability.
+ */
+fun createRemoteUnfoldSharedComponent(
+        context: Context,
+        config: UnfoldTransitionConfig,
+        mainExecutor: Executor,
+        singleThreadBgExecutor: Executor,
+        tracingTagPrefix: String,
+        windowManager: IWindowManager,
+        ): RemoteUnfoldSharedComponent =
+        DaggerRemoteUnfoldSharedComponent.factory()
+                .create(
+                        context,
+                        config,
+                        mainExecutor,
+                        singleThreadBgExecutor,
+                        windowManager,
+                        tracingTagPrefix,
+                )
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/IUnfoldAnimation.aidl b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/IUnfoldAnimation.aidl
new file mode 100644
index 0000000..07a1db4
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/IUnfoldAnimation.aidl
@@ -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.unfold.progress;
+
+
+import com.android.systemui.unfold.progress.IUnfoldTransitionListener;
+
+
+/**
+ * Interface exposed by System UI to allow remote process to register for unfold animation events.
+ */
+oneway interface IUnfoldAnimation {
+
+    /**
+     * Sets a listener for the animation.
+     *
+     * Only one listener is supported. If there are multiple, the earlier one will be overridden.
+     */
+    void setListener(in IUnfoldTransitionListener listener);
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/IUnfoldTransitionListener.aidl b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/IUnfoldTransitionListener.aidl
new file mode 100644
index 0000000..8f46b1b
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/IUnfoldTransitionListener.aidl
@@ -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.unfold.progress;
+
+
+/**
+ * Implemented by remote processes to receive unfold animation events from System UI.
+ */
+oneway interface IUnfoldTransitionListener {
+    /**
+    * Sent when unfold animation started.
+    */
+    void onTransitionStarted() = 1;
+
+    /**
+    * Sent when unfold animation progress changes.
+    */
+    void onTransitionProgress(float progress) = 2;
+
+    /**
+    * Sent when unfold animation finished.
+    */
+    void onTransitionFinished() = 3;
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiver.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiver.kt
new file mode 100644
index 0000000..5e4bcc9
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiver.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.unfold.progress
+
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.dagger.UnfoldMain
+import java.util.concurrent.Executor
+import javax.inject.Inject
+
+/**
+ * Receives unfold events from remote senders (System UI).
+ *
+ * A binder to an instance to this class (created with [RemoteUnfoldTransitionReceiver.asBinder])
+ * should be sent to the remote process providing events.
+ */
+class RemoteUnfoldTransitionReceiver
+@Inject
+constructor(@UnfoldMain private val executor: Executor) :
+    UnfoldTransitionProgressProvider, IUnfoldTransitionListener.Stub() {
+
+    private val listeners: MutableSet<TransitionProgressListener> = mutableSetOf()
+
+    override fun onTransitionStarted() {
+        executor.execute { listeners.forEach { it.onTransitionStarted() } }
+    }
+
+    override fun onTransitionProgress(progress: Float) {
+        executor.execute { listeners.forEach { it.onTransitionProgress(progress) } }
+    }
+
+    override fun onTransitionFinished() {
+        executor.execute { listeners.forEach { it.onTransitionFinished() } }
+    }
+
+    override fun addCallback(listener: TransitionProgressListener) {
+        listeners += listener
+    }
+
+    override fun removeCallback(listener: TransitionProgressListener) {
+        listeners -= listener
+    }
+
+    override fun destroy() {
+        listeners.clear()
+    }
+}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldTransitionProgressForwarder.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldTransitionProgressForwarder.kt
new file mode 100644
index 0000000..b654521
--- /dev/null
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/UnfoldTransitionProgressForwarder.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.unfold.progress
+
+import android.os.RemoteException
+import android.util.Log
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import javax.inject.Inject
+
+/** Forwards received unfold events to [remoteListener], when present. */
+class UnfoldTransitionProgressForwarder @Inject constructor() :
+    TransitionProgressListener, IUnfoldAnimation.Stub() {
+
+    private var remoteListener: IUnfoldTransitionListener? = null
+
+    override fun onTransitionStarted() {
+        try {
+            Log.d(TAG, "onTransitionStarted")
+            remoteListener?.onTransitionStarted()
+        } catch (e: RemoteException) {
+            Log.e(TAG, "Failed call onTransitionStarted", e)
+        }
+    }
+
+    override fun onTransitionFinished() {
+        try {
+            Log.d(TAG, "onTransitionFinished")
+            remoteListener?.onTransitionFinished()
+        } catch (e: RemoteException) {
+            Log.e(TAG, "Failed call onTransitionFinished", e)
+        }
+    }
+
+    override fun onTransitionProgress(progress: Float) {
+        try {
+            remoteListener?.onTransitionProgress(progress)
+        } catch (e: RemoteException) {
+            Log.e(TAG, "Failed call onTransitionProgress", e)
+        }
+    }
+
+    override fun setListener(listener: IUnfoldTransitionListener?) {
+        remoteListener = listener
+    }
+
+    companion object {
+        private val TAG = UnfoldTransitionProgressForwarder::class.java.simpleName
+    }
+}
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 12e7226..12a8230 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -306,6 +306,10 @@
     // Package: android
     NOTE_BT_APM_NOTIFICATION = 74;
 
+    // Inform that USB is configured as a Universal Video Class gadget
+    // Package: android
+    NOTE_USB_UVC = 75;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/rs/java/android/renderscript/package.html b/rs/java/android/renderscript/package.html
index eb178c1..8179928 100644
--- a/rs/java/android/renderscript/package.html
+++ b/rs/java/android/renderscript/package.html
@@ -1,9 +1,9 @@
 <HTML>
 <BODY>
-<p>RenderScript provides support for high-performance computation across heterogeneous processors.</p>
+<p>Renderscript is deprecated since API level 31. Please refer to the
+<a href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration guide</a>
+for alternatives.
 
-<p>For more information, see the
-<a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
 {@more}
 
 </BODY>
diff --git a/services/Android.bp b/services/Android.bp
index 3f3ba06..f8097ec 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -191,6 +191,10 @@
         "service-sdksandbox.stubs.system_server",
     ],
 
+    vintf_fragments: [
+        "manifest_services.xml",
+    ],
+
     // Uncomment to enable output of certain warnings (deprecated, unchecked)
     //javacflags: ["-Xlint"],
 }
diff --git a/services/OWNERS b/services/OWNERS
index eace906..3ce5ae1 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -3,6 +3,8 @@
 # art-team@ manages the system server profile
 per-file art-profile* = calin@google.com, ngeoffray@google.com, vmarko@google.com
 
+per-file java/com/android/server/HsumBootUserInitializer.java = file:/MULTIUSER_OWNERS
+
 per-file java/com/android/server/* = patb@google.com #{LAST_RESORT_SUGGESTION}
 per-file tests/servicestests/src/com/android/server/systemconfig/* = patb@google.com
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index c87d1c8..8e7d277 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -229,17 +229,12 @@
     }
 
     void onDisplayAdded(@NonNull Display display) {
-        if (mInstalled) {
-            resetStreamStateForDisplay(display.getDisplayId());
-            enableFeaturesForDisplay(display);
-        }
+        enableFeaturesForDisplayIfInstalled(display);
+
     }
 
     void onDisplayRemoved(int displayId) {
-        if (mInstalled) {
-            disableFeaturesForDisplay(displayId);
-            resetStreamStateForDisplay(displayId);
-        }
+        disableFeaturesForDisplayIfInstalled(displayId);
     }
 
     @Override
@@ -479,6 +474,9 @@
 
         final Context displayContext = mContext.createDisplayContext(display);
         final int displayId = display.getDisplayId();
+        if (mAms.isDisplayProxyed(displayId)) {
+            return;
+        }
         if (!mServiceDetectsGestures.contains(displayId)) {
             mServiceDetectsGestures.put(displayId, false);
         }
@@ -613,6 +611,18 @@
             mEventHandler.remove(displayId);
         }
     }
+    void enableFeaturesForDisplayIfInstalled(Display display) {
+        if (mInstalled) {
+            resetStreamStateForDisplay(display.getDisplayId());
+            enableFeaturesForDisplay(display);
+        }
+    }
+    void disableFeaturesForDisplayIfInstalled(int displayId) {
+        if (mInstalled) {
+            disableFeaturesForDisplay(displayId);
+            resetStreamStateForDisplay(displayId);
+        }
+    }
 
     private void disableDisplayIndependentFeatures() {
         if (mAutoclickController != null) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index c1c486e..311e43a 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -28,10 +28,10 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED;
 import static android.provider.Settings.Secure.CONTRAST_LEVEL;
 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_MENU_IN_SYSTEM;
 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 import static android.view.accessibility.AccessibilityManager.CONTRAST_DEFAULT_VALUE;
 import static android.view.accessibility.AccessibilityManager.CONTRAST_NOT_SET;
+import static android.view.accessibility.AccessibilityManager.FlashNotificationReason;
 import static android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
@@ -137,6 +137,7 @@
 import com.android.internal.accessibility.AccessibilityShortcutController.LaunchableFrameworkFeatureInfo;
 import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
 import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity;
+import com.android.internal.accessibility.util.AccessibilityUtils;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
@@ -171,7 +172,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -217,9 +217,6 @@
     private static final String SET_PIP_ACTION_REPLACEMENT =
             "setPictureInPictureActionReplacingConnection";
 
-    @VisibleForTesting
-    static final String MENU_SERVICE_RELATIVE_CLASS_NAME = ".AccessibilityMenuService";
-
     private static final char COMPONENT_NAME_SEPARATOR = ':';
 
     private static final int OWN_PROCESS_ID = android.os.Process.myPid();
@@ -314,6 +311,8 @@
     boolean mInputSessionRequested;
     private SparseArray<SurfaceControl> mA11yOverlayLayers = new SparseArray<>();
 
+    private final FlashNotificationsController mFlashNotificationsController;
+
     private AccessibilityUserState getCurrentUserStateLocked() {
         return getUserStateLocked(mCurrentUserId);
     }
@@ -441,6 +440,7 @@
             mInputFilter = inputFilter;
             mHasInputFilter = true;
         }
+        mFlashNotificationsController = new FlashNotificationsController(mContext);
         init();
     }
 
@@ -470,7 +470,8 @@
                 new MagnificationScaleProvider(mContext));
         mMagnificationProcessor = new MagnificationProcessor(mMagnificationController);
         mCaptioningManagerImpl = new CaptioningManagerImpl(mContext);
-        mProxyManager = new ProxyManager(mLock, mA11yWindowManager);
+        mProxyManager = new ProxyManager(mLock, mA11yWindowManager, mContext);
+        mFlashNotificationsController = new FlashNotificationsController(mContext);
         init();
     }
 
@@ -479,6 +480,7 @@
         registerBroadcastReceivers();
         new AccessibilityContentObserver(mMainHandler).register(
                 mContext.getContentResolver());
+        disableAccessibilityMenuToMigrateIfNeeded();
     }
 
     @Override
@@ -850,91 +852,27 @@
     }
 
     /**
-     * Migrates the Accessibility Menu to the version provided by the system build,
-     * if necessary based on presence of the service on the device.
+     * Disables the component returned by
+     * {@link AccessibilityUtils#getAccessibilityMenuComponentToMigrate} so that it does not appear
+     * in Settings or other places that query for installed accessibility services.
+     *
+     * <p>
+     * SettingsProvider is responsible for migrating users off of Menu-outside-system,
+     * which it performs in its initialization before AccessibilityManagerService is started.
+     * </p>
      */
-    @VisibleForTesting
-    void migrateAccessibilityMenuIfNecessaryLocked(AccessibilityUserState userState) {
-        final Set<ComponentName> menuComponentNames = findA11yMenuComponentNamesLocked();
-        final ComponentName menuOutsideSystem = getA11yMenuOutsideSystem(menuComponentNames);
-        final boolean shouldMigrateToMenuInSystem = menuComponentNames.size() == 2
-                && menuComponentNames.contains(ACCESSIBILITY_MENU_IN_SYSTEM)
-                && menuOutsideSystem != null;
-
-        if (!shouldMigrateToMenuInSystem) {
-            if (menuComponentNames.size() == 1) {
-                // If only one Menu package exists then reset its component to the default state.
-                mPackageManager.setComponentEnabledSetting(
-                        menuComponentNames.stream().findFirst().get(),
-                        PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
-                        PackageManager.DONT_KILL_APP);
-            }
-            return;
+    private void disableAccessibilityMenuToMigrateIfNeeded() {
+        int userId;
+        synchronized (mLock) {
+            userId = mCurrentUserId;
         }
-
-        // Hide Menu-outside-system so that it does not appear in Settings.
-        mPackageManager.setComponentEnabledSetting(
-                menuOutsideSystem,
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
-        // Migrate the accessibility shortcuts.
-        migrateA11yMenuInSettingLocked(userState,
-                Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, menuOutsideSystem);
-        migrateA11yMenuInSettingLocked(userState,
-                Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT, menuOutsideSystem);
-        migrateA11yMenuInSettingLocked(userState,
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, menuOutsideSystem);
-        // If Menu-outside-system is currently enabled by the user then automatically
-        // disable it and enable Menu-in-system.
-        migrateA11yMenuInSettingLocked(userState,
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, menuOutsideSystem);
-    }
-
-    /**
-     * Returns all {@link ComponentName}s whose class name ends in {@link
-     * #MENU_SERVICE_RELATIVE_CLASS_NAME}.
-     **/
-    private Set<ComponentName> findA11yMenuComponentNamesLocked() {
-        Set<ComponentName> result = new ArraySet<>();
-        final var flags =
-                PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DISABLED_COMPONENTS
-                        | PackageManager.MATCH_DIRECT_BOOT_AWARE
-                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
-        for (ResolveInfo resolveInfo : mPackageManager.queryIntentServicesAsUser(
-                new Intent(AccessibilityService.SERVICE_INTERFACE), flags, mCurrentUserId)) {
-            final ComponentName componentName = resolveInfo.serviceInfo.getComponentName();
-            if (componentName.getClassName().endsWith(MENU_SERVICE_RELATIVE_CLASS_NAME)) {
-                result.add(componentName);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Returns the first {@link ComponentName} in the provided set that is not equal to {@link
-     * AccessibilityManager#ACCESSIBILITY_MENU_IN_SYSTEM}.
-     */
-    private static ComponentName getA11yMenuOutsideSystem(Set<ComponentName> menuComponentNames) {
-        Optional<ComponentName> menuOutsideSystem = menuComponentNames.stream().filter(
-                name -> !name.equals(ACCESSIBILITY_MENU_IN_SYSTEM)).findFirst();
-        if (menuOutsideSystem.isEmpty()) {
-            return null;
-        }
-        return menuOutsideSystem.get();
-    }
-
-    /**
-     * Replaces <code>toRemove</code> with {@link AccessibilityManager#ACCESSIBILITY_MENU_IN_SYSTEM}
-     * in the requested setting, if present already.
-     */
-    private void migrateA11yMenuInSettingLocked(AccessibilityUserState userState, String setting,
-            ComponentName toRemove) {
-        mTempComponentNameSet.clear();
-        readComponentNamesFromSettingLocked(setting, userState.mUserId, mTempComponentNameSet);
-        if (mTempComponentNameSet.contains(toRemove)) {
-            mTempComponentNameSet.remove(toRemove);
-            mTempComponentNameSet.add(ACCESSIBILITY_MENU_IN_SYSTEM);
-            persistComponentNamesToSettingLocked(setting, mTempComponentNameSet, userState.mUserId);
+        final ComponentName menuToMigrate =
+                AccessibilityUtils.getAccessibilityMenuComponentToMigrate(mPackageManager, userId);
+        if (menuToMigrate != null) {
+            mPackageManager.setComponentEnabledSetting(
+                    menuToMigrate,
+                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                    PackageManager.DONT_KILL_APP);
         }
     }
 
@@ -1707,8 +1645,6 @@
             mCurrentUserId = userId;
             AccessibilityUserState userState = getCurrentUserStateLocked();
 
-            migrateAccessibilityMenuIfNecessaryLocked(userState);
-
             readConfigurationForUserStateLocked(userState);
             mSecurityPolicy.onSwitchUserLocked(mCurrentUserId, userState.mEnabledServices);
             // Even if reading did not yield change, we have to update
@@ -1980,6 +1916,12 @@
             AccessibilityServiceInfo accessibilityServiceInfo;
             try {
                 accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext);
+                if (!accessibilityServiceInfo.isWithinParcelableSize()) {
+                    Slog.e(LOG_TAG, "Skipping service "
+                            + accessibilityServiceInfo.getResolveInfo().getComponentInfo()
+                            + " because service info size is larger than safe parcelable limits.");
+                    continue;
+                }
                 if (userState.mCrashedServices.contains(serviceInfo.getComponentName())) {
                     // Restore the crashed attribute.
                     accessibilityServiceInfo.crashed = true;
@@ -2490,6 +2432,7 @@
                     }
                     inputFilter = mInputFilter;
                     setInputFilter = true;
+                    mProxyManager.setAccessibilityInputFilter(mInputFilter);
                 }
                 mInputFilter.setUserAndEnabledFeatures(userState.mUserId, flags);
                 mInputFilter.setCombinedGenericMotionEventSources(
@@ -2720,6 +2663,7 @@
         somethingChanged |= readMagnificationModeForDefaultDisplayLocked(userState);
         somethingChanged |= readMagnificationCapabilitiesLocked(userState);
         somethingChanged |= readMagnificationFollowTypingLocked(userState);
+        somethingChanged |= readAlwaysOnMagnificationLocked(userState);
         somethingChanged |= readUiContrastLocked(userState);
         return somethingChanged;
     }
@@ -3879,6 +3823,10 @@
         return mProxyManager.unregisterProxy(displayId);
     }
 
+    boolean isDisplayProxyed(int displayId) {
+        return mProxyManager.isProxyed(displayId);
+    }
+
     @Override public float getUiContrast() {
         if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) {
             mTraceManager.logTrace(LOG_TAG + ".getUiContrast", FLAGS_ACCESSIBILITY_MANAGER);
@@ -3893,6 +3841,40 @@
     }
 
     @Override
+    public boolean startFlashNotificationSequence(String opPkg,
+            @FlashNotificationReason int reason, IBinder token) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return mFlashNotificationsController.startFlashNotificationSequence(opPkg,
+                    reason, token);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public boolean stopFlashNotificationSequence(String opPkg) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return mFlashNotificationsController.stopFlashNotificationSequence(opPkg);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public boolean startFlashNotificationEvent(String opPkg,
+            @FlashNotificationReason int reason, String reasonPkg) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return mFlashNotificationsController.startFlashNotificationEvent(opPkg,
+                    reason, reasonPkg);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
         synchronized (mLock) {
@@ -4339,6 +4321,9 @@
         private final Uri mMagnificationFollowTypingUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED);
 
+        private final Uri mAlwaysOnMagnificationUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED);
+
         private final Uri mUiContrastUri = Settings.Secure.getUriFor(
                 CONTRAST_LEVEL);
 
@@ -4383,6 +4368,8 @@
             contentResolver.registerContentObserver(
                     mMagnificationFollowTypingUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
+                    mAlwaysOnMagnificationUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
                     mUiContrastUri, false, this, UserHandle.USER_ALL);
         }
 
@@ -4453,6 +4440,8 @@
                     }
                 } else if (mMagnificationFollowTypingUri.equals(uri)) {
                     readMagnificationFollowTypingLocked(userState);
+                } else if (mAlwaysOnMagnificationUri.equals(uri)) {
+                    readAlwaysOnMagnificationLocked(userState);
                 } else if (mUiContrastUri.equals(uri)) {
                     if (readUiContrastLocked(userState)) {
                         updateUiContrastLocked(userState);
@@ -4566,6 +4555,22 @@
         return false;
     }
 
+    boolean readAlwaysOnMagnificationLocked(AccessibilityUserState userState) {
+        final boolean isSettingsAlwaysOnEnabled = Settings.Secure.getIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
+                1, userState.mUserId) == 1;
+        final boolean isAlwaysOnFeatureFlagEnabled = mMagnificationController
+                .isAlwaysOnMagnificationFeatureFlagEnabled();
+        final boolean isAlwaysOnEnabled = isAlwaysOnFeatureFlagEnabled && isSettingsAlwaysOnEnabled;
+        if (isAlwaysOnEnabled != userState.isAlwaysOnMagnificationEnabled()) {
+            userState.setAlwaysOnMagnificationEnabled(isAlwaysOnEnabled);
+            mMagnificationController.setAlwaysOnMagnificationEnabled(isAlwaysOnEnabled);
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void setGestureDetectionPassthroughRegion(int displayId, Region region) {
         mMainHandler.sendMessage(
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
index ce269f5..4806001 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
@@ -78,7 +78,8 @@
             | AccessibilityEvent.TYPE_VIEW_SCROLLED
             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
-            | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
+            | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+            | AccessibilityEvent.TYPE_VIEW_TARGETED_BY_SCROLL;
 
     /**
      * Methods that should find their way into separate modules, but are still in AMS
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 43730fc..1c9ce3c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -136,6 +136,8 @@
     private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
     // Whether the following typing focus feature for magnification is enabled.
     private boolean mMagnificationFollowTypingEnabled = true;
+    // Whether the always on magnification feature is enabled.
+    private boolean mAlwaysOnMagnificationEnabled = false;
 
     /** The stroke width of the focus rectangle in pixels */
     private int mFocusStrokeWidth;
@@ -221,6 +223,7 @@
         mFocusStrokeWidth = mFocusStrokeWidthDefaultValue;
         mFocusColor = mFocusColorDefaultValue;
         mMagnificationFollowTypingEnabled = true;
+        mAlwaysOnMagnificationEnabled = false;
         mUiContrast = CONTRAST_NOT_SET;
     }
 
@@ -531,6 +534,8 @@
                 .append(String.valueOf(mIsAudioDescriptionByDefaultRequested));
         pw.append(", magnificationFollowTypingEnabled=")
                 .append(String.valueOf(mMagnificationFollowTypingEnabled));
+        pw.append(", alwaysOnMagnificationEnabled=")
+                .append(String.valueOf(mAlwaysOnMagnificationEnabled));
         pw.append("}");
         pw.println();
         pw.append("     shortcut key:{");
@@ -711,6 +716,14 @@
         return mMagnificationFollowTypingEnabled;
     }
 
+    public void setAlwaysOnMagnificationEnabled(boolean enabled) {
+        mAlwaysOnMagnificationEnabled = enabled;
+    }
+
+    public boolean isAlwaysOnMagnificationEnabled() {
+        return mAlwaysOnMagnificationEnabled;
+    }
+
     /**
      * Sets the magnification mode to the given display.
      *
diff --git a/services/accessibility/java/com/android/server/accessibility/FlashNotificationsController.java b/services/accessibility/java/com/android/server/accessibility/FlashNotificationsController.java
new file mode 100644
index 0000000..86b5a12
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/FlashNotificationsController.java
@@ -0,0 +1,937 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.accessibility;
+
+import static android.view.accessibility.AccessibilityManager.FLASH_REASON_ALARM;
+import static android.view.accessibility.AccessibilityManager.FLASH_REASON_PREVIEW;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.animation.ObjectAnimator;
+import android.annotation.ColorInt;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.display.DisplayManager;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager.FlashNotificationReason;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.FrameLayout;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+class FlashNotificationsController {
+    private static final String LOG_TAG = "FlashNotifController";
+    private static final boolean DEBUG = true;
+
+    private static final String WAKE_LOCK_TAG = "a11y:FlashNotificationsController";
+
+    /** The tag for flash notification which is triggered by short/long preview. */
+    private static final String TAG_PREVIEW = "preview";
+    /** The tag for flash notification which is triggered by alarm. */
+    private static final String TAG_ALARM = "alarm";
+
+    /** The default flashing type: triggered by an event. It'll flash 2 times in a short period. */
+    private static final int TYPE_DEFAULT = 1;
+    /**
+     * The sequence flashing type: usually triggered by call/alarm. It'll flash infinitely until the
+     * call/alarm ends.
+     */
+    private static final int TYPE_SEQUENCE = 2;
+    /**
+     * The long preview flashing type: it's only for screen flash preview. It'll flash only 1 time
+     * with a long period to show the screen flash effect more clearly.
+     */
+    private static final int TYPE_LONG_PREVIEW = 3;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "TYPE_" }, value = {
+            TYPE_DEFAULT,
+            TYPE_SEQUENCE,
+            TYPE_LONG_PREVIEW
+    })
+    @interface FlashNotificationType {}
+
+    private static final int TYPE_DEFAULT_ON_MS = 350;
+    private static final int TYPE_DEFAULT_OFF_MS = 250;
+    private static final int TYPE_SEQUENCE_ON_MS = 700;
+    private static final int TYPE_SEQUENCE_OFF_MS = 700;
+    private static final int TYPE_LONG_PREVIEW_ON_MS = 5000;
+    private static final int TYPE_LONG_PREVIEW_OFF_MS = 1000;
+    private static final int TYPE_DEFAULT_SCREEN_DELAY_MS = 300;
+
+    private static final int SCREEN_FADE_DURATION_MS = 200;
+    private static final int SCREEN_FADE_OUT_TIMEOUT_MS = 10;
+
+    @ColorInt
+    private static final int SCREEN_DEFAULT_COLOR = 0x00FFFF00;
+    @ColorInt
+    private static final int SCREEN_DEFAULT_ALPHA = 0x66000000;
+    @ColorInt
+    private static final int SCREEN_DEFAULT_COLOR_WITH_ALPHA =
+            SCREEN_DEFAULT_COLOR | SCREEN_DEFAULT_ALPHA;
+
+    // TODO(b/266775677): Make protected-broadcast intent
+    @VisibleForTesting
+    static final String ACTION_FLASH_NOTIFICATION_START_PREVIEW =
+            "com.android.internal.intent.action.FLASH_NOTIFICATION_START_PREVIEW";
+    // TODO(b/266775677): Make protected-broadcast intent
+    @VisibleForTesting
+    static final String ACTION_FLASH_NOTIFICATION_STOP_PREVIEW =
+            "com.android.internal.intent.action.FLASH_NOTIFICATION_STOP_PREVIEW";
+    @VisibleForTesting
+    static final String EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR =
+            "com.android.internal.intent.extra.FLASH_NOTIFICATION_PREVIEW_COLOR";
+    @VisibleForTesting
+    static final String EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE =
+            "com.android.internal.intent.extra.FLASH_NOTIFICATION_PREVIEW_TYPE";
+
+    @VisibleForTesting
+    static final int PREVIEW_TYPE_SHORT = 0;
+    @VisibleForTesting
+    static final int PREVIEW_TYPE_LONG = 1;
+
+    // TODO(b/266775683): Move to settings provider
+    @VisibleForTesting
+    static final String SETTING_KEY_CAMERA_FLASH_NOTIFICATION = "camera_flash_notification";
+    // TODO(b/266775683): Move to settings provider
+    @VisibleForTesting
+    static final String SETTING_KEY_SCREEN_FLASH_NOTIFICATION = "screen_flash_notification";
+    // TODO(b/266775683): Move to settings provider
+    @VisibleForTesting
+    static final String SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR =
+            "screen_flash_notification_color_global";
+
+    /**
+     * Timeout of the wake lock (5 minutes). It should normally never triggered, the wakelock
+     * should be released after the flashing notification is completed.
+     */
+    private static final long WAKE_LOCK_TIMEOUT_MS = 5 * 60 * 1000;
+
+    private final Context mContext;
+    private final DisplayManager mDisplayManager;
+    private final PowerManager.WakeLock mWakeLock;
+    @GuardedBy("mFlashNotifications")
+    private final LinkedList<FlashNotification> mFlashNotifications = new LinkedList<>();
+    private final Handler mMainHandler;
+    private final Handler mCallbackHandler;
+    private boolean mIsTorchTouched = false;
+    private boolean mIsTorchOn = false;
+    private boolean mIsCameraFlashNotificationEnabled = false;
+    private boolean mIsScreenFlashNotificationEnabled = false;
+    private boolean mIsAlarming = false;
+    private int mDisplayState = Display.STATE_OFF;
+    private boolean mIsCameraOpened = false;
+    private CameraManager mCameraManager;
+    private String mCameraId = null;
+
+    private final CameraManager.TorchCallback mTorchCallback = new CameraManager.TorchCallback() {
+        @Override
+        public void onTorchModeChanged(String cameraId, boolean enabled) {
+            if (mCameraId != null && mCameraId.equals(cameraId)) {
+                mIsTorchOn = enabled;
+                if (DEBUG) Log.d(LOG_TAG, "onTorchModeChanged, set mIsTorchOn=" + enabled);
+            }
+        }
+    };
+    @VisibleForTesting
+    final CameraManager.AvailabilityCallback mTorchAvailabilityCallback =
+            new CameraManager.AvailabilityCallback() {
+                @Override
+                public void onCameraOpened(@NonNull String cameraId, @NonNull String packageId) {
+                    if (mCameraId != null && mCameraId.equals(cameraId)) {
+                        mIsCameraOpened = true;
+                    }
+                }
+
+                @Override
+                public void onCameraClosed(@NonNull String cameraId) {
+                    if (mCameraId != null && mCameraId.equals(cameraId)) {
+                        mIsCameraOpened = false;
+                    }
+                }
+            };
+    private View mScreenFlashNotificationOverlayView;
+    private FlashNotification mCurrentFlashNotification;
+
+    private final AudioManager.AudioPlaybackCallback mAudioPlaybackCallback =
+            new AudioManager.AudioPlaybackCallback() {
+                @Override
+                public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
+                    boolean isAlarmActive = false;
+                    if (configs != null) {
+                        isAlarmActive = configs.stream()
+                                .anyMatch(config -> config.isActive()
+                                        && config.getAudioAttributes().getUsage()
+                                        == AudioAttributes.USAGE_ALARM);
+                    }
+
+                    if (mIsAlarming != isAlarmActive) {
+                        if (DEBUG) Log.d(LOG_TAG, "alarm state changed: " + isAlarmActive);
+                        if (isAlarmActive) {
+                            startFlashNotificationSequenceForAlarm();
+                        } else {
+                            stopFlashNotificationSequenceForAlarm();
+                        }
+                        mIsAlarming = isAlarmActive;
+                    }
+                }
+            };
+    private volatile FlashNotificationThread mThread;
+    private final Handler mFlashNotificationHandler;
+    @VisibleForTesting
+    final FlashBroadcastReceiver mFlashBroadcastReceiver;
+
+
+    FlashNotificationsController(Context context) {
+        this(context, getStartedHandler("FlashNotificationThread"), getStartedHandler(LOG_TAG));
+    }
+
+    @VisibleForTesting
+    FlashNotificationsController(Context context, Handler flashNotificationHandler,
+            Handler callbackHandler) {
+        mContext = context;
+        mMainHandler = new Handler(mContext.getMainLooper());
+        mFlashNotificationHandler = flashNotificationHandler;
+        mCallbackHandler = callbackHandler;
+
+        new FlashContentObserver(mMainHandler).register(mContext.getContentResolver());
+
+        final IntentFilter broadcastFilter = new IntentFilter();
+        broadcastFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
+        broadcastFilter.addAction(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
+        broadcastFilter.addAction(ACTION_FLASH_NOTIFICATION_STOP_PREVIEW);
+        mFlashBroadcastReceiver = new FlashBroadcastReceiver();
+        mContext.registerReceiver(
+                mFlashBroadcastReceiver, broadcastFilter, Context.RECEIVER_EXPORTED);
+
+        final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
+        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
+
+        mDisplayManager = mContext.getSystemService(DisplayManager.class);
+        final DisplayManager.DisplayListener displayListener =
+                new DisplayManager.DisplayListener() {
+                    @Override
+                    public void onDisplayAdded(int displayId) {
+                    }
+
+                    @Override
+                    public void onDisplayRemoved(int displayId) {
+                    }
+
+                    @Override
+                    public void onDisplayChanged(int displayId) {
+                        if (mDisplayManager != null) {
+                            Display display = mDisplayManager.getDisplay(displayId);
+                            if (display != null) {
+                                mDisplayState = display.getState();
+                            }
+                        }
+                    }
+                };
+
+        if (mDisplayManager != null) {
+            mDisplayManager.registerDisplayListener(displayListener, null);
+        }
+    }
+
+    private static Handler getStartedHandler(String tag) {
+        HandlerThread handlerThread = new HandlerThread(tag);
+        handlerThread.start();
+        return handlerThread.getThreadHandler();
+    }
+
+
+    boolean startFlashNotificationSequence(String opPkg,
+            @FlashNotificationReason int reason, IBinder token) {
+        final FlashNotification flashNotification = new FlashNotification(opPkg, TYPE_SEQUENCE,
+                getScreenFlashColorPreference(reason),
+                token, () -> stopFlashNotification(opPkg));
+
+        if (!flashNotification.tryLinkToDeath()) return false;
+
+        requestStartFlashNotification(flashNotification);
+        return true;
+    }
+
+    boolean stopFlashNotificationSequence(String opPkg) {
+        stopFlashNotification(opPkg);
+        return true;
+    }
+
+    boolean startFlashNotificationEvent(String opPkg, int reason, String reasonPkg) {
+        requestStartFlashNotification(new FlashNotification(opPkg, TYPE_DEFAULT,
+                getScreenFlashColorPreference(reason, reasonPkg)));
+        return true;
+    }
+
+    private void startFlashNotificationShortPreview() {
+        requestStartFlashNotification(new FlashNotification(TAG_PREVIEW, TYPE_DEFAULT,
+                getScreenFlashColorPreference(FLASH_REASON_PREVIEW)));
+    }
+
+    private void startFlashNotificationLongPreview(@ColorInt int color) {
+        requestStartFlashNotification(new FlashNotification(TAG_PREVIEW, TYPE_LONG_PREVIEW,
+                color));
+    }
+
+    private void stopFlashNotificationLongPreview() {
+        stopFlashNotification(TAG_PREVIEW);
+    }
+
+    private void startFlashNotificationSequenceForAlarm() {
+        requestStartFlashNotification(new FlashNotification(TAG_ALARM, TYPE_SEQUENCE,
+                getScreenFlashColorPreference(FLASH_REASON_ALARM)));
+    }
+
+    private void stopFlashNotificationSequenceForAlarm() {
+        stopFlashNotification(TAG_ALARM);
+    }
+
+    private void requestStartFlashNotification(FlashNotification flashNotification) {
+        if (DEBUG) Log.d(LOG_TAG, "requestStartFlashNotification");
+
+        mIsCameraFlashNotificationEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0,
+                UserHandle.USER_CURRENT) != 0;
+        mIsScreenFlashNotificationEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0,
+                UserHandle.USER_CURRENT) != 0;
+
+        // To prevent unexpectedly screen flash when screen is off, delays the TYPE_DEFAULT screen
+        // flash since mDisplayState is not refreshed to STATE_OFF immediately after screen is
+        // turned off. No need to delay TYPE_SEQUENCE screen flash as calls and alarms will always
+        // wake up the screen.
+        // TODO(b/267121704) refactor the logic to remove delay workaround
+        if (flashNotification.mType == TYPE_DEFAULT && mIsScreenFlashNotificationEnabled) {
+            mMainHandler.sendMessageDelayed(
+                    obtainMessage(FlashNotificationsController::startFlashNotification, this,
+                            flashNotification), TYPE_DEFAULT_SCREEN_DELAY_MS);
+            if (DEBUG) Log.i(LOG_TAG, "give some delay for flash notification");
+        } else {
+            startFlashNotification(flashNotification);
+        }
+    }
+
+    private void stopFlashNotification(String tag) {
+        if (DEBUG) Log.i(LOG_TAG, "stopFlashNotification: tag=" + tag);
+        synchronized (mFlashNotifications) {
+            final FlashNotification notification = removeFlashNotificationLocked(tag);
+            if (mCurrentFlashNotification != null && notification == mCurrentFlashNotification) {
+                stopFlashNotificationLocked();
+                startNextFlashNotificationLocked();
+            }
+        }
+    }
+
+    private void prepareForCameraFlashNotification() {
+        mCameraManager = mContext.getSystemService(CameraManager.class);
+
+        if (mCameraManager != null) {
+            try {
+                mCameraId = getCameraId();
+            } catch (CameraAccessException e) {
+                Log.e(LOG_TAG, "CameraAccessException", e);
+            }
+            mCameraManager.registerTorchCallback(mTorchCallback, null);
+        }
+    }
+
+    private String getCameraId() throws CameraAccessException {
+        String[] ids = mCameraManager.getCameraIdList();
+
+        for (String id : ids) {
+            CameraCharacteristics c = mCameraManager.getCameraCharacteristics(id);
+            Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
+            Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
+            if (flashAvailable != null && lensFacing != null
+                    && flashAvailable && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+                if (DEBUG) Log.d(LOG_TAG, "Found valid camera, cameraId=" + id);
+                return id;
+            }
+        }
+        return null;
+    }
+
+    private void showScreenNotificationOverlayView(@ColorInt int color) {
+        mMainHandler.sendMessage(obtainMessage(
+                FlashNotificationsController::showScreenNotificationOverlayViewMainThread,
+                this, color));
+    }
+
+    private void hideScreenNotificationOverlayView() {
+        mMainHandler.sendMessage(obtainMessage(
+                FlashNotificationsController::fadeOutScreenNotificationOverlayViewMainThread,
+                this));
+        mMainHandler.sendMessageDelayed(obtainMessage(
+                FlashNotificationsController::hideScreenNotificationOverlayViewMainThread,
+                this), SCREEN_FADE_DURATION_MS + SCREEN_FADE_OUT_TIMEOUT_MS);
+    }
+
+    private void showScreenNotificationOverlayViewMainThread(@ColorInt int color) {
+        if (DEBUG) Log.d(LOG_TAG, "showScreenNotificationOverlayViewMainThread");
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                PixelFormat.TRANSLUCENT);
+        params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        params.layoutInDisplayCutoutMode =
+                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+        params.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+
+        // Main display
+        if (mScreenFlashNotificationOverlayView == null) {
+            mScreenFlashNotificationOverlayView = getScreenNotificationOverlayView(color);
+            mContext.getSystemService(WindowManager.class).addView(
+                    mScreenFlashNotificationOverlayView, params);
+            fadeScreenNotificationOverlayViewMainThread(mScreenFlashNotificationOverlayView, true);
+        }
+    }
+
+    private void fadeOutScreenNotificationOverlayViewMainThread() {
+        if (DEBUG) Log.d(LOG_TAG, "fadeOutScreenNotificationOverlayViewMainThread");
+        if (mScreenFlashNotificationOverlayView != null) {
+            fadeScreenNotificationOverlayViewMainThread(mScreenFlashNotificationOverlayView, false);
+        }
+    }
+
+    private void fadeScreenNotificationOverlayViewMainThread(View view, boolean in) {
+        ObjectAnimator fade = ObjectAnimator.ofFloat(view, "alpha", in ? 0.0f : 1.0f,
+                in ? 1.0f : 0.0f);
+        fade.setInterpolator(new AccelerateInterpolator());
+        fade.setAutoCancel(true);
+        fade.setDuration(SCREEN_FADE_DURATION_MS);
+        fade.start();
+    }
+
+    private void hideScreenNotificationOverlayViewMainThread() {
+        if (DEBUG) Log.d(LOG_TAG, "hideScreenNotificationOverlayViewMainThread");
+        if (mScreenFlashNotificationOverlayView != null) {
+            mScreenFlashNotificationOverlayView.setVisibility(View.GONE);
+            mContext.getSystemService(WindowManager.class).removeView(
+                    mScreenFlashNotificationOverlayView);
+            mScreenFlashNotificationOverlayView = null;
+        }
+    }
+
+    private View getScreenNotificationOverlayView(@ColorInt int color) {
+        View screenNotificationOverlayView = new FrameLayout(mContext);
+        screenNotificationOverlayView.setBackgroundColor(color);
+        screenNotificationOverlayView.setAlpha(0.0f);
+        return screenNotificationOverlayView;
+    }
+
+    @ColorInt
+    private int getScreenFlashColorPreference(@FlashNotificationReason int reason,
+            String reasonPkg) {
+        // TODO(b/267121466) implement getting color per reason, reasonPkg basis
+        return getScreenFlashColorPreference();
+    }
+
+    @ColorInt
+    private int getScreenFlashColorPreference(@FlashNotificationReason int reason) {
+        // TODO(b/267121466) implement getting color per reason basis
+        return getScreenFlashColorPreference();
+    }
+
+    @ColorInt
+    private int getScreenFlashColorPreference() {
+        return Settings.System.getIntForUser(mContext.getContentResolver(),
+                SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, SCREEN_DEFAULT_COLOR_WITH_ALPHA,
+                UserHandle.USER_CURRENT);
+    }
+
+    private void startFlashNotification(@NonNull FlashNotification flashNotification) {
+        final int type = flashNotification.mType;
+        final String tag = flashNotification.mTag;
+        if (DEBUG) Log.i(LOG_TAG, "startFlashNotification: type=" + type + ", tag=" + tag);
+
+        if (!(mIsCameraFlashNotificationEnabled
+                || mIsScreenFlashNotificationEnabled
+                || flashNotification.mForceStartScreenFlash)) {
+            if (DEBUG) Log.d(LOG_TAG, "Flash notification is disabled");
+            return;
+        }
+
+        if (mIsCameraOpened) {
+            if (DEBUG) Log.d(LOG_TAG, "Since camera for torch is opened, block notification.");
+            return;
+        }
+
+        if (mIsCameraFlashNotificationEnabled && mCameraId == null) {
+            prepareForCameraFlashNotification();
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            synchronized (mFlashNotifications) {
+                if (type == TYPE_DEFAULT || type == TYPE_LONG_PREVIEW) {
+                    if (mCurrentFlashNotification != null) {
+                        if (DEBUG) {
+                            Log.i(LOG_TAG,
+                                    "Default type of flash notification can not work because "
+                                            + "previous flash notification is working");
+                        }
+                    } else {
+                        startFlashNotificationLocked(flashNotification);
+                    }
+                } else if (type == TYPE_SEQUENCE) {
+                    if (mCurrentFlashNotification != null) {
+                        removeFlashNotificationLocked(tag);
+                        stopFlashNotificationLocked();
+                    }
+                    mFlashNotifications.addFirst(flashNotification);
+                    startNextFlashNotificationLocked();
+                } else {
+                    Log.e(LOG_TAG, "Unavailable flash notification type");
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @GuardedBy("mFlashNotifications")
+    private FlashNotification removeFlashNotificationLocked(String tag) {
+        ListIterator<FlashNotification> iterator = mFlashNotifications.listIterator(0);
+        while (iterator.hasNext()) {
+            FlashNotification notification = iterator.next();
+            if (notification != null && notification.mTag.equals(tag)) {
+                iterator.remove();
+                notification.tryUnlinkToDeath();
+                if (DEBUG) {
+                    Log.i(LOG_TAG,
+                            "removeFlashNotificationLocked: tag=" + notification.mTag);
+                }
+                return notification;
+            }
+        }
+        if (mCurrentFlashNotification != null && mCurrentFlashNotification.mTag.equals(tag)) {
+            mCurrentFlashNotification.tryUnlinkToDeath();
+            return mCurrentFlashNotification;
+        }
+        return null;
+    }
+
+    @GuardedBy("mFlashNotifications")
+    private void stopFlashNotificationLocked() {
+        if (mThread != null) {
+            if (DEBUG) {
+                Log.i(LOG_TAG,
+                        "stopFlashNotificationLocked: tag=" + mThread.mFlashNotification.mTag);
+            }
+            mThread.cancel();
+            mThread = null;
+        }
+        doCameraFlashNotificationOff();
+        doScreenFlashNotificationOff();
+    }
+
+    @GuardedBy("mFlashNotifications")
+    private void startNextFlashNotificationLocked() {
+        if (DEBUG) Log.i(LOG_TAG, "startNextFlashNotificationLocked");
+        if (mFlashNotifications.size() <= 0) {
+            mCurrentFlashNotification = null;
+            return;
+        }
+        startFlashNotificationLocked(mFlashNotifications.getFirst());
+    }
+
+    @GuardedBy("mFlashNotifications")
+    private void startFlashNotificationLocked(@NonNull final FlashNotification notification) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "startFlashNotificationLocked: type=" + notification.mType + ", tag="
+                    + notification.mTag);
+        }
+        mCurrentFlashNotification = notification;
+        mThread = new FlashNotificationThread(notification);
+        mFlashNotificationHandler.post(mThread);
+    }
+
+    private boolean isDozeMode() {
+        return mDisplayState == Display.STATE_DOZE || mDisplayState == Display.STATE_DOZE_SUSPEND;
+    }
+
+    private void doCameraFlashNotificationOn() {
+        if (mIsCameraFlashNotificationEnabled && !mIsTorchOn) {
+            doCameraFlashNotification(true);
+        }
+        if (DEBUG) {
+            Log.i(LOG_TAG, "doCameraFlashNotificationOn: "
+                    + "isCameraFlashNotificationEnabled=" + mIsCameraFlashNotificationEnabled
+                    + ", isTorchOn=" + mIsTorchOn
+                    + ", isTorchTouched=" + mIsTorchTouched);
+        }
+    }
+
+    private void doCameraFlashNotificationOff() {
+        if (mIsTorchTouched) {
+            doCameraFlashNotification(false);
+        }
+        if (DEBUG) {
+            Log.i(LOG_TAG, "doCameraFlashNotificationOff: "
+                    + "isCameraFlashNotificationEnabled=" + mIsCameraFlashNotificationEnabled
+                    + ", isTorchOn=" + mIsTorchOn
+                    + ", isTorchTouched=" + mIsTorchTouched);
+        }
+    }
+
+    private void doScreenFlashNotificationOn(@ColorInt int color, boolean forceStartScreenFlash) {
+        final boolean isDoze = isDozeMode();
+        if ((mIsScreenFlashNotificationEnabled || forceStartScreenFlash) && !isDoze) {
+            showScreenNotificationOverlayView(color);
+        }
+        if (DEBUG) {
+            Log.i(LOG_TAG, "doScreenFlashNotificationOn: "
+                    + "isScreenFlashNotificationEnabled=" + mIsScreenFlashNotificationEnabled
+                    + ", isDozeMode=" + isDoze
+                    + ", color=" + Integer.toHexString(color));
+        }
+    }
+
+    private void doScreenFlashNotificationOff() {
+        hideScreenNotificationOverlayView();
+        if (DEBUG) {
+            Log.i(LOG_TAG, "doScreenFlashNotificationOff: "
+                    + "isScreenFlashNotificationEnabled=" + mIsScreenFlashNotificationEnabled);
+        }
+    }
+
+    private void doCameraFlashNotification(boolean on) {
+        if (DEBUG) Log.d(LOG_TAG, "doCameraFlashNotification: " + on + " mCameraId : " + mCameraId);
+        if (mCameraManager != null && mCameraId != null) {
+            try {
+                mCameraManager.setTorchMode(mCameraId, on);
+                mIsTorchTouched = on;
+            } catch (CameraAccessException e) {
+                Log.e(LOG_TAG, "Failed to setTorchMode: " + e);
+            }
+        } else {
+            Log.e(LOG_TAG, "Can not use camera flash notification, please check CameraManager!");
+        }
+    }
+
+    private static class FlashNotification {
+        // Tag could be the requesting package name or constants like TAG_PREVIEW and TAG_ALARM.
+        private final String mTag;
+        @FlashNotificationType
+        private final int mType;
+        private final int mOnDuration;
+        private final int mOffDuration;
+        @ColorInt
+        private final int mColor;
+        private int mRepeat;
+        @Nullable
+        private final IBinder mToken;
+        @Nullable
+        private final IBinder.DeathRecipient mDeathRecipient;
+        private final boolean mForceStartScreenFlash;
+
+        private FlashNotification(String tag, @FlashNotificationType int type,
+                @ColorInt int color) {
+            this(tag, type, color, null, null);
+        }
+
+        private FlashNotification(String tag, @FlashNotificationType int type, @ColorInt int color,
+                IBinder token, IBinder.DeathRecipient deathRecipient) {
+            mType = type;
+            mTag = tag;
+            mColor = color;
+            mToken = token;
+            mDeathRecipient = deathRecipient;
+
+            switch (type) {
+                case TYPE_SEQUENCE:
+                    mOnDuration = TYPE_SEQUENCE_ON_MS;
+                    mOffDuration = TYPE_SEQUENCE_OFF_MS;
+                    mRepeat = 0; // indefinite
+                    mForceStartScreenFlash = false;
+                    break;
+                case TYPE_LONG_PREVIEW:
+                    mOnDuration = TYPE_LONG_PREVIEW_ON_MS;
+                    mOffDuration = TYPE_LONG_PREVIEW_OFF_MS;
+                    mRepeat = 1;
+                    mForceStartScreenFlash = true;
+                    break;
+                case TYPE_DEFAULT:
+                default:
+                    mOnDuration = TYPE_DEFAULT_ON_MS;
+                    mOffDuration = TYPE_DEFAULT_OFF_MS;
+                    mRepeat = 2;
+                    mForceStartScreenFlash = false;
+                    break;
+            }
+        }
+
+        boolean tryLinkToDeath() {
+            if (mToken == null || mDeathRecipient == null) return false;
+
+            try {
+                mToken.linkToDeath(mDeathRecipient, 0);
+                return true;
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "RemoteException", e);
+                return false;
+            }
+        }
+
+        boolean tryUnlinkToDeath() {
+            if (mToken == null || mDeathRecipient == null) return false;
+            try {
+                mToken.unlinkToDeath(mDeathRecipient, 0);
+                return true;
+            } catch (Exception ignored) {
+                return false;
+            }
+        }
+    }
+
+    private class FlashNotificationThread extends Thread {
+        private final FlashNotification mFlashNotification;
+        private boolean mForceStop;
+        @ColorInt
+        private int mColor = Color.TRANSPARENT;
+        private boolean mShouldDoScreenFlash = false;
+        private boolean mShouldDoCameraFlash = false;
+
+        private FlashNotificationThread(@NonNull FlashNotification flashNotification) {
+            mFlashNotification = flashNotification;
+            mForceStop = false;
+        }
+
+        @Override
+        public void run() {
+            if (DEBUG) Log.d(LOG_TAG, "run started: " + mFlashNotification.mTag);
+            Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
+            mColor = mFlashNotification.mColor;
+            mShouldDoScreenFlash = (Color.alpha(mColor) != Color.TRANSPARENT)
+                    || mFlashNotification.mForceStartScreenFlash;
+            mShouldDoCameraFlash = mFlashNotification.mType != TYPE_LONG_PREVIEW;
+            synchronized (this) {
+                mWakeLock.acquire(WAKE_LOCK_TIMEOUT_MS);
+                try {
+                    startFlashNotification();
+                } finally {
+                    doScreenFlashNotificationOff();
+                    doCameraFlashNotificationOff();
+                    try {
+                        mWakeLock.release();
+                    } catch (RuntimeException e) {
+                        Log.e(LOG_TAG, "Error while releasing FlashNotificationsController"
+                                + " wakelock (already released by the system?)");
+                    }
+                }
+            }
+            synchronized (mFlashNotifications) {
+                if (mThread == this) {
+                    mThread = null;
+                }
+                // Unlink to death recipient for not interrupted flash notification. For flash
+                // notification interrupted and stopped by stopFlashNotification(), unlink to
+                // death is already handled in stopFlashNotification().
+                if (!mForceStop) {
+                    mFlashNotification.tryUnlinkToDeath();
+                    mCurrentFlashNotification = null;
+                }
+            }
+            if (DEBUG) Log.d(LOG_TAG, "run finished: " + mFlashNotification.mTag);
+        }
+
+        private void startFlashNotification() {
+            synchronized (this) {
+                while (!mForceStop) {
+                    if (mFlashNotification.mType != TYPE_SEQUENCE
+                            && mFlashNotification.mRepeat >= 0) {
+                        if (mFlashNotification.mRepeat-- == 0) {
+                            break;
+                        }
+                    }
+                    if (mShouldDoScreenFlash) {
+                        doScreenFlashNotificationOn(mColor,
+                                mFlashNotification.mForceStartScreenFlash);
+                    }
+                    if (mShouldDoCameraFlash) {
+                        doCameraFlashNotificationOn();
+                    }
+                    delay(mFlashNotification.mOnDuration);
+                    doScreenFlashNotificationOff();
+                    doCameraFlashNotificationOff();
+                    if (mForceStop) {
+                        break;
+                    }
+                    delay(mFlashNotification.mOffDuration);
+                }
+            }
+        }
+
+        void cancel() {
+            if (DEBUG) Log.d(LOG_TAG, "run canceled: " + mFlashNotification.mTag);
+            synchronized (this) {
+                mThread.mForceStop = true;
+                mThread.notify();
+            }
+        }
+
+        private void delay(long duration) {
+            if (duration > 0) {
+                long bedtime = duration + SystemClock.uptimeMillis();
+                do {
+                    try {
+                        this.wait(duration);
+                    } catch (InterruptedException ignored) {
+                    }
+                    if (mForceStop) {
+                        break;
+                    }
+                    duration = bedtime - SystemClock.uptimeMillis();
+                } while (duration > 0);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    class FlashBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            // Some system services not properly initiated before boot complete. Should do the
+            // initialization after receiving ACTION_BOOT_COMPLETED.
+            if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+                if (UserHandle.myUserId() != ActivityManager.getCurrentUser()) {
+                    return;
+                }
+
+                mIsCameraFlashNotificationEnabled = Settings.System.getIntForUser(
+                        mContext.getContentResolver(), SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0,
+                        UserHandle.USER_CURRENT) != 0;
+                if (mIsCameraFlashNotificationEnabled) {
+                    prepareForCameraFlashNotification();
+                } else {
+                    if (mCameraManager != null) {
+                        mCameraManager.unregisterTorchCallback(mTorchCallback);
+                    }
+                }
+
+                final AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+                if (audioManager != null) {
+                    audioManager.registerAudioPlaybackCallback(mAudioPlaybackCallback,
+                            mCallbackHandler);
+                }
+
+                mCameraManager = mContext.getSystemService(CameraManager.class);
+                mCameraManager.registerAvailabilityCallback(mTorchAvailabilityCallback,
+                        mCallbackHandler);
+
+            } else if (ACTION_FLASH_NOTIFICATION_START_PREVIEW.equals(intent.getAction())) {
+                if (DEBUG) Log.i(LOG_TAG, "ACTION_FLASH_NOTIFICATION_START_PREVIEW");
+                final int color = intent.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR,
+                        Color.TRANSPARENT);
+                final int type = intent.getIntExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE,
+                        PREVIEW_TYPE_SHORT);
+                if (type == PREVIEW_TYPE_LONG) {
+                    startFlashNotificationLongPreview(color);
+                } else if (type == PREVIEW_TYPE_SHORT) {
+                    startFlashNotificationShortPreview();
+                }
+            } else if (ACTION_FLASH_NOTIFICATION_STOP_PREVIEW.equals(intent.getAction())) {
+                if (DEBUG) Log.i(LOG_TAG, "ACTION_FLASH_NOTIFICATION_STOP_PREVIEW");
+                stopFlashNotificationLongPreview();
+            }
+        }
+    }
+
+    private final class FlashContentObserver extends ContentObserver {
+        private final Uri mCameraFlashNotificationUri = Settings.System.getUriFor(
+                SETTING_KEY_CAMERA_FLASH_NOTIFICATION);
+        private final Uri mScreenFlashNotificationUri = Settings.System.getUriFor(
+                SETTING_KEY_SCREEN_FLASH_NOTIFICATION);
+
+        FlashContentObserver(Handler handler) {
+            super(handler);
+        }
+
+        void register(ContentResolver contentResolver) {
+            contentResolver.registerContentObserver(mCameraFlashNotificationUri, false, this,
+                    UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(mScreenFlashNotificationUri, false, this,
+                    UserHandle.USER_ALL);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mCameraFlashNotificationUri.equals(uri)) {
+                mIsCameraFlashNotificationEnabled = Settings.System.getIntForUser(
+                        mContext.getContentResolver(), SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0,
+                        UserHandle.USER_CURRENT) != 0;
+                if (mIsCameraFlashNotificationEnabled) {
+                    prepareForCameraFlashNotification();
+                } else {
+                    mIsTorchOn = false;
+                    if (mCameraManager != null) {
+                        mCameraManager.unregisterTorchCallback(mTorchCallback);
+                    }
+                }
+            } else if (mScreenFlashNotificationUri.equals(uri)) {
+                mIsScreenFlashNotificationEnabled = Settings.System.getIntForUser(
+                        mContext.getContentResolver(), SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0,
+                        UserHandle.USER_CURRENT) != 0;
+            }
+        }
+    }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
index 54cdb04..2530338 100644
--- a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
@@ -19,10 +19,12 @@
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.content.ComponentName;
 import android.content.Context;
+import android.hardware.display.DisplayManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
@@ -47,6 +49,8 @@
 
     private final Object mLock;
 
+    private final Context mContext;
+
     // Used to determine if we should notify AccessibilityManager clients of updates.
     // TODO(254545943): Separate this so each display id has its own state. Currently there is no
     // way to identify from AccessibilityManager which proxy state should be returned.
@@ -57,9 +61,12 @@
 
     private AccessibilityWindowManager mA11yWindowManager;
 
-    ProxyManager(Object lock, AccessibilityWindowManager awm) {
+    private AccessibilityInputFilter mA11yInputFilter;
+
+    ProxyManager(Object lock, AccessibilityWindowManager awm, Context context) {
         mLock = lock;
         mA11yWindowManager = awm;
+        mContext = context;
     }
 
     /**
@@ -109,6 +116,9 @@
             connection.mSystemSupport.onClientChangeLocked(true);
         }
 
+        if (mA11yInputFilter != null) {
+            mA11yInputFilter.disableFeaturesForDisplayIfInstalled(displayId);
+        }
         connection.initializeServiceInterface(client);
     }
 
@@ -120,14 +130,25 @@
     }
 
     private boolean clearConnection(int displayId) {
+        boolean removed = false;
         synchronized (mLock) {
             if (mProxyA11yServiceConnections.contains(displayId)) {
                 mProxyA11yServiceConnections.remove(displayId);
-                return true;
+                removed = true;
             }
         }
-        mA11yWindowManager.stopTrackingDisplayProxy(displayId);
-        return false;
+        if (removed) {
+            mA11yWindowManager.stopTrackingDisplayProxy(displayId);
+            if (mA11yInputFilter != null) {
+                final DisplayManager displayManager = (DisplayManager)
+                        mContext.getSystemService(Context.DISPLAY_SERVICE);
+                final Display proxyDisplay = displayManager.getDisplay(displayId);
+                if (proxyDisplay != null) {
+                    mA11yInputFilter.enableFeaturesForDisplayIfInstalled(proxyDisplay);
+                }
+            }
+        }
+        return removed;
     }
 
     /**
@@ -251,4 +272,8 @@
             proxy.notifyClearAccessibilityNodeInfoCache();
         }
     }
+
+    void setAccessibilityInputFilter(AccessibilityInputFilter filter) {
+        mA11yInputFilter = filter;
+    }
 }
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java b/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java
new file mode 100644
index 0000000..ed45e7b
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/AlwaysOnMagnificationFeatureFlag.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.accessibility.magnification;
+
+import android.provider.DeviceConfig;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Encapsulates the feature flags for always on magnification. {@see DeviceConfig}
+ *
+ * @hide
+ */
+public class AlwaysOnMagnificationFeatureFlag {
+
+    private static final String NAMESPACE = DeviceConfig.NAMESPACE_WINDOW_MANAGER;
+    private static final String FEATURE_NAME_ENABLE_ALWAYS_ON_MAGNIFICATION =
+            "AlwaysOnMagnifier__enable_always_on_magnifier";
+
+    private AlwaysOnMagnificationFeatureFlag() {}
+
+    /** Returns true if the feature flag is enabled for always on magnification */
+    public static boolean isAlwaysOnMagnificationEnabled() {
+        return DeviceConfig.getBoolean(
+                NAMESPACE,
+                FEATURE_NAME_ENABLE_ALWAYS_ON_MAGNIFICATION,
+                /* defaultValue= */ false);
+    }
+
+    /** Sets the feature flag. Only used for testing; requires shell permissions. */
+    @VisibleForTesting
+    public static boolean setAlwaysOnMagnificationEnabled(boolean isEnabled) {
+        return DeviceConfig.setProperty(
+                NAMESPACE,
+                FEATURE_NAME_ENABLE_ALWAYS_ON_MAGNIFICATION,
+                Boolean.toString(isEnabled),
+                /* makeDefault= */ false);
+    }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index 37069dc..d7c5b5d 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -52,10 +52,12 @@
 import android.view.animation.DecelerateInterpolator;
 
 import com.android.internal.R;
+import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
+import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.accessibility.AccessibilityTraceManager;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -98,7 +100,8 @@
     private final Rect mTempRect = new Rect();
     // Whether the following typing focus feature for magnification is enabled.
     private boolean mMagnificationFollowTypingEnabled = true;
-
+    // Whether the always on magnification feature is enabled.
+    private boolean mAlwaysOnMagnificationEnabled = false;
     private final DisplayManagerInternal mDisplayManagerInternal;
 
     /**
@@ -290,18 +293,15 @@
 
         @Override
         public void onDisplaySizeChanged() {
-            // Treat as context change and reset
-            final Message m = PooledLambda.obtainMessage(
-                    FullScreenMagnificationController::resetIfNeeded,
-                    FullScreenMagnificationController.this, mDisplayId, true);
-            mControllerCtx.getHandler().sendMessage(m);
+            // Treat as context change
+            onUserContextChanged();
         }
 
         @Override
         public void onUserContextChanged() {
             final Message m = PooledLambda.obtainMessage(
-                    FullScreenMagnificationController::resetIfNeeded,
-                    FullScreenMagnificationController.this, mDisplayId, true);
+                    FullScreenMagnificationController::onUserContextChanged,
+                    FullScreenMagnificationController.this, mDisplayId);
             mControllerCtx.getHandler().sendMessage(m);
         }
 
@@ -794,6 +794,33 @@
         return mMagnificationFollowTypingEnabled;
     }
 
+    void setAlwaysOnMagnificationEnabled(boolean enabled) {
+        mAlwaysOnMagnificationEnabled = enabled;
+    }
+
+    boolean isAlwaysOnMagnificationEnabled() {
+        return mAlwaysOnMagnificationEnabled;
+    }
+
+    /**
+     * if the magnifier with given displayId is activated:
+     * 1. if {@link #isAlwaysOnMagnificationEnabled()}, zoom the magnifier to 100%,
+     * 2. otherwise, reset the magnification.
+     *
+     * @param displayId The logical display id.
+     */
+    void onUserContextChanged(int displayId) {
+        synchronized (mLock) {
+            if (isAlwaysOnMagnificationEnabled()) {
+                setScaleAndCenter(displayId, 1.0f, Float.NaN, Float.NaN,
+                        true,
+                        AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
+            } else {
+                reset(displayId, true);
+            }
+        }
+    }
+
     /**
      * Remove the display magnification with given id.
      *
@@ -1157,11 +1184,14 @@
     }
 
     /**
-     * Persists the default display magnification scale to the current user's settings.
+     * Persists the default display magnification scale to the current user's settings
+     * <strong>if scale is >= {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}</strong>.
+     * We assume if the scale is < {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}, there
+     * will be no obvious magnification effect.
      */
     public void persistScale(int displayId) {
         final float scale = getScale(Display.DEFAULT_DISPLAY);
-        if (scale < 2.0f) {
+        if (scale < MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) {
             return;
         }
         mScaleProvider.putScale(scale, displayId);
@@ -1176,7 +1206,8 @@
      */
     public float getPersistedScale(int displayId) {
         return MathUtils.constrain(mScaleProvider.getScale(displayId),
-                2.0f, MagnificationScaleProvider.MAX_SCALE);
+                MagnificationConstants.PERSISTED_SCALE_MIN_VALUE,
+                MagnificationScaleProvider.MAX_SCALE);
     }
 
     /**
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 6bf37a1..9c84c04 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -445,12 +445,12 @@
      */
     final class ViewportDraggingState implements State {
 
-        /** Whether to disable zoom after dragging ends */
-        @VisibleForTesting boolean mActivatedBeforeDrag;
-        /** Whether to restore scale after dragging ends */
-        private boolean mZoomedInTemporary;
-        /** The cached scale for recovering after dragging ends */
-        private float mScaleBeforeZoomedInTemporary;
+        /**
+         * The cached scale for recovering after dragging ends.
+         * If the scale >= 1.0, the magnifier needs to recover to scale.
+         * Otherwise, the magnifier should be disabled.
+         */
+        @VisibleForTesting float mScaleToRecoverAfterDraggingEnd = Float.NaN;
 
         private boolean mLastMoveOutsideMagnifiedRegion;
 
@@ -460,8 +460,7 @@
             final int action = event.getActionMasked();
             switch (action) {
                 case ACTION_POINTER_DOWN: {
-                    clear();
-                    transitionTo(mPanningScalingState);
+                    clearAndTransitToPanningScalingState();
                 }
                 break;
                 case ACTION_MOVE: {
@@ -484,14 +483,18 @@
 
                 case ACTION_UP:
                 case ACTION_CANCEL: {
-                    if (mActivatedBeforeDrag) {
-                        if (mZoomedInTemporary) {
-                            zoomToScale(mScaleBeforeZoomedInTemporary, event.getX(), event.getY());
-                        }
+                    // If mScaleToRecoverAfterDraggingEnd >= 1.0, the dragging state is triggered
+                    // by zoom in temporary, and the magnifier needs to recover to original scale
+                    // after exiting dragging state.
+                    // Otherwise, the magnifier should be disabled.
+                    if (mScaleToRecoverAfterDraggingEnd >= 1.0f) {
+                        zoomToScale(mScaleToRecoverAfterDraggingEnd, event.getX(),
+                                event.getY());
                     } else {
                         zoomOff();
                     }
                     clear();
+                    mScaleToRecoverAfterDraggingEnd = Float.NaN;
                     transitionTo(mDetectingState);
                 }
                     break;
@@ -504,27 +507,49 @@
             }
         }
 
-        public void prepareForZoomInTemporary() {
-            mViewportDraggingState.mActivatedBeforeDrag =
-                    mFullScreenMagnificationController.isActivated(mDisplayId);
+        private boolean isAlwaysOnMagnificationEnabled() {
+            return mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled();
+        }
 
-            mViewportDraggingState.mZoomedInTemporary = true;
-            mViewportDraggingState.mScaleBeforeZoomedInTemporary =
-                    mFullScreenMagnificationController.getScale(mDisplayId);
+        public void prepareForZoomInTemporary(boolean shortcutTriggered) {
+            boolean shouldRecoverAfterDraggingEnd;
+            if (mFullScreenMagnificationController.isActivated(mDisplayId)) {
+                // For b/267210808, if always-on feature is not enabled, we keep the expected
+                // behavior. If users tap shortcut and then tap-and-hold to zoom in temporary,
+                // the magnifier should be disabled after release.
+                // If always-on feature is enabled, in the same scenario the magnifier would
+                // zoom to 1.0 and keep activated.
+                if (shortcutTriggered) {
+                    shouldRecoverAfterDraggingEnd = isAlwaysOnMagnificationEnabled();
+                } else {
+                    shouldRecoverAfterDraggingEnd = true;
+                }
+            } else {
+                shouldRecoverAfterDraggingEnd = false;
+            }
+
+            mScaleToRecoverAfterDraggingEnd = shouldRecoverAfterDraggingEnd
+                    ? mFullScreenMagnificationController.getScale(mDisplayId) : Float.NaN;
+        }
+
+        private void clearAndTransitToPanningScalingState() {
+            final float scaleToRecovery = mScaleToRecoverAfterDraggingEnd;
+            clear();
+            mScaleToRecoverAfterDraggingEnd = scaleToRecovery;
+            transitionTo(mPanningScalingState);
         }
 
         @Override
         public void clear() {
             mLastMoveOutsideMagnifiedRegion = false;
 
-            mZoomedInTemporary = false;
-            mScaleBeforeZoomedInTemporary = 1.0f;
+            mScaleToRecoverAfterDraggingEnd = Float.NaN;
         }
 
         @Override
         public String toString() {
             return "ViewportDraggingState{"
-                    + "mActivatedBeforeDrag=" + mActivatedBeforeDrag
+                    + "mScaleToRecoverAfterDraggingEnd=" + mScaleToRecoverAfterDraggingEnd
                     + ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion
                     + '}';
         }
@@ -921,13 +946,14 @@
         void transitionToViewportDraggingStateAndClear(MotionEvent down) {
 
             if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
+            final boolean shortcutTriggered = mShortcutTriggered;
             clear();
 
             // Triple tap and hold also belongs to triple tap event.
             final boolean enabled = !isActivated();
             logMagnificationTripleTap(enabled);
 
-            mViewportDraggingState.prepareForZoomInTemporary();
+            mViewportDraggingState.prepareForZoomInTemporary(shortcutTriggered);
 
             zoomInTemporary(down.getX(), down.getY());
 
@@ -992,9 +1018,8 @@
                 mFullScreenMagnificationController.getPersistedScale(mDisplayId),
                 MIN_SCALE, MAX_SCALE);
 
-        final float scale = MathUtils.constrain(Math.max(currentScale + 1.0f, persistedScale),
-                MIN_SCALE, MAX_SCALE);
-
+        final boolean isActivated = mFullScreenMagnificationController.isActivated(mDisplayId);
+        final float scale = isActivated ? (currentScale + 1.0f) : persistedScale;
         zoomToScale(scale, centerX, centerY);
     }
 
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 558c71b..a6e6bd7 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -677,6 +677,19 @@
         getFullScreenMagnificationController().setMagnificationFollowTypingEnabled(enabled);
     }
 
+    /**
+     * Called when the always on magnification feature is switched.
+     *
+     * @param enabled Enable the always on magnification feature
+     */
+    public void setAlwaysOnMagnificationEnabled(boolean enabled) {
+        getFullScreenMagnificationController().setAlwaysOnMagnificationEnabled(enabled);
+    }
+
+    public boolean isAlwaysOnMagnificationFeatureFlagEnabled() {
+        return AlwaysOnMagnificationFeatureFlag.isAlwaysOnMagnificationEnabled();
+    }
+
     private DisableMagnificationCallback getDisableMagnificationEndRunnableLocked(
             int displayId) {
         return mMagnificationEndRunnableSparseArray.get(displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index 2d5f894..d9391f4 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -46,6 +46,7 @@
 import android.view.accessibility.IWindowMagnificationConnectionCallback;
 import android.view.accessibility.MagnificationAnimationCallback;
 
+import com.android.internal.accessibility.common.MagnificationConstants;
 import com.android.internal.accessibility.util.AccessibilityStatsLogUtils;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -716,17 +717,20 @@
      */
     float getPersistedScale(int displayId) {
         return MathUtils.constrain(mScaleProvider.getScale(displayId),
-                2.0f, MagnificationScaleProvider.MAX_SCALE);
+                MagnificationConstants.PERSISTED_SCALE_MIN_VALUE,
+                MagnificationScaleProvider.MAX_SCALE);
     }
 
     /**
      * Persists the default display magnification scale to the current user's settings
-     *     <strong>if scale is >= 2.0</strong>. Only the
-     * value of the default display is persisted in user's settings.
+     * <strong>if scale is >= {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}</strong>.
+     * We assume if the scale is < {@link MagnificationConstants.PERSISTED_SCALE_MIN_VALUE}, there
+     * will be no obvious magnification effect.
+     * Only the value of the default display is persisted in user's settings.
      */
     void persistScale(int displayId) {
         float scale = getScale(displayId);
-        if (scale < 2.0f) {
+        if (scale < MagnificationConstants.PERSISTED_SCALE_MIN_VALUE) {
             return;
         }
         mScaleProvider.putScale(scale, displayId);
diff --git a/services/api/current.txt b/services/api/current.txt
index 70ee3b8..a4deed3 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -227,8 +227,9 @@
 
 package com.android.server.security {
 
-  public final class FileIntegrityLocal {
-    method public static void setUpFsVerity(@NonNull String) throws java.io.IOException;
+  public final class FileIntegrity {
+    method public static void setUpFsVerity(@NonNull java.io.File) throws java.io.IOException;
+    method public static void setUpFsVerity(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException;
   }
 
 }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 7df4899..e86d997 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1028,8 +1028,9 @@
             intent.setComponent(provider.getInfoLocked(mContext).configure);
             intent.setFlags(secureFlags);
 
-            final ActivityOptions options = ActivityOptions.makeBasic();
-            options.setIgnorePendingIntentCreatorForegroundState(true);
+            final ActivityOptions options =
+                    ActivityOptions.makeBasic().setPendingIntentCreatorBackgroundActivityStartMode(
+                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED);
 
             // All right, create the sender.
             final long identity = Binder.clearCallingIdentity();
diff --git a/services/art-profile b/services/art-profile
index 2bb85a4..132b9ab 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -20484,12 +20484,12 @@
 Lcom/android/server/usage/UsageStatsShellCommand;
 Lcom/android/server/usage/UserUsageStatsService$StatsUpdatedListener;
 Lcom/android/server/usb/UsbAlsaJackDetector;
+Lcom/android/server/usb/UsbAlsaMidiDevice$2;
+Lcom/android/server/usb/UsbAlsaMidiDevice$3;
+Lcom/android/server/usb/UsbAlsaMidiDevice$InputReceiverProxy;
+Lcom/android/server/usb/UsbAlsaMidiDevice;
 Lcom/android/server/usb/UsbDeviceManager;
 Lcom/android/server/usb/UsbHostManager;
-Lcom/android/server/usb/UsbMidiDevice$2;
-Lcom/android/server/usb/UsbMidiDevice$3;
-Lcom/android/server/usb/UsbMidiDevice$InputReceiverProxy;
-Lcom/android/server/usb/UsbMidiDevice;
 Lcom/android/server/usb/descriptors/UsbDescriptor;
 Lcom/android/server/usb/descriptors/UsbInterfaceDescriptor;
 Lcom/android/server/utils/AlarmQueue$1;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 6b61e97..a3c09ab 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -150,6 +150,12 @@
     @NonNull
     final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver;
 
+    /**
+     * Object used to set the name of the field classification service.
+     */
+    @NonNull
+    final FrameworkResourcesServiceNameResolver mFieldClassificationResolver;
+
     private final AutoFillUI mUi;
 
     private final LocalLog mRequestsHistory = new LocalLog(20);
@@ -193,6 +199,32 @@
 
     final AugmentedAutofillState mAugmentedAutofillState = new AugmentedAutofillState();
 
+    /**
+     * Lock used to synchronize access to flags.
+     */
+    private final Object mFlagLock = new Object();
+
+    // Flag holders for Autofill PCC classification
+
+    @GuardedBy("mFlagLock")
+    private boolean mPccClassificationEnabled;
+
+    @GuardedBy("mFlagLock")
+    private boolean mPccPreferProviderOverPcc;
+
+    @GuardedBy("mFlagLock")
+    private boolean mPccUseFallbackDetection;
+
+    @GuardedBy("mFlagLock")
+    private String mPccProviderHints;
+
+    // Default flag values for Autofill PCC
+
+    private static final String DEFAULT_PCC_FEATURE_PROVIDER_HINTS = "";
+    private static final boolean DEFAULT_PREFER_PROVIDER_OVER_PCC = true;
+
+    private static final boolean DEFAULT_PCC_USE_FALLBACK = true;
+
     public AutofillManagerService(Context context) {
         super(context,
                 new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE),
@@ -219,6 +251,15 @@
         mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
                 (u, s, t) -> onAugmentedServiceNameChanged(u, s, t));
 
+        mFieldClassificationResolver = new FrameworkResourcesServiceNameResolver(getContext(),
+                com.android.internal.R.string.config_defaultFieldClassificationService);
+        if (sVerbose) {
+            Slog.v(TAG, "Resolving FieldClassificationService to serviceName: "
+                    + mFieldClassificationResolver.readServiceName(0));
+        }
+        mFieldClassificationResolver.setOnTemporaryServiceNameChangedCallback(
+                (u, s, t) -> onFieldClassificationServiceNameChanged(u, s, t));
+
         if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) {
             final List<UserInfo> users = getSupportedUsers();
             for (int i = 0; i < users.size(); i++) {
@@ -302,6 +343,10 @@
                 case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
                 case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
                 case AutofillFeatureFlags.DEVICE_CONFIG_AUGMENTED_SERVICE_REQUEST_TIMEOUT:
+                case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED:
+                case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS:
+                case AutofillFeatureFlags.DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC:
+                case AutofillFeatureFlags.DEVICE_CONFIG_PCC_USE_FALLBACK:
                     setDeviceConfigProperties();
                     break;
                 case AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
@@ -328,6 +373,20 @@
         }
     }
 
+    private void onFieldClassificationServiceNameChanged(
+            @UserIdInt int userId, @Nullable String serviceName, boolean isTemporary) {
+        synchronized (mLock) {
+            final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+            if (service == null) {
+                // If we cannot get the service from the services cache, it will call
+                // updateRemoteAugmentedAutofillService() finally. Skip call this update again.
+                getServiceForUserLocked(userId);
+            } else {
+                service.updateRemoteFieldClassificationService();
+            }
+        }
+    }
+
     @Override // from AbstractMasterSystemService
     protected AutofillManagerServiceImpl newServiceLocked(@UserIdInt int resolvedUserId,
             boolean disabled) {
@@ -579,13 +638,38 @@
                     AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES,
                     AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM);
             if (verbose) {
-                Slog.v(mTag, "setDeviceConfigProperties(): "
+                Slog.v(mTag, "setDeviceConfigProperties() for AugmentedAutofill: "
                         + "augmentedIdleTimeout=" + mAugmentedServiceIdleUnbindTimeoutMs
                         + ", augmentedRequestTimeout=" + mAugmentedServiceRequestTimeoutMs
                         + ", smartSuggestionMode="
                         + getSmartSuggestionModeToString(mSupportedSmartSuggestionModes));
             }
         }
+        synchronized (mFlagLock) {
+            mPccClassificationEnabled = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_AUTOFILL,
+                    AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_CLASSIFICATION_ENABLED,
+                    AutofillFeatureFlags.DEFAULT_AUTOFILL_PCC_CLASSIFICATION_ENABLED);
+            mPccPreferProviderOverPcc = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_AUTOFILL,
+                    AutofillFeatureFlags.DEVICE_CONFIG_PREFER_PROVIDER_OVER_PCC,
+                    DEFAULT_PREFER_PROVIDER_OVER_PCC);
+            mPccUseFallbackDetection = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_AUTOFILL,
+                    AutofillFeatureFlags.DEVICE_CONFIG_PCC_USE_FALLBACK,
+                    DEFAULT_PCC_USE_FALLBACK);
+            mPccProviderHints = DeviceConfig.getString(
+                    DeviceConfig.NAMESPACE_AUTOFILL,
+                    AutofillFeatureFlags.DEVICE_CONFIG_AUTOFILL_PCC_FEATURE_PROVIDER_HINTS,
+                    DEFAULT_PCC_FEATURE_PROVIDER_HINTS);
+            if (verbose) {
+                Slog.v(mTag, "setDeviceConfigProperties() for PCC: "
+                        + "mPccClassificationEnabled=" + mPccClassificationEnabled
+                        + ", mPccPreferProviderOverPcc=" + mPccPreferProviderOverPcc
+                        + ", mPccUseFallbackDetection=" + mPccUseFallbackDetection
+                        + ", mPccProviderHints=" + mPccProviderHints);
+            }
+        }
     }
 
     private void updateCachedServices() {
@@ -672,6 +756,29 @@
         return false;
     }
 
+    // Called by Shell command
+    boolean setTemporaryDetectionService(@UserIdInt int userId, @NonNull String serviceName,
+            int durationMs) {
+        Slog.i(mTag, "setTemporaryDetectionService(" + userId + ") to " + serviceName
+                + " for " + durationMs + "ms");
+        enforceCallingPermissionForManagement();
+
+        Objects.requireNonNull(serviceName);
+        if (durationMs > 100000) {
+            // limit duration
+        }
+
+        mFieldClassificationResolver.setTemporaryService(userId, serviceName, durationMs);
+
+        return false;
+    }
+
+    // Called by Shell command
+    void resetTemporaryDetectionService(@UserIdInt int userId) {
+        enforceCallingPermissionForManagement();
+        mFieldClassificationResolver.resetTemporaryService(userId);
+    }
+
     /**
      * Requests a count of saved passwords from the current service.
      *
@@ -791,6 +898,46 @@
         }
     }
 
+    /**
+     * Whether the Autofill PCC Classification feature is enabled.
+     */
+    public boolean isPccClassificationEnabled() {
+        synchronized (mFlagLock) {
+            return mPccClassificationEnabled;
+        }
+    }
+
+    /**
+     * Whether the Autofill Provider shouldbe preferred over PCC results for selecting datasets.
+     */
+    public boolean preferProviderOverPcc() {
+        synchronized (mFlagLock) {
+            return mPccPreferProviderOverPcc;
+        }
+    }
+
+    /**
+     * Whether to use the fallback for detection.
+     * If true, use data from secondary source if primary not present .
+     * For eg: if we prefer PCC over provider, and PCC detection didn't classify a field, however,
+     * autofill provider did, this flag would decide whether we use that result, and show some
+     * presentation for that particular field.
+     */
+    public boolean shouldUsePccFallback() {
+        synchronized (mFlagLock) {
+            return mPccUseFallbackDetection;
+        }
+    }
+
+    /**
+     * Provides Autofill Hints that would be requested by the service from the Autofill Provider.
+     */
+    public String getPccProviderHints() {
+        synchronized (mFlagLock) {
+            return mPccProviderHints;
+        }
+    }
+
     @Nullable
     @VisibleForTesting
     static Map<String, String[]> getAllowedCompatModePackages(String setting) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index cc29109..43b816b 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -162,6 +162,17 @@
     private long mLastPrune = 0;
 
     /**
+     * Reference to the {@link RemoteFieldClassificationService}, is set on demand.
+     */
+    @GuardedBy("mLock")
+    @Nullable
+    private RemoteFieldClassificationService mRemoteFieldClassificationService;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ServiceInfo mRemoteFieldClassificationServiceInfo;
+
+    /**
      * Reference to the {@link RemoteAugmentedAutofillService}, is set on demand.
      */
     @GuardedBy("mLock")
@@ -1051,10 +1062,11 @@
         }
         pw.print(prefix); pw.print("Default component: "); pw.println(getContext()
                 .getString(R.string.config_defaultAutofillService));
+        pw.println();
 
-        pw.print(prefix); pw.println("mAugmentedAutofillNamer: ");
-        pw.print(prefix2); mMaster.mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println();
-
+        pw.print(prefix); pw.println("mAugmentedAutofillName: ");
+        pw.print(prefix2); mMaster.mAugmentedAutofillResolver.dumpShort(pw, mUserId);
+        pw.println();
         if (mRemoteAugmentedAutofillService != null) {
             pw.print(prefix); pw.println("RemoteAugmentedAutofillService: ");
             mRemoteAugmentedAutofillService.dump(prefix2, pw);
@@ -1063,6 +1075,27 @@
             pw.print(prefix); pw.print("RemoteAugmentedAutofillServiceInfo: ");
             pw.println(mRemoteAugmentedAutofillServiceInfo);
         }
+        pw.println();
+
+        pw.print(prefix); pw.println("mFieldClassificationService for system detection");
+        pw.print(prefix2); pw.print("Default component: "); pw.println(getContext()
+                .getString(R.string.config_defaultFieldClassificationService));
+        pw.print(prefix2); mMaster.mFieldClassificationResolver.dumpShort(pw, mUserId);
+        pw.println();
+
+        if (mRemoteFieldClassificationService != null) {
+            pw.print(prefix); pw.println("RemoteFieldClassificationService: ");
+            mRemoteFieldClassificationService.dump(prefix2, pw);
+        } else {
+            pw.print(prefix); pw.println("mRemoteFieldClassificationService: null");
+        }
+        if (mRemoteFieldClassificationServiceInfo != null) {
+            pw.print(prefix); pw.print("RemoteFieldClassificationServiceInfo: ");
+            pw.println(mRemoteFieldClassificationServiceInfo);
+        } else {
+            pw.print(prefix); pw.println("mRemoteFieldClassificationServiceInfo: null");
+        }
+        pw.println();
 
         pw.print(prefix); pw.print("Field classification enabled: ");
             pw.println(isFieldClassificationEnabledLocked());
@@ -1629,6 +1662,95 @@
         }
     }
 
+    @GuardedBy("mLock")
+    @Nullable RemoteFieldClassificationService getRemoteFieldClassificationServiceLocked() {
+        if (mRemoteFieldClassificationService == null) {
+            final String serviceName = mMaster.mFieldClassificationResolver.getServiceName(mUserId);
+            if (serviceName == null) {
+                if (mMaster.verbose) {
+                    Slog.v(TAG, "getRemoteFieldClassificationServiceLocked(): not set");
+                }
+                return null;
+            }
+            if (sVerbose) {
+                Slog.v(TAG, "getRemoteFieldClassificationServiceLocked serviceName: "
+                        + serviceName);
+            }
+            boolean sTemporaryFieldDetectionService =
+                    mMaster.mFieldClassificationResolver.isTemporary(mUserId);
+            final Pair<ServiceInfo, ComponentName> pair = RemoteFieldClassificationService
+                    .getComponentName(serviceName, mUserId, sTemporaryFieldDetectionService);
+            if (pair == null) {
+                Slog.w(TAG, "RemoteFieldClassificationService.getComponentName returned null "
+                        + "with serviceName: " + serviceName);
+                return null;
+            }
+
+            mRemoteFieldClassificationServiceInfo = pair.first;
+            final ComponentName componentName = pair.second;
+            if (sVerbose) {
+                Slog.v(TAG, "getRemoteFieldClassificationServiceLocked(): " + componentName);
+            }
+            final int serviceUid = mRemoteFieldClassificationServiceInfo.applicationInfo.uid;
+            mRemoteFieldClassificationService = new RemoteFieldClassificationService(getContext(),
+                    componentName, serviceUid, mUserId);
+        }
+
+        return mRemoteFieldClassificationService;
+    }
+
+    @GuardedBy("mLock")
+    @Nullable RemoteFieldClassificationService
+            getRemoteFieldClassificationServiceIfCreatedLocked() {
+        return mRemoteFieldClassificationService;
+    }
+
+    /**
+     * Called when the {@link AutofillManagerService#mAugmentedAutofillResolver}
+     * changed (among other places).
+     */
+    void updateRemoteFieldClassificationService() {
+        synchronized (mLock) {
+            if (mRemoteFieldClassificationService != null) {
+                if (sVerbose) {
+                    Slog.v(TAG, "updateRemoteFieldClassificationService(): "
+                            + "destroying old remote service");
+                }
+                mRemoteFieldClassificationService.unbind();
+
+                mRemoteFieldClassificationService = null;
+                mRemoteFieldClassificationServiceInfo = null;
+            }
+
+            final boolean available = isFieldClassificationServiceAvailableLocked();
+            if (sVerbose) Slog.v(TAG, "updateRemoteFieldClassificationService(): " + available);
+
+            if (available) {
+                mRemoteFieldClassificationService = getRemoteFieldClassificationServiceLocked();
+            }
+        }
+    }
+
+    private boolean isFieldClassificationServiceAvailableLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "isFieldClassificationService(): "
+                    + "setupCompleted=" + isSetupCompletedLocked()
+                    + ", disabled=" + isDisabledByUserRestrictionsLocked()
+                    + ", augmentedService="
+                    + mMaster.mFieldClassificationResolver.getServiceName(mUserId));
+        }
+        if (!isSetupCompletedLocked() || isDisabledByUserRestrictionsLocked()
+                || mMaster.mFieldClassificationResolver.getServiceName(mUserId) == null) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean isRemoteClassificationServiceForUserLocked(int callingUid) {
+        return mRemoteFieldClassificationServiceInfo != null
+                && mRemoteFieldClassificationServiceInfo.applicationInfo.uid == callingUid;
+    }
+
     @Override
     public String toString() {
         return "AutofillManagerServiceImpl: [userId=" + mUserId
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index b09cb00..b4e636e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -116,6 +116,11 @@
             pw.println("  set default-augmented-service-enabled USER_ID [true|false]");
             pw.println("    Enable / disable the default augmented autofill service for the user.");
             pw.println("");
+            pw.println("  set temporary-detection-service USER_ID [COMPONENT_NAME DURATION]");
+            pw.println("    Temporarily (for DURATION ms) changes the autofill detection service "
+                    + "implementation.");
+            pw.println("    To reset, call with [COMPONENT_NAME 0].");
+            pw.println("");
             pw.println("  get default-augmented-service-enabled USER_ID");
             pw.println("    Checks whether the default augmented autofill service is enabled for "
                     + "the user.");
@@ -175,6 +180,8 @@
                 return setTemporaryAugmentedService(pw);
             case "default-augmented-service-enabled":
                 return setDefaultAugmentedServiceEnabled(pw);
+            case "temporary-detection-service":
+                return setTemporaryDetectionService(pw);
             default:
                 pw.println("Invalid set: " + what);
                 return -1;
@@ -317,6 +324,27 @@
         }
     }
 
+    private int setTemporaryDetectionService(PrintWriter pw) {
+        final int userId = getNextIntArgRequired();
+        final String serviceName = getNextArg();
+        final int duration = getNextIntArgRequired();
+
+        if (serviceName == null) {
+            mService.resetTemporaryDetectionService(userId);
+            return 0;
+        }
+
+        if (duration <= 0) {
+            mService.resetTemporaryDetectionService(userId);
+            return 0;
+        }
+
+        mService.setTemporaryDetectionService(userId, serviceName, duration);
+        pw.println("Autofill Detection Service temporarily set to " + serviceName + " for "
+                + duration + "ms");
+        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/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index 5f1da7b..590f472 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -315,7 +315,12 @@
                 event.mFillRequestSentTimestampMs,
                 event.mFillResponseReceivedTimestampMs,
                 event.mSuggestionSentTimestampMs,
-                event.mSuggestionPresentedTimestampMs);
+                event.mSuggestionPresentedTimestampMs,
+                //TODO(b/265051751): add new framework logging.
+                /* selected_dataset_id= */ 0,
+                /* dialog_dismissed= */ false,
+                /* negative_cta_button_clicked= */ false,
+                /* positive_cta_button_clicked= */ false);
         mEventInternal = Optional.empty();
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
new file mode 100644
index 0000000..99a2291
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/RemoteFieldClassificationService.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import static com.android.server.autofill.Helper.sDebug;
+import static com.android.server.autofill.Helper.sVerbose;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.os.ICancellationSignal;
+import android.os.RemoteException;
+import android.service.assist.classification.FieldClassificationRequest;
+import android.service.assist.classification.FieldClassificationResponse;
+import android.service.assist.classification.FieldClassificationService;
+import android.service.assist.classification.IFieldClassificationCallback;
+import android.service.assist.classification.IFieldClassificationService;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.infra.AbstractRemoteService;
+import com.android.internal.infra.ServiceConnector;
+
+/**
+ * Class responsible for connection with the Remote {@link FieldClassificationService}.
+ * This class is instantiated when {@link AutofillManagerServiceImpl} is established.
+ * The connection is supposed to be bounded forever, as such, this class persists beyond
+ * Autofill {@link Session}'s lifecycle. As such, it can't contain information relevant to Session.
+ * This design is completely different from {@link RemoteFillService}.
+ */
+final class RemoteFieldClassificationService
+        extends ServiceConnector.Impl<IFieldClassificationService> {
+
+    private static final String TAG =
+            "Autofill" + RemoteFieldClassificationService.class.getSimpleName();
+
+    // Bind forever.
+    private static final long TIMEOUT_IDLE_UNBIND_MS =
+            AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS;
+    private final ComponentName mComponentName;
+
+    public interface FieldClassificationServiceCallbacks {
+        void onClassificationRequestSuccess(@NonNull FieldClassificationResponse response);
+        void onClassificationRequestFailure(int requestId, @Nullable CharSequence message);
+        void onClassificationRequestTimeout(int requestId);
+        void onServiceDied(@NonNull RemoteFieldClassificationService service);
+    }
+
+    RemoteFieldClassificationService(Context context, ComponentName serviceName,
+            int serviceUid, int userId) {
+        super(context,
+                // TODO(b/266379948): Update service
+                new Intent(FieldClassificationService.SERVICE_INTERFACE).setComponent(serviceName),
+                /* bindingFlags= */ 0, userId, IFieldClassificationService.Stub::asInterface);
+        mComponentName = serviceName;
+        if (sDebug) {
+            Slog.d(TAG, "About to connect to serviceName: " + serviceName);
+        }
+        // Bind right away.
+        connect();
+    }
+
+    @Nullable
+    static Pair<ServiceInfo, ComponentName> getComponentName(@NonNull String serviceName,
+            @UserIdInt int userId, boolean isTemporary) {
+        int flags = PackageManager.GET_META_DATA;
+        if (!isTemporary) {
+            flags |= PackageManager.MATCH_SYSTEM_ONLY;
+        }
+
+        final ComponentName serviceComponent;
+        ServiceInfo serviceInfo = null;
+        try {
+            serviceComponent = ComponentName.unflattenFromString(serviceName);
+            serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, flags,
+                    userId);
+            if (serviceInfo == null) {
+                Slog.e(TAG, "Bad service name for flags " + flags + ": " + serviceName);
+                return null;
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Error getting service info for '" + serviceName + "': " + e);
+            return null;
+        }
+        return new Pair<>(serviceInfo, serviceComponent);
+    }
+
+    public ComponentName getComponentName() {
+        return mComponentName;
+    }
+
+    @Override // from ServiceConnector.Impl
+    protected void onServiceConnectionStatusChanged(IFieldClassificationService service,
+            boolean connected) {
+        try {
+            if (connected) {
+                service.onConnected(false, false);
+            } else {
+                service.onDisconnected();
+            }
+        } catch (Exception e) {
+            Slog.w(TAG,
+                    "Exception calling onServiceConnectionStatusChanged(" + connected + "): ", e);
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    protected long getAutoDisconnectTimeoutMs() {
+        return TIMEOUT_IDLE_UNBIND_MS;
+    }
+
+    public void onFieldClassificationRequest(@NonNull FieldClassificationRequest request,
+            FieldClassificationServiceCallbacks fieldClassificationServiceCallbacks) {
+
+        if (sVerbose) {
+            Slog.v(TAG, "onFieldClassificationRequest request:" + request);
+        }
+
+        run(
+                (s) ->
+                        s.onFieldClassificationRequest(
+                                request,
+                                new IFieldClassificationCallback.Stub() {
+                                    @Override
+                                    public void onCancellable(ICancellationSignal cancellation) {
+                                        if (sDebug) {
+                                            Log.d(TAG, "onCancellable");
+                                        }
+                                    }
+
+                                    @Override
+                                    public void onSuccess(FieldClassificationResponse response) {
+                                        if (sDebug) {
+                                            Log.d(TAG, "onSuccess Response: " + response);
+                                        }
+                                        fieldClassificationServiceCallbacks
+                                                .onClassificationRequestSuccess(response);
+                                    }
+
+                                    @Override
+                                    public void onFailure() {
+                                        if (sDebug) {
+                                            Log.d(TAG, "onFailure");
+                                        }
+                                    }
+
+                                    @Override
+                                    public boolean isCompleted() throws RemoteException {
+                                        return false;
+                                    }
+
+                                    @Override
+                                    public void cancel() throws RemoteException {}
+                                }));
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 94872b0..4688658 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -135,6 +135,9 @@
     }
 
     public void onFillRequest(@NonNull FillRequest request) {
+        if (sVerbose) {
+            Slog.v(TAG, "onFillRequest:" + request);
+        }
         AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
         AtomicReference<CompletableFuture<FillResponse>> futureRef = new AtomicReference<>();
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 939047f..24d7c90 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -24,6 +24,7 @@
 import static android.service.autofill.FillEventHistory.Event.UI_TYPE_UNKNOWN;
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
+import static android.service.autofill.FillRequest.FLAG_PCC_DETECTION;
 import static android.service.autofill.FillRequest.FLAG_RESET_FILL_DIALOG_STATE;
 import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
 import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
@@ -87,6 +88,8 @@
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.service.assist.classification.FieldClassificationRequest;
+import android.service.assist.classification.FieldClassificationResponse;
 import android.service.autofill.AutofillFieldClassificationService.Scores;
 import android.service.autofill.AutofillService;
 import android.service.autofill.CompositeUserData;
@@ -124,6 +127,7 @@
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.autofill.IAutofillWindowPresenter;
 import android.view.inputmethod.InlineSuggestionsRequest;
+import android.widget.RemoteViews;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -145,6 +149,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -162,13 +167,16 @@
  * until the user authenticates or it times out.
  */
 final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
-        AutoFillUI.AutoFillUiCallback, ValueFinder {
+        AutoFillUI.AutoFillUiCallback, ValueFinder,
+        RemoteFieldClassificationService.FieldClassificationServiceCallbacks {
     private static final String TAG = "AutofillSession";
 
     private static final String ACTION_DELAYED_FILL =
             "android.service.autofill.action.DELAYED_FILL";
     private static final String EXTRA_REQUEST_ID = "android.service.autofill.extra.REQUEST_ID";
 
+    private static final String PCC_HINTS_DELIMITER = ",";
+
     final Object mLock;
 
     private final AutofillManagerServiceImpl mService;
@@ -182,6 +190,8 @@
 
     private static AtomicInteger sIdCounter = new AtomicInteger(2);
 
+    private static AtomicInteger sIdCounterForPcc = new AtomicInteger(2);
+
     @GuardedBy("mLock")
     private @SessionState int mSessionState = STATE_UNKNOWN;
 
@@ -384,9 +394,16 @@
      */
     private final AssistDataReceiverImpl mAssistReceiver = new AssistDataReceiverImpl();
 
+    /**
+     * Receiver of assist data for pcc purpose
+     */
+    private final PccAssistDataReceiverImpl mPccAssistReceiver = new PccAssistDataReceiverImpl();
+
     @Nullable
     private ClientSuggestionsSession mClientSuggestionsSession;
 
+    private final ClassificationState mClassificationState = new ClassificationState();
+
     // TODO(b/216576510): Share one BroadcastReceiver between all Sessions instead of creating a
     // new one per Session.
     private final BroadcastReceiver mDelayedFillBroadcastReceiver =
@@ -558,6 +575,7 @@
                 if (mPendingInlineSuggestionsRequest.isServiceSupported()) {
                     mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
                             mPendingFillRequest.getFillContexts(),
+                            mPendingFillRequest.getHints(),
                             mPendingFillRequest.getClientState(),
                             mPendingFillRequest.getFlags(),
                             mPendingInlineSuggestionsRequest,
@@ -666,8 +684,10 @@
 
                 final ArrayList<FillContext> contexts =
                         mergePreviousSessionLocked(/* forSave= */ false);
+                final List<String> hints = getTypeHintsForProvider();
+
                 mDelayedFillPendingIntent = createPendingIntent(requestId);
-                request = new FillRequest(requestId, contexts, mClientState, flags,
+                request = new FillRequest(requestId, contexts, hints, mClientState, flags,
                         /*inlineSuggestionsRequest=*/ null,
                         /*delayedFillIntentSender=*/ mDelayedFillPendingIntent == null
                             ? null
@@ -698,6 +718,99 @@
         }
     }
 
+    /**
+     * Get the list of valid autofill hint types from Device flags
+     * Returns empty list if PCC is off or no types available
+    */
+    private List<String> getTypeHintsForProvider() {
+        if (!mService.getMaster().isPccClassificationEnabled()) {
+            return Collections.EMPTY_LIST;
+        }
+        final String typeHints = mService.getMaster().getPccProviderHints();
+        if (TextUtils.isEmpty(typeHints)) {
+            return new ArrayList<>();
+        }
+
+        return List.of(typeHints.split(PCC_HINTS_DELIMITER));
+    }
+
+    /**
+     * Assist Data Receiver for PCC
+     */
+    private final class PccAssistDataReceiverImpl extends IAssistDataReceiver.Stub {
+
+        @GuardedBy("mLock")
+        void maybeRequestFieldClassificationFromServiceLocked() {
+            if (mClassificationState.mPendingFieldClassificationRequest == null) {
+                Log.w(TAG, "Received AssistData without pending classification request");
+                return;
+            }
+
+            RemoteFieldClassificationService remoteFieldClassificationService =
+                    mService.getRemoteFieldClassificationServiceLocked();
+            if (remoteFieldClassificationService != null) {
+                remoteFieldClassificationService.onFieldClassificationRequest(
+                        mClassificationState.mPendingFieldClassificationRequest, Session.this);
+            }
+            mClassificationState.onFieldClassificationRequestSent();
+        }
+
+        @Override
+        public void onHandleAssistData(Bundle resultData) throws RemoteException {
+            // TODO: add a check if pcc field classification service is present
+            final AssistStructure structure = resultData.getParcelable(ASSIST_KEY_STRUCTURE,
+                android.app.assist.AssistStructure.class);
+            if (structure == null) {
+                Slog.e(TAG, "No assist structure for pcc detection - "
+                    + "app might have crashed providing it");
+                return;
+            }
+
+            final Bundle receiverExtras = resultData.getBundle(ASSIST_KEY_RECEIVER_EXTRAS);
+            if (receiverExtras == null) {
+                Slog.e(TAG, "No receiver extras for pcc detection - "
+                    + "app might have crashed providing it");
+                return;
+            }
+
+            final int requestId = receiverExtras.getInt(EXTRA_REQUEST_ID);
+
+            if (sVerbose) {
+                Slog.v(TAG, "New structure for requestId " + requestId + ": " + structure);
+            }
+
+            synchronized (mLock) {
+                // TODO(b/35708678): Must fetch the data so it's available later on handleSave(),
+                // even if the activity is gone by then, but structure .ensureData() gives a
+                // ONE_WAY warning because system_service could block on app calls. We need to
+                // change AssistStructure so it provides a "one-way" writeToParcel() method that
+                // sends all the data
+                try {
+                    structure.ensureDataForAutofill();
+                } catch (RuntimeException e) {
+                    wtf(e, "Exception lazy loading assist structure for %s: %s",
+                        structure.getActivityComponent(), e);
+                    return;
+                }
+
+                final ArrayList<AutofillId> ids = Helper.getAutofillIds(structure,
+                    /* autofillableOnly= */false);
+                for (int i = 0; i < ids.size(); i++) {
+                    ids.get(i).setSessionId(Session.this.id);
+                }
+
+                mClassificationState.onAssistStructureReceived(structure);
+
+                maybeRequestFieldClassificationFromServiceLocked();
+            }
+        }
+
+        @Override
+        public void onHandleAssistScreenshot(Bitmap screenshot) {
+            // Do nothing
+        }
+    }
+
     /** Creates {@link PendingIntent} for autofill service to send a delayed fill. */
     private PendingIntent createPendingIntent(int requestId) {
         Slog.d(TAG, "createPendingIntent for request " + requestId);
@@ -1062,6 +1175,35 @@
     }
 
     @GuardedBy("mLock")
+    private void requestAssistStructureForPccLocked(int flags) {
+        // Get request id
+        int requestId;
+        // TODO(b/158623971): Update this to prevent possible overflow
+        do {
+            requestId = sIdCounterForPcc.getAndIncrement();
+        } while (requestId == INVALID_REQUEST_ID);
+
+        if (sVerbose) {
+            Slog.v(TAG, "request id is " + requestId + ", requesting assist structure for pcc");
+        }
+        // Call requestAutofilLData
+        try {
+            final Bundle receiverExtras = new Bundle();
+            receiverExtras.putInt(EXTRA_REQUEST_ID, requestId);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                if (!ActivityTaskManager.getService().requestAutofillData(mPccAssistReceiver,
+                        receiverExtras, mActivityToken, flags)) {
+                    Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        } catch (RemoteException e) {
+        }
+    }
+
+    @GuardedBy("mLock")
     private void requestAssistStructureLocked(int requestId, int flags) {
         try {
             final Bundle receiverExtras = new Bundle();
@@ -1250,6 +1392,8 @@
                 return;
             }
 
+            // TODO: Check if this is required. We can still present datasets to the user even if
+            //  traditional field classification is disabled.
             fieldClassificationIds = response.getFieldClassificationIds();
             if (!mSessionFlags.mClientSuggestionsEnabled && fieldClassificationIds != null
                     && !mService.isFieldClassificationEnabledLocked()) {
@@ -1334,11 +1478,231 @@
             }
         }
 
+        // TODO(b/266379948): Ideally wait for PCC request to finish for a while more
+        // (say 100ms) before proceeding further on.
+
         synchronized (mLock) {
+            response = getEffectiveFillResponse(response);
             processResponseLocked(response, null, requestFlags);
         }
     }
 
+    private FillResponse getEffectiveFillResponse(FillResponse response) {
+        // TODO(b/266379948): label dataset source
+        if (!mService.getMaster().isPccClassificationEnabled()) return response;
+        synchronized (mLock) {
+            if (mClassificationState.mState != ClassificationState.STATE_RESPONSE
+                    || mClassificationState.mLastFieldClassificationResponse == null) {
+                return response;
+            }
+            if (!mClassificationState.processResponse()) return response;
+        }
+        boolean preferAutofillProvider = mService.getMaster().preferProviderOverPcc();
+        boolean shouldUseFallback = mService.getMaster().shouldUsePccFallback();
+        if (preferAutofillProvider && !shouldUseFallback) {
+            return response;
+        }
+
+        DatasetComputationContainer autofillProviderContainer = new DatasetComputationContainer();
+        DatasetComputationContainer detectionPccContainer = new DatasetComputationContainer();
+
+        computeDatasetsForProviderAndUpdateContainer(response, autofillProviderContainer);
+        computeDatasetsForPccAndUpdateContainer(response, detectionPccContainer);
+
+        DatasetComputationContainer resultContainer;
+        if (preferAutofillProvider) {
+            resultContainer = autofillProviderContainer;
+            if (shouldUseFallback) {
+                // add PCC datasets that are not detected by provider.
+                addFallbackDatasets(autofillProviderContainer, detectionPccContainer);
+            }
+        } else {
+            resultContainer = detectionPccContainer;
+            if (shouldUseFallback) {
+                // add Provider's datasets that are not detected by PCC.
+                addFallbackDatasets(detectionPccContainer, autofillProviderContainer);
+            }
+        }
+        // Create FillResponse with effectiveDatasets, and all the rest value from the original
+        // response.
+        return FillResponse.shallowCopy(response, new ArrayList<>(resultContainer.mDatasets));
+    }
+
+    /**
+     * A private class to hold & compute datasets to be shown
+     */
+    private static class DatasetComputationContainer {
+        // List of all autofill ids that have a corresponding datasets
+        Set<AutofillId> mAutofillIds = new ArraySet<>();
+        // Set of datasets. Kept separately, to be able to be used directly for composing
+        // FillResponse.
+        Set<Dataset> mDatasets = new ArraySet<>();
+        ArrayMap<AutofillId, Set<Dataset>> mAutofillIdToDatasetMap = new ArrayMap<>();
+    }
+
+    // Adds fallback datasets to the first container.
+    // This function will destruct and modify c2 container.
+    private void addFallbackDatasets(
+            DatasetComputationContainer c1, DatasetComputationContainer c2) {
+        for (AutofillId id : c2.mAutofillIds) {
+            if (!c1.mAutofillIds.contains(id)) {
+
+                // Since c2 could be modified in a previous iteration, it's possible that all
+                // datasets corresponding to it have been evaluated, and it's map no longer has
+                // any more datasets left. Early return in this case.
+                if (c2.mAutofillIdToDatasetMap.get(id).isEmpty()) return;
+
+                // For AutofillId id, do the following
+                // 1. Add all the datasets corresponding to it to c1's dataset, and update c1
+                // properly.
+                // 2. All the datasets that were added should be removed from the other autofill
+                // ids that were in this dataset. This prevents us from revisiting those datasets.
+                // Although we are using Sets, and that'd avoid re-adding them, using this logic
+                // for now to keep safe. TODO(b/266379948): Revisit this logic.
+
+                Set<Dataset> datasets = c2.mAutofillIdToDatasetMap.get(id);
+                Set<Dataset> copyDatasets = new ArraySet<>(datasets);
+                c1.mAutofillIds.add(id);
+                c1.mAutofillIdToDatasetMap.put(id, copyDatasets);
+                c1.mDatasets.addAll(copyDatasets);
+
+                for (Dataset dataset : datasets) {
+                    for (AutofillId currentId : dataset.getFieldIds()) {
+                        if (currentId.equals(id)) continue;
+                        // For this id, we need to remove the dataset from it's map.
+                        c2.mAutofillIdToDatasetMap.get(currentId).remove(dataset);
+                    }
+                }
+            }
+        }
+    }
+
+    private void computeDatasetsForProviderAndUpdateContainer(
+            FillResponse response, DatasetComputationContainer container) {
+        List<Dataset> datasets = response.getDatasets();
+        if (datasets == null) return;
+        ArrayMap<AutofillId, Set<Dataset>> autofillIdToDatasetMap = new ArrayMap<>();
+        Set<Dataset> eligibleDatasets = new ArraySet<>();
+        Set<AutofillId> eligibleAutofillIds = new ArraySet<>();
+        for (Dataset dataset : response.getDatasets()) {
+            if (dataset.getFieldIds() == null) continue;
+            if (dataset.getAutofillDatatypes() != null
+                    && dataset.getAutofillDatatypes().size() > 0) {
+                continue;
+            }
+            eligibleDatasets.add(dataset);
+            for (AutofillId id : dataset.getFieldIds()) {
+                eligibleAutofillIds.add(id);
+                Set<Dataset> datasetForIds = autofillIdToDatasetMap.get(id);
+                if (datasetForIds == null) {
+                    datasetForIds = new ArraySet<>();
+                }
+                datasetForIds.add(dataset);
+                autofillIdToDatasetMap.put(id, datasetForIds);
+            }
+        }
+        container.mAutofillIdToDatasetMap = autofillIdToDatasetMap;
+        container.mDatasets = eligibleDatasets;
+        container.mAutofillIds = eligibleAutofillIds;
+    }
+
+    private void computeDatasetsForPccAndUpdateContainer(
+            FillResponse response, DatasetComputationContainer container) {
+        List<Dataset> datasets = response.getDatasets();
+        if (datasets == null) return;
+
+        synchronized (mLock) {
+            ArrayMap<String, Set<AutofillId>> hintsToAutofillIdMap =
+                    mClassificationState.mHintsToAutofillIdMap;
+
+            ArrayMap<String, Set<AutofillId>> groupHintsToAutofillIdMap =
+                    mClassificationState.mGroupHintsToAutofillIdMap;
+
+            ArrayMap<AutofillId, Set<Dataset>> map = new ArrayMap<>();
+
+            Set<Dataset> eligibleDatasets = new ArraySet<>();
+            Set<AutofillId> eligibleAutofillIds = new ArraySet<>();
+
+            for (int i = 0; i < datasets.size(); i++) {
+                Dataset dataset = datasets.get(i);
+                if (dataset.getAutofillDatatypes() == null) continue;
+                if (dataset.getFieldIds() != null && dataset.getFieldIds().size() > 0) continue;
+
+                ArrayList<AutofillId> fieldIds = new ArrayList<>();
+                ArrayList<AutofillValue> fieldValues = new ArrayList<>();
+                ArrayList<RemoteViews> fieldPresentations = new ArrayList<>();
+                ArrayList<RemoteViews> fieldDialogPresentations = new ArrayList<>();
+                ArrayList<InlinePresentation> fieldInlinePresentations = new ArrayList<>();
+                ArrayList<InlinePresentation> fieldInlineTooltipPresentations = new ArrayList<>();
+                ArrayList<Dataset.DatasetFieldFilter> fieldFilters = new ArrayList<>();
+
+                for (int j = 0; j < dataset.getAutofillDatatypes().size(); j++) {
+                    String hint = dataset.getAutofillDatatypes().get(j);
+
+                    if (hintsToAutofillIdMap.containsKey(hint)) {
+                        ArrayList<AutofillId> tempIds =
+                                new ArrayList<>(hintsToAutofillIdMap.get(hint));
+
+                        for (AutofillId autofillId : tempIds) {
+                            eligibleAutofillIds.add(autofillId);
+                            // For each of the field, copy over values.
+                            fieldIds.add(autofillId);
+                            fieldValues.add(dataset.getFieldValues().get(j));
+                            //  TODO(b/266379948): might need to make it more efficient by not
+                            //  copying over value if it didn't exist. This would require creating
+                            //  a getter for the presentations arraylist.
+                            fieldPresentations.add(dataset.getFieldPresentation(j));
+                            fieldDialogPresentations.add(dataset.getFieldDialogPresentation(j));
+                            fieldInlinePresentations.add(dataset.getFieldInlinePresentation(j));
+                            fieldInlineTooltipPresentations.add(
+                                    dataset.getFieldInlineTooltipPresentation(j));
+                            fieldFilters.add(dataset.getFilter(j));
+                        }
+
+                        Dataset newDataset =
+                                new Dataset(
+                                        fieldIds,
+                                        fieldValues,
+                                        fieldPresentations,
+                                        fieldDialogPresentations,
+                                        fieldInlinePresentations,
+                                        fieldInlineTooltipPresentations,
+                                        fieldFilters,
+                                        new ArrayList<>(),
+                                        dataset.getFieldContent(),
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        dataset.getId(),
+                                        dataset.getAuthentication());
+                        eligibleDatasets.add(newDataset);
+
+                        // Associate this dataset with all the ids that are represented with it.
+                        Set<Dataset> newDatasets;
+                        for (AutofillId autofillId : tempIds) {
+                            if (map.containsKey(autofillId)) {
+                                newDatasets = map.get(autofillId);
+                            } else {
+                                newDatasets = new ArraySet<>();
+                            }
+                            newDatasets.add(newDataset);
+                            map.put(autofillId, newDatasets);
+                        }
+                    }
+                    // TODO(b/266379948):  handle the case:
+                    // groupHintsToAutofillIdMap.containsKey(hint))
+                    // but the autofill id not being applicable to other hints.
+                    // TODO(b/266379948):  also handle the case where there could be more types in
+                    // the dataset, provided by the provider, however, they aren't applicable.
+                }
+            }
+            container.mAutofillIds = eligibleAutofillIds;
+            container.mDatasets = eligibleDatasets;
+            container.mAutofillIdToDatasetMap = map;
+        }
+    }
+
     @GuardedBy("mLock")
     private void processNullResponseOrFallbackLocked(int requestId, int flags) {
         if (!mSessionFlags.mClientSuggestionsEnabled) {
@@ -3095,6 +3459,12 @@
             mSessionFlags.mFillDialogDisabled = false;
         }
 
+        /* request assist structure for pcc */
+        if ((flags & FLAG_PCC_DETECTION) != 0) {
+            requestAssistStructureForPccLocked(flags);
+            return;
+        }
+
         switch(action) {
             case ACTION_START_SESSION:
                 // View is triggering autofill.
@@ -4070,8 +4440,7 @@
                 && (mSessionFlags.mAugmentedAutofillOnly
                         || !mSessionFlags.mInlineSupportedByService
                         || mSessionFlags.mExpiredResponse)
-                && isViewFocusedLocked(flags)
-                || isFillDialogUiEnabled()) {
+                && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
             if (sDebug) Slog.d(TAG, "Create inline request for augmented autofill");
             remoteRenderService.getInlineSuggestionsRendererInfo(new RemoteCallback(
                     (extras) -> {
@@ -4437,6 +4806,189 @@
         }
     }
 
+    /**
+     * Class maintaining the state of the requests to
+     * {@link android.service.assist.classification.FieldClassificationService}.
+     */
+    private static final class ClassificationState {
+
+        /**
+         * Initial state indicating that the request for classification hasn't been triggered yet.
+         */
+        private static final int STATE_INITIAL = 1;
+        /**
+         * Assist request has been triggered, but awaiting response.
+         */
+        private static final int STATE_PENDING_ASSIST_REQUEST = 2;
+        /**
+         * Classification request has been triggered, but awaiting response.
+         */
+        private static final int STATE_PENDING_REQUEST = 3;
+        /**
+         * Classification response has been received.
+         */
+        private static final int STATE_RESPONSE = 4;
+        /**
+         * Classification state has been invalidated, and the last response may no longer be valid.
+         * This could occur due to various reasons like views changing their layouts, becoming
+         * visible or invisible, thereby rendering previous response potentially inaccurate or
+         * incomplete.
+         */
+        private static final int STATE_INVALIDATED = 5;
+
+        @IntDef(prefix = { "STATE_" }, value = {
+                STATE_INITIAL,
+                STATE_PENDING_ASSIST_REQUEST,
+                STATE_PENDING_REQUEST,
+                STATE_RESPONSE,
+                STATE_INVALIDATED
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface ClassificationRequestState{}
+
+        @GuardedBy("mLock")
+        private @ClassificationRequestState int mState = STATE_INITIAL;
+
+        @GuardedBy("mLock")
+        private FieldClassificationRequest mPendingFieldClassificationRequest;
+
+        @GuardedBy("mLock")
+        private FieldClassificationResponse mLastFieldClassificationResponse;
+
+        @GuardedBy("mLock")
+        private ArrayMap<AutofillId, Set<String>> mClassificationHintsMap;
+
+        @GuardedBy("mLock")
+        private ArrayMap<AutofillId, Set<String>> mClassificationGroupHintsMap;
+
+        @GuardedBy("mLock")
+        private ArrayMap<AutofillId, Set<String>> mClassificationCombinedHintsMap;
+
+        /**
+         * Typically, there would be a 1:1 mapping. However, in certain cases, we may have a hint
+         * being applicable to many types. An example of this being new/change password forms,
+         * where you need to confirm the passward twice.
+         */
+        @GuardedBy("mLock")
+        private ArrayMap<String, Set<AutofillId>> mHintsToAutofillIdMap;
+
+        /**
+         * Group hints are expected to have a 1:many mapping. For example, different credit card
+         * fields (creditCardNumber, expiry, cvv) will all map to the same group hints.
+         */
+        @GuardedBy("mLock")
+        private ArrayMap<String, Set<AutofillId>> mGroupHintsToAutofillIdMap;
+
+        @GuardedBy("mLock")
+        private String stateToString() {
+            switch (mState) {
+                case STATE_INITIAL:
+                    return "STATE_INITIAL";
+                case STATE_PENDING_ASSIST_REQUEST:
+                    return "STATE_PENDING_ASSIST_REQUEST";
+                case STATE_PENDING_REQUEST:
+                    return "STATE_PENDING_REQUEST";
+                case STATE_RESPONSE:
+                    return "STATE_RESPONSE";
+                case STATE_INVALIDATED:
+                    return "STATE_INVALIDATED";
+                default:
+                    return "UNKNOWN_CLASSIFICATION_STATE_" + mState;
+            }
+        }
+
+        /**
+         * Process the response received.
+         * @return true if the response was processed, false otherwise. If there wasn't any
+         * response, yet this function was called, it would return false.
+         */
+        @GuardedBy("mLock")
+        private boolean processResponse() {
+            if (mClassificationHintsMap != null && !mClassificationHintsMap.isEmpty()) {
+                // Already processed, so return
+                return true;
+            }
+
+            FieldClassificationResponse response = mLastFieldClassificationResponse;
+            if (response == null) return false;
+
+            mClassificationHintsMap = new ArrayMap<>();
+            mClassificationGroupHintsMap = new ArrayMap<>();
+            mHintsToAutofillIdMap = new ArrayMap<>();
+            mGroupHintsToAutofillIdMap = new ArrayMap<>();
+            Set<android.service.assist.classification.FieldClassification> classifications =
+                    response.getClassifications();
+
+            for (android.service.assist.classification.FieldClassification classification :
+                    classifications) {
+                AutofillId id = classification.getAutofillId();
+                Set<String> hintDetections = classification.getHints();
+                Set<String> groupHintsDetections = classification.getGroupHints();
+                ArraySet<String> combinedHints = new ArraySet<>(hintDetections);
+                mClassificationHintsMap.put(id, hintDetections);
+                if (groupHintsDetections != null) {
+                    mClassificationGroupHintsMap.put(id, groupHintsDetections);
+                    combinedHints.addAll(groupHintsDetections);
+                }
+                mClassificationCombinedHintsMap.put(id, combinedHints);
+
+                processDetections(hintDetections, id, mHintsToAutofillIdMap);
+                processDetections(groupHintsDetections, id, mGroupHintsToAutofillIdMap);
+            }
+            return true;
+        }
+
+        @GuardedBy("mLock")
+        private static void processDetections(Set<String> detections, AutofillId id,
+                ArrayMap<String, Set<AutofillId>> currentMap) {
+            for (String detection : detections) {
+                Set<AutofillId> autofillIds;
+                if (currentMap.containsKey(detection)) {
+                    autofillIds = currentMap.get(detection);
+                } else {
+                    autofillIds = new ArraySet<>();
+                }
+                autofillIds.add(id);
+                currentMap.put(detection, autofillIds);
+            }
+        }
+
+        @GuardedBy("mLock")
+        private void invalidateState() {
+            mState = STATE_INVALIDATED;
+        }
+
+        @GuardedBy("mLock")
+        private void updatePendingAssistData() {
+            mState = STATE_PENDING_ASSIST_REQUEST;
+        }
+
+        @GuardedBy("mLock")
+        private void updatePendingRequest() {
+            mState = STATE_PENDING_REQUEST;
+        }
+
+        @GuardedBy("mLock")
+        private void updateResponseReceived(FieldClassificationResponse response) {
+            mState = STATE_RESPONSE;
+            mLastFieldClassificationResponse = response;
+            mPendingFieldClassificationRequest = null;
+            processResponse();
+        }
+
+        @GuardedBy("mLock")
+        private void onAssistStructureReceived(AssistStructure structure) {
+            mState = STATE_PENDING_REQUEST;
+            mPendingFieldClassificationRequest = new FieldClassificationRequest(structure);
+        }
+
+        @GuardedBy("mLock")
+        private void onFieldClassificationRequestSent() {
+            mState = STATE_PENDING_REQUEST;
+            mPendingFieldClassificationRequest = null;
+        }
+    }
+
     @Override
     public String toString() {
         return "Session: [id=" + id + ", component=" + mComponentName
@@ -4946,4 +5498,28 @@
         ServiceInfo serviceInfo = mService.getServiceInfo();
         return serviceInfo == null ? Process.INVALID_UID : serviceInfo.applicationInfo.uid;
     }
+
+    // DetectionServiceCallbacks
+    public void onClassificationRequestSuccess(@Nullable FieldClassificationResponse response) {
+        mClassificationState.updateResponseReceived(response);
+    }
+
+    public void onClassificationRequestFailure(int requestId, @Nullable CharSequence message) {
+
+    }
+
+    public void onClassificationRequestTimeout(int requestId) {
+
+    }
+
+    @Override
+    public void onServiceDied(@NonNull RemoteFieldClassificationService service) {
+        Slog.w(TAG, "removing session because service died");
+        synchronized (mLock) {
+            // TODO(b/266379948)
+            // forceRemoveFromServiceLocked();
+        }
+    }
+    // DetectionServiceCallbacks end
+
 }
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 b68adab..756dcd2 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -361,7 +361,6 @@
         params.width = WindowManager.LayoutParams.MATCH_PARENT;
         params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
         params.windowAnimations = R.style.AutofillSaveAnimation;
-        params.setTrustedOverlay();
 
         show();
     }
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 998c9c2..7261709 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -551,7 +551,7 @@
         mPackageManagerBinder = AppGlobals.getPackageManager();
         mActivityManager = ActivityManager.getService();
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
-        mScheduledBackupEligibility = getEligibilityRules(mPackageManager, userId,
+        mScheduledBackupEligibility = getEligibilityRules(mPackageManager, userId, mContext,
                 BackupDestination.CLOUD);
 
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
@@ -4118,13 +4118,14 @@
 
     public BackupEligibilityRules getEligibilityRulesForOperation(
             @BackupDestination int backupDestination) {
-        return getEligibilityRules(mPackageManager, mUserId, backupDestination);
+        return getEligibilityRules(mPackageManager, mUserId, mContext, backupDestination);
     }
 
     private static BackupEligibilityRules getEligibilityRules(PackageManager packageManager,
-            int userId, @BackupDestination int backupDestination) {
+            int userId, Context context, @BackupDestination int backupDestination) {
         return new BackupEligibilityRules(packageManager,
-                LocalServices.getService(PackageManagerInternal.class), userId, backupDestination);
+                LocalServices.getService(PackageManagerInternal.class), userId, context,
+                backupDestination);
     }
 
     /** Prints service state for 'dumpsys backup'. */
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index 515a172..2374dee 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -112,7 +112,9 @@
             BackupEligibilityRules eligibilityRules = new BackupEligibilityRules(
                     mBackupManagerService.getPackageManager(),
                     LocalServices.getService(PackageManagerInternal.class),
-                    mBackupManagerService.getUserId(), BackupDestination.ADB_BACKUP);
+                    mBackupManagerService.getUserId(),
+                    mBackupManagerService.getContext(),
+                    BackupDestination.ADB_BACKUP);
             FullRestoreEngine mEngine = new FullRestoreEngine(mBackupManagerService,
                     mOperationStorage, null, mObserver, null, null,
                     true, 0 /*unused*/, true, eligibilityRules);
diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
index 2ee9174..7c47f1e 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
@@ -31,6 +31,7 @@
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.compat.annotation.Overridable;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -39,10 +40,12 @@
 import android.content.pm.SigningInfo;
 import android.os.Build;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
+import com.android.server.backup.SetUtils;
 import com.android.server.backup.transport.BackupTransportClient;
 import com.android.server.backup.transport.TransportConnection;
 
@@ -56,13 +59,26 @@
  */
 public class BackupEligibilityRules {
     private static final boolean DEBUG = false;
-    // List of system packages that are eligible for backup in non-system users.
-    private static final Set<String> systemPackagesAllowedForAllUsers = Sets.newArraySet(
-            PACKAGE_MANAGER_SENTINEL, PLATFORM_PACKAGE_NAME, WALLPAPER_PACKAGE, SETTINGS_PACKAGE);
+
+    /**
+     * List of system packages that are eligible for backup in "profile" users (such as work
+     * profile). See {@link UserManager#isProfile()}. This is a subset of {@link
+     * #systemPackagesAllowedForNonSystemUsers}
+     */
+    private static final Set<String> systemPackagesAllowedForProfileUser =
+            Sets.newArraySet(PACKAGE_MANAGER_SENTINEL, PLATFORM_PACKAGE_NAME);
+
+    /**
+     * List of system packages that are eligible for backup in non-system users.
+     */
+    private static final Set<String> systemPackagesAllowedForNonSystemUsers = SetUtils.union(
+            systemPackagesAllowedForProfileUser,
+            Sets.newArraySet(WALLPAPER_PACKAGE, SETTINGS_PACKAGE));
 
     private final PackageManager mPackageManager;
     private final PackageManagerInternal mPackageManagerInternal;
     private final int mUserId;
+    private boolean mIsProfileUser = false;
     @BackupDestination  private final int mBackupDestination;
 
     /**
@@ -85,19 +101,23 @@
 
     public static BackupEligibilityRules forBackup(PackageManager packageManager,
             PackageManagerInternal packageManagerInternal,
-            int userId) {
-        return new BackupEligibilityRules(packageManager, packageManagerInternal, userId,
+            int userId,
+            Context context) {
+        return new BackupEligibilityRules(packageManager, packageManagerInternal, userId, context,
                 BackupDestination.CLOUD);
     }
 
     public BackupEligibilityRules(PackageManager packageManager,
             PackageManagerInternal packageManagerInternal,
             int userId,
+            Context context,
             @BackupDestination int backupDestination) {
         mPackageManager = packageManager;
         mPackageManagerInternal = packageManagerInternal;
         mUserId = userId;
         mBackupDestination = backupDestination;
+        UserManager userManager = context.getSystemService(UserManager.class);
+        mIsProfileUser = userManager.isProfile();
     }
 
     /**
@@ -125,11 +145,17 @@
 
         // 2. they run as a system-level uid
         if (UserHandle.isCore(app.uid)) {
-            // and the backup is happening for a non-system user on a package that is not explicitly
-            // allowed.
-            if (mUserId != UserHandle.USER_SYSTEM
-                    && !systemPackagesAllowedForAllUsers.contains(app.packageName)) {
-                return false;
+            // and the backup is happening for a non-system user or profile on a package that is
+            // not explicitly allowed.
+            if (mUserId != UserHandle.USER_SYSTEM) {
+                if (mIsProfileUser && !systemPackagesAllowedForProfileUser.contains(
+                        app.packageName)) {
+                    return false;
+                }
+                if (!mIsProfileUser && !systemPackagesAllowedForNonSystemUsers.contains(
+                        app.packageName)) {
+                    return false;
+                }
             }
 
             // or do not supply their own backup agent
diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
index 8e8bac4..0accb9f 100644
--- a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java
@@ -160,7 +160,8 @@
                             PackageManagerInternal pmi = LocalServices.getService(
                                     PackageManagerInternal.class);
                             BackupEligibilityRules eligibilityRules =
-                                    BackupEligibilityRules.forBackup(packageManager, pmi, userId);
+                                    BackupEligibilityRules.forBackup(packageManager, pmi, userId,
+                                            context);
                             if (eligibilityRules.signaturesMatch(sigs, pkg)) {
                                 // If this is a system-uid app without a declared backup agent,
                                 // don't restore any of the file data.
diff --git a/services/backup/java/com/android/server/backup/utils/SetUtils.java b/services/backup/java/com/android/server/backup/utils/SetUtils.java
new file mode 100644
index 0000000..ecd628f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/utils/SetUtils.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.backup.utils;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Helper class containing common operation on {@link java.util.Set}.
+ */
+public final class SetUtils {
+    // Statics only
+    private SetUtils() {}
+
+    /**
+     * Returns union of two sets.
+     */
+    public static <T> Set<T> union(Set<T> set1, Set<T> set2) {
+        Set<T> unionSet = new HashSet<>(set1);
+        unionSet.addAll(set2);
+        return unionSet;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 6963248..71ca8ca 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -47,6 +47,7 @@
 import android.app.backup.BackupManagerMonitor;
 import android.app.backup.FullBackup;
 import android.app.backup.IBackupManagerMonitor;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -384,13 +385,14 @@
      * @param info - file metadata.
      * @param signatures - array of signatures parsed from backup file.
      * @param userId - ID of the user for which restore is performed.
+     * @param context - Context instance.
      * @return a restore policy constant.
      */
     public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
             boolean allowApks, FileMetadata info, Signature[] signatures,
-            PackageManagerInternal pmi, int userId) {
+            PackageManagerInternal pmi, int userId, Context context) {
         return chooseRestorePolicy(packageManager, allowApks, info, signatures, pmi, userId,
-                BackupEligibilityRules.forBackup(packageManager, pmi, userId));
+                BackupEligibilityRules.forBackup(packageManager, pmi, userId, context));
     }
 
     /**
diff --git a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
index 312ab54..6675568 100644
--- a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
+++ b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
@@ -45,6 +45,7 @@
     private static final String TAG = "CameraAccessController";
 
     private final Object mLock = new Object();
+    private final Object mObserverLock = new Object();
 
     private final Context mContext;
     private final VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
@@ -53,7 +54,7 @@
     private final PackageManager mPackageManager;
     private final UserManager mUserManager;
 
-    @GuardedBy("mLock")
+    @GuardedBy("mObserverLock")
     private int mObserverCount = 0;
 
     @GuardedBy("mLock")
@@ -107,7 +108,7 @@
      * Returns the number of observers currently relying on this controller.
      */
     public int getObserverCount() {
-        synchronized (mLock) {
+        synchronized (mObserverLock) {
             return mObserverCount;
         }
     }
@@ -117,7 +118,7 @@
      * already doing so.
      */
     public void startObservingIfNeeded() {
-        synchronized (mLock) {
+        synchronized (mObserverLock) {
             if (mObserverCount == 0) {
                 mCameraManager.registerAvailabilityCallback(mContext.getMainExecutor(), this);
             }
@@ -129,7 +130,7 @@
      * Stop watching for camera access.
      */
     public void stopObservingIfNeeded() {
-        synchronized (mLock) {
+        synchronized (mObserverLock) {
             mObserverCount--;
             if (mObserverCount <= 0) {
                 close();
@@ -169,7 +170,7 @@
 
     @Override
     public void close() {
-        synchronized (mLock) {
+        synchronized (mObserverLock) {
             if (mObserverCount < 0) {
                 Slog.wtf(TAG, "Unexpected negative mObserverCount: " + mObserverCount);
             } else if (mObserverCount > 0) {
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index 6b2e893..e52f1d9 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -23,6 +23,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.WindowConfiguration;
 import android.app.compat.CompatChanges;
 import android.companion.virtual.VirtualDeviceManager.ActivityListener;
@@ -302,14 +303,14 @@
     }
 
     @Override
-    public void onTopActivityChanged(ComponentName topActivity, int uid) {
+    public void onTopActivityChanged(ComponentName topActivity, int uid, @UserIdInt int userId) {
         // Don't send onTopActivityChanged() callback when topActivity is null because it's defined
         // as @NonNull in ActivityListener interface. Sends onDisplayEmpty() callback instead when
         // there is no activity running on virtual display.
         if (mActivityListener != null && topActivity != null) {
             // Post callback on the main thread so it doesn't block activity launching
             mHandler.post(() ->
-                    mActivityListener.onTopActivityChanged(mDisplayId, topActivity));
+                    mActivityListener.onTopActivityChanged(mDisplayId, topActivity, userId));
         }
     }
 
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 3100277..7fce442 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -26,6 +26,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
@@ -137,7 +138,18 @@
             @Override
             public void onTopActivityChanged(int displayId, ComponentName topActivity) {
                 try {
-                    mActivityListener.onTopActivityChanged(displayId, topActivity);
+                    mActivityListener.onTopActivityChanged(displayId, topActivity,
+                            UserHandle.USER_NULL);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Unable to call mActivityListener", e);
+                }
+            }
+
+            @Override
+            public void onTopActivityChanged(int displayId, ComponentName topActivity,
+                    @UserIdInt int userId) {
+                try {
+                    mActivityListener.onTopActivityChanged(displayId, topActivity, userId);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Unable to call mActivityListener", e);
                 }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index bd072f5..c8caab9 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -146,6 +146,7 @@
     ],
 
     static_libs: [
+        "android.frameworks.location.altitude-V1-java", // AIDL
         "android.hardware.authsecret-V1.0-java",
         "android.hardware.authsecret-V1-java",
         "android.hardware.boot-V1.0-java", // HIDL
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index 9c2de65..17ef9a2 100644
--- a/services/core/java/android/os/BatteryStatsInternal.java
+++ b/services/core/java/android/os/BatteryStatsInternal.java
@@ -104,8 +104,18 @@
 
     /**
      * Reports any activity that could potentially have caused the CPU to wake up.
-     * Accepts a timestamp to allow the reporter to report it before or after the event.
+     * Accepts a timestamp to allow free ordering between the event and its reporting.
+     * @param subsystem The subsystem this activity should be attributed to.
+     * @param elapsedMillis The time when this activity happened in the elapsed timebase.
+     * @param uids The uid (or uids) that should be blamed for this activity.
      */
     public abstract void noteCpuWakingActivity(@CpuWakeupSubsystem int subsystem,
             long elapsedMillis, @NonNull int... uids);
+
+    /**
+     * Reports a sound trigger recognition event that may have woken up the CPU.
+     * @param elapsedMillis The time when the event happened in the elapsed timebase.
+     * @param uid The uid that requested this trigger.
+     */
+    public abstract void noteWakingSoundTrigger(long elapsedMillis, int uid);
 }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 7a93719..54c47b2 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -162,6 +162,7 @@
     private int mLowBatteryWarningLevel;
     private int mLastLowBatteryWarningLevel;
     private int mLowBatteryCloseWarningLevel;
+    private int mBatteryNearlyFullLevel;
     private int mShutdownBatteryTemperature;
 
     private int mPlugType;
@@ -1212,6 +1213,8 @@
                     com.android.internal.R.integer.config_notificationsBatteryLedOn);
             mBatteryLedOff = context.getResources().getInteger(
                     com.android.internal.R.integer.config_notificationsBatteryLedOff);
+            mBatteryNearlyFullLevel = context.getResources().getInteger(
+                    com.android.internal.R.integer.config_notificationsBatteryNearlyFullLevel);
         }
 
         /**
@@ -1234,7 +1237,8 @@
                 }
             } else if (status == BatteryManager.BATTERY_STATUS_CHARGING
                     || status == BatteryManager.BATTERY_STATUS_FULL) {
-                if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {
+                if (status == BatteryManager.BATTERY_STATUS_FULL
+                        || level >= mBatteryNearlyFullLevel) {
                     // Solid green when full or charging and nearly full
                     mBatteryLight.setColor(mBatteryFullARGB);
                 } else {
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index b6a2a0e..eafd3e0 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -34,6 +34,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ApexStagedEvent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.Checksum;
 import android.content.pm.IBackgroundInstallControlService;
 import android.content.pm.IPackageManagerNative;
 import android.content.pm.IStagedApexObserver;
@@ -84,6 +85,7 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.pm.ApexManager;
 import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.pm.pkg.AndroidPackageSplit;
 import com.android.server.pm.pkg.PackageState;
 
 import libcore.util.HexEncoding;
@@ -120,15 +122,6 @@
 
     static final long RECORD_MEASUREMENTS_COOLDOWN_MS = 24 * 60 * 60 * 1000;
 
-    @VisibleForTesting
-    static final String BUNDLE_PACKAGE_NAME = "package-name";
-    @VisibleForTesting
-    static final String BUNDLE_PACKAGE_IS_APEX = "package-is-apex";
-    @VisibleForTesting
-    static final String BUNDLE_CONTENT_DIGEST_ALGORITHM = "content-digest-algo";
-    @VisibleForTesting
-    static final String BUNDLE_CONTENT_DIGEST = "content-digest";
-
     static final String APEX_PRELOAD_LOCATION_ERROR = "could-not-be-determined";
 
     // used for indicating any type of error during MBA measurement
@@ -170,29 +163,6 @@
             return mVbmetaDigest;
         }
 
-        @Override
-        public List getApexInfo() {
-            List<Bundle> results = new ArrayList<>();
-
-            for (PackageInfo packageInfo : getCurrentInstalledApexs()) {
-                PackageState packageState = mPackageManagerInternal.getPackageStateInternal(
-                        packageInfo.packageName);
-                if (packageState == null) {
-                    Slog.w(TAG, "Package state is unavailable, ignoring the package "
-                            + packageInfo.packageName);
-                    continue;
-                }
-                Bundle apexMeasurement = measurePackage(packageState);
-                if (apexMeasurement == null) {
-                    Slog.w(TAG, "Skipping the missing APEX in " + packageState.getPath());
-                    continue;
-                }
-                results.add(apexMeasurement);
-            }
-
-            return results;
-        }
-
         /**
          * A helper function to compute the SHA256 digest of APK package signer.
          * @param signingInfo The signingInfo of a package, usually {@link PackageInfo#signingInfo}.
@@ -217,58 +187,102 @@
             return resultList.toArray(new String[1]);
         }
 
-        /**
-         * Perform basic measurement (i.e. content digest) on a given package.
+        /*
+         * Perform basic measurement (i.e. content digest) on a given app, including the split APKs.
+         *
          * @param packageState The package to be measured.
-         * @return a {@link android.os.Bundle} that packs the measurement result with the following
-         *         keys: {@link #BUNDLE_PACKAGE_NAME},
-         *               {@link #BUNDLE_PACKAGE_IS_APEX}
-         *               {@link #BUNDLE_CONTENT_DIGEST_ALGORITHM}
-         *               {@link #BUNDLE_CONTENT_DIGEST}
+         * @param mbaStatus Assign this value of MBA status to the returned elements.
+         * @return a @{@code List<IBinaryTransparencyService.AppInfo>}
          */
-        private @Nullable Bundle measurePackage(PackageState packageState) {
-            Bundle result = new Bundle();
-
+        private @NonNull List<IBinaryTransparencyService.AppInfo> collectAppInfo(
+                PackageState packageState, int mbaStatus) {
             // compute content digest
             if (DEBUG) {
                 Slog.d(TAG, "Computing content digest for " + packageState.getPackageName() + " at "
                         + packageState.getPath());
             }
+
+            var results = new ArrayList<IBinaryTransparencyService.AppInfo>();
+
+            // Same attributes across base and splits.
+            String packageName = packageState.getPackageName();
+            long versionCode = packageState.getVersionCode();
+            String[] signerDigests =
+                    computePackageSignerSha256Digests(packageState.getSigningInfo());
+
             AndroidPackage pkg = packageState.getAndroidPackage();
-            if (pkg == null) {
-                Slog.w(TAG, "Skipping the missing APK in " + packageState.getPath());
-                return null;
+            for (AndroidPackageSplit split : pkg.getSplits()) {
+                var appInfo = new IBinaryTransparencyService.AppInfo();
+                appInfo.packageName = packageName;
+                appInfo.longVersion = versionCode;
+                appInfo.splitName = split.getName();  // base's split name is null
+                // Signer digests are consistent between splits, guaranteed by Package Manager.
+                appInfo.signerDigests = signerDigests;
+                appInfo.mbaStatus = mbaStatus;
+
+                // Only digest and split name are different between splits.
+                Checksum checksum = measureApk(split.getPath());
+                appInfo.digest = checksum.getValue();
+                appInfo.digestAlgorithm = checksum.getType();
+
+                results.add(appInfo);
             }
-            Map<Integer, byte[]> contentDigests = computeApkContentDigest(pkg.getBaseApkPath());
-            result.putString(BUNDLE_PACKAGE_NAME, pkg.getPackageName());
+
+            // InstallSourceInfo is only available per package name, so store it only on the base
+            // APK. It's not current currently available in PackageState (there's a TODO), to we
+            // need to extract manually with another call.
+            //
+            // Base APK is already the 0-th split from getSplits() and can't be null.
+            AppInfo base = results.get(0);
+            InstallSourceInfo installSourceInfo = getInstallSourceInfo(
+                    packageState.getPackageName());
+            if (installSourceInfo != null) {
+                base.initiator = installSourceInfo.getInitiatingPackageName();
+                SigningInfo initiatorSignerInfo =
+                        installSourceInfo.getInitiatingPackageSigningInfo();
+                if (initiatorSignerInfo != null) {
+                    base.initiatorSignerDigests =
+                        computePackageSignerSha256Digests(initiatorSignerInfo);
+                }
+                base.installer = installSourceInfo.getInstallingPackageName();
+                base.originator = installSourceInfo.getOriginatingPackageName();
+            }
+
+            return results;
+        }
+
+        /**
+         * Perform basic measurement (i.e. content digest) on a given APK.
+         *
+         * @param apkPath The APK (or APEX, since it's also an APK) file to be measured.
+         * @return a {@link android.content.pm.Checksum} with preferred digest algorithm type and
+         *         the checksum.
+         */
+        private @Nullable Checksum measureApk(@NonNull String apkPath) {
+            // compute content digest
+            Map<Integer, byte[]> contentDigests = computeApkContentDigest(apkPath);
             if (contentDigests == null) {
-                Slog.d(TAG, "Failed to compute content digest for " + pkg.getBaseApkPath());
-                result.putInt(BUNDLE_CONTENT_DIGEST_ALGORITHM, 0);
-                result.putByteArray(BUNDLE_CONTENT_DIGEST, null);
-                return result;
+                Slog.d(TAG, "Failed to compute content digest for " + apkPath);
+                return new Checksum(0, new byte[] { -1 });
             }
 
             // in this iteration, we'll be supporting only 2 types of digests:
             // CHUNKED_SHA256 and CHUNKED_SHA512.
             // And only one of them will be available per package.
             if (contentDigests.containsKey(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256)) {
-                Integer algorithmId = ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256;
-                result.putInt(BUNDLE_CONTENT_DIGEST_ALGORITHM, algorithmId);
-                result.putByteArray(BUNDLE_CONTENT_DIGEST, contentDigests.get(algorithmId));
+                return new Checksum(
+                        Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256,
+                        contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA256));
             } else if (contentDigests.containsKey(
                     ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512)) {
-                Integer algorithmId = ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512;
-                result.putInt(BUNDLE_CONTENT_DIGEST_ALGORITHM, algorithmId);
-                result.putByteArray(BUNDLE_CONTENT_DIGEST, contentDigests.get(algorithmId));
+                return new Checksum(
+                        Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512,
+                        contentDigests.get(ApkSigningBlockUtils.CONTENT_DIGEST_CHUNKED_SHA512));
             } else {
                 // TODO(b/259423111): considering putting the raw values for the algorithm & digest
                 //  into the bundle to track potential other digest algorithms that may be in use
-                result.putInt(BUNDLE_CONTENT_DIGEST_ALGORITHM, 0);
-                result.putByteArray(BUNDLE_CONTENT_DIGEST, null);
+                return new Checksum(0, new byte[] { -1 });
             }
-            result.putBoolean(BUNDLE_PACKAGE_IS_APEX, packageState.isApex());
-
-            return result;
         }
 
 
@@ -330,7 +344,7 @@
             if (CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
                 // lastly measure all newly installed MBAs
                 List<IBinaryTransparencyService.AppInfo> allMbaInfo =
-                        collectAllMbaInfo(packagesMeasured);
+                        collectAllSilentInstalledMbaInfo(packagesMeasured);
                 for (IBinaryTransparencyService.AppInfo appInfo : allUpdatedPreloadInfo) {
                     packagesMeasured.putBoolean(appInfo.packageName, true);
                     writeAppInfoToLog(appInfo);
@@ -356,18 +370,22 @@
                     continue;
                 }
 
-                Bundle apexMeasurement = measurePackage(packageState);
-                if (apexMeasurement == null) {
-                    Slog.w(TAG, "Skipping the missing APEX in " + packageState.getPath());
+                AndroidPackage pkg = packageState.getAndroidPackage();
+                if (pkg == null) {
+                    Slog.w(TAG, "Skipping the missing APK in " + pkg.getPath());
+                    continue;
+                }
+                Checksum apexChecksum = measureApk(pkg.getPath());
+                if (apexChecksum == null) {
+                    Slog.w(TAG, "Skipping the missing APEX in " + pkg.getPath());
                     continue;
                 }
 
                 var apexInfo = new IBinaryTransparencyService.ApexInfo();
                 apexInfo.packageName = packageState.getPackageName();
                 apexInfo.longVersion = packageState.getVersionCode();
-                apexInfo.digest = apexMeasurement.getByteArray(BUNDLE_CONTENT_DIGEST);
-                apexInfo.digestAlgorithm =
-                        apexMeasurement.getInt(BUNDLE_CONTENT_DIGEST_ALGORITHM);
+                apexInfo.digest = apexChecksum.getValue();
+                apexInfo.digestAlgorithm = apexChecksum.getType();
                 apexInfo.signerDigests =
                         computePackageSignerSha256Digests(packageState.getSigningInfo());
 
@@ -398,28 +416,16 @@
                 Slog.d(TAG, "Preload " + packageState.getPackageName() + " at "
                         + packageState.getPath() + " has likely been updated.");
 
-                Bundle packageMeasurement = measurePackage(packageState);
-                if (packageMeasurement == null) {
-                    Slog.w(TAG, "Skipping the missing APK in " + packageState.getPath());
-                    return;
-                }
-
-                var appInfo = new IBinaryTransparencyService.AppInfo();
-                appInfo.packageName = packageState.getPackageName();
-                appInfo.longVersion = packageState.getVersionCode();
-                appInfo.digest = packageMeasurement.getByteArray(BUNDLE_CONTENT_DIGEST);
-                appInfo.digestAlgorithm =
-                        packageMeasurement.getInt(BUNDLE_CONTENT_DIGEST_ALGORITHM);
-                appInfo.signerDigests =
-                        computePackageSignerSha256Digests(packageState.getSigningInfo());
-                appInfo.mbaStatus = MBA_STATUS_UPDATED_PRELOAD;
-
-                results.add(appInfo);
+                List<IBinaryTransparencyService.AppInfo> resultsForApp = collectAppInfo(
+                        packageState, MBA_STATUS_UPDATED_PRELOAD);
+                results.addAll(resultsForApp);
             });
             return results;
         }
 
-        public List<IBinaryTransparencyService.AppInfo> collectAllMbaInfo(Bundle packagesToSkip) {
+        @Override
+        public List<IBinaryTransparencyService.AppInfo> collectAllSilentInstalledMbaInfo(
+                Bundle packagesToSkip) {
             var results = new ArrayList<IBinaryTransparencyService.AppInfo>();
             for (PackageInfo packageInfo : getNewlyInstalledMbas()) {
                 if (packagesToSkip.containsKey(packageInfo.packageName)) {
@@ -433,42 +439,9 @@
                     continue;
                 }
 
-                Bundle packageMeasurement = measurePackage(packageState);
-                if (packageMeasurement == null) {
-                    Slog.w(TAG, "Skipping the missing APK in " + packageState.getPath());
-                    continue;
-                }
-                if (DEBUG) {
-                    Slog.d(TAG,
-                            "Extracting InstallSourceInfo for " + packageState.getPackageName());
-                }
-                var appInfo = new IBinaryTransparencyService.AppInfo();
-                appInfo.packageName = packageState.getPackageName();
-                appInfo.longVersion = packageState.getVersionCode();
-                appInfo.digest = packageMeasurement.getByteArray(BUNDLE_CONTENT_DIGEST);
-                appInfo.digestAlgorithm =
-                    packageMeasurement.getInt(BUNDLE_CONTENT_DIGEST_ALGORITHM);
-                appInfo.signerDigests =
-                        computePackageSignerSha256Digests(packageState.getSigningInfo());
-                appInfo.mbaStatus = MBA_STATUS_NEW_INSTALL;
-
-                // Install source isn't currently available in PackageState (there's a TODO).
-                // Extract manually with another call.
-                InstallSourceInfo installSourceInfo = getInstallSourceInfo(
-                        packageState.getPackageName());
-                if (installSourceInfo != null) {
-                    appInfo.initiator = installSourceInfo.getInitiatingPackageName();
-                    SigningInfo initiatorSignerInfo =
-                            installSourceInfo.getInitiatingPackageSigningInfo();
-                    if (initiatorSignerInfo != null) {
-                        appInfo.initiatorSignerDigests =
-                                computePackageSignerSha256Digests(initiatorSignerInfo);
-                    }
-                    appInfo.installer = installSourceInfo.getInstallingPackageName();
-                    appInfo.originator = installSourceInfo.getOriginatingPackageName();
-                }
-
-                results.add(appInfo);
+                List<IBinaryTransparencyService.AppInfo> resultsForApp = collectAppInfo(
+                        packageState, MBA_STATUS_NEW_INSTALL);
+                results.addAll(resultsForApp);
             }
             return results;
         }
@@ -611,7 +584,7 @@
                             + packageInfo.applicationInfo.sourceDir);
                     if (packageInfo.applicationInfo.sourceDir.startsWith("/data/apex/")) {
                         String origPackageFilepath = getOriginalApexPreinstalledLocation(
-                                packageInfo.packageName, packageInfo.applicationInfo.sourceDir);
+                                packageInfo.packageName);
                         pw.println("|--> Pre-installed package install location: "
                                 + origPackageFilepath);
 
@@ -1655,8 +1628,7 @@
     }
 
     @NonNull
-    private String getOriginalApexPreinstalledLocation(String packageName,
-            String currentInstalledLocation) {
+    private String getOriginalApexPreinstalledLocation(String packageName) {
         try {
             final String moduleName = apexPackageNameToModuleName(packageName);
             IApexService apexService = IApexService.Stub.asInterface(
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index 27ee627..725ea5c 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -29,6 +30,8 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Bundle;
+import android.os.BundleMerger;
 import android.os.Debug;
 import android.os.DropBoxManager;
 import android.os.FileUtils;
@@ -264,7 +267,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_SEND_BROADCAST:
-                    prepareAndSendBroadcast((Intent) msg.obj);
+                    prepareAndSendBroadcast((Intent) msg.obj, null);
                     break;
                 case MSG_SEND_DEFERRED_BROADCAST:
                     Intent deferredIntent;
@@ -272,27 +275,50 @@
                         deferredIntent = mDeferredMap.remove((String) msg.obj);
                     }
                     if (deferredIntent != null) {
-                        prepareAndSendBroadcast(deferredIntent);
+                        prepareAndSendBroadcast(deferredIntent,
+                                createBroadcastOptions(deferredIntent));
                     }
                     break;
             }
         }
 
-        private void prepareAndSendBroadcast(Intent intent) {
+        private void prepareAndSendBroadcast(Intent intent, Bundle options) {
             if (!DropBoxManagerService.this.mBooted) {
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             }
             getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
-                    android.Manifest.permission.READ_LOGS);
+                    android.Manifest.permission.READ_LOGS, options);
         }
 
         private Intent createIntent(String tag, long time) {
             final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
             dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag);
             dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time);
+            dropboxIntent.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, 0);
             return dropboxIntent;
         }
 
+        private Bundle createBroadcastOptions(Intent intent) {
+            final BundleMerger extrasMerger = new BundleMerger();
+            extrasMerger.setDefaultMergeStrategy(BundleMerger.STRATEGY_FIRST);
+            extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
+                    BundleMerger.STRATEGY_COMPARABLE_MAX);
+            extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
+                    BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);
+
+            final String tag = intent.getStringExtra(DropBoxManager.EXTRA_TAG);
+            final IntentFilter matchingFilter = new IntentFilter(
+                    DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
+            matchingFilter.addExtra(DropBoxManager.EXTRA_TAG, tag);
+
+            return BroadcastOptions.makeBasic()
+                    .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED)
+                    .setDeliveryGroupMatchingFilter(matchingFilter)
+                    .setDeliveryGroupExtrasMerger(extrasMerger)
+                    .setDeferUntilActive(true)
+                    .toBundle();
+        }
+
         /**
          * Schedule a dropbox broadcast to be sent asynchronously.
          */
@@ -697,7 +723,7 @@
                 out.append(file.getPath()).append("\n");
             }
 
-            if ((entry.flags & DropBoxManager.IS_TEXT) != 0 && (doPrint || !doFile)) {
+            if ((entry.flags & DropBoxManager.IS_TEXT) != 0 && doPrint) {
                 DropBoxManager.Entry dbe = null;
                 InputStreamReader isr = null;
                 try {
@@ -721,17 +747,6 @@
                             }
                         }
                         if (!newline) out.append("\n");
-                    } else {
-                        String text = dbe.getText(70);
-                        out.append("    ");
-                        if (text == null) {
-                            out.append("[null]");
-                        } else {
-                            boolean truncated = (text.length() == 70);
-                            out.append(text.trim().replace('\n', '/'));
-                            if (truncated) out.append(" ...");
-                        }
-                        out.append("\n");
                     }
                 } catch (IOException e) {
                     out.append("*** ").append(e.toString()).append("\n");
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index a1adc6f4..2a46d86 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -77,80 +77,6 @@
         }
     }
 
-    public static boolean filterEquals(IntentFilter f1, IntentFilter f2) {
-        int s1 = f1.countActions();
-        int s2 = f2.countActions();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasAction(f1.getAction(i))) {
-                return false;
-            }
-        }
-        s1 = f1.countCategories();
-        s2 = f2.countCategories();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasCategory(f1.getCategory(i))) {
-                return false;
-            }
-        }
-        s1 = f1.countDataTypes();
-        s2 = f2.countDataTypes();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasExactDataType(f1.getDataType(i))) {
-                return false;
-            }
-        }
-        s1 = f1.countDataSchemes();
-        s2 = f2.countDataSchemes();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasDataScheme(f1.getDataScheme(i))) {
-                return false;
-            }
-        }
-        s1 = f1.countDataAuthorities();
-        s2 = f2.countDataAuthorities();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasDataAuthority(f1.getDataAuthority(i))) {
-                return false;
-            }
-        }
-        s1 = f1.countDataPaths();
-        s2 = f2.countDataPaths();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasDataPath(f1.getDataPath(i))) {
-                return false;
-            }
-        }
-        s1 = f1.countDataSchemeSpecificParts();
-        s2 = f2.countDataSchemeSpecificParts();
-        if (s1 != s2) {
-            return false;
-        }
-        for (int i=0; i<s1; i++) {
-            if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     /**
      * Returns whether an intent matches the IntentFilter with a pre-resolved type.
      */
@@ -200,7 +126,7 @@
                 if (cur == null) {
                     break;
                 }
-                if (filterEquals(getIntentFilter(cur), matching)) {
+                if (IntentFilter.filterEquals(getIntentFilter(cur), matching)) {
                     if (res == null) {
                         res = new ArrayList<>();
                     }
@@ -225,7 +151,7 @@
         } else {
             ArrayList<F> res = null;
             for (F cur : mFilters) {
-                if (filterEquals(getIntentFilter(cur), matching)) {
+                if (IntentFilter.filterEquals(getIntentFilter(cur), matching)) {
                     if (res == null) {
                         res = new ArrayList<>();
                     }
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 5eb0db1..6fd6afe 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -182,7 +182,6 @@
     public void onStart() {
         // Do init on a separate thread, will join in PHASE_ACTIVITY_MANAGER_READY
         SystemServerInitThreadPool.submit(() -> {
-            mAllowedUid = getAllowedUid();
             enforceChecksumValidity();
             formatIfOemUnlockEnabled();
             publishBinderService(Context.PERSISTENT_DATA_BLOCK_SERVICE, mService);
@@ -202,6 +201,8 @@
                 Thread.currentThread().interrupt();
                 throw new IllegalStateException("Service " + TAG + " init interrupted", e);
             }
+            // The user responsible for FRP should exist by now.
+            mAllowedUid = getAllowedUid();
             LocalServices.addService(PersistentDataBlockManagerInternal.class, mInternalService);
         }
         super.onBootPhase(phase);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 6435869..0252492 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3380,8 +3380,9 @@
                     appInfo.manageSpaceActivityName);
             intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
 
-            final ActivityOptions options = ActivityOptions.makeBasic();
-            options.setIgnorePendingIntentCreatorForegroundState(true);
+            final ActivityOptions options = ActivityOptions.makeBasic()
+                    .setPendingIntentCreatorBackgroundActivityStartMode(
+                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED);
 
             PendingIntent activity = PendingIntent.getActivity(targetAppContext, requestCode,
                     intent,
@@ -3747,8 +3748,12 @@
                     // Return both read only and write only volumes. When includeSharedProfile is
                     // true, all the volumes of userIdSharingMedia should be returned when queried
                     // from the user it shares media with
+                    // Public Volumes will be also be returned if visible to the
+                    // userIdSharingMedia with.
                     match = vol.isVisibleForUser(userId)
                             || (!vol.isVisible() && includeInvisible && vol.getPath() != null)
+                            || (vol.getType() == VolumeInfo.TYPE_PUBLIC
+                                    && vol.isVisibleForUser(userIdSharingMedia))
                             || (includeSharedProfile && vol.isVisibleForUser(userIdSharingMedia));
                 }
                 if (!match) continue;
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index cc8aec7..c5b0f05 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -39,6 +39,26 @@
                 }
             ],
             "file_patterns": ["BinaryTransparencyService\\.java"]
+        },
+        {
+            "name": "BinaryTransparencyHostTest",
+            "file_patterns": [
+                "BinaryTransparencyService\\.java"
+            ]
+        },
+        {
+            "name": "CtsMediaProjectionTestCases",
+            "options": [
+                {
+                    "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                }
+            ]
         }
     ],
     "presubmit-large": [
@@ -69,11 +89,5 @@
             ],
             "file_patterns": ["ClipboardService\\.java"]
         }
-    ],
-    "postsubmit": [
-        {
-            "name": "BinaryTransparencyHostTest",
-            "file_patterns": ["BinaryTransparencyService\\.java"]
-        }
     ]
 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index cfd22e8..a66e598 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -846,7 +846,7 @@
             mCallForwarding[i] =  false;
             mCellIdentity[i] = null;
             mCellInfo.add(i, Collections.EMPTY_LIST);
-            mImsReasonInfo.add(i, null);
+            mImsReasonInfo.add(i, new ImsReasonInfo());
             mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
             mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
             mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
@@ -1265,10 +1265,13 @@
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) {
-                    try {
-                        r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(r.phoneId));
-                    } catch (RemoteException ex) {
-                        remove(r.binder);
+                    ImsReasonInfo imsReasonInfo = mImsReasonInfo.get(r.phoneId);
+                    if (imsReasonInfo != null) {
+                        try {
+                            r.callback.onImsCallDisconnectCauseChanged(imsReasonInfo);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
                     }
                 }
                 if (events.contains(
@@ -2418,6 +2421,11 @@
         int phoneId = getPhoneIdFromSubId(subId);
         synchronized (mRecords) {
             if (validatePhoneId(phoneId)) {
+                if (imsReasonInfo == null) {
+                    loge("ImsReasonInfo is null, subId=" + subId + ", phoneId=" + phoneId);
+                    mImsReasonInfo.set(phoneId, new ImsReasonInfo());
+                    return;
+                }
                 mImsReasonInfo.set(phoneId, imsReasonInfo);
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index ce6a6c8..24ce684 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -20,6 +20,9 @@
 import static android.Manifest.permission.REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND;
 import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
 import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
 import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
 import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -177,6 +180,7 @@
 import android.provider.Settings;
 import android.service.voice.HotwordDetectionService;
 import android.service.voice.VisualQueryDetectionService;
+import android.service.wearable.WearableSensingService;
 import android.stats.devicepolicy.DevicePolicyEnums;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -3810,12 +3814,14 @@
                 inSharedIsolatedProcess);
     }
 
-    // TODO(b/265746493): Special case for HotwordDetectionService and
-    // VisualQueryDetectionService. Need a cleaner way to append this seInfo.
+    // TODO(b/265746493): Special case for HotwordDetectionService,
+    // VisualQueryDetectionService and WearableSensingService.
+    // Need a cleaner way to append this seInfo.
     private String generateAdditionalSeInfoFromService(Intent service) {
         if (service != null && service.getAction() != null
                 && (service.getAction().equals(HotwordDetectionService.SERVICE_INTERFACE)
-                || service.getAction().equals(VisualQueryDetectionService.SERVICE_INTERFACE))) {
+                || service.getAction().equals(VisualQueryDetectionService.SERVICE_INTERFACE)
+                || service.getAction().equals(WearableSensingService.SERVICE_INTERFACE))) {
             return ":isolatedComputeApp";
         }
         return "";
@@ -7395,6 +7401,12 @@
         int ret = shouldAllowFgsStartForegroundNoBindingCheckLocked(allowWhileInUse, callingPid,
                 callingUid, callingPackage, r, backgroundStartPrivileges);
 
+        // If an app (App 1) is bound by another app (App 2) that could start an FGS, then App 1
+        // is also allowed to start an FGS. We check all the binding
+        // in canBindingClientStartFgsLocked() to do this check.
+        // (Note we won't check more than 1 level of binding.)
+        // [bookmark: 61867f60-007c-408c-a2c4-e19e96056135] -- this code is referred to from
+        // OomAdjuster.
         String bindFromPackage = null;
         if (ret == REASON_DENIED) {
             bindFromPackage = canBindingClientStartFgsLocked(callingUid);
@@ -7410,10 +7422,13 @@
                     .getTargetSdkVersion(callingPackage);
         } catch (PackageManager.NameNotFoundException ignored) {
         }
+        final boolean uidBfsl = (mAm.getUidProcessCapabilityLocked(callingUid)
+                & PROCESS_CAPABILITY_BFSL) != 0;
         final String debugInfo =
                 "[callingPackage: " + callingPackage
                         + "; callingUid: " + callingUid
                         + "; uidState: " + ProcessList.makeProcStateString(uidState)
+                        + "; uidBFSL: " + (uidBfsl ? "[BFSL]" : "n/a")
                         + "; intent: " + intent
                         + "; code:" + reasonCodeToString(ret)
                         + "; tempAllowListReason:<"
@@ -7452,11 +7467,15 @@
         }
 
         if (ret == REASON_DENIED) {
+            final boolean uidBfsl =
+                    (mAm.getUidProcessCapabilityLocked(callingUid) & PROCESS_CAPABILITY_BFSL) != 0;
             final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> {
                 if (app.uid == callingUid) {
                     final ProcessStateRecord state = app.mState;
-                    if (state.isAllowedStartFgs()) { // Procstate <= BFGS?
-                        return getReasonCodeFromProcState(state.getCurProcState());
+                    final int procstate = state.getCurProcState();
+                    if ((procstate <= PROCESS_STATE_BOUND_TOP)
+                            || (uidBfsl && (procstate <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE))) {
+                        return getReasonCodeFromProcState(procstate);
                     } else {
                         final ActiveInstrumentation instr = app.getActiveInstrumentation();
                         if (instr != null
@@ -7684,6 +7703,8 @@
         }
         final int callerTargetSdkVersion = r.mRecentCallerApplicationInfo != null
                 ? r.mRecentCallerApplicationInfo.targetSdkVersion : 0;
+
+        // TODO(short-service): Log BFSL too.
         FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED,
                 r.appInfo.uid,
                 r.shortInstanceName,
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index ef79351..2aeaa2f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -770,10 +770,6 @@
     // initialized in the constructor.
     public int CUR_MAX_EMPTY_PROCESSES;
 
-    /** @see mEnforceReceiverExportedFlagRequirement */
-    private static final String KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT =
-            "enforce_exported_flag_requirement";
-
     /** @see #mNoKillCachedProcessesUntilBootCompleted */
     private static final String KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED =
             "no_kill_cached_processes_until_boot_completed";
@@ -782,9 +778,6 @@
     private static final String KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS =
             "no_kill_cached_processes_post_boot_completed_duration_millis";
 
-    /** @see mEnforceReceiverExportedFlagRequirement */
-    private static final boolean DEFAULT_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT = true;
-
     /** @see #mNoKillCachedProcessesUntilBootCompleted */
     private static final boolean DEFAULT_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED = true;
 
@@ -793,15 +786,6 @@
             DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS = 600_000;
 
     /**
-     * If true, enforce the requirement that dynamically registered receivers specify one of
-     * {@link android.content.Context#RECEIVER_EXPORTED} or
-     * {@link android.content.Context#RECEIVER_NOT_EXPORTED} if registering for any non-system
-     * broadcasts.
-     */
-    volatile boolean mEnforceReceiverExportedFlagRequirement =
-            DEFAULT_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT;
-
-    /**
      * If true, do not kill excessive cached processes proactively, until user-0 is unlocked.
      * @see #mNoKillCachedProcessesPostBootCompletedDurationMillis
      */
@@ -971,6 +955,20 @@
             DEFAULT_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION;
 
     /**
+     * If enabled, when starting an application, the system will wait for a
+     * {@link ActivityManagerService#finishAttachApplication} from the app before scheduling
+     * Broadcasts or Services to it.
+     */
+    private static final String KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION =
+            "enable_wait_for_finish_attach_application";
+
+    private static final boolean DEFAULT_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION = false;
+
+    /** @see #KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION */
+    public volatile boolean mEnableWaitForFinishAttachApplication =
+            DEFAULT_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION;
+
+    /**
      * If a "short service" doesn't finish within this after the timeout (
      * {@link #KEY_SHORT_FGS_TIMEOUT_DURATION}), then we'll declare an ANR.
      * i.e. if the timeout is 60 seconds, and this ANR extra duration is 5 seconds, then
@@ -1112,9 +1110,6 @@
                             case KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED:
                                 updateNoKillCachedProcessesUntilBootCompleted();
                                 break;
-                            case KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT:
-                                updateEnforceReceiverExportedFlagRequirement();
-                                break;
                             case KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS:
                                 updateNoKillCachedProcessesPostBootCompletedDurationMillis();
                                 break;
@@ -1144,6 +1139,10 @@
                                 break;
                             case KEY_TOP_TO_FGS_GRACE_DURATION:
                                 updateTopToFgsGraceDuration();
+                                break;
+                            case KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION:
+                                updateEnableWaitForFinishAttachApplication();
+                                break;
                             default:
                                 break;
                         }
@@ -1616,13 +1615,6 @@
                 DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST);
     }
 
-    private void updateEnforceReceiverExportedFlagRequirement() {
-        mEnforceReceiverExportedFlagRequirement = DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
-                KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT,
-                DEFAULT_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT);
-    }
-
     private void updateNoKillCachedProcessesUntilBootCompleted() {
         mNoKillCachedProcessesUntilBootCompleted = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1866,6 +1858,13 @@
                 DEFAULT_SHORT_FGS_ANR_EXTRA_WAIT_DURATION);
     }
 
+    private void updateEnableWaitForFinishAttachApplication() {
+        mEnableWaitForFinishAttachApplication = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION,
+                DEFAULT_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION);
+    }
+
     @NeverCompile // Avoid size overhead of debugging code.
     void dump(PrintWriter pw) {
         pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
@@ -2002,8 +2001,6 @@
         pw.print("="); pw.println(mPrioritizeAlarmBroadcasts);
         pw.print("  "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED);
         pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted);
-        pw.print("  "); pw.print(KEY_ENFORCE_RECEIVER_EXPORTED_FLAG_REQUIREMENT);
-        pw.print("="); pw.println(mEnforceReceiverExportedFlagRequirement);
         pw.print("  "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS);
         pw.print("="); pw.println(mNoKillCachedProcessesPostBootCompletedDurationMillis);
         pw.print("  "); pw.print(KEY_MAX_EMPTY_TIME_MILLIS);
@@ -2055,5 +2052,7 @@
         pw.print("  CUR_TRIM_EMPTY_PROCESSES="); pw.println(CUR_TRIM_EMPTY_PROCESSES);
         pw.print("  CUR_TRIM_CACHED_PROCESSES="); pw.println(CUR_TRIM_CACHED_PROCESSES);
         pw.print("  OOMADJ_UPDATE_QUICK="); pw.println(OOMADJ_UPDATE_QUICK);
+        pw.print("  ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION=");
+        pw.println(mEnableWaitForFinishAttachApplication);
     }
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 423a090..1fe097e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -87,6 +87,7 @@
 import static android.os.Process.getTotalMemory;
 import static android.os.Process.isThreadInProcess;
 import static android.os.Process.killProcess;
+import static android.os.Process.killProcessGroup;
 import static android.os.Process.killProcessQuiet;
 import static android.os.Process.myPid;
 import static android.os.Process.myUid;
@@ -969,13 +970,6 @@
             }
             return false;
         }
-
-        boolean doRemoveIfNoThreadInternal(int pid, ProcessRecord app) {
-            if (app == null || app.getThread() != null) {
-                return false;
-            }
-            return doRemoveInternal(pid, app);
-        }
     }
 
     private final PendingStartActivityUids mPendingStartActivityUids;
@@ -1007,7 +1001,7 @@
      * method.
      */
     @GuardedBy("this")
-    void removePidLocked(int pid, ProcessRecord app) {
+    boolean removePidLocked(int pid, ProcessRecord app) {
         final boolean removed;
         synchronized (mPidsSelfLocked) {
             removed = mPidsSelfLocked.doRemoveInternal(pid, app);
@@ -1018,26 +1012,6 @@
             }
             mAtmInternal.onProcessUnMapped(pid);
         }
-    }
-
-    /**
-     * Removes the process record from the map if it doesn't have a thread.
-     * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
-     * method.
-     */
-    @GuardedBy("this")
-    private boolean removePidIfNoThreadLocked(ProcessRecord app) {
-        final boolean removed;
-        final int pid = app.getPid();
-        synchronized (mPidsSelfLocked) {
-            removed = mPidsSelfLocked.doRemoveIfNoThreadInternal(pid, app);
-        }
-        if (removed) {
-            synchronized (sActiveProcessInfoSelfLocked) {
-                sActiveProcessInfoSelfLocked.remove(pid);
-            }
-            mAtmInternal.onProcessUnMapped(pid);
-        }
         return removed;
     }
 
@@ -1820,11 +1794,13 @@
                 synchronized (ActivityManagerService.this) {
                     final int appId = msg.arg1;
                     final int userId = msg.arg2;
-                    Bundle bundle = (Bundle) msg.obj;
-                    String pkg = bundle.getString("pkg");
-                    String reason = bundle.getString("reason");
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    String pkg = (String) args.arg1;
+                    String reason = (String) args.arg2;
+                    int exitInfoReason = (int) args.arg3;
+                    args.recycle();
                     forceStopPackageLocked(pkg, appId, false, false, true, false,
-                            false, userId, reason);
+                            false, userId, reason, exitInfoReason);
                 }
             } break;
 
@@ -2338,8 +2314,9 @@
         mUiContext = null;
         mAppErrors = null;
         mPackageWatchdog = null;
-        mAppOpsService = mInjector.getAppOpsService(null /* file */, null /* handler */);
-        mBatteryStatsService = null;
+        mAppOpsService = mInjector.getAppOpsService(null /* recentAccessesFile */,
+            null /* storageFile */, null /* handler */);
+        mBatteryStatsService = mInjector.getBatteryStatsService();
         mHandler = new MainHandler(handlerThread.getLooper());
         mHandlerThread = handlerThread;
         mConstants = new ActivityManagerConstants(mContext, this, mHandler);
@@ -2354,7 +2331,7 @@
         mIntentFirewall = null;
         mProcessStats = new ProcessStatsService(this, mContext.getCacheDir());
         mCpHelper = new ContentProviderHelper(this, false);
-        mServices = null;
+        mServices = mInjector.getActiveServices(this);
         mSystemThread = null;
         mUiHandler = injector.getUiHandler(null /* service */);
         mUidObserverController = new UidObserverController(mUiHandler);
@@ -2467,7 +2444,8 @@
 
         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
 
-        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
+        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops_accesses.xml"),
+                new File(systemDir, "appops.xml"), mHandler);
 
         mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
 
@@ -3301,8 +3279,7 @@
         ProcessRecord record = mProcessList.getLRURecordForAppLOSP(threadBinder);
         if (record != null) return record;
 
-        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
-        // double-check that.
+        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's double-check that.
         final ArrayMap<String, SparseArray<ProcessRecord>> pmap =
                 mProcessList.getProcessNamesLOSP().getMap();
         for (int i = pmap.size()-1; i >= 0; i--) {
@@ -3311,8 +3288,10 @@
                 final ProcessRecord proc = procs.valueAt(j);
                 final IApplicationThread procThread = proc.getThread();
                 if (procThread != null && procThread.asBinder() == threadBinder) {
-                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
-                            + proc);
+                    if (!proc.isPendingFinishAttach()) {
+                        Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
+                                + proc);
+                    }
                     return proc;
                 }
             }
@@ -4236,7 +4215,8 @@
      * The pkg name and app id have to be specified.
      */
     @Override
-    public void killApplication(String pkg, int appId, int userId, String reason) {
+    public void killApplication(String pkg, int appId, int userId, String reason,
+            int exitInfoReason) {
         if (pkg == null) {
             return;
         }
@@ -4252,10 +4232,11 @@
             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
             msg.arg1 = appId;
             msg.arg2 = userId;
-            Bundle bundle = new Bundle();
-            bundle.putString("pkg", pkg);
-            bundle.putString("reason", reason);
-            msg.obj = bundle;
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = pkg;
+            args.arg2 = reason;
+            args.arg3 = exitInfoReason;
+            msg.obj = args;
             mHandler.sendMessage(msg);
         } else {
             throw new SecurityException(callerUid + " cannot kill pkg: " +
@@ -4645,7 +4626,20 @@
     @GuardedBy("this")
     final boolean forceStopPackageLocked(String packageName, int appId,
             boolean callerWillRestart, boolean purgeCache, boolean doit,
-            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
+            boolean evenPersistent, boolean uninstalling, int userId, String reasonString) {
+
+        int reason = packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
+                : ApplicationExitInfo.REASON_USER_REQUESTED;
+        return forceStopPackageLocked(packageName, appId, callerWillRestart, purgeCache, doit,
+                evenPersistent, uninstalling, userId, reasonString, reason);
+
+    }
+
+    @GuardedBy("this")
+    final boolean forceStopPackageLocked(String packageName, int appId,
+            boolean callerWillRestart, boolean purgeCache, boolean doit,
+            boolean evenPersistent, boolean uninstalling, int userId, String reasonString,
+            int reason) {
         int i;
 
         if (userId == UserHandle.USER_ALL && packageName == null) {
@@ -4661,9 +4655,9 @@
         if (doit) {
             if (packageName != null) {
                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
-                        + " user=" + userId + ": " + reason);
+                        + " user=" + userId + ": " + reasonString);
             } else {
-                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
+                Slog.i(TAG, "Force stopping u" + userId + ": " + reasonString);
             }
 
             mAppErrors.resetProcessCrashTime(packageName == null, appId, userId);
@@ -4675,15 +4669,20 @@
             // becomes visible when killing its other processes with visible activities.
             didSomething = mAtmInternal.onForceStopPackage(
                     packageName, doit, evenPersistent, userId);
+            int subReason;
+            if (reason == ApplicationExitInfo.REASON_USER_REQUESTED) {
+                subReason = ApplicationExitInfo.SUBREASON_FORCE_STOP;
+            } else {
+                subReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
+            }
 
             didSomething |= mProcessList.killPackageProcessesLSP(packageName, appId, userId,
                     ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit,
                     evenPersistent, true /* setRemoved */, uninstalling,
-                    packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
-                    : ApplicationExitInfo.REASON_USER_REQUESTED,
-                    ApplicationExitInfo.SUBREASON_FORCE_STOP,
+                    reason,
+                    subReason,
                     (packageName == null ? ("stop user " + userId) : ("stop " + packageName))
-                    + " due to " + reason);
+                    + " due to " + reasonString);
         }
 
         if (mServices.bringDownDisabledPackageServicesLocked(
@@ -4744,7 +4743,7 @@
     @GuardedBy("this")
     void handleProcessStartOrKillTimeoutLocked(ProcessRecord app, boolean isKillTimeout) {
         final int pid = app.getPid();
-        boolean gone = isKillTimeout || removePidIfNoThreadLocked(app);
+        boolean gone = isKillTimeout || removePidLocked(pid, app);
 
         if (gone) {
             if (isKillTimeout) {
@@ -4825,7 +4824,7 @@
     }
 
     @GuardedBy("this")
-    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
+    private void attachApplicationLocked(@NonNull IApplicationThread thread,
             int pid, int callingUid, long startSeq) {
 
         // Find the application record that is being attached...  either via
@@ -4890,7 +4889,7 @@
                     // Ignore exceptions.
                 }
             }
-            return false;
+            return;
         }
 
         // If this application record is still attached to a previous
@@ -4915,7 +4914,7 @@
             mProcessList.startProcessLocked(app,
                     new HostingRecord(HostingRecord.HOSTING_TYPE_LINK_FAIL, processName),
                     ZYGOTE_POLICY_FLAG_EMPTY);
-            return false;
+            return;
         }
 
         EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
@@ -4938,8 +4937,6 @@
             app.setUnlocked(StorageManager.isUserKeyUnlocked(app.userId));
         }
 
-        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-
         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
         List<ProviderInfo> providers = normalMode
                                             ? mCpHelper.generateApplicationProvidersLocked(app)
@@ -5090,6 +5087,8 @@
                 profilerInfo = null;
             }
 
+            app.setBindApplicationTime(bindApplicationTimeMillis);
+
             // Make app active after binding application or client may be running requests (e.g
             // starting activities) before it is ready.
             synchronized (mProcLock) {
@@ -5103,6 +5102,19 @@
                 app.mProfile.setLastRequestedGc(now);
                 app.mProfile.setLastLowMemory(now);
             }
+
+            // Remove this record from the list of starting applications.
+            mPersistentStartingProcesses.remove(app);
+            if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) {
+                Slog.v(TAG_PROCESSES, "Attach application locked removing on hold: " + app);
+            }
+            mProcessesOnHold.remove(app);
+
+            if (!mConstants.mEnableWaitForFinishAttachApplication) {
+                finishAttachApplicationInner(startSeq, callingUid, pid);
+            } else {
+                app.setPendingFinishAttach(true);
+            }
         } catch (Exception e) {
             // We need kill the process group here. (b/148588589)
             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
@@ -5111,99 +5123,8 @@
             app.killLocked("error during bind", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
                     true);
             handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
-            return false;
+            return;
         }
-
-        // Remove this record from the list of starting applications.
-        mPersistentStartingProcesses.remove(app);
-        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
-                "Attach application locked removing on hold: " + app);
-        mProcessesOnHold.remove(app);
-
-        boolean badApp = false;
-        boolean didSomething = false;
-
-        // See if the top visible activity is waiting to run in this process...
-        if (normalMode) {
-            try {
-                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
-            } catch (Exception e) {
-                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
-                badApp = true;
-            }
-        }
-
-        // Find any services that should be running in this process...
-        if (!badApp) {
-            try {
-                didSomething |= mServices.attachApplicationLocked(app, processName);
-                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
-            } catch (Exception e) {
-                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
-                badApp = true;
-            }
-        }
-
-        // Check if a next-broadcast receiver is in this process...
-        if (!badApp) {
-            try {
-                for (BroadcastQueue queue : mBroadcastQueues) {
-                    didSomething |= queue.onApplicationAttachedLocked(app);
-                }
-                checkTime(startTime, "attachApplicationLocked: after dispatching broadcasts");
-            } catch (Exception e) {
-                // If the app died trying to launch the receiver we declare it 'bad'
-                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
-                badApp = true;
-            }
-        }
-
-        // Check whether the next backup agent is in this process...
-        if (!badApp && backupTarget != null && backupTarget.app == app) {
-            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
-                    "New app is backup target, launching agent for " + app);
-            notifyPackageUse(backupTarget.appInfo.packageName,
-                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
-            try {
-                thread.scheduleCreateBackupAgent(backupTarget.appInfo,
-                        backupTarget.backupMode, backupTarget.userId,
-                        backupTarget.backupDestination);
-            } catch (Exception e) {
-                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
-                badApp = true;
-            }
-        }
-
-        if (badApp) {
-            app.killLocked("error during init", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
-                    true);
-            handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
-            return false;
-        }
-
-        if (!didSomething) {
-            updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
-            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
-        }
-
-
-        final HostingRecord hostingRecord = app.getHostingRecord();
-        String shortAction = getShortAction(hostingRecord.getAction());
-        FrameworkStatsLog.write(
-                FrameworkStatsLog.PROCESS_START_TIME,
-                app.info.uid,
-                pid,
-                app.info.packageName,
-                FrameworkStatsLog.PROCESS_START_TIME__TYPE__COLD,
-                app.getStartElapsedTime(),
-                (int) (bindApplicationTimeMillis - app.getStartUptime()),
-                (int) (SystemClock.uptimeMillis() - app.getStartUptime()),
-                hostingRecord.getType(),
-                hostingRecord.getName(),
-                shortAction,
-                HostingRecord.getHostingTypeIdStatsd(hostingRecord.getType()),
-                HostingRecord.getTriggerTypeForStatsd(hostingRecord.getTriggerType()));
-        return true;
     }
 
     @Override
@@ -5220,6 +5141,154 @@
         }
     }
 
+    private void finishAttachApplicationInner(long startSeq, int uid, int pid) {
+        final long startTime = SystemClock.uptimeMillis();
+        // Find the application record that is being attached...  either via
+        // the pid if we are running in multiple processes, or just pull the
+        // next app record if we are emulating process with anonymous threads.
+        final ProcessRecord app;
+        synchronized (mPidsSelfLocked) {
+            app = mPidsSelfLocked.get(pid);
+        }
+
+        if (app != null && app.getStartUid() == uid && app.getStartSeq() == startSeq) {
+            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
+        } else {
+            Slog.wtf(TAG, "Mismatched or missing ProcessRecord: " + app + ". Pid: " + pid
+                    + ". Uid: " + uid);
+            killProcess(pid);
+            killProcessGroup(uid, pid);
+            mProcessList.noteAppKill(pid, uid,
+                    ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
+                    ApplicationExitInfo.SUBREASON_UNKNOWN,
+                    "wrong startSeq");
+            synchronized (this) {
+                app.killLocked("unexpected process record",
+                        ApplicationExitInfo.REASON_OTHER, true);
+            }
+            return;
+        }
+
+        synchronized (this) {
+            // Mark the finish attach application phase as completed
+            app.setPendingFinishAttach(false);
+
+            final boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
+            final String processName = app.processName;
+            boolean badApp = false;
+            boolean didSomething = false;
+
+            // See if the top visible activity is waiting to run in this process...
+            if (normalMode) {
+                try {
+                    didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
+                } catch (Exception e) {
+                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
+                    badApp = true;
+                }
+            }
+
+            // Find any services that should be running in this process...
+            if (!badApp) {
+                try {
+                    didSomething |= mServices.attachApplicationLocked(app, processName);
+                    checkTime(startTime, "finishAttachApplicationInner: "
+                            + "after mServices.attachApplicationLocked");
+                } catch (Exception e) {
+                    Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
+                    badApp = true;
+                }
+            }
+
+            // Check if a next-broadcast receiver is in this process...
+            if (!badApp) {
+                try {
+                    for (BroadcastQueue queue : mBroadcastQueues) {
+                        didSomething |= queue.onApplicationAttachedLocked(app);
+                    }
+                    checkTime(startTime, "finishAttachApplicationInner: "
+                            + "after dispatching broadcasts");
+                } catch (Exception e) {
+                    // If the app died trying to launch the receiver we declare it 'bad'
+                    Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
+                    badApp = true;
+                }
+            }
+
+            // Check whether the next backup agent is in this process...
+            final BackupRecord backupTarget = mBackupTargets.get(app.userId);
+            if (!badApp && backupTarget != null && backupTarget.app == app) {
+                if (DEBUG_BACKUP) {
+                    Slog.v(TAG_BACKUP,
+                            "New app is backup target, launching agent for " + app);
+                }
+
+                notifyPackageUse(backupTarget.appInfo.packageName,
+                        PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
+                try {
+                    app.getThread().scheduleCreateBackupAgent(backupTarget.appInfo,
+                            backupTarget.backupMode, backupTarget.userId,
+                            backupTarget.backupDestination);
+                } catch (Exception e) {
+                    Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
+                    badApp = true;
+                }
+            }
+
+            if (badApp) {
+                app.killLocked("error during init",
+                        ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true);
+                handleAppDiedLocked(app, pid, false, true, false /* fromBinderDied */);
+                return;
+            }
+
+            if (!didSomething) {
+                updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN);
+                checkTime(startTime, "finishAttachApplicationInner: after updateOomAdjLocked");
+            }
+
+            final HostingRecord hostingRecord = app.getHostingRecord();
+            final String shortAction = getShortAction(hostingRecord.getAction());
+            FrameworkStatsLog.write(
+                    FrameworkStatsLog.PROCESS_START_TIME,
+                    app.info.uid,
+                    pid,
+                    app.info.packageName,
+                    FrameworkStatsLog.PROCESS_START_TIME__TYPE__COLD,
+                    app.getStartElapsedTime(),
+                    (int) (app.getBindApplicationTime() - app.getStartUptime()),
+                    (int) (SystemClock.uptimeMillis() - app.getStartUptime()),
+                    hostingRecord.getType(),
+                    hostingRecord.getName(),
+                    shortAction,
+                    HostingRecord.getHostingTypeIdStatsd(hostingRecord.getType()),
+                    HostingRecord.getTriggerTypeForStatsd(hostingRecord.getTriggerType()));
+        }
+    }
+
+    @Override
+    public final void finishAttachApplication(long startSeq) {
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+
+        if (!mConstants.mEnableWaitForFinishAttachApplication) {
+            Slog.i(TAG, "Flag disabled. Ignoring finishAttachApplication from uid: "
+                    + uid + ". pid: " + pid);
+            return;
+        }
+
+        if (pid == MY_PID && uid == SYSTEM_UID) {
+            return;
+        }
+
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            finishAttachApplicationInner(startSeq, uid, pid);
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
     /**
      * @return The last part of the string of an intent's action.
      */
@@ -5566,8 +5635,35 @@
             IBinder allowlistToken, int code, Intent intent, String resolvedType,
             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
         if (target instanceof PendingIntentRecord) {
-            return ((PendingIntentRecord) target).sendWithResult(caller, code, intent,
-                    resolvedType, allowlistToken, finishedReceiver, requiredPermission, options);
+            final PendingIntentRecord originalRecord = (PendingIntentRecord) target;
+
+            // In multi-display scenarios, there can be background users who execute the
+            // PendingIntent. In these scenarios, we don't want to use the foreground user as the
+            // current user.
+            final PendingIntentRecord.Key originalKey = originalRecord.key;
+            final UserManagerInternal umInternal =
+                    LocalServices.getService(UserManagerInternal.class);
+            final int callingUserId = UserHandle.getCallingUserId();
+            if (UserManager.isVisibleBackgroundUsersEnabled()
+                    && originalKey.userId == UserHandle.USER_CURRENT
+                    && callingUserId != UserHandle.USER_SYSTEM
+                    && umInternal.isUserVisible(callingUserId)) {
+                EventLogTags.writeAmIntentSenderRedirectUser(callingUserId);
+                final PendingIntentRecord.Key key = new PendingIntentRecord.Key(originalKey.type,
+                        originalKey.packageName, originalKey.featureId, originalKey.activity,
+                        originalKey.who, originalKey.requestCode, originalKey.allIntents,
+                        originalKey.allResolvedTypes, originalKey.flags, originalKey.options,
+                        callingUserId);
+
+                final PendingIntentRecord newRecord = new PendingIntentRecord(
+                        originalRecord.controller, key, originalRecord.uid);
+
+                return newRecord.sendWithResult(caller, code, intent, resolvedType, allowlistToken,
+                        finishedReceiver, requiredPermission, options);
+            }
+
+            return originalRecord.sendWithResult(caller, code, intent, resolvedType, allowlistToken,
+                    finishedReceiver, requiredPermission, options);
         } else {
             if (intent == null) {
                 // Weird case: someone has given us their own custom IIntentSender, and now
@@ -5874,6 +5970,11 @@
         return mProcessList.getUidProcStateLOSP(uid);
     }
 
+    @GuardedBy("this")
+    int getUidProcessCapabilityLocked(int uid) {
+        return mProcessList.getUidProcessCapabilityLOSP(uid);
+    }
+
     // =========================================================
     // PROCESS INFO
     // =========================================================
@@ -13210,8 +13311,10 @@
         // restored. This distinction is important for system-process packages that live in the
         // system user's process but backup/restore data for non-system users.
         // TODO (b/123688746): Handle all system-process packages with singleton check.
-        final int instantiatedUserId =
-                PLATFORM_PACKAGE_NAME.equals(packageName) ? UserHandle.USER_SYSTEM : targetUserId;
+        boolean useSystemUser = PLATFORM_PACKAGE_NAME.equals(packageName)
+                || getPackageManagerInternal().getSystemUiServiceComponent().getPackageName()
+                        .equals(packageName);
+        final int instantiatedUserId = useSystemUser ? UserHandle.USER_SYSTEM : targetUserId;
 
         IPackageManager pm = AppGlobals.getPackageManager();
         ApplicationInfo app = null;
@@ -13588,8 +13691,7 @@
             // broadcasts, or the receiver is null (a sticky broadcast). Sticky broadcasts should
             // not be used generally, so we will be marking them as exported by default
             boolean requireExplicitFlagForDynamicReceivers = CompatChanges.isChangeEnabled(
-                    DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED, callingUid)
-                    && mConstants.mEnforceReceiverExportedFlagRequirement;
+                    DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED, callingUid);
             // STOPSHIP(b/259139792): Allow apps that are currently targeting U and in process of
             // updating their receivers to be exempt from this requirement until their receivers
             // are flagged.
@@ -14352,12 +14454,13 @@
                                 final boolean killProcess =
                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
                                 final boolean fullUninstall = removed && !replacing;
+
                                 if (removed) {
                                     if (killProcess) {
                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                                 false, true, true, false, fullUninstall, userId,
-                                                removed ? "pkg removed" : "pkg changed");
+                                                "pkg removed");
                                         getPackageManagerInternal()
                                                 .onPackageProcessKilledForUninstall(ssp);
                                     } else {
@@ -14388,14 +14491,25 @@
                                     }
                                 } else {
                                     if (killProcess) {
+                                        int reason;
+                                        int subReason;
+                                        if (replacing) {
+                                            reason = ApplicationExitInfo.REASON_PACKAGE_UPDATED;
+                                            subReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
+                                        } else {
+                                            reason =
+                                                    ApplicationExitInfo.REASON_PACKAGE_STATE_CHANGE;
+                                            subReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
+                                        }
+
                                         final int extraUid = intent.getIntExtra(Intent.EXTRA_UID,
                                                 -1);
                                         synchronized (mProcLock) {
                                             mProcessList.killPackageProcessesLSP(ssp,
                                                     UserHandle.getAppId(extraUid),
                                                     userId, ProcessList.INVALID_ADJ,
-                                                    ApplicationExitInfo.REASON_USER_REQUESTED,
-                                                    ApplicationExitInfo.SUBREASON_PACKAGE_UPDATE,
+                                                    reason,
+                                                    subReason,
                                                     "change " + ssp);
                                         }
                                     }
@@ -16630,7 +16744,8 @@
     }
 
     @Override
-    public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId) {
+    public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId,
+            @Nullable IProgressListener unlockListener) {
         int[] displayIds = getDisplayIdsForStartingVisibleBackgroundUsers();
         boolean validDisplay = false;
         if (displayIds != null) {
@@ -16647,11 +16762,11 @@
         }
 
         if (DEBUG_MU) {
-            Slogf.d(TAG_MU, "Calling startUserOnSecondaryDisplay(%d, %d) using injector %s", userId,
-                    displayId, mInjector);
+            Slogf.d(TAG_MU, "Calling startUserOnSecondaryDisplay(%d, %d, %s) using injector %s",
+                    userId, displayId, unlockListener, mInjector);
         }
         // Permission check done inside UserController.
-        return mInjector.startUserInBackgroundVisibleOnDisplay(userId, displayId);
+        return mInjector.startUserInBackgroundVisibleOnDisplay(userId, displayId, unlockListener);
     }
 
     @Override
@@ -18917,8 +19032,9 @@
             return mContext;
         }
 
-        public AppOpsService getAppOpsService(File file, Handler handler) {
-            return new AppOpsService(file, handler, getContext());
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
+            return new AppOpsService(recentAccessesFile, storageFile, handler, getContext());
         }
 
         public Handler getUiHandler(ActivityManagerService service) {
@@ -19032,8 +19148,10 @@
         /**
          * Called by {@code AMS.startUserInBackgroundVisibleOnDisplay()}.
          */
-        public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId) {
-            return mUserController.startUserVisibleOnDisplay(userId, displayId);
+        public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId,
+                @Nullable IProgressListener unlockProgressListener) {
+            return mUserController.startUserVisibleOnDisplay(userId, displayId,
+                    unlockProgressListener);
         }
 
         /**
@@ -19043,6 +19161,21 @@
             return new ProcessList();
         }
 
+        /**
+         * Returns the {@link BatteryStatsService} instance
+         */
+        public BatteryStatsService getBatteryStatsService() {
+            return new BatteryStatsService(mContext, SystemServiceManager.ensureSystemDir(),
+                BackgroundThread.get().getHandler());
+        }
+
+        /**
+         * Returns the {@link ActiveServices} instance
+         */
+        public ActiveServices getActiveServices(ActivityManagerService service) {
+            return new ActiveServices(service);
+        }
+
         private boolean ensureHasNetworkManagementInternal() {
             if (mNmi == null) {
                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 3ab1cd7..aa9d4cc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -16,6 +16,10 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
@@ -99,7 +103,6 @@
 import android.os.ShellCommand;
 import android.os.StrictMode;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -188,6 +191,7 @@
     private boolean mStreaming;   // Streaming the profiling output to a file.
     private String mAgent;  // Agent to attach on startup.
     private boolean mAttachAgentDuringBind;  // Whether agent should be attached late.
+    private int mClockType; // Whether we need thread cpu / wall clock / both.
     private int mDisplayId;
     private int mTaskDisplayAreaFeatureId;
     private int mWindowingMode;
@@ -476,6 +480,9 @@
                     mAutoStop = false;
                 } else if (opt.equals("--sampling")) {
                     mSamplingInterval = Integer.parseInt(getNextArgRequired());
+                } else if (opt.equals("--clock-type")) {
+                    String clock_type = getNextArgRequired();
+                    mClockType = ProfilerInfo.getClockTypeFromString(clock_type);
                 } else if (opt.equals("--streaming")) {
                     mStreaming = true;
                 } else if (opt.equals("--attach-agent")) {
@@ -638,7 +645,7 @@
                     }
                 }
                 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
-                        mStreaming, mAgent, mAttachAgentDuringBind);
+                        mStreaming, mAgent, mAttachAgentDuringBind, mClockType);
             }
 
             pw.println("Starting: " + intent);
@@ -968,26 +975,17 @@
         return 0;
     }
 
-    static void removeWallOption() {
-        String props = SystemProperties.get("dalvik.vm.extra-opts");
-        if (props != null && props.contains("-Xprofile:wallclock")) {
-            props = props.replace("-Xprofile:wallclock", "");
-            props = props.trim();
-            SystemProperties.set("dalvik.vm.extra-opts", props);
-        }
-    }
-
     // NOTE: current profiles can only be started on default display (even on automotive builds with
     // passenger displays), so there's no need to pass a display-id
     private int runProfile(PrintWriter pw) throws RemoteException {
         final PrintWriter err = getErrPrintWriter();
         String profileFile = null;
         boolean start = false;
-        boolean wall = false;
         int userId = UserHandle.USER_CURRENT;
         int profileType = 0;
         mSamplingInterval = 0;
         mStreaming = false;
+        mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT;
 
         String process = null;
 
@@ -999,8 +997,9 @@
             while ((opt=getNextOption()) != null) {
                 if (opt.equals("--user")) {
                     userId = UserHandle.parseUserArg(getNextArgRequired());
-                } else if (opt.equals("--wall")) {
-                    wall = true;
+                } else if (opt.equals("--clock-type")) {
+                    String clock_type = getNextArgRequired();
+                    mClockType = ProfilerInfo.getClockTypeFromString(clock_type);
                 } else if (opt.equals("--streaming")) {
                     mStreaming = true;
                 } else if (opt.equals("--sampling")) {
@@ -1048,29 +1047,12 @@
                 return -1;
             }
             profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
-                    null, false);
+                    null, false, mClockType);
         }
 
-        try {
-            if (wall) {
-                // XXX doesn't work -- this needs to be set before booting.
-                String props = SystemProperties.get("dalvik.vm.extra-opts");
-                if (props == null || !props.contains("-Xprofile:wallclock")) {
-                    props = props + " -Xprofile:wallclock";
-                    //SystemProperties.set("dalvik.vm.extra-opts", props);
-                }
-            } else if (start) {
-                //removeWallOption();
-            }
-            if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
-                wall = false;
-                err.println("PROFILE FAILED on process " + process);
-                return -1;
-            }
-        } finally {
-            if (!wall) {
-                //removeWallOption();
-            }
+        if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
+            err.println("PROFILE FAILED on process " + process);
+            return -1;
         }
         return 0;
     }
@@ -1420,6 +1402,7 @@
         final boolean mSimpleMode;
         final String mTarget;
         final boolean mAlwaysContinue;
+        final boolean mAlwaysKill;
 
         static final int STATE_NORMAL = 0;
         static final int STATE_CRASHED = 1;
@@ -1448,7 +1431,7 @@
 
         MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
                 String gdbPort, boolean monkey, boolean simpleMode, String target,
-                boolean alwaysContinue) {
+                boolean alwaysContinue, boolean alwaysKill) {
             mInterface = iam;
             mPw = pw;
             mInput = input;
@@ -1457,6 +1440,7 @@
             mSimpleMode = simpleMode;
             mTarget = target;
             mAlwaysContinue = alwaysContinue;
+            mAlwaysKill = alwaysKill;
         }
 
         private boolean shouldHandlePackageOrProcess(String packageOrProcess) {
@@ -1515,6 +1499,9 @@
                 if (mAlwaysContinue) {
                     return true;
                 }
+                if (mAlwaysKill) {
+                    return false;
+                }
                 int result = waitControllerLocked(pid, STATE_CRASHED);
                 return result == RESULT_CRASH_KILL ? false : true;
             }
@@ -1539,6 +1526,9 @@
                 if (mAlwaysContinue) {
                     return 0;
                 }
+                if (mAlwaysKill) {
+                    return -1;
+                }
                 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
                 if (result == RESULT_EARLY_ANR_KILL) return -1;
                 return 0;
@@ -1566,6 +1556,9 @@
                 if (mAlwaysContinue) {
                     return 0;
                 }
+                if (mAlwaysKill) {
+                    return -1;
+                }
                 int result = waitControllerLocked(pid, STATE_ANR);
                 if (result == RESULT_ANR_KILL) return -1;
                 if (result == RESULT_ANR_WAIT) return 1;
@@ -1690,7 +1683,7 @@
         }
 
         void printMessageForState() {
-            if (mAlwaysContinue && mSimpleMode) {
+            if ((mAlwaysContinue || mAlwaysKill) && mSimpleMode) {
                 return; // In the simplest mode, we don't need to show anything.
             }
             switch (mState) {
@@ -1790,6 +1783,7 @@
         boolean monkey = false;
         boolean simpleMode = false;
         boolean alwaysContinue = false;
+        boolean alwaysKill = false;
         String target = null;
 
         while ((opt=getNextOption()) != null) {
@@ -1803,14 +1797,21 @@
                 simpleMode = true;
             } else if (opt.equals("-c")) {
                 alwaysContinue = true;
+            } else if (opt.equals("-k")) {
+                alwaysKill = true;
             } else {
                 getErrPrintWriter().println("Error: Unknown option: " + opt);
                 return -1;
             }
         }
+        if (alwaysContinue && alwaysKill) {
+            getErrPrintWriter().println("Error: -k and -c options can't be used together.");
+            return -1;
+        }
 
         MyActivityController controller = new MyActivityController(mInterface, pw,
-                getRawInputStream(), gdbPort, monkey, simpleMode, target, alwaysContinue);
+                getRawInputStream(), gdbPort, monkey, simpleMode, target, alwaysContinue,
+                alwaysKill);
         controller.run();
         return 0;
     }
@@ -1823,16 +1824,20 @@
         final InputStream mInput;
         final int mUid;
 
+        final int mMask;
+
         static final int STATE_NORMAL = 0;
 
         int mState;
 
-        MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
+        MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid,
+                int mask) {
             mInterface = service;
             mInternal = service;
             mPw = pw;
             mInput = input;
             mUid = uid;
+            mMask = mask;
         }
 
         @Override
@@ -1847,7 +1852,7 @@
                     mPw.print(" seq ");
                     mPw.print(procStateSeq);
                     mPw.print(" capability ");
-                    mPw.println(capability);
+                    mPw.println(capability & mMask);
                     mPw.flush();
                 } finally {
                     StrictMode.setThreadPolicy(oldPolicy);
@@ -1998,9 +2003,19 @@
     int runWatchUids(PrintWriter pw) throws RemoteException {
         String opt;
         int uid = -1;
+
+        // Because a lot of CTS won't ignore capabilities newly added, we report
+        // only the following capabilities -- the ones we had on Android T -- by default.
+        int mask = PROCESS_CAPABILITY_FOREGROUND_LOCATION
+                | PROCESS_CAPABILITY_FOREGROUND_CAMERA
+                | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
+                | PROCESS_CAPABILITY_NETWORK;
+
         while ((opt=getNextOption()) != null) {
             if (opt.equals("--oom")) {
                 uid = Integer.parseInt(getNextArgRequired());
+            } else if (opt.equals("--mask")) {
+                mask = Integer.parseInt(getNextArgRequired());
             } else {
                 getErrPrintWriter().println("Error: Unknown option: " + opt);
                 return -1;
@@ -2008,7 +2023,7 @@
             }
         }
 
-        MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
+        MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid, mask);
         controller.run();
         return 0;
     }
@@ -2243,9 +2258,10 @@
                     pw.println("Not supported");
                     return -1;
                 }
-                Slogf.d(TAG, "calling startUserInBackgroundVisibleOnDisplay(%d,%d)", userId,
-                        displayId);
-                success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId);
+                Slogf.d(TAG, "calling startUserInBackgroundVisibleOnDisplay(%d, %d, %s)", userId,
+                        displayId, waiter);
+                success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId,
+                        waiter);
                 displaySuffix = " on display " + displayId;
             }
             if (wait && success) {
@@ -3849,6 +3865,7 @@
 
     int runListDisplaysForStartingUsers(PrintWriter pw) throws RemoteException {
         int[] displayIds = mInterface.getDisplayIdsForStartingVisibleBackgroundUsers();
+        // NOTE: format below cannot be changed as it's used by ITestDevice
         pw.println(displayIds == null || displayIds.length == 0
                 ? "none"
                 : Arrays.toString(displayIds));
@@ -3928,9 +3945,9 @@
             pw.println("  help");
             pw.println("      Print this help text.");
             pw.println("  start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
-            pw.println("          [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
-            pw.println("          [--track-allocation] [--user <USER_ID> | current] [--suspend]");
-            pw.println("          <INTENT>");
+            pw.println("          [--sampling INTERVAL] [--clock-type <TYPE>] [--streaming]");
+            pw.println("          [-R COUNT] [-S] [--track-allocation]");
+            pw.println("          [--user <USER_ID> | current] [--suspend] <INTENT>");
             pw.println("      Start an Activity.  Options are:");
             pw.println("      -D: enable debugging");
             pw.println("      --suspend: debugged app suspend threads at startup (only with -D)");
@@ -3939,6 +3956,9 @@
             pw.println("      --start-profiler <FILE>: start profiler and send results to <FILE>");
             pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
             pw.println("          between samples (use with --start-profiler)");
+            pw.println("      --clock-type <TYPE>: type can be wall / thread-cpu / dual. Specify");
+            pw.println("          the clock that is used to report the timestamps when profiling");
+            pw.println("          The default value is dual. (use with --start-profiler)");
             pw.println("      --streaming: stream the profiling output to the specified file");
             pw.println("          (use with --start-profiler)");
             pw.println("      -P <FILE>: like above, but profiling stops when app goes idle");
@@ -4017,12 +4037,16 @@
             pw.println("      stop: stop tracing IPC transactions and dump the results to file.");
             pw.println("      --dump-file <FILE>: Specify the file the trace should be dumped to.");
             pw.println("  profile start [--user <USER_ID> current]");
+            pw.println("          [--clock-type <TYPE>]");
             pw.println("          [--sampling INTERVAL | --streaming] <PROCESS> <FILE>");
             pw.println("      Start profiler on a process.  The given <PROCESS> argument");
             pw.println("        may be either a process name or pid.  Options are:");
             pw.println("      --user <USER_ID> | current: When supplying a process name,");
             pw.println("          specify user of process to profile; uses current user if not");
             pw.println("          specified.");
+            pw.println("      --clock-type <TYPE>: use the specified clock to report timestamps.");
+            pw.println("          The type can be one of wall | thread-cpu | dual. The default");
+            pw.println("          value is dual.");
             pw.println("      --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
             pw.println("          between samples.");
             pw.println("      --streaming: stream the profiling output to the specified file.");
@@ -4073,15 +4097,22 @@
             pw.println("  make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
             pw.println("      If the given application's uid is in the background and waiting to");
             pw.println("      become idle (not allowing background services), do that now.");
-            pw.println("  monitor [--gdb <port>] [-p <TARGET>] [-s] [-c]");
+            pw.println("  monitor [--gdb <port>] [-p <TARGET>] [-s] [-c] [-k]");
             pw.println("      Start monitoring for crashes or ANRs.");
             pw.println("      --gdb: start gdbserv on the given port at crash/ANR");
             pw.println("      -p: only show events related to a specific process / package");
             pw.println("      -s: simple mode, only show a summary line for each event");
             pw.println("      -c: assume the input is always [c]ontinue");
-            pw.println("  watch-uids [--oom <uid>]");
+            pw.println("      -k: assume the input is always [k]ill");
+            pw.println("         -c and -k are mutually exclusive.");
+            pw.println("  watch-uids [--oom <uid>] [--mask <capabilities integer>]");
             pw.println("      Start watching for and reporting uid state changes.");
             pw.println("      --oom: specify a uid for which to report detailed change messages.");
+            pw.println("      --mask: Specify PROCESS_CAPABILITY_XXX mask to report. ");
+            pw.println("              By default, it only reports FOREGROUND_LOCATION (1)");
+            pw.println("              FOREGROUND_CAMERA (2), FOREGROUND_MICROPHONE (4)");
+            pw.println("              and NETWORK (8). New capabilities added on or after");
+            pw.println("              Android UDC will not be reported by default.");
             pw.println("  hang [--allow-restart]");
             pw.println("      Hang the system.");
             pw.println("      --allow-restart: allow watchdog to perform normal system restart");
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 4ad43fa..050ac19 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -2055,7 +2055,7 @@
                 }
             } else if (instr != null && instr.mProfileFile != null) {
                 profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false,
-                        null, false);
+                        null, false, 0);
             }
             if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
                 // We need to do a debuggable check here. See setAgentApp for why the check is
@@ -2065,7 +2065,7 @@
                     // Do not overwrite already requested agent.
                     if (profilerInfo == null) {
                         profilerInfo = new ProfilerInfo(null, null, 0, false, false,
-                                mAppAgentMap.get(processName), true);
+                                mAppAgentMap.get(processName), true, 0);
                     } else if (profilerInfo.agent == null) {
                         profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
                     }
@@ -2197,7 +2197,9 @@
                             + " mAutoStopProfiler="
                             + mProfileData.getProfilerInfo().autoStopProfiler
                             + " mStreamingOutput="
-                            + mProfileData.getProfilerInfo().streamingOutput);
+                            + mProfileData.getProfilerInfo().streamingOutput
+                            + " mClockType="
+                            + mProfileData.getProfilerInfo().clockType);
                     pw.println("  mProfileType=" + mProfileType);
                 }
             }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index f09622f..19235c9 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -483,6 +483,12 @@
             Objects.requireNonNull(uids);
             mCpuWakeupStats.noteWakingActivity(subsystem, elapsedMillis, uids);
         }
+
+        @Override
+        public void noteWakingSoundTrigger(long elapsedMillis, int uid) {
+            // TODO(b/267717665): Pipe to noteCpuWakingActivity once SoundTrigger starts using this.
+            Slog.w(TAG, "Sound trigger event dispatched to uid " + uid);
+        }
     }
 
     @Override
@@ -2880,7 +2886,7 @@
                                 checkinStats.setPowerProfileLocked(mPowerProfile);
                                 checkinStats.readSummaryFromParcel(in);
                                 in.recycle();
-                                checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
+                                checkinStats.dumpCheckin(mContext, pw, apps, flags,
                                         historyStart);
                                 mStats.mCheckinFile.delete();
                                 return;
@@ -2892,17 +2898,15 @@
                     }
                 }
             }
-            if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
+            if (DBG) Slog.d(TAG, "begin dumpCheckin from UID " + Binder.getCallingUid());
             awaitCompletion();
-            synchronized (mStats) {
-                mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
-                if (writeData) {
-                    mStats.writeAsyncLocked();
-                }
+            mStats.dumpCheckin(mContext, pw, apps, flags, historyStart);
+            if (writeData) {
+                mStats.writeAsyncLocked();
             }
-            if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
+            if (DBG) Slog.d(TAG, "end dumpCheckin");
         } else {
-            if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
+            if (DBG) Slog.d(TAG, "begin dump from UID " + Binder.getCallingUid());
             awaitCompletion();
 
             mStats.dump(mContext, pw, flags, reqUid, historyStart);
@@ -2912,7 +2916,7 @@
             pw.println();
             mCpuWakeupStats.dump(new IndentingPrintWriter(pw, "  "), SystemClock.elapsedRealtime());
 
-            if (DBG) Slog.d(TAG, "end dumpLocked");
+            if (DBG) Slog.d(TAG, "end dump");
         }
     }
 
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index 7290f32..c07ef1d 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -273,7 +273,7 @@
                         performReceiveLocked(oldRecord.resultToApp, oldRecord.resultTo,
                                 oldRecord.intent,
                                 Activity.RESULT_CANCELED, null, null,
-                                false, false, r.shareIdentity, oldRecord.userId,
+                                false, false, oldRecord.shareIdentity, oldRecord.userId,
                                 oldRecord.callingUid, r.callingUid, r.callerPackage,
                                 SystemClock.uptimeMillis() - oldRecord.enqueueTime, 0);
                     } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index b952ce0..f954420 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -1064,7 +1064,7 @@
         if (thread != null) {
             mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(
                     app, OOM_ADJ_REASON_FINISH_RECEIVER);
-            if (r.shareIdentity) {
+            if (r.shareIdentity && app.uid != r.callingUid) {
                 mService.mPackageManagerInt.grantImplicitAccess(r.userId, r.intent,
                         UserHandle.getAppId(app.uid), r.callingUid, true);
             }
diff --git a/services/core/java/com/android/server/am/BroadcastReceiverBatch.java b/services/core/java/com/android/server/am/BroadcastReceiverBatch.java
index 153403a..63575ba 100644
--- a/services/core/java/com/android/server/am/BroadcastReceiverBatch.java
+++ b/services/core/java/com/android/server/am/BroadcastReceiverBatch.java
@@ -171,8 +171,9 @@
     // Add a ReceiverInfo for a registered receiver.
     void schedule(@Nullable IIntentReceiver receiver, Intent intent,
             int resultCode, @Nullable String data, @Nullable Bundle extras, boolean ordered,
-            boolean sticky, boolean assumeDelivered, int sendingUser, int callingUid,
-            String callingPackage, int processState, @Nullable BroadcastRecord r, int index) {
+            boolean sticky, boolean assumeDelivered, int sendingUser, int sendingUid,
+            @Nullable String sendingPackage, int processState, @Nullable BroadcastRecord r,
+            int index) {
         ReceiverInfo ri = new ReceiverInfo();
         ri.intent = intent;
         ri.data = data;
@@ -185,8 +186,8 @@
         ri.receiver = receiver;
         ri.ordered = ordered;
         ri.sticky = sticky;
-        ri.sentFromUid = callingUid;
-        ri.sentFromPackage = callingPackage;
+        ri.sendingUid = sendingUid;
+        ri.sendingPackage = sendingPackage;
 
         mReceivers.add(ri);
         mCookies.add(cookiePool.next().set(r, index));
@@ -195,7 +196,7 @@
     void schedule(@Nullable Intent intent, @Nullable ActivityInfo activityInfo,
             @Nullable CompatibilityInfo compatInfo, int resultCode, @Nullable String data,
             @Nullable Bundle extras, boolean sync, boolean assumeDelivered, int sendingUser,
-            int callingUid, @Nullable String callingPackage, int processState,
+            int sendingUid, @Nullable String sendingPackage, int processState,
             @Nullable BroadcastRecord r, int index) {
         ReceiverInfo ri = new ReceiverInfo();
         ri.intent = intent;
@@ -209,8 +210,8 @@
         ri.activityInfo = activityInfo;
         ri.compatInfo = compatInfo;
         ri.sync = sync;
-        ri.sentFromUid = callingUid;
-        ri.sentFromPackage = callingPackage;
+        ri.sendingUid = sendingUid;
+        ri.sendingPackage = sendingPackage;
         mReceivers.add(ri);
         mCookies.add(cookiePool.next().set(r, index));
     }
@@ -223,21 +224,21 @@
     ArrayList<ReceiverInfo> registeredReceiver(@Nullable IIntentReceiver receiver,
             @Nullable Intent intent, int resultCode, @Nullable String data,
             @Nullable Bundle extras, boolean ordered, boolean sticky, boolean assumeDelivered,
-            int sendingUser, int callingUid, String callingPackage, int processState) {
+            int sendingUser, int sendingUid, @Nullable String sendingPackage, int processState) {
         reset();
         schedule(receiver, intent, resultCode, data, extras, ordered, sticky, assumeDelivered,
-                sendingUser, callingUid, callingPackage, processState, null, 0);
+                sendingUser, sendingUid, sendingPackage, processState, null, 0);
         return receivers();
     }
 
     ArrayList<ReceiverInfo> manifestReceiver(@Nullable Intent intent,
             @Nullable ActivityInfo activityInfo, @Nullable CompatibilityInfo compatInfo,
             int resultCode, @Nullable String data, @Nullable Bundle extras, boolean sync,
-            boolean assumeDelivered, int sendingUser, int callingUid, String callingPackage,
-            int processState) {
+            boolean assumeDelivered, int sendingUser, int sendingUid,
+            @Nullable String sendingPackage, int processState) {
         reset();
         schedule(intent, activityInfo, compatInfo, resultCode, data, extras, sync, assumeDelivered,
-                sendingUser, callingUid, callingPackage, processState, null, 0);
+                sendingUser, sendingUid, sendingPackage, processState, null, 0);
         return receivers();
     }
 
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 2689193..913f151 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -742,9 +742,6 @@
                         "compactApp " + app.mOptRecord.getReqCompactSource().name() + " "
                                 + app.mOptRecord.getReqCompactProfile().name() + " " + processName);
             }
-            Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER, ATRACE_COMPACTION_TRACK,
-                    "compactApp " + app.mOptRecord.getReqCompactSource().name() + " "
-                            + app.mOptRecord.getReqCompactProfile().name() + " " + processName);
             app.mOptRecord.setHasPendingCompact(true);
             app.mOptRecord.setForceCompact(force);
             mPendingCompactionProcesses.add(app);
@@ -1820,7 +1817,8 @@
                     try {
                         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                                 "Compact " + resolvedAction.name() + ": " + name
-                                        + " lastOomAdjReason: " + oomAdjReason);
+                                        + " lastOomAdjReason: " + oomAdjReason
+                                        + " source: " + compactSource.name());
                         long zramUsedKbBefore = getUsedZramMemory();
                         long startCpuTime = threadCpuTimeNs();
                         mProcessDependencies.performCompaction(resolvedAction, pid);
diff --git a/services/core/java/com/android/server/am/DropboxRateLimiter.java b/services/core/java/com/android/server/am/DropboxRateLimiter.java
index e5975c3..3792625 100644
--- a/services/core/java/com/android/server/am/DropboxRateLimiter.java
+++ b/services/core/java/com/android/server/am/DropboxRateLimiter.java
@@ -22,6 +22,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.expresslog.Counter;
 
 /** Rate limiter for adding errors into dropbox. */
 public class DropboxRateLimiter {
@@ -100,6 +101,9 @@
 
         for (int i = mErrorClusterRecords.size() - 1; i >= 0; i--) {
             if (now - mErrorClusterRecords.valueAt(i).getStartTime() > RATE_LIMIT_BUFFER_EXPIRY) {
+                Counter.logIncrement(
+                        "stability_errors.value_dropbox_buffer_expired_count",
+                        mErrorClusterRecords.valueAt(i).getCount());
                 mErrorClusterRecords.removeAt(i);
             }
         }
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index ea3c8dc..1534ff5 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package com.android.server.am
 
@@ -125,3 +125,6 @@
 30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)
 30101 am_foreground_service_denied (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)
 30102 am_foreground_service_stop (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)
+
+# Intent Sender redirect for UserHandle.USER_CURRENT
+30110 am_intent_sender_redirect_user (userId|1|5)
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 5cdcd42..ef15beb 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -38,6 +38,8 @@
 
 per-file ContentProviderHelper.java = varunshah@google.com, omakoto@google.com, jsharkey@google.com, yamasani@google.com
 
+per-file CachedAppOptimizer.java = file:/PERFORMANCE_OWNERS
+
 # Multiuser
 per-file User* = file:/MULTIUSER_OWNERS
 
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 3643db0..f11a3be 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
@@ -1242,7 +1243,7 @@
         for (int i = numLru - 1; i >= 0; i--) {
             ProcessRecord app = lruList.get(i);
             final ProcessStateRecord state = app.mState;
-            if (!app.isKilledByAm() && app.getThread() != null) {
+            if (!app.isKilledByAm() && app.getThread() != null && !app.isPendingFinishAttach()) {
                 // We don't need to apply the update for the process which didn't get computed
                 if (state.getCompletedAdjSeq() == mAdjSeq) {
                     applyOomAdjLSP(app, true, now, nowElapsed, oomAdjReason);
@@ -1706,7 +1707,7 @@
             state.setCurRawAdj(state.getMaxAdj());
             state.setHasForegroundActivities(false);
             state.setCurrentSchedulingGroup(SCHED_GROUP_DEFAULT);
-            state.setCurCapability(PROCESS_CAPABILITY_ALL);
+            state.setCurCapability(PROCESS_CAPABILITY_ALL); // BFSL allowed
             state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
             // System processes can do UI, and when they do we want to have
             // them trim their memory after the user leaves the UI.  To
@@ -1788,6 +1789,7 @@
             schedGroup = SCHED_GROUP_DEFAULT;
             state.setAdjType("instrumentation");
             procState = PROCESS_STATE_FOREGROUND_SERVICE;
+            capability |= PROCESS_CAPABILITY_BFSL;
             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
             }
@@ -1880,37 +1882,28 @@
                 adjType = "fg-service";
                 newAdj = PERCEPTIBLE_APP_ADJ;
                 newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+                capabilityFromFGS |= PROCESS_CAPABILITY_BFSL;
+
+            } else if (hasShortForegroundServices) {
+
+                // For short FGS.
+                adjType = "fg-service-short";
+
+                // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ
+                // (which uses MEDIUM_APP_ADJ + 1)
+                // from short-FGS.
+                // (We use +1 and +2, not +0 and +1, to be consistent with the following
+                // RECENT_FOREGROUND_APP_ADJ tweak)
+                newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1;
+
+                // We give the FGS procstate, but not PROCESS_CAPABILITY_BFSL, so
+                // short-fgs can't start FGS from the background.
+                newProcState = PROCESS_STATE_FOREGROUND_SERVICE;
 
             } else if (state.hasOverlayUi()) {
                 adjType = "has-overlay-ui";
                 newAdj = PERCEPTIBLE_APP_ADJ;
                 newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
-
-            } else if (hasForegroundServices) {
-                // If we get here, hasNonShortForegroundServices() must be false.
-
-                // TODO(short-service): Proactively run OomAjudster when the grace period finish.
-                if (!hasShortForegroundServices) {
-                    // All the short-FGSes within this process are timed out. Don't promote to FGS.
-                    // TODO(short-service): Should we set some unique oom-adj to make it detectable,
-                    // in a long trace?
-                } else {
-                    // For short FGS.
-                    adjType = "fg-service-short";
-                    // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ
-                    // (which uses MEDIUM_APP_ADJ + 2)
-                    // from short-FGS.
-                    // (We use +1 and +2, not +0 and +1, to be consistent with the following
-                    // RECENT_FOREGROUND_APP_ADJ tweak)
-                    newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1;
-
-                    // Short-FGS gets a below-BFGS procstate, so it can't start another FGS from it.
-                    newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
-
-                    // Same as EJ, we explicitly grant network access to short FGS,
-                    // even when battery saver or data saver is enabled.
-                    capabilityFromFGS |= PROCESS_CAPABILITY_NETWORK;
-                }
             }
 
             if (adjType != null) {
@@ -2220,6 +2213,11 @@
                         app.mOptRecord.setShouldNotFreeze(true);
                     }
 
+                    // We always propagate PROCESS_CAPABILITY_BFSL over bindings here,
+                    // but, right before actually setting it to the process,
+                    // we check the final procstate, and remove it if the procsate is below BFGS.
+                    capability |= getBfslCapabilityFromClient(client);
+
                     if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) {
                         if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
                             capability |= cstate.getCurCapability();
@@ -2540,6 +2538,11 @@
                 int clientAdj = cstate.getCurRawAdj();
                 int clientProcState = cstate.getCurRawProcState();
 
+                // We always propagate PROCESS_CAPABILITY_BFSL to providers here,
+                // but, right before actually setting it to the process,
+                // we check the final procstate, and remove it if the procsate is below BFGS.
+                capability |= getBfslCapabilityFromClient(client);
+
                 if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
                     // If the other app is cached for any reason, for purposes here
                     // we are going to consider it empty.
@@ -2718,6 +2721,11 @@
 
         capability |= getDefaultCapability(app, procState);
 
+        // Procstates below BFGS should never have this capability.
+        if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+            capability &= ~PROCESS_CAPABILITY_BFSL;
+        }
+
         // Do final modification to adj.  Everything we do between here and applying
         // the final setAdj must be done in this function, because we will also use
         // it when computing the final cached adj later.  Note that we don't need to
@@ -2743,9 +2751,9 @@
             case PROCESS_STATE_PERSISTENT:
             case PROCESS_STATE_PERSISTENT_UI:
             case PROCESS_STATE_TOP:
-                return PROCESS_CAPABILITY_ALL;
+                return PROCESS_CAPABILITY_ALL; // BFSL allowed
             case PROCESS_STATE_BOUND_TOP:
-                return PROCESS_CAPABILITY_NETWORK;
+                return PROCESS_CAPABILITY_NETWORK | PROCESS_CAPABILITY_BFSL;
             case PROCESS_STATE_FOREGROUND_SERVICE:
                 if (app.getActiveInstrumentation() != null) {
                     return PROCESS_CAPABILITY_ALL_IMPLICIT | PROCESS_CAPABILITY_NETWORK ;
@@ -2763,6 +2771,53 @@
     }
 
     /**
+     * @return the BFSL capability from a client (of a service binding or provider).
+     */
+    int getBfslCapabilityFromClient(ProcessRecord client) {
+        // Procstates above FGS should always have this flag. We shouldn't need this logic,
+        // but let's do it just in case.
+        if (client.mState.getCurProcState() < PROCESS_STATE_FOREGROUND_SERVICE) {
+            return PROCESS_CAPABILITY_BFSL;
+        }
+        // Otherwise, use the process's cur capability.
+
+        // Note: BFSL is a per-UID check, not per-process, but here, the BFSL capability is still
+        // propagated on a per-process basis.
+        //
+        // For example, consider this case:
+        // - There are App 1 and App 2.
+        // - App 1 has two processes
+        //   Proc #1A, procstate BFGS with CAPABILITY_BFSL
+        //   Proc #1B, procstate FGS with no CAPABILITY_BFSL (i.e. process has a short FGS)
+        //        And this process binds to Proc #2 of App 2.
+        //
+        //       (Note because #1A has CAPABILITY_BFSL, App 1's UidRecord has CAPABILITY_BFSL.)
+        //
+        // - App 2 has one process:
+        //   Proc #2, procstate FGS due to the above binding, _with no CAPABILITY_BFSL_.
+        //
+        // In this case, #2 will not get CAPABILITY_BFSL because the binding client (#1B)
+        // doesn't have this capability. (Even though App 1's UidRecord has it.)
+        //
+        // This may look weird, because App 2 _is_ still BFSL allowed, because "it's bound by
+        // an app that is BFSL-allowed". (See [bookmark: 61867f60-007c-408c-a2c4-e19e96056135]
+        // in ActiveServices.)
+        //
+        // So why don't we propagate PROCESS_CAPABILITY_BFSL from App 1's UID record?
+        // This is because short-FGS acts like "below BFGS" as far as BFSL is concerned,
+        // similar to how JobScheduler jobs are below BFGS and apps can't start FGS from there.
+        //
+        // If #1B was running a job instead of a short-FGS, then its procstate would be below BFGS.
+        // Then #2's procstate would also be below BFGS. So #2 wouldn't get CAPABILITY_BFSL.
+        // Similarly, if #1B has a short FGS, even though the procstate of #1B and #2 would be FGS,
+        // they both still wouldn't get CAPABILITY_BFSL.
+        //
+        // However, again, because #2 is bound by App 1, which is BFSL-allowed (because of #1A)
+        // App 2 would still BFSL-allowed, due to the aforementioned check in ActiveServices.
+        return client.mState.getCurCapability() & PROCESS_CAPABILITY_BFSL;
+    }
+
+    /**
      * Checks if for the given app and client, there's a cycle that should skip over the client
      * for now or use partial values to evaluate the effect of the client binding.
      * @param app
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 04c0d64..ee315bd 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2514,7 +2514,7 @@
     }
 
     @GuardedBy("mService")
-    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
+    String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
         StringBuilder sb = null;
         if (app.isKilledByAm()) {
             if (sb == null) sb = new StringBuilder();
@@ -3888,7 +3888,7 @@
         return runList;
     }
 
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     int getLruSizeLOSP() {
         return mLruProcesses.size();
     }
@@ -3896,7 +3896,7 @@
     /**
      * Return the reference to the LRU list, call this function for read-only access
      */
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     ArrayList<ProcessRecord> getLruProcessesLOSP() {
         return mLruProcesses;
     }
@@ -3904,7 +3904,7 @@
     /**
      * Return the reference to the LRU list, call this function for read/write access
      */
-    @GuardedBy({"mService", "mProfileLock"})
+    @GuardedBy({"mService", "mProcLock"})
     ArrayList<ProcessRecord> getLruProcessesLSP() {
         return mLruProcesses;
     }
@@ -3913,12 +3913,12 @@
      * For test only
      */
     @VisibleForTesting
-    @GuardedBy({"mService", "mProfileLock"})
+    @GuardedBy({"mService", "mProcLock"})
     void setLruProcessServiceStartLSP(int pos) {
         mLruProcessServiceStart = pos;
     }
 
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     int getLruProcessServiceStartLOSP() {
         return mLruProcessServiceStart;
     }
@@ -3931,7 +3931,7 @@
      *                       to most recent used ProcessRecord.
      * @param callback The callback interface to accept the current ProcessRecord.
      */
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     void forEachLruProcessesLOSP(boolean iterateForward,
             @NonNull Consumer<ProcessRecord> callback) {
         if (iterateForward) {
@@ -3956,7 +3956,7 @@
      *                 a non-null object, the search will be halted and this object will be used
      *                 as the return value of this search function.
      */
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     <R> R searchEachLruProcessesLOSP(boolean iterateForward,
             @NonNull Function<ProcessRecord, R> callback) {
         if (iterateForward) {
@@ -3977,17 +3977,17 @@
         return null;
     }
 
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     boolean isInLruListLOSP(ProcessRecord app) {
         return mLruProcesses.contains(app);
     }
 
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     int getLruSeqLOSP() {
         return mLruSeq;
     }
 
-    @GuardedBy(anyOf = {"mService", "mProfileLock"})
+    @GuardedBy(anyOf = {"mService", "mProcLock"})
     MyProcessMap getProcessNamesLOSP() {
         return mProcessNames;
     }
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index e6cb596..a707202 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -175,6 +175,12 @@
     private boolean mPendingStart;
 
     /**
+     * Process finish attach application is pending.
+     */
+    @GuardedBy("mService")
+    private boolean mPendingFinishAttach;
+
+    /**
      * Seq no. Indicating the latest process start associated with this process record.
      */
     @GuardedBy("mService")
@@ -201,6 +207,11 @@
     private volatile long mStartElapsedTime;
 
     /**
+     * When the process was sent the bindApplication request
+     */
+    private volatile long mBindApplicationTime;
+
+    /**
      * This will be same as {@link #uid} usually except for some apps used during factory testing.
      */
     private volatile int mStartUid;
@@ -698,6 +709,16 @@
     }
 
     @GuardedBy("mService")
+    void setPendingFinishAttach(boolean pendingFinishAttach) {
+        mPendingFinishAttach = pendingFinishAttach;
+    }
+
+    @GuardedBy("mService")
+    boolean isPendingFinishAttach() {
+        return mPendingFinishAttach;
+    }
+
+    @GuardedBy("mService")
     long getStartSeq() {
         return mStartSeq;
     }
@@ -740,6 +761,14 @@
         return mStartElapsedTime;
     }
 
+    long getBindApplicationTime() {
+        return mBindApplicationTime;
+    }
+
+    void setBindApplicationTime(long bindApplicationTime) {
+        mBindApplicationTime = bindApplicationTime;
+    }
+
     int getStartUid() {
         return mStartUid;
     }
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index 2ad2077..71d5d39 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -17,7 +17,6 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
-import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
@@ -1180,11 +1179,6 @@
     }
 
     @GuardedBy("mService")
-    boolean isAllowedStartFgs() {
-        return mCurProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
-    }
-
-    @GuardedBy("mService")
     boolean isBackgroundRestricted() {
         return mBackgroundRestricted;
     }
diff --git a/services/core/java/com/android/server/am/ReceiverList.java b/services/core/java/com/android/server/am/ReceiverList.java
index f3d8ba15..7d2dab6 100644
--- a/services/core/java/com/android/server/am/ReceiverList.java
+++ b/services/core/java/com/android/server/am/ReceiverList.java
@@ -25,8 +25,6 @@
 import android.util.Printer;
 import android.util.proto.ProtoOutputStream;
 
-import com.android.server.IntentResolver;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
@@ -74,7 +72,7 @@
         final int N = size();
         for (int i = 0; i < N; i++) {
             final BroadcastFilter f = get(i);
-            if (IntentResolver.filterEquals(f, filter)) {
+            if (IntentFilter.filterEquals(f, filter)) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/am/SameProcessApplicationThread.java b/services/core/java/com/android/server/am/SameProcessApplicationThread.java
index dcb02ea..82dd5c2 100644
--- a/services/core/java/com/android/server/am/SameProcessApplicationThread.java
+++ b/services/core/java/com/android/server/am/SameProcessApplicationThread.java
@@ -48,12 +48,12 @@
     @Override
     public void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
             int resultCode, String data, Bundle extras, boolean ordered, boolean assumeDelivered,
-            int sendingUser, int processState, int sentFromUid, String sentFromPackage) {
+            int sendingUser, int processState, int sendingUid, String sendingPackage) {
         mHandler.post(() -> {
             try {
                 mWrapped.scheduleReceiver(intent, info, compatInfo, resultCode, data, extras,
-                        ordered, assumeDelivered, sendingUser, processState, sentFromUid,
-                        sentFromPackage);
+                        ordered, assumeDelivered, sendingUser, processState, sendingUid,
+                        sendingPackage);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -63,12 +63,12 @@
     @Override
     public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, int resultCode,
             String data, Bundle extras, boolean ordered, boolean sticky, boolean assumeDelivered,
-            int sendingUser, int processState, int sentFromUid, String sentFromPackage) {
+            int sendingUser, int processState, int sendingUid, String sendingPackage) {
         mHandler.post(() -> {
             try {
                 mWrapped.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras,
-                        ordered, sticky, assumeDelivered, sendingUser, processState, sentFromUid,
-                        sentFromPackage);
+                        ordered, sticky, assumeDelivered, sendingUser, processState, sendingUid,
+                        sendingPackage);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -82,11 +82,11 @@
             if (r.registered) {
                 scheduleRegisteredReceiver(r.receiver, r.intent,
                         r.resultCode, r.data, r.extras, r.ordered, r.sticky, r.assumeDelivered,
-                        r.sendingUser, r.processState, r.sentFromUid, r.sentFromPackage);
+                        r.sendingUser, r.processState, r.sendingUid, r.sendingPackage);
             } else {
                 scheduleReceiver(r.intent, r.activityInfo, r.compatInfo,
                         r.resultCode, r.data, r.extras, r.sync, r.assumeDelivered,
-                        r.sendingUser, r.processState, r.sentFromUid, r.sentFromPackage);
+                        r.sendingUser, r.processState, r.sendingUid, r.sendingPackage);
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index f22624c..60a7f93 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -80,6 +80,7 @@
     @VisibleForTesting
     static final String[] sDeviceConfigScopes = new String[] {
         DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+        DeviceConfig.NAMESPACE_CAMERA_NATIVE,
         DeviceConfig.NAMESPACE_CONFIGURATION,
         DeviceConfig.NAMESPACE_CONNECTIVITY,
         DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
@@ -103,6 +104,7 @@
         DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE,
         DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
+        DeviceConfig.NAMESPACE_MEMORY_SAFETY_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_MEMORY_SAFETY_NATIVE,
         DeviceConfig.NAMESPACE_HDMI_CONTROL
     };
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index b617582..bfc022b 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -443,6 +443,8 @@
         sb.append(",");
         sb.append(lastNetworkUpdatedProcStateSeq);
         sb.append(")}");
+        sb.append(" caps=");
+        ActivityManager.printCapabilitiesSummary(sb, mCurCapability);
         return sb.toString();
     }
 }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index b2e4740..b0a14ab 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1560,16 +1560,18 @@
      *
      * @param userId user to be started
      * @param displayId display where the user will be visible
+     * @param unlockListener Listener to be informed when the user has started and unlocked.
      *
      * @return whether the user was started
      */
-    boolean startUserVisibleOnDisplay(@UserIdInt int userId, int displayId) {
+    boolean startUserVisibleOnDisplay(@UserIdInt int userId, int displayId,
+            @Nullable IProgressListener unlockListener) {
         checkCallingHasOneOfThosePermissions("startUserOnDisplay",
                 MANAGE_USERS, INTERACT_ACROSS_USERS);
 
         try {
             return startUserNoChecks(userId, displayId, USER_START_MODE_BACKGROUND_VISIBLE,
-                    /* unlockListener= */ null);
+                    unlockListener);
         } catch (RuntimeException e) {
             Slogf.e(TAG, "startUserOnSecondaryDisplay(%d, %d) failed: %s", userId, displayId, e);
             return false;
@@ -1984,10 +1986,6 @@
             Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
             return false;
         }
-        if (targetUserInfo.isProfile()) {
-            Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
-            return false;
-        }
         if (FactoryResetter.isFactoryResetting()) {
             Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": factory reset in progress");
             return false;
@@ -2246,7 +2244,7 @@
         // If there is no challenge set, dismiss the keyguard right away
         if (isUserSwitchUiEnabled && !mInjector.getKeyguardManager().isDeviceSecure(newUserId)) {
             // Wait until the keyguard is dismissed to unfreeze
-            mInjector.dismissKeyguard(runnable, "User Switch");
+            mInjector.dismissKeyguard(runnable);
         } else {
             runnable.run();
         }
@@ -3714,7 +3712,7 @@
             return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
         }
 
-        protected void dismissKeyguard(Runnable runnable, String reason) {
+        protected void dismissKeyguard(Runnable runnable) {
             final AtomicBoolean isFirst = new AtomicBoolean(true);
             final Runnable runOnce = () -> {
                 if (isFirst.getAndSet(false)) {
@@ -3738,7 +3736,7 @@
                 public void onDismissCancelled() throws RemoteException {
                     mHandler.post(runOnce);
                 }
-            }, reason);
+            }, /* message= */ null);
         }
 
         boolean isUsersOnSecondaryDisplaysEnabled() {
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
index ef0de18..f520f6a 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java
@@ -16,9 +16,12 @@
 
 package com.android.server.appop;
 
+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.WATCH_FOREGROUND_CHANGES;
 import static android.app.AppOpsManager.opRestrictsRead;
+import static android.app.AppOpsManager.opToDefaultMode;
 
 import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS;
 
@@ -31,24 +34,46 @@
 import android.app.AppOpsManager.Mode;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserPackage;
+import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
+import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.XmlUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.LocalServices;
+import com.android.server.pm.UserManagerInternal;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import libcore.util.EmptyArray;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
 
 
@@ -60,6 +85,36 @@
 
     static final String TAG = "LegacyAppOpsServiceInterfaceImpl";
 
+    private static final boolean DEBUG = false;
+
+    // Write at most every 30 minutes.
+    private static final long WRITE_DELAY = DEBUG ? 1000 : 30 * 60 * 1000;
+
+    /**
+     * Sentinel integer version to denote that there was no appops.xml found on boot.
+     * This will happen when a device boots with no existing userdata.
+     */
+    private static final int NO_FILE_VERSION = -2;
+
+    /**
+     * Sentinel integer version to denote that there was no version in the appops.xml found on boot.
+     * This means the file is coming from a build before versioning was added.
+     */
+    private static final int NO_VERSION = -1;
+
+    /**
+     * Increment by one every time and add the corresponding upgrade logic in
+     * {@link #upgradeLocked(int)} below. The first version was 1.
+     */
+    @VisibleForTesting
+    static final int CURRENT_VERSION = 3;
+
+    /**
+     * This stores the version of appops.xml seen at boot. If this is smaller than
+     * {@link #CURRENT_VERSION}, then we will run {@link #upgradeLocked(int)} on startup.
+     */
+    private int mVersionAtBoot = NO_FILE_VERSION;
+
     // Must be the same object that the AppOpsService is using for locking.
     final Object mLock;
     final Handler mHandler;
@@ -77,17 +132,35 @@
     final ArrayMap<String, ArraySet<OnOpModeChangedListener>> mPackageModeWatchers =
             new ArrayMap<>();
 
-    final PersistenceScheduler mPersistenceScheduler;
+    final AtomicFile mFile;
+    final Runnable mWriteRunner = new Runnable() {
+        public void run() {
+            synchronized (mLock) {
+                mWriteScheduled = false;
+                mFastWriteScheduled = false;
+                AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+                    @Override
+                    protected Void doInBackground(Void... params) {
+                        writeState();
+                        return null;
+                    }
+                };
+                task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+            }
+        }
+    };
+
+    boolean mWriteScheduled;
+    boolean mFastWriteScheduled;
 
 
     // Constant meaning that any UID should be matched when dispatching callbacks
     private static final int UID_ANY = -2;
 
-
-    AppOpsCheckingServiceImpl(PersistenceScheduler persistenceScheduler,
+    AppOpsCheckingServiceImpl(File storageFile,
             @NonNull Object lock, Handler handler, Context context,
             SparseArray<int[]> switchedOps) {
-        this.mPersistenceScheduler = persistenceScheduler;
+        this.mFile = new AtomicFile(storageFile);
         this.mLock = lock;
         this.mHandler = handler;
         this.mContext = context;
@@ -95,6 +168,15 @@
     }
 
     @Override
+    public void systemReady() {
+        synchronized (mLock) {
+            // TODO: This file version upgrade code may still need to happen after we switch to
+            //  another implementation of AppOpsCheckingServiceInterface.
+            upgradeLocked(mVersionAtBoot);
+        }
+    }
+
+    @Override
     public SparseIntArray getNonDefaultUidModes(int uid) {
         synchronized (mLock) {
             SparseIntArray opModes = mUidModes.get(uid, null);
@@ -106,6 +188,21 @@
     }
 
     @Override
+    public SparseIntArray getNonDefaultPackageModes(String packageName, int userId) {
+        synchronized (mLock) {
+            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId);
+            if (packageModes == null) {
+                return new SparseIntArray();
+            }
+            SparseIntArray opModes = packageModes.get(packageName);
+            if (opModes == null) {
+                return new SparseIntArray();
+            }
+            return opModes.clone();
+        }
+    }
+
+    @Override
     public int getUidMode(int uid, int op) {
         synchronized (mLock) {
             SparseIntArray opModes = mUidModes.get(uid, null);
@@ -126,7 +223,7 @@
                     opModes = new SparseIntArray();
                     mUidModes.put(uid, opModes);
                     opModes.put(op, mode);
-                    mPersistenceScheduler.scheduleWriteLocked();
+                    scheduleWriteLocked();
                 }
             } else {
                 if (opModes.indexOfKey(op) >= 0 && opModes.get(op) == mode) {
@@ -141,7 +238,7 @@
                 } else {
                     opModes.put(op, mode);
                 }
-                mPersistenceScheduler.scheduleWriteLocked();
+                scheduleWriteLocked();
             }
         }
         return true;
@@ -177,7 +274,7 @@
                     opModes = new SparseIntArray();
                     packageModes.put(packageName, opModes);
                     opModes.put(op, mode);
-                    mPersistenceScheduler.scheduleWriteLocked();
+                    scheduleWriteLocked();
                 }
             } else {
                 if (opModes.indexOfKey(op) >= 0 && opModes.get(op) == mode) {
@@ -192,7 +289,7 @@
                 } else {
                     opModes.put(op, mode);
                 }
-                mPersistenceScheduler.scheduleWriteLocked();
+                scheduleWriteLocked();
             }
         }
     }
@@ -205,7 +302,7 @@
                 return;
             }
             mUidModes.remove(uid);
-            mPersistenceScheduler.scheduleFastWriteLocked();
+            scheduleFastWriteLocked();
         }
     }
 
@@ -238,7 +335,7 @@
             }
             SparseIntArray ops = packageModes.remove(packageName);
             if (ops != null) {
-                mPersistenceScheduler.scheduleFastWriteLocked();
+                scheduleFastWriteLocked();
                 return true;
             }
             return false;
@@ -598,4 +695,487 @@
         return needSep;
     }
 
+    private void scheduleWriteLocked() {
+        if (!mWriteScheduled) {
+            mWriteScheduled = true;
+            mHandler.postDelayed(mWriteRunner, WRITE_DELAY);
+        }
+    }
+
+    private void scheduleFastWriteLocked() {
+        if (!mFastWriteScheduled) {
+            mWriteScheduled = true;
+            mFastWriteScheduled = true;
+            mHandler.removeCallbacks(mWriteRunner);
+            mHandler.postDelayed(mWriteRunner, 10 * 1000);
+        }
+    }
+
+    @Override
+    public void writeState() {
+        synchronized (mFile) {
+            FileOutputStream stream;
+            try {
+                stream = mFile.startWrite();
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to write state: " + e);
+                return;
+            }
+
+            try {
+                TypedXmlSerializer out = Xml.resolveSerializer(stream);
+                out.startDocument(null, true);
+                out.startTag(null, "app-ops");
+                out.attributeInt(null, "v", CURRENT_VERSION);
+
+                SparseArray<SparseIntArray> uidModesCopy = new SparseArray<>();
+                SparseArray<ArrayMap<String, SparseIntArray>> userPackageModesCopy =
+                        new SparseArray<>();
+                int uidModesSize;
+                int usersSize;
+                synchronized (mLock) {
+                    uidModesSize = mUidModes.size();
+                    for (int uidIdx = 0; uidIdx < uidModesSize; uidIdx++) {
+                        int uid = mUidModes.keyAt(uidIdx);
+                        SparseIntArray modes = mUidModes.valueAt(uidIdx);
+                        uidModesCopy.put(uid, modes.clone());
+                    }
+                    usersSize = mUserPackageModes.size();
+                    for (int userIdx = 0; userIdx < usersSize; userIdx++) {
+                        int user = mUserPackageModes.keyAt(userIdx);
+                        ArrayMap<String, SparseIntArray> packageModes =
+                                mUserPackageModes.valueAt(userIdx);
+                        ArrayMap<String, SparseIntArray> packageModesCopy = new ArrayMap<>();
+                        userPackageModesCopy.put(user, packageModesCopy);
+                        for (int pkgIdx = 0, packageModesSize = packageModes.size();
+                                pkgIdx < packageModesSize; pkgIdx++) {
+                            String pkg = packageModes.keyAt(pkgIdx);
+                            SparseIntArray modes = packageModes.valueAt(pkgIdx);
+                            packageModesCopy.put(pkg, modes.clone());
+                        }
+                    }
+                }
+
+                for (int uidStateNum = 0; uidStateNum < uidModesSize; uidStateNum++) {
+                    int uid = uidModesCopy.keyAt(uidStateNum);
+                    SparseIntArray modes = uidModesCopy.valueAt(uidStateNum);
+
+                    out.startTag(null, "uid");
+                    out.attributeInt(null, "n", uid);
+
+                    final int modesSize = modes.size();
+                    for (int modeIdx = 0; modeIdx < modesSize; modeIdx++) {
+                        final int op = modes.keyAt(modeIdx);
+                        final int mode = modes.valueAt(modeIdx);
+                        out.startTag(null, "op");
+                        out.attributeInt(null, "n", op);
+                        out.attributeInt(null, "m", mode);
+                        out.endTag(null, "op");
+                    }
+                    out.endTag(null, "uid");
+                }
+
+                for (int userIdx = 0; userIdx < usersSize; userIdx++) {
+                    int userId = userPackageModesCopy.keyAt(userIdx);
+                    ArrayMap<String, SparseIntArray> packageModes =
+                            userPackageModesCopy.valueAt(userIdx);
+
+                    out.startTag(null, "user");
+                    out.attributeInt(null, "n", userId);
+
+                    int packageModesSize = packageModes.size();
+                    for (int pkgIdx = 0; pkgIdx < packageModesSize; pkgIdx++) {
+                        String pkg = packageModes.keyAt(pkgIdx);
+                        SparseIntArray modes = packageModes.valueAt(pkgIdx);
+
+                        out.startTag(null, "pkg");
+                        out.attribute(null, "n", pkg);
+
+                        final int modesSize = modes.size();
+                        for (int modeIdx = 0; modeIdx < modesSize; modeIdx++) {
+                            final int op = modes.keyAt(modeIdx);
+                            final int mode = modes.valueAt(modeIdx);
+
+                            out.startTag(null, "op");
+                            out.attributeInt(null, "n", op);
+                            out.attributeInt(null, "m", mode);
+                            out.endTag(null, "op");
+                        }
+                        out.endTag(null, "pkg");
+                    }
+                    out.endTag(null, "user");
+                }
+
+                out.endTag(null, "app-ops");
+                out.endDocument();
+                mFile.finishWrite(stream);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to write state, restoring backup.", e);
+                mFile.failWrite(stream);
+            }
+        }
+    }
+
+    /* Current format
+        <uid>
+          <op>
+        </uid>
+
+        <user>
+          <pkg>
+            <op>
+          </pkg>
+        </user>
+     */
+
+    @Override
+    public void readState() {
+        synchronized (mFile) {
+            synchronized (mLock) {
+                FileInputStream stream;
+                try {
+                    stream = mFile.openRead();
+                } catch (FileNotFoundException e) {
+                    Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty");
+                    mVersionAtBoot = NO_FILE_VERSION;
+                    return;
+                }
+
+                try {
+                    TypedXmlPullParser parser = Xml.resolvePullParser(stream);
+                    int type;
+                    while ((type = parser.next()) != XmlPullParser.START_TAG
+                            && type != XmlPullParser.END_DOCUMENT) {
+                        // Parse next until we reach the start or end
+                    }
+
+                    if (type != XmlPullParser.START_TAG) {
+                        throw new IllegalStateException("no start tag found");
+                    }
+
+                    mVersionAtBoot = parser.getAttributeInt(null, "v", NO_VERSION);
+
+                    int outerDepth = parser.getDepth();
+                    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                            continue;
+                        }
+
+                        String tagName = parser.getName();
+                        if (tagName.equals("pkg")) {
+                            // version 2 has the structure pkg -> uid -> op ->
+                            // in version 3, since pkg and uid states are kept completely
+                            // independent we switch to user -> pkg -> op
+                            readPackage(parser);
+                        } else if (tagName.equals("uid")) {
+                            readUidOps(parser);
+                        } else if (tagName.equals("user")) {
+                            readUser(parser);
+                        } else {
+                            Slog.w(TAG, "Unknown element under <app-ops>: "
+                                    + parser.getName());
+                            XmlUtils.skipCurrentTag(parser);
+                        }
+                    }
+                    return;
+                } catch (XmlPullParserException e) {
+                    throw new RuntimeException(e);
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        boolean doWrite = false;
+        synchronized (this) {
+            if (mWriteScheduled) {
+                mWriteScheduled = false;
+                mFastWriteScheduled = false;
+                mHandler.removeCallbacks(mWriteRunner);
+                doWrite = true;
+            }
+        }
+        if (doWrite) {
+            writeState();
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void readUidOps(TypedXmlPullParser parser) throws NumberFormatException,
+            XmlPullParserException, IOException {
+        final int uid = parser.getAttributeInt(null, "n");
+        SparseIntArray modes = mUidModes.get(uid);
+        if (modes == null) {
+            modes = new SparseIntArray();
+            mUidModes.put(uid, modes);
+        }
+
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            String tagName = parser.getName();
+            if (tagName.equals("op")) {
+                final int code = parser.getAttributeInt(null, "n");
+                final int mode = parser.getAttributeInt(null, "m");
+
+                if (mode != opToDefaultMode(code)) {
+                    modes.put(code, mode);
+                }
+            } else {
+                Slog.w(TAG, "Unknown element under <uid>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
+    /*
+     * Used for migration when pkg is the depth=1 tag
+     */
+    @GuardedBy("mLock")
+    private void readPackage(TypedXmlPullParser parser)
+            throws NumberFormatException, XmlPullParserException, IOException {
+        String pkgName = parser.getAttributeValue(null, "n");
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            String tagName = parser.getName();
+            if (tagName.equals("uid")) {
+                readUid(parser, pkgName);
+            } else {
+                Slog.w(TAG, "Unknown element under <pkg>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
+    /*
+     * Used for migration when uid is the depth=2 tag
+     */
+    @GuardedBy("mLock")
+    private void readUid(TypedXmlPullParser parser, String pkgName)
+            throws NumberFormatException, XmlPullParserException, IOException {
+        int userId = UserHandle.getUserId(parser.getAttributeInt(null, "n"));
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            String tagName = parser.getName();
+            if (tagName.equals("op")) {
+                readOp(parser, userId, pkgName);
+            } else {
+                Slog.w(TAG, "Unknown element under <pkg>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void readUser(TypedXmlPullParser parser)
+            throws NumberFormatException, XmlPullParserException, IOException {
+        int userId = parser.getAttributeInt(null, "n");
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            String tagName = parser.getName();
+            if (tagName.equals("pkg")) {
+                readPackage(parser, userId);
+            } else {
+                Slog.w(TAG, "Unknown element under <user>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void readPackage(TypedXmlPullParser parser, int userId)
+            throws NumberFormatException, XmlPullParserException, IOException {
+        String pkgName = parser.getAttributeValue(null, "n");
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+
+            String tagName = parser.getName();
+            if (tagName.equals("op")) {
+                readOp(parser, userId, pkgName);
+            } else {
+                Slog.w(TAG, "Unknown element under <pkg>: "
+                        + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void readOp(TypedXmlPullParser parser, int userId, @NonNull String pkgName)
+            throws NumberFormatException, XmlPullParserException {
+        final int opCode = parser.getAttributeInt(null, "n");
+        final int defaultMode = AppOpsManager.opToDefaultMode(opCode);
+        final int mode = parser.getAttributeInt(null, "m", defaultMode);
+
+        if (mode != defaultMode) {
+            ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId);
+            if (packageModes == null) {
+                packageModes = new ArrayMap<>();
+                mUserPackageModes.put(userId, packageModes);
+            }
+
+            SparseIntArray modes = packageModes.get(pkgName);
+            if (modes == null) {
+                modes = new SparseIntArray();
+                packageModes.put(pkgName, modes);
+            }
+
+            modes.put(opCode, mode);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void upgradeLocked(int oldVersion) {
+        if (oldVersion == NO_FILE_VERSION || oldVersion >= CURRENT_VERSION) {
+            return;
+        }
+        Slog.d(TAG, "Upgrading app-ops xml from version " + oldVersion + " to " + CURRENT_VERSION);
+        switch (oldVersion) {
+            case NO_VERSION:
+                upgradeRunAnyInBackgroundLocked();
+                // fall through
+            case 1:
+                upgradeScheduleExactAlarmLocked();
+                // fall through
+            case 2:
+                // for future upgrades
+        }
+        scheduleFastWriteLocked();
+    }
+
+    /**
+     * For all installed apps at time of upgrade, OP_RUN_ANY_IN_BACKGROUND will inherit the mode
+     *  from RUN_IN_BACKGROUND.
+     */
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    void upgradeRunAnyInBackgroundLocked() {
+        final int uidModesSize = mUidModes.size();
+        for (int uidIdx = 0; uidIdx < uidModesSize; uidIdx++) {
+            SparseIntArray modesForUid = mUidModes.valueAt(uidIdx);
+
+            final int idx = modesForUid.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND);
+            if (idx >= 0) {
+                // Only non-default should exist in the map
+                modesForUid.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, modesForUid.valueAt(idx));
+            }
+        }
+
+        final int usersSize = mUserPackageModes.size();
+        for (int userIdx = 0; userIdx < usersSize; userIdx++) {
+            ArrayMap<String, SparseIntArray> packageModes =
+                    mUserPackageModes.valueAt(userIdx);
+
+            for (int pkgIdx = 0, packageModesSize = packageModes.size();
+                    pkgIdx < packageModesSize; pkgIdx++) {
+                SparseIntArray modes = packageModes.valueAt(pkgIdx);
+
+                final int idx = modes.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND);
+                if (idx >= 0) {
+                    // Only non-default should exist in the map
+                    modes.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, modes.valueAt(idx));
+                }
+            }
+        }
+    }
+
+    /**
+     * The interpretation of the default mode - MODE_DEFAULT - for OP_SCHEDULE_EXACT_ALARM is
+     * changing. Simultaneously, we want to change this op's mode from MODE_DEFAULT to MODE_ALLOWED
+     * for already installed apps. For newer apps, it will stay as MODE_DEFAULT.
+     */
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    void upgradeScheduleExactAlarmLocked() {
+        final PermissionManagerServiceInternal pmsi = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+        final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+
+        final String[] packagesDeclaringPermission = pmsi.getAppOpPermissionPackages(
+                AppOpsManager.opToPermission(OP_SCHEDULE_EXACT_ALARM));
+        final int[] userIds = umi.getUserIds();
+
+        for (final String pkg : packagesDeclaringPermission) {
+            for (int userId : userIds) {
+                final int uid = pmi.getPackageUid(pkg, 0, userId);
+                final int oldMode = getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
+                if (oldMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
+                    setUidMode(uid, OP_SCHEDULE_EXACT_ALARM, MODE_ALLOWED);
+                }
+            }
+            // This appop is meant to be controlled at a uid level. So we leave package modes as
+            // they are.
+        }
+    }
+
+    @VisibleForTesting
+    List<Integer> getUidsWithNonDefaultModes() {
+        List<Integer> result = new ArrayList<>();
+        synchronized (mLock) {
+            for (int i = 0; i < mUidModes.size(); i++) {
+                SparseIntArray modes = mUidModes.valueAt(i);
+                if (modes.size() > 0) {
+                    result.add(mUidModes.keyAt(i));
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @VisibleForTesting
+    List<UserPackage> getPackagesWithNonDefaultModes() {
+        List<UserPackage> result = new ArrayList<>();
+        synchronized (mLock) {
+            for (int i = 0; i < mUserPackageModes.size(); i++) {
+                ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.valueAt(i);
+                for (int j = 0; j < packageModes.size(); j++) {
+                    SparseIntArray modes = packageModes.valueAt(j);
+                    if (modes.size() > 0) {
+                        result.add(
+                                UserPackage.of(mUserPackageModes.keyAt(i), packageModes.keyAt(j)));
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java
index d8d0d48..9096898 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java
@@ -23,6 +23,8 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.PrintWriter;
 
 /**
@@ -31,6 +33,32 @@
  * In the future this interface will also include op restrictions.
  */
 public interface AppOpsCheckingServiceInterface {
+
+    /**
+     * Tells the checking service to write its state to persistence (unconditionally).
+     * This is only made visible for testing.
+     */
+    @VisibleForTesting
+    void writeState();
+
+    /**
+     * Tells the checking service to read its state from persistence. This is generally called
+     * shortly after instantiation. If extra system services need to be guaranteed to be published
+     * that work should be done in {@link #systemReady()}
+     */
+    void readState();
+
+    /**
+     * Tells the checking service that a shutdown is occurring. This gives it a chance to write its
+     * state to persistence (if there are any pending changes).
+     */
+    void shutdown();
+
+    /**
+     * Do additional initialization work that is dependent on external system services.
+     */
+    void systemReady();
+
     /**
      * Returns a copy of non-default app-ops with op as keys and their modes as values for a uid.
      * Returns an empty SparseIntArray if nothing is set.
@@ -39,6 +67,15 @@
     SparseIntArray getNonDefaultUidModes(int uid);
 
     /**
+     * Returns a copy of non-default app-ops with op as keys and their modes as values for a package
+     * and user.
+     * Returns an empty SparseIntArray if nothing is set.
+     * @param packageName for which we need the app-ops and their modes.
+     * @param userId for which the package is installed in.
+     */
+    SparseIntArray getNonDefaultPackageModes(String packageName, int userId);
+
+    /**
      * Returns the app-op mode for a particular app-op of a uid.
      * Returns default op mode if the op mode for particular uid and op is not set.
      * @param uid user id for which we need the mode.
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java
index ac479b2..0094b86 100644
--- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java
@@ -40,12 +40,43 @@
     }
 
     @Override
+    public void writeState() {
+        Log.i(LOG_TAG, "writeState()");
+        mService.writeState();
+    }
+
+    @Override
+    public void readState() {
+        Log.i(LOG_TAG, "readState()");
+        mService.readState();
+    }
+
+    @Override
+    public void shutdown() {
+        Log.i(LOG_TAG, "shutdown()");
+        mService.shutdown();
+    }
+
+    @Override
+    public void systemReady() {
+        Log.i(LOG_TAG, "systemReady()");
+        mService.systemReady();
+    }
+
+    @Override
     public SparseIntArray getNonDefaultUidModes(int uid) {
         Log.i(LOG_TAG, "getNonDefaultUidModes(uid = " + uid + ")");
         return mService.getNonDefaultUidModes(uid);
     }
 
     @Override
+    public SparseIntArray getNonDefaultPackageModes(String packageName, int userId) {
+        Log.i(LOG_TAG, "getNonDefaultPackageModes("
+                + "packageName = " + packageName + ", userId = " + userId + ") ");
+        return mService.getNonDefaultPackageModes(packageName, userId);
+    }
+
+    @Override
     public int getUidMode(int uid, int op) {
         Log.i(LOG_TAG, "getUidMode(uid = " + uid + ", op = " + op + ")");
         return mService.getUidMode(uid, op);
diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java
new file mode 100644
index 0000000..dd06464
--- /dev/null
+++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.appop;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.AppOpsManager;
+import android.os.Trace;
+import android.util.ArraySet;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+
+import java.io.PrintWriter;
+
+/**
+ * Surrounds all AppOpsCheckingServiceInterface method calls with Trace.traceBegin and
+ * Trace.traceEnd. These traces are used for performance testing.
+ */
+public class AppOpsCheckingServiceTracingDecorator implements AppOpsCheckingServiceInterface {
+    private static final long TRACE_TAG = Trace.TRACE_TAG_SYSTEM_SERVER;
+    private final AppOpsCheckingServiceInterface mService;
+
+    AppOpsCheckingServiceTracingDecorator(
+            @NonNull AppOpsCheckingServiceInterface appOpsCheckingServiceInterface) {
+        mService = appOpsCheckingServiceInterface;
+    }
+
+    @Override
+    public void writeState() {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#writeState");
+        try {
+            mService.writeState();
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void readState() {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#readState");
+        try {
+            mService.readState();
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void shutdown() {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#shutdown");
+        try {
+            mService.shutdown();
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void systemReady() {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#systemReady");
+        try {
+            mService.systemReady();
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public SparseIntArray getNonDefaultUidModes(int uid) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getNonDefaultUidModes");
+        try {
+            return mService.getNonDefaultUidModes(uid);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public SparseIntArray getNonDefaultPackageModes(String packageName, int userId) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getNonDefaultPackageModes");
+        try {
+            return mService.getNonDefaultPackageModes(packageName, userId);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public int getUidMode(int uid, int op) {
+        Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getUidMode");
+        try {
+            return mService.getUidMode(uid, op);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public boolean setUidMode(int uid, int op, @AppOpsManager.Mode int mode) {
+        Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#setUidMode");
+        try {
+            return mService.setUidMode(uid, op, mode);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public int getPackageMode(@NonNull String packageName, int op, @UserIdInt int userId) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getPackageMode");
+        try {
+            return mService.getPackageMode(packageName, op, userId);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void setPackageMode(@NonNull String packageName, int op, @AppOpsManager.Mode int mode,
+            @UserIdInt int userId) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#setPackageMode");
+        try {
+            mService.setPackageMode(packageName, op, mode, userId);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public boolean removePackage(@NonNull String packageName, @UserIdInt int userId) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#removePackage");
+        try {
+            return mService.removePackage(packageName, userId);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void removeUid(int uid) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#removeUid");
+        try {
+            mService.removeUid(uid);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public boolean areUidModesDefault(int uid) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#areUidModesDefault");
+        try {
+            return mService.areUidModesDefault(uid);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public boolean arePackageModesDefault(String packageName, @UserIdInt int userId) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#arePackageModesDefault");
+        try {
+            return mService.arePackageModesDefault(packageName, userId);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void clearAllModes() {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#clearAllModes");
+        try {
+            mService.clearAllModes();
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void startWatchingOpModeChanged(@NonNull OnOpModeChangedListener changedListener,
+            int op) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#startWatchingOpModeChanged");
+        try {
+            mService.startWatchingOpModeChanged(changedListener, op);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void startWatchingPackageModeChanged(@NonNull OnOpModeChangedListener changedListener,
+            @NonNull String packageName) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#startWatchingPackageModeChanged");
+        try {
+            mService.startWatchingPackageModeChanged(changedListener, packageName);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void removeListener(@NonNull OnOpModeChangedListener changedListener) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#removeListener");
+        try {
+            mService.removeListener(changedListener);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public ArraySet<OnOpModeChangedListener> getOpModeChangedListeners(int op) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getOpModeChangedListeners");
+        try {
+            return mService.getOpModeChangedListeners(op);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public ArraySet<OnOpModeChangedListener> getPackageModeChangedListeners(
+            @NonNull String packageName) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getPackageModeChangedListeners");
+        try {
+            return mService.getPackageModeChangedListeners(packageName);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void notifyWatchersOfChange(int op, int uid) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#notifyWatchersOfChange");
+        try {
+            mService.notifyWatchersOfChange(op, uid);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void notifyOpChanged(@NonNull OnOpModeChangedListener changedListener, int op, int uid,
+            @Nullable String packageName) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#notifyOpChanged");
+        try {
+            mService.notifyOpChanged(changedListener, op, uid, packageName);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public void notifyOpChangedForAllPkgsInUid(int op, int uid, boolean onlyForeground,
+            @Nullable OnOpModeChangedListener callbackToIgnore) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#notifyOpChangedForAllPkgsInUid");
+        try {
+            mService.notifyOpChangedForAllPkgsInUid(op, uid, onlyForeground, callbackToIgnore);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public SparseBooleanArray evalForegroundUidOps(int uid, SparseBooleanArray foregroundOps) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#evalForegroundUidOps");
+        try {
+            return mService.evalForegroundUidOps(uid, foregroundOps);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public SparseBooleanArray evalForegroundPackageOps(String packageName,
+            SparseBooleanArray foregroundOps, @UserIdInt int userId) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#evalForegroundPackageOps");
+        try {
+            return mService.evalForegroundPackageOps(packageName, foregroundOps, userId);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+
+    @Override
+    public boolean dumpListeners(int dumpOp, int dumpUid, String dumpPackage,
+            PrintWriter printWriter) {
+        Trace.traceBegin(TRACE_TAG,
+                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#dumpListeners");
+        try {
+            return mService.dumpListeners(dumpOp, dumpUid, dumpPackage, printWriter);
+        } finally {
+            Trace.traceEnd(TRACE_TAG);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index c50f2b7..fb5359c 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -42,7 +42,6 @@
 import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO;
 import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
-import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
 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;
@@ -98,6 +97,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PermissionInfo;
+import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.hardware.camera2.CameraDevice.CAMERA_AUDIO_RESTRICTION;
 import android.net.Uri;
@@ -153,15 +153,16 @@
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.LocalManagerRegistry;
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemServiceManager;
 import com.android.server.pm.PackageList;
 import com.android.server.pm.UserManagerInternal;
-import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageState;
+import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.pkg.component.ParsedAttribution;
 import com.android.server.policy.AppOpsPolicy;
 
@@ -199,7 +200,7 @@
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.function.Consumer;
 
-public class AppOpsService extends IAppOpsService.Stub implements PersistenceScheduler {
+public class AppOpsService extends IAppOpsService.Stub {
     static final String TAG = "AppOps";
     static final boolean DEBUG = false;
 
@@ -209,26 +210,10 @@
     private final ArraySet<NoteOpTrace> mNoteOpCallerStacktraces = new ArraySet<>();
 
     /**
-     * Sentinel integer version to denote that there was no appops.xml found on boot.
-     * This will happen when a device boots with no existing userdata.
+     * Version of the mRecentAccessesFile.
+     * Increment by one every time an upgrade step is added at boot, none currently exists.
      */
-    private static final int NO_FILE_VERSION = -2;
-
-    /**
-     * Sentinel integer version to denote that there was no version in the appops.xml found on boot.
-     * This means the file is coming from a build before versioning was added.
-     */
-    private static final int NO_VERSION = -1;
-
-    /** Increment by one every time and add the corresponding upgrade logic in
-     *  {@link #upgradeLocked(int)} below. The first version was 1 */
-    static final int CURRENT_VERSION = 2;
-
-    /**
-     * This stores the version of appops.xml seen at boot. If this is smaller than
-     * {@link #CURRENT_VERSION}, then we will run {@link #upgradeLocked(int)} on startup.
-     */
-    private int mVersionAtBoot = NO_FILE_VERSION;
+    private static final int CURRENT_VERSION = 1;
 
     // Write at most every 30 minutes.
     static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000;
@@ -248,7 +233,8 @@
     private static final int RARELY_USED_PACKAGES_INITIALIZATION_DELAY_MILLIS = 300000;
 
     final Context mContext;
-    final AtomicFile mFile;
+    final AtomicFile mStorageFile;
+    final AtomicFile mRecentAccessesFile;
     private final @Nullable File mNoteOpCallerStacktracesFile;
     final Handler mHandler;
 
@@ -311,7 +297,7 @@
                 mFastWriteScheduled = false;
                 AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
                     @Override protected Void doInBackground(Void... params) {
-                        writeState();
+                        writeRecentAccesses();
                         return null;
                     }
                 };
@@ -383,6 +369,9 @@
     /** Package Manager internal. Access via {@link #getPackageManagerInternal()} */
     private @Nullable PackageManagerInternal mPackageManagerInternal;
 
+    /** User Manager internal. Access via {@link #getUserManagerInternal()} */
+    private @Nullable UserManagerInternal mUserManagerInternal;
+
     /** Interface for app-op modes.*/
     @VisibleForTesting
     AppOpsCheckingServiceInterface mAppOpsCheckingService;
@@ -525,22 +514,6 @@
             pkgOps = null;
         }
 
-        public boolean isDefault() {
-            boolean areAllPackageModesDefault = true;
-            if (pkgOps != null) {
-                for (String packageName : pkgOps.keySet()) {
-                    if (!mAppOpsCheckingService.arePackageModesDefault(packageName,
-                            UserHandle.getUserId(uid))) {
-                        areAllPackageModesDefault = false;
-                        break;
-                    }
-                }
-            }
-            return (pkgOps == null || pkgOps.isEmpty())
-                    && mAppOpsCheckingService.areUidModesDefault(uid)
-                    && areAllPackageModesDefault;
-        }
-
         // Functions for uid mode access and manipulation.
         public SparseIntArray getNonDefaultUidModes() {
             return mAppOpsCheckingService.getNonDefaultUidModes(uid);
@@ -616,7 +589,7 @@
         }
     }
 
-    /** Returned from {@link #verifyAndGetBypass(int, String, String, String)}. */
+    /** Returned from {@link #verifyAndGetBypass(int, String, String, String, boolean)}. */
     private static final class PackageVerificationResult {
 
         final RestrictionBypass bypass;
@@ -946,7 +919,9 @@
         }
     }
 
-    public AppOpsService(File storagePath, Handler handler, Context context) {
+    @VisibleForTesting
+    public AppOpsService(File recentAccessesFile, File storageFile, Handler handler,
+            Context context) {
         mContext = context;
 
         for (int switchedCode = 0; switchedCode < _NUM_OP; switchedCode++) {
@@ -954,15 +929,17 @@
             mSwitchedOps.put(switchCode,
                     ArrayUtils.appendInt(mSwitchedOps.get(switchCode), switchedCode));
         }
-        mAppOpsCheckingService =
-                new AppOpsCheckingServiceImpl(this, this, handler, context, mSwitchedOps);
+        mAppOpsCheckingService = new AppOpsCheckingServiceTracingDecorator(
+                new AppOpsCheckingServiceImpl(
+                        storageFile, this, handler, context,  mSwitchedOps));
         //mAppOpsCheckingService = new AppOpsCheckingServiceLoggingDecorator(
         //        LocalServices.getService(AppOpsCheckingServiceInterface.class));
-        mAppOpsRestrictions = new AppOpsRestrictionsImpl(context, handler,
-                mAppOpsCheckingService);
+        mAppOpsRestrictions = new AppOpsRestrictionsImpl(context, handler, mAppOpsCheckingService);
 
         LockGuard.installLock(this, LockGuard.INDEX_APP_OPS);
-        mFile = new AtomicFile(storagePath, "appops");
+        mStorageFile = new AtomicFile(storageFile, "appops_legacy");
+        mRecentAccessesFile = new AtomicFile(recentAccessesFile, "appops_accesses");
+
         if (AppOpsManager.NOTE_OP_COLLECTION_ENABLED) {
             mNoteOpCallerStacktracesFile = new File(SystemServiceManager.ensureSystemDir(),
                     "noteOpStackTraces.json");
@@ -972,13 +949,15 @@
         }
         mHandler = handler;
         mConstants = new Constants(mHandler);
-        readState();
+        // To migrate storageFile to recentAccessesFile, these reads must be called in this order.
+        readRecentAccesses();
+        mAppOpsCheckingService.readState();
     }
 
     public void publish() {
         ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder());
         LocalServices.addService(AppOpsManagerInternal.class, mAppOpsManagerInternal);
-        LocalServices.addService(AppOpsManagerLocal.class, new AppOpsManagerLocalImpl());
+        LocalManagerRegistry.addManager(AppOpsManagerLocal.class, new AppOpsManagerLocalImpl());
     }
 
     /** Handler for work when packages are removed or updated */
@@ -1073,9 +1052,18 @@
     };
 
     public void systemReady() {
-        synchronized (this) {
-            upgradeLocked(mVersionAtBoot);
-        }
+        mAppOpsCheckingService.systemReady();
+        initializeUidStates();
+
+        getUserManagerInternal().addUserLifecycleListener(
+                new UserManagerInternal.UserLifecycleListener() {
+                    @Override
+                    public void onUserCreated(UserInfo user, Object token) {
+                        initializeUserUidStates(user.id);
+                    }
+
+                    // onUserRemoved handled by #removeUser
+                });
 
         mConstants.startMonitoring(mContext.getContentResolver());
         mHistoricalRegistry.systemReady(mContext.getContentResolver());
@@ -1203,6 +1191,50 @@
     }
 
     /**
+     * Initialize uid state objects for state contained in the checking service.
+     */
+    private void initializeUidStates() {
+        UserManagerInternal umi = getUserManagerInternal();
+        int[] userIds = umi.getUserIds();
+        synchronized (this) {
+            for (int i = 0; i < userIds.length; i++) {
+                int userId = userIds[i];
+                initializeUserUidStatesLocked(userId);
+            }
+        }
+    }
+
+    private void initializeUserUidStates(int userId) {
+        synchronized (this) {
+            initializeUserUidStatesLocked(userId);
+        }
+    }
+
+    private void initializeUserUidStatesLocked(int userId) {
+        ArrayMap<String, ? extends PackageStateInternal> packageStates =
+                getPackageManagerInternal().getPackageStates();
+        for (int j = 0; j < packageStates.size(); j++) {
+            PackageStateInternal packageState = packageStates.valueAt(j);
+            int uid = UserHandle.getUid(userId, packageState.getAppId());
+            UidState uidState = getUidStateLocked(uid, true);
+            if (uidState.pkgOps == null) {
+                uidState.pkgOps = new ArrayMap<>();
+            }
+            String packageName = packageStates.keyAt(j);
+            Ops ops = new Ops(packageName, uidState);
+            uidState.pkgOps.put(packageName, ops);
+
+            SparseIntArray packageModes =
+                    mAppOpsCheckingService.getNonDefaultPackageModes(packageName, userId);
+            for (int k = 0; k < packageModes.size(); k++) {
+                int code = packageModes.get(k);
+                ops.put(code, new Op(uidState, packageName, code, uid));
+            }
+            uidState.evalForegroundOps();
+        }
+    }
+
+    /**
      * Sets a policy for handling app ops.
      *
      * @param policy The policy.
@@ -1273,7 +1305,7 @@
         }
     }
 
-    // The callback method from ForegroundPolicyInterface
+    // The callback method from AppOpsUidStateTracker
     private void onUidStateChanged(int uid, int state, boolean foregroundModeMayChange) {
         synchronized (this) {
             UidState uidState = getUidStateLocked(uid, true);
@@ -1370,12 +1402,12 @@
             }
         }
         if (doWrite) {
-            writeState();
+            writeRecentAccesses();
         }
+        mAppOpsCheckingService.shutdown();
         if (AppOpsManager.NOTE_OP_COLLECTION_ENABLED && mWriteNoteOpsScheduled) {
             writeNoteOps();
         }
-
         mHistoricalRegistry.shutdown();
     }
 
@@ -1647,8 +1679,13 @@
     public void reloadNonHistoricalState() {
         mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS,
                 Binder.getCallingPid(), Binder.getCallingUid(), "reloadNonHistoricalState");
-        writeState();
-        readState();
+        mAppOpsCheckingService.writeState();
+        mAppOpsCheckingService.readState();
+    }
+
+    @VisibleForTesting
+    void readState() {
+        mAppOpsCheckingService.readState();
     }
 
     @Override
@@ -1687,13 +1724,6 @@
                         pkgOps.remove(ops.packageName);
                         mAppOpsCheckingService.removePackage(ops.packageName,
                                 UserHandle.getUserId(uidState.uid));
-                        if (pkgOps.isEmpty()) {
-                            uidState.pkgOps = null;
-                        }
-                        if (uidState.isDefault()) {
-                            uidState.clear();
-                            mUidStates.remove(uid);
-                        }
                     }
                 }
             }
@@ -2147,10 +2177,6 @@
                                 UserHandle.getUserId(uidState.uid));
                     }
                 }
-                if (uidState.isDefault()) {
-                    uidState.clear();
-                    mUidStates.remove(uidState.uid);
-                }
                 if (uidChanged) {
                     uidState.evalForegroundOps();
                 }
@@ -2407,7 +2433,7 @@
     public int checkPackage(int uid, String packageName) {
         Objects.requireNonNull(packageName);
         try {
-            verifyAndGetBypass(uid, packageName, null);
+            verifyAndGetBypass(uid, packageName, null, null, true);
             // When the caller is the system, it's possible that the packageName is the special
             // one (e.g., "root") which isn't actually existed.
             if (resolveUid(packageName) == uid
@@ -3583,11 +3609,28 @@
         if (mPackageManagerInternal == null) {
             mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         }
+        if (mPackageManagerInternal == null) {
+            throw new IllegalStateException("PackageManagerInternal not loaded");
+        }
 
         return mPackageManagerInternal;
     }
 
     /**
+     * @return {@link UserManagerInternal}
+     */
+    private @NonNull UserManagerInternal getUserManagerInternal() {
+        if (mUserManagerInternal == null) {
+            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+        }
+        if (mUserManagerInternal == null) {
+            throw new IllegalStateException("UserManagerInternal not loaded");
+        }
+
+        return mUserManagerInternal;
+    }
+
+    /**
      * Create a restriction description matching the properties of the package.
      *
      * @param pkg The package to create the restriction description for
@@ -3602,7 +3645,7 @@
     }
 
     /**
-     * @see #verifyAndGetBypass(int, String, String, String)
+     * @see #verifyAndGetBypass(int, String, String, String, boolean)
      */
     private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName,
             @Nullable String attributionTag) {
@@ -3610,6 +3653,14 @@
     }
 
     /**
+     * @see #verifyAndGetBypass(int, String, String, String, boolean)
+     */
+    private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName,
+            @Nullable String attributionTag, @Nullable String proxyPackageName) {
+        return verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName, false);
+    }
+
+    /**
      * Verify that package belongs to uid and return the {@link RestrictionBypass bypass
      * description} for the package, along with a boolean indicating whether the attribution tag is
      * valid.
@@ -3618,12 +3669,14 @@
      * @param packageName The package the might belong to the uid
      * @param attributionTag attribution tag or {@code null} if no need to verify
      * @param proxyPackageName The proxy package, from which the attribution tag is to be pulled
+     * @param suppressErrorLogs Whether to print to logcat about nonmatching parameters
      *
      * @return PackageVerificationResult containing {@link RestrictionBypass} and whether the
      *         attribution tag is valid
      */
     private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName,
-            @Nullable String attributionTag, @Nullable String proxyPackageName) {
+            @Nullable String attributionTag, @Nullable String proxyPackageName,
+            boolean suppressErrorLogs) {
         if (uid == Process.ROOT_UID) {
             // For backwards compatibility, don't check package name for root UID.
             return new PackageVerificationResult(null,
@@ -3677,8 +3730,11 @@
         }
         if (pkgUid != Process.INVALID_UID) {
             if (pkgUid != UserHandle.getAppId(uid)) {
-                Slog.e(TAG, "Bad call made by uid " + callingUid + ". "
-                        + "Package \"" + packageName + "\" does not belong to uid " + uid + ".");
+                if (!suppressErrorLogs) {
+                    Slog.e(TAG, "Bad call made by uid " + callingUid + ". "
+                            + "Package \"" + packageName + "\" does not belong to uid " + uid
+                            + ".");
+                }
                 String otherUidMessage = DEBUG ? " but it is really " + pkgUid : " but it is not";
                 throw new SecurityException("Specified package \"" + packageName + "\" under uid "
                         +  UserHandle.getAppId(uid) + otherUidMessage);
@@ -3736,8 +3792,10 @@
         }
 
         if (pkgUid != uid) {
-            Slog.e(TAG, "Bad call made by uid " + callingUid + ". "
-                    + "Package \"" + packageName + "\" does not belong to uid " + uid + ".");
+            if (!suppressErrorLogs) {
+                Slog.e(TAG, "Bad call made by uid " + callingUid + ". "
+                        + "Package \"" + packageName + "\" does not belong to uid " + uid + ".");
+            }
             String otherUidMessage = DEBUG ? " but it is really " + pkgUid : " but it is not";
             throw new SecurityException("Specified package \"" + packageName + "\" under uid " + uid
                     + otherUidMessage);
@@ -3818,16 +3876,14 @@
         return ops;
     }
 
-    @Override
-    public void scheduleWriteLocked() {
+    private void scheduleWriteLocked() {
         if (!mWriteScheduled) {
             mWriteScheduled = true;
             mHandler.postDelayed(mWriteRunner, WRITE_DELAY);
         }
     }
 
-    @Override
-    public void scheduleFastWriteLocked() {
+    private void scheduleFastWriteLocked() {
         if (!mFastWriteScheduled) {
             mWriteScheduled = true;
             mFastWriteScheduled = true;
@@ -3925,14 +3981,28 @@
         return false;
     }
 
-    void readState() {
-        synchronized (mFile) {
+    /**
+     * Read recent accesses from persistence (mRecentAccessesFile).
+     * If there is no mRecentAccessesFile yet, we'll need migrate from mStorageFile: first read from
+     * mStorageFile, then all subsequent reads/writes will use mRecentAccessesFile.
+     * If neither file exists, there's nothing to migrate.
+     */
+    private void readRecentAccesses() {
+        if (!mRecentAccessesFile.exists()) {
+            readRecentAccesses(mStorageFile);
+        } else {
+            readRecentAccesses(mRecentAccessesFile);
+        }
+    }
+
+    private void readRecentAccesses(AtomicFile file) {
+        synchronized (file) {
             synchronized (this) {
                 FileInputStream stream;
                 try {
-                    stream = mFile.openRead();
+                    stream = file.openRead();
                 } catch (FileNotFoundException e) {
-                    Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty");
+                    Slog.i(TAG, "No existing app ops " + file.getBaseFile() + "; starting empty");
                     return;
                 }
                 boolean success = false;
@@ -3943,15 +4013,13 @@
                     int type;
                     while ((type = parser.next()) != XmlPullParser.START_TAG
                             && type != XmlPullParser.END_DOCUMENT) {
-                        ;
+                        // Parse next until we reach the start or end
                     }
 
                     if (type != XmlPullParser.START_TAG) {
                         throw new IllegalStateException("no start tag found");
                     }
 
-                    mVersionAtBoot = parser.getAttributeInt(null, "v", NO_VERSION);
-
                     int outerDepth = parser.getDepth();
                     while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                             && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -3963,13 +4031,15 @@
                         if (tagName.equals("pkg")) {
                             readPackage(parser);
                         } else if (tagName.equals("uid")) {
-                            readUidOps(parser);
+                            // uid tag may be present during migration, don't print warning.
+                            XmlUtils.skipCurrentTag(parser);
                         } else {
                             Slog.w(TAG, "Unknown element under <app-ops>: "
                                     + parser.getName());
                             XmlUtils.skipCurrentTag(parser);
                         }
                     }
+
                     success = true;
                 } catch (IllegalStateException e) {
                     Slog.w(TAG, "Failed parsing " + e);
@@ -3997,123 +4067,6 @@
         }
     }
 
-    @VisibleForTesting
-    @GuardedBy("this")
-    void upgradeRunAnyInBackgroundLocked() {
-        for (int i = 0; i < mUidStates.size(); i++) {
-            final UidState uidState = mUidStates.valueAt(i);
-            if (uidState == null) {
-                continue;
-            }
-            SparseIntArray opModes = uidState.getNonDefaultUidModes();
-            if (opModes != null) {
-                final int idx = opModes.indexOfKey(AppOpsManager.OP_RUN_IN_BACKGROUND);
-                if (idx >= 0) {
-                    uidState.setUidMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
-                            opModes.valueAt(idx));
-                }
-            }
-            if (uidState.pkgOps == null) {
-                continue;
-            }
-            boolean changed = false;
-            for (int j = 0; j < uidState.pkgOps.size(); j++) {
-                Ops ops = uidState.pkgOps.valueAt(j);
-                if (ops != null) {
-                    final Op op = ops.get(AppOpsManager.OP_RUN_IN_BACKGROUND);
-                    if (op != null && op.getMode() != AppOpsManager.opToDefaultMode(op.op)) {
-                        final Op copy = new Op(op.uidState, op.packageName,
-                                AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uidState.uid);
-                        copy.setMode(op.getMode());
-                        ops.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, copy);
-                        changed = true;
-                    }
-                }
-            }
-            if (changed) {
-                uidState.evalForegroundOps();
-            }
-        }
-    }
-
-    /**
-     * The interpretation of the default mode - MODE_DEFAULT - for OP_SCHEDULE_EXACT_ALARM is
-     * changing. Simultaneously, we want to change this op's mode from MODE_DEFAULT to MODE_ALLOWED
-     * for already installed apps. For newer apps, it will stay as MODE_DEFAULT.
-     */
-    @VisibleForTesting
-    @GuardedBy("this")
-    void upgradeScheduleExactAlarmLocked() {
-        final PermissionManagerServiceInternal pmsi = LocalServices.getService(
-                PermissionManagerServiceInternal.class);
-        final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
-        final PackageManagerInternal pmi = getPackageManagerInternal();
-
-        final String[] packagesDeclaringPermission = pmsi.getAppOpPermissionPackages(
-                AppOpsManager.opToPermission(OP_SCHEDULE_EXACT_ALARM));
-        final int[] userIds = umi.getUserIds();
-
-        for (final String pkg : packagesDeclaringPermission) {
-            for (int userId : userIds) {
-                final int uid = pmi.getPackageUid(pkg, 0, userId);
-
-                UidState uidState = mUidStates.get(uid);
-                if (uidState == null) {
-                    uidState = new UidState(uid);
-                    mUidStates.put(uid, uidState);
-                }
-                final int oldMode = uidState.getUidMode(OP_SCHEDULE_EXACT_ALARM);
-                if (oldMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
-                    uidState.setUidMode(OP_SCHEDULE_EXACT_ALARM, MODE_ALLOWED);
-                }
-            }
-            // This appop is meant to be controlled at a uid level. So we leave package modes as
-            // they are.
-        }
-    }
-
-    private void upgradeLocked(int oldVersion) {
-        if (oldVersion >= CURRENT_VERSION) {
-            return;
-        }
-        Slog.d(TAG, "Upgrading app-ops xml from version " + oldVersion + " to " + CURRENT_VERSION);
-        switch (oldVersion) {
-            case NO_VERSION:
-                upgradeRunAnyInBackgroundLocked();
-                // fall through
-            case 1:
-                upgradeScheduleExactAlarmLocked();
-                // fall through
-            case 2:
-                // for future upgrades
-        }
-        scheduleFastWriteLocked();
-    }
-
-    private void readUidOps(TypedXmlPullParser parser) throws NumberFormatException,
-            XmlPullParserException, IOException {
-        final int uid = parser.getAttributeInt(null, "n");
-        int outerDepth = parser.getDepth();
-        int type;
-        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                continue;
-            }
-
-            String tagName = parser.getName();
-            if (tagName.equals("op")) {
-                final int code = parser.getAttributeInt(null, "n");
-                final int mode = parser.getAttributeInt(null, "m");
-                setUidMode(code, uid, mode);
-            } else {
-                Slog.w(TAG, "Unknown element under <uid-ops>: "
-                        + parser.getName());
-                XmlUtils.skipCurrentTag(parser);
-            }
-        }
-    }
-
     private void readPackage(TypedXmlPullParser parser)
             throws NumberFormatException, XmlPullParserException, IOException {
         String pkgName = parser.getAttributeValue(null, "n");
@@ -4156,7 +4109,6 @@
                 XmlUtils.skipCurrentTag(parser);
             }
         }
-        uidState.evalForegroundOps();
     }
 
     private void readAttributionOp(TypedXmlPullParser parser, @NonNull Op parent,
@@ -4190,9 +4142,6 @@
         int opCode = parser.getAttributeInt(null, "n");
         Op op = new Op(uidState, pkgName, opCode, uidState.uid);
 
-        final int mode = parser.getAttributeInt(null, "m", AppOpsManager.opToDefaultMode(op.op));
-        op.setMode(mode);
-
         int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -4221,11 +4170,12 @@
         ops.put(op.op, op);
     }
 
-    void writeState() {
-        synchronized (mFile) {
+    @VisibleForTesting
+    void writeRecentAccesses() {
+        synchronized (mRecentAccessesFile) {
             FileOutputStream stream;
             try {
-                stream = mFile.startWrite();
+                stream = mRecentAccessesFile.startWrite();
             } catch (IOException e) {
                 Slog.w(TAG, "Failed to write state: " + e);
                 return;
@@ -4239,41 +4189,6 @@
                 out.startTag(null, "app-ops");
                 out.attributeInt(null, "v", CURRENT_VERSION);
 
-                SparseArray<SparseIntArray> uidStatesClone;
-                synchronized (this) {
-                    uidStatesClone = new SparseArray<>(mUidStates.size());
-
-                    final int uidStateCount = mUidStates.size();
-                    for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
-                        UidState uidState = mUidStates.valueAt(uidStateNum);
-                        int uid = mUidStates.keyAt(uidStateNum);
-
-                        SparseIntArray opModes = uidState.getNonDefaultUidModes();
-                        if (opModes != null && opModes.size() > 0) {
-                            uidStatesClone.put(uid, opModes);
-                        }
-                    }
-                }
-
-                final int uidStateCount = uidStatesClone.size();
-                for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) {
-                    SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum);
-                    if (opModes != null && opModes.size() > 0) {
-                        out.startTag(null, "uid");
-                        out.attributeInt(null, "n", uidStatesClone.keyAt(uidStateNum));
-                        final int opCount = opModes.size();
-                        for (int opCountNum = 0; opCountNum < opCount; opCountNum++) {
-                            final int op = opModes.keyAt(opCountNum);
-                            final int mode = opModes.valueAt(opCountNum);
-                            out.startTag(null, "op");
-                            out.attributeInt(null, "n", op);
-                            out.attributeInt(null, "m", mode);
-                            out.endTag(null, "op");
-                        }
-                        out.endTag(null, "uid");
-                    }
-                }
-
                 if (allOps != null) {
                     String lastPkg = null;
                     for (int i=0; i<allOps.size(); i++) {
@@ -4374,10 +4289,10 @@
 
                 out.endTag(null, "app-ops");
                 out.endDocument();
-                mFile.finishWrite(stream);
+                mRecentAccessesFile.finishWrite(stream);
             } catch (IOException e) {
                 Slog.w(TAG, "Failed to write state, restoring backup.", e);
-                mFile.failWrite(stream);
+                mRecentAccessesFile.failWrite(stream);
             }
         }
         mHistoricalRegistry.writeAndClearDiscreteHistory();
@@ -4824,7 +4739,8 @@
                         synchronized (shell.mInternal) {
                             shell.mInternal.mHandler.removeCallbacks(shell.mInternal.mWriteRunner);
                         }
-                        shell.mInternal.writeState();
+                        shell.mInternal.writeRecentAccesses();
+                        shell.mInternal.mAppOpsCheckingService.writeState();
                         pw.println("Current settings written.");
                     } finally {
                         Binder.restoreCallingIdentity(token);
@@ -4836,7 +4752,8 @@
                             Binder.getCallingUid(), -1);
                     final long token = Binder.clearCallingIdentity();
                     try {
-                        shell.mInternal.readState();
+                        shell.mInternal.readRecentAccesses();
+                        shell.mInternal.mAppOpsCheckingService.readState();
                         pw.println("Last settings read.");
                     } finally {
                         Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/appop/PersistenceScheduler.java b/services/core/java/com/android/server/appop/PersistenceScheduler.java
deleted file mode 100644
index e50b658..0000000
--- a/services/core/java/com/android/server/appop/PersistenceScheduler.java
+++ /dev/null
@@ -1,35 +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.server.appop;
-
-/**
- * Interface that allows callers to persist AppOpsService's internal state
- * to disk.
- */
-public interface PersistenceScheduler {
-
-    /**
-     * Schedules disk writes for appOpsService and it's internal states.
-     */
-    void scheduleWriteLocked();
-
-    /**
-     * Schedules fast disk writes for appOpsService and it's internal states.
-     */
-    void scheduleFastWriteLocked();
-
-}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d888c81..e55bddb 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -692,6 +692,7 @@
 
     // Devices where the framework sends a full scale audio signal, and controls the volume of
     // the external audio system separately.
+    // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
 
     /**
@@ -702,13 +703,19 @@
         private final List<VolumeInfo> mVolumeInfos;
         private final IAudioDeviceVolumeDispatcher mCallback;
         private final boolean mHandlesVolumeAdjustment;
+        private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
 
-        private AbsoluteVolumeDeviceInfo(AudioDeviceAttributes device, List<VolumeInfo> volumeInfos,
-                IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment) {
+        private AbsoluteVolumeDeviceInfo(
+                AudioDeviceAttributes device,
+                List<VolumeInfo> volumeInfos,
+                IAudioDeviceVolumeDispatcher callback,
+                boolean handlesVolumeAdjustment,
+                @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
             this.mDevice = device;
             this.mVolumeInfos = volumeInfos;
             this.mCallback = callback;
             this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
+            this.mDeviceVolumeBehavior = behavior;
         }
 
         /**
@@ -3647,11 +3654,12 @@
         synchronized (VolumeStreamState.class) {
             List<Integer> streamsToMute = new ArrayList<>();
             for (int stream = 0; stream < mStreamStates.length; stream++) {
-                if (streamAlias == mStreamVolumeAlias[stream]) {
+                VolumeStreamState vss = mStreamStates[stream];
+                if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) {
                     if (!(readCameraSoundForced()
-                            && (mStreamStates[stream].getStreamType()
+                            && (vss.getStreamType()
                                     == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
-                        boolean changed = mStreamStates[stream].mute(state, /* apply= */ false);
+                        boolean changed = vss.mute(state, /* apply= */ false);
                         if (changed) {
                             streamsToMute.add(stream);
                         }
@@ -5329,7 +5337,8 @@
             if (!shouldMute) {
                 // unmute
                 // ring and notifications volume should never be 0 when not silenced
-                if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
+                if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING
+                        || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) {
                     synchronized (VolumeStreamState.class) {
                         final VolumeStreamState vss = mStreamStates[streamType];
                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
@@ -6060,6 +6069,8 @@
             }
         }
 
+        readVolumeGroupsSettings(userSwitch);
+
         // apply new ringer mode before checking volume for alias streams so that streams
         // muted by ringer mode have the correct volume
         setRingerModeInt(getRingerModeInternal(), false);
@@ -6071,8 +6082,6 @@
         mSoundDoseHelper.restoreMusicActiveMs();
         mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG);
 
-        readVolumeGroupsSettings(userSwitch);
-
         if (DEBUG_VOL) {
             Log.d(TAG, "Restoring device volume behavior");
         }
@@ -7055,7 +7064,8 @@
     public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
             IAudioDeviceVolumeDispatcher cb, String packageName,
             AudioDeviceAttributes device, List<VolumeInfo> volumes,
-            boolean handlesVolumeAdjustment) {
+            boolean handlesVolumeAdjustment,
+            @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
         // verify permissions
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
                 != PackageManager.PERMISSION_GRANTED
@@ -7071,13 +7081,16 @@
         int deviceOut = device.getInternalType();
         if (register) {
             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
-                    device, volumes, cb, handlesVolumeAdjustment);
-            boolean volumeBehaviorChanged =
-                    removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut)
-                    | removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut)
-                    | (addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info) == null);
+                    device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior);
+            AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut);
+            boolean volumeBehaviorChanged = (oldInfo == null)
+                    || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior);
             if (volumeBehaviorChanged) {
-                dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+                removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut);
+                removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut);
+                addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info);
+
+                dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior);
             }
             // Update stream volumes to the given device, if specified in a VolumeInfo.
             // Mute state is not updated because it is stream-wide - the only way to mute a
@@ -7169,6 +7182,7 @@
                                 != null);
                 break;
             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
+            case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
                 throw new IllegalArgumentException("Absolute volume unsupported for now");
         }
@@ -7212,11 +7226,6 @@
         // AudioDeviceInfo.convertDeviceTypeToInternalDevice()
         final int audioSystemDeviceOut = device.getInternalType();
 
-        int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut);
-        if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
-            return setDeviceVolumeBehavior;
-        }
-
         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
         // current volume behavior.
         if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
@@ -7228,8 +7237,11 @@
         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
         }
-        if (isAbsoluteVolumeDevice(audioSystemDeviceOut)
-                || isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
+        if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
+            return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior;
+        }
+
+        if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
                 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) {
             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
         }
@@ -8478,9 +8490,10 @@
                     }
                     mVolumeGroupState.updateVolumeIndex(groupIndex, device);
                     // Only propage mute of stream when applicable
-                    if (mIndexMin == 0 || isCallStream(mStreamType)) {
+                    if (isMutable()) {
                         // For call stream, align mute only when muted, not when index is set to 0
-                        mVolumeGroupState.mute(forceMuteState ? mIsMuted : groupIndex == 0);
+                        mVolumeGroupState.mute(
+                                forceMuteState ? mIsMuted : groupIndex == 0 || mIsMuted);
                     }
                 }
             }
@@ -8529,6 +8542,12 @@
             return mIsMuted || mIsMutedInternally;
         }
 
+
+        private boolean isMutable() {
+            return isStreamAffectedByMute(mStreamType)
+                    && (mIndexMin == 0 || isCallStream(mStreamType));
+        }
+
         /**
          * Mute/unmute the stream
          * @param state the new mute state
@@ -10671,6 +10690,13 @@
         pw.println();
     }
 
+    private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) {
+        return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
+                .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
+                .map(Map.Entry::getKey)
+                .collect(Collectors.toSet());
+    }
+
     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
         Iterator<Integer> it = deviceTypes.iterator();
         if (!it.hasNext()) {
@@ -10719,14 +10745,20 @@
         pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
-        pw.print("  mAbsoluteVolumeDevices.keySet()="); pw.println(dumpDeviceTypes(
-                mAbsoluteVolumeDeviceInfoMap.keySet()));
+        pw.print("  absolute volume devices="); pw.println(dumpDeviceTypes(
+                getAbsoluteVolumeDevicesWithBehavior(
+                        AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
+        pw.print("  adjust-only absolute volume devices="); pw.println(dumpDeviceTypes(
+                getAbsoluteVolumeDevicesWithBehavior(
+                        AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY)));
         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
-        pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
+        synchronized (mHdmiClientLock) {
+            pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
+        }
         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
         pw.print("  mic mute FromSwitch=" + mMicMuteFromSwitch
                         + " FromRestrictions=" + mMicMuteFromRestrictions
@@ -12771,11 +12803,14 @@
     }
 
     /**
-     * Returns whether the input device uses absolute volume behavior. This is distinct
-     * from Bluetooth A2DP absolute volume behavior ({@link #isA2dpAbsoluteVolumeDevice}).
+     * Returns whether the input device uses absolute volume behavior, including its variants.
+     * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
+     *
+     * This is distinct from Bluetooth A2DP absolute volume behavior
+     * ({@link #isA2dpAbsoluteVolumeDevice}).
      */
     private boolean isAbsoluteVolumeDevice(int deviceType) {
-        return  mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
+        return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
     }
 
     /**
@@ -12879,13 +12914,15 @@
         return mFullVolumeDevices.remove(audioSystemDeviceOut);
     }
 
-    private AbsoluteVolumeDeviceInfo addAudioSystemDeviceOutToAbsVolumeDevices(
-            int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info) {
+    private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut,
+            AbsoluteVolumeDeviceInfo info) {
         if (DEBUG_VOL) {
             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
-                    + " from mAbsoluteVolumeDeviceInfoMap");
+                    + " to mAbsoluteVolumeDeviceInfoMap with behavior "
+                    + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior)
+            );
         }
-        return mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
+        mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
     }
 
     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index ac02eb7..748c4ce5 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -595,9 +595,12 @@
                         Settings.Global.AUDIO_SAFE_CSD_CURRENT_VALUE, /* defaultValue= */0.f);
                 mNextCsdWarning = parseGlobalSettingFloat(
                         Settings.Global.AUDIO_SAFE_CSD_NEXT_WARNING, /* defaultValue= */1.f);
-                mDoseRecords.addAll(persistedStringToRecordList(
+                final List<SoundDoseRecord> records = persistedStringToRecordList(
                         mSettings.getGlobalString(mAudioService.getContentResolver(),
-                                Settings.Global.AUDIO_SAFE_CSD_DOSE_RECORDS)));
+                                Settings.Global.AUDIO_SAFE_CSD_DOSE_RECORDS));
+                if (records != null) {
+                    mDoseRecords.addAll(records);
+                }
             }
 
             reset();
diff --git a/services/core/java/com/android/server/backup/SetUtils.java b/services/core/java/com/android/server/backup/SetUtils.java
new file mode 100644
index 0000000..ae70e19
--- /dev/null
+++ b/services/core/java/com/android/server/backup/SetUtils.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.backup;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Helper class containing common operation on {@link java.util.Set}.
+ */
+public final class SetUtils {
+    // Statics only
+    private SetUtils() {}
+
+    /**
+     * Returns union of two sets.
+     */
+    public static <T> Set<T> union(Set<T> set1, Set<T> set2) {
+        Set<T> unionSet = new HashSet<>(set1);
+        unionSet.addAll(set2);
+        return unionSet;
+    }
+}
diff --git a/services/core/java/com/android/server/backup/SystemBackupAgent.java b/services/core/java/com/android/server/backup/SystemBackupAgent.java
index c0ea561..224e34d 100644
--- a/services/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/services/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -30,6 +30,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Slog;
 
 import com.google.android.collect.Sets;
@@ -84,30 +85,50 @@
     // Use old keys to keep legacy data compatibility and avoid writing two wallpapers
     private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
 
-    private static final Set<String> sEligibleForMultiUser = Sets.newArraySet(
-            PERMISSION_HELPER, NOTIFICATION_HELPER, SYNC_SETTINGS_HELPER, APP_LOCALES_HELPER,
-            ACCOUNT_MANAGER_HELPER, USAGE_STATS_HELPER, PREFERRED_HELPER, SHORTCUT_MANAGER_HELPER
-    );
+    /**
+     * Helpers that are enabled for "profile" users (such as work profile). See {@link
+     * UserManager#isProfile()}. This is a subset of {@link #sEligibleHelpersForNonSystemUser}.
+     */
+    private static final Set<String> sEligibleHelpersForProfileUser =
+            Sets.newArraySet(
+                    PERMISSION_HELPER,
+                    NOTIFICATION_HELPER,
+                    SYNC_SETTINGS_HELPER,
+                    APP_LOCALES_HELPER);
+
+    /** Helpers that are enabled for full, non-system users. */
+    private static final Set<String> sEligibleHelpersForNonSystemUser =
+            SetUtils.union(sEligibleHelpersForProfileUser,
+                    Sets.newArraySet(ACCOUNT_MANAGER_HELPER, USAGE_STATS_HELPER, PREFERRED_HELPER,
+                            SHORTCUT_MANAGER_HELPER));
 
     private int mUserId = UserHandle.USER_SYSTEM;
+    private boolean mIsProfileUser = false;
 
     @Override
     public void onCreate(UserHandle user, @BackupDestination int backupDestination) {
         super.onCreate(user, backupDestination);
 
         mUserId = user.getIdentifier();
+        if (mUserId != UserHandle.USER_SYSTEM) {
+            Context context = createContextAsUser(user, /* flags= */ 0);
+            UserManager userManager = context.getSystemService(UserManager.class);
+            mIsProfileUser = userManager.isProfile();
+        }
 
-        addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this, mUserId));
-        addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper(mUserId));
-        addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
-        addHelper(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
-        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(mUserId));
-        addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper(mUserId));
-        addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper(mUserId));
-        addHelper(SLICES_HELPER, new SliceBackupHelper(this));
-        addHelper(PEOPLE_HELPER, new PeopleBackupHelper(mUserId));
-        addHelper(APP_LOCALES_HELPER, new AppSpecificLocalesBackupHelper(mUserId));
-        addHelper(APP_GENDER_HELPER, new AppGrammaticalGenderBackupHelper(mUserId));
+        addHelperIfEligibleForUser(
+                SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this, mUserId));
+        addHelperIfEligibleForUser(PREFERRED_HELPER, new PreferredActivityBackupHelper(mUserId));
+        addHelperIfEligibleForUser(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
+        addHelperIfEligibleForUser(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
+        addHelperIfEligibleForUser(USAGE_STATS_HELPER, new UsageStatsBackupHelper(mUserId));
+        addHelperIfEligibleForUser(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper(mUserId));
+        addHelperIfEligibleForUser(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper(mUserId));
+        addHelperIfEligibleForUser(SLICES_HELPER, new SliceBackupHelper(this));
+        addHelperIfEligibleForUser(PEOPLE_HELPER, new PeopleBackupHelper(mUserId));
+        addHelperIfEligibleForUser(APP_LOCALES_HELPER, new AppSpecificLocalesBackupHelper(mUserId));
+        addHelperIfEligibleForUser(APP_GENDER_HELPER,
+                new AppGrammaticalGenderBackupHelper(mUserId));
     }
 
     @Override
@@ -131,15 +152,6 @@
         super.onRestore(data, appVersionCode, newState);
     }
 
-    @Override
-    public void addHelper(String keyPrefix, BackupHelper helper) {
-        if (mUserId != UserHandle.USER_SYSTEM && !sEligibleForMultiUser.contains(keyPrefix)) {
-            return;
-        }
-
-        super.addHelper(keyPrefix, helper);
-    }
-
     /**
      * Support for 'adb restore' of legacy archives
      */
@@ -190,4 +202,25 @@
             }
         }
     }
+
+    private void addHelperIfEligibleForUser(String keyPrefix, BackupHelper helper) {
+        if (isHelperEligibleForUser(keyPrefix)) {
+            addHelper(keyPrefix, helper);
+        }
+    }
+
+    private boolean isHelperEligibleForUser(String keyPrefix) {
+        // All helpers are eligible for the system user.
+        if (mUserId == UserHandle.USER_SYSTEM) {
+            return true;
+        }
+
+        // Profile users (such as work profile) have their own allow list.
+        if (mIsProfileUser) {
+            return sEligibleHelpersForProfileUser.contains(keyPrefix);
+        }
+
+        // Full, non-system users have their own allow list.
+        return sEligibleHelpersForNonSystemUser.contains(keyPrefix);
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index c8d43e4..ffa5d20 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -563,6 +563,14 @@
                 }
             }
 
+            // Set the default subtitle if necessary.
+            if (promptInfo.isUseDefaultSubtitle()) {
+                if (TextUtils.isEmpty(promptInfo.getSubtitle())) {
+                    promptInfo.setSubtitle(getContext()
+                            .getString(R.string.biometric_dialog_default_subtitle));
+                }
+            }
+
             final long requestId = mRequestCounter.get();
             mHandler.post(() -> handleAuthenticate(
                     token, requestId, operationId, userId, receiver, opPackageName, promptInfo));
diff --git a/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java b/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java
index 969a174..0b5c1c1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java
+++ b/services/core/java/com/android/server/biometrics/sensors/SensorOverlays.java
@@ -150,6 +150,13 @@
     }
 
     /**
+     * Returns if the sensor is side fps.
+     */
+    public boolean isSfps() {
+        return mSidefpsController.isPresent();
+    }
+
+    /**
      * Consumer for a biometric overlay controller.
      *
      * This behaves like a normal {@link Consumer} except that it will trap and log
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index a90679e..932c0b4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -236,8 +236,14 @@
 
     @Override
     public void onError(int errorCode, int vendorCode) {
-        super.onError(errorCode, vendorCode);
-
+        if (errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR
+                && vendorCode == BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED
+                && mSensorOverlays.isSfps()) {
+            super.onError(BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED,
+                    0 /* vendorCode */);
+        } else {
+            super.onError(errorCode, vendorCode);
+        }
         if (errorCode == BiometricFingerprintConstants.FINGERPRINT_ERROR_BAD_CALIBRATION) {
             BiometricNotificationUtils.showBadCalibrationNotification(getContext());
         }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index 513b3e3..cf54662 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -146,7 +146,14 @@
             }
         });
         mCallback.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
-        super.onAcquired(acquiredInfo, vendorCode);
+        if (acquiredInfo == BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR
+                && vendorCode == BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED
+                && mSensorOverlays.isSfps()) {
+            super.onAcquired(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED,
+                    0 /* vendorCode */);
+        } else {
+            super.onAcquired(acquiredInfo, vendorCode);
+        }
     }
 
     @Override
@@ -274,8 +281,5 @@
     }
 
     @Override
-    public void onPowerPressed() {
-        onAcquired(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED,
-                0 /* vendorCode */);
-    }
+    public void onPowerPressed() { }
 }
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 0b03005..12134f7 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -247,7 +247,7 @@
         private long mDurationOrStartTimeMs;  // Either start time, or duration once completed
 
         CameraUsageEvent(String cameraId, int facing, String clientName, int apiLevel,
-                boolean isNdk, int action, int latencyMs, int operatingMode) {
+                boolean isNdk, int action, int latencyMs, int operatingMode, boolean deviceError) {
             mCameraId = cameraId;
             mCameraFacing = facing;
             mClientName = clientName;
@@ -258,6 +258,7 @@
             mAction = action;
             mLatencyMs = latencyMs;
             mOperatingMode = operatingMode;
+            mDeviceError = deviceError;
         }
 
         public void markCompleted(int internalReconfigure, long requestCount,
@@ -1108,7 +1109,7 @@
                     CameraUsageEvent openEvent = new CameraUsageEvent(
                             cameraId, facing, clientName, apiLevel, isNdk,
                             FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__OPEN,
-                            latencyMs, sessionType);
+                            latencyMs, sessionType, deviceError);
                     mCameraUsageHistory.add(openEvent);
                     break;
                 case CameraSessionStats.CAMERA_STATE_ACTIVE:
@@ -1135,7 +1136,7 @@
                     CameraUsageEvent newEvent = new CameraUsageEvent(
                             cameraId, facing, clientName, apiLevel, isNdk,
                             FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__SESSION,
-                            latencyMs, sessionType);
+                            latencyMs, sessionType, deviceError);
                     CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
                     if (oldEvent != null) {
                         Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
@@ -1154,6 +1155,8 @@
                                 resultErrorCount, deviceError, streamStats, userTag,
                                 videoStabilizationMode);
                         mCameraUsageHistory.add(doneEvent);
+                        // Do not double count device error
+                        deviceError = false;
 
                         // Check current active camera IDs to see if this package is still
                         // talking to some camera
@@ -1177,7 +1180,7 @@
                         CameraUsageEvent closeEvent = new CameraUsageEvent(
                                 cameraId, facing, clientName, apiLevel, isNdk,
                                 FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__CLOSE,
-                                latencyMs, sessionType);
+                                latencyMs, sessionType, deviceError);
                         mCameraUsageHistory.add(closeEvent);
                     }
 
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index ecff0a7..f7183e6 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -824,7 +824,9 @@
     @GuardedBy("mLock")
     private void setPrimaryClipInternalLocked(
             @Nullable ClipData clip, int uid, int deviceId, @Nullable String sourcePackage) {
-        mEmulatorClipboardMonitor.accept(clip);
+        if (deviceId == DEVICE_ID_DEFAULT) {
+            mEmulatorClipboardMonitor.accept(clip);
+        }
 
         final int userId = UserHandle.getUserId(uid);
 
diff --git a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
index dce1c96..39c649b 100644
--- a/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
+++ b/services/core/java/com/android/server/clipboard/EmulatorClipboardMonitor.java
@@ -111,7 +111,7 @@
         bb.order(ByteOrder.LITTLE_ENDIAN);
         final int msgLen = bb.getInt();
 
-        if (msgLen <= 0 || msgLen > MAX_CLIPBOARD_BYTES) {
+        if (msgLen < 0 || msgLen > MAX_CLIPBOARD_BYTES) {
             throw new ProtocolException("Clipboard message length: " + msgLen + " out of bounds.");
         }
 
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index ec2e254..0318b24 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -488,31 +488,65 @@
      * migrated already.
      */
     private void migrateSyncJobNamespaceIfNeeded() {
-        if (mSyncStorageEngine.isJobNamespaceMigrated()) {
+        final boolean namespaceMigrated = mSyncStorageEngine.isJobNamespaceMigrated();
+        final boolean attributionFixed = mSyncStorageEngine.isJobAttributionFixed();
+        if (namespaceMigrated && attributionFixed) {
             return;
         }
         final JobScheduler jobSchedulerDefaultNamespace =
                 mContext.getSystemService(JobScheduler.class);
-        final List<JobInfo> pendingJobs = jobSchedulerDefaultNamespace.getAllPendingJobs();
-        // Wait until we've confirmed that all syncs have been migrated to the new namespace
-        // before we persist successful migration to our status file. This is done to avoid
+        if (!namespaceMigrated) {
+            final List<JobInfo> pendingJobs = jobSchedulerDefaultNamespace.getAllPendingJobs();
+            // Wait until we've confirmed that all syncs have been migrated to the new namespace
+            // before we persist successful migration to our status file. This is done to avoid
+            // internal consistency issues if the devices reboots right after SyncManager has
+            // done the migration on its side but before JobScheduler has finished persisting
+            // the updated jobs to disk. If JobScheduler hasn't persisted the update to disk,
+            // then nothing that happened afterwards should have been persisted either, so there's
+            // no concern over activity happening after the migration causing issues.
+            boolean allSyncsMigrated = true;
+            for (int i = pendingJobs.size() - 1; i >= 0; --i) {
+                final JobInfo job = pendingJobs.get(i);
+                final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
+                if (op != null) {
+                    // This is a sync. Move it over to SyncManager's namespace.
+                    mJobScheduler.scheduleAsPackage(job,
+                            op.owningPackage, op.target.userId, op.wakeLockName());
+                    jobSchedulerDefaultNamespace.cancel(job.getId());
+                    allSyncsMigrated = false;
+                }
+            }
+            mSyncStorageEngine.setJobNamespaceMigrated(allSyncsMigrated);
+        }
+
+        // Fix attribution for any syncs that were previously scheduled using
+        // JobScheduler.schedule() instead of JobScheduler.scheduleAsPackage().
+        final List<JobInfo> namespacedJobs = LocalServices.getService(JobSchedulerInternal.class)
+                .getSystemScheduledOwnJobs(mJobScheduler.getNamespace());
+        // Wait until we've confirmed that all syncs have been proper attribution
+        // before we persist attribution state to our status file. This is done to avoid
         // internal consistency issues if the devices reboots right after SyncManager has
-        // done the migration on its side but before JobScheduler has finished persisting
+        // rescheduled the job on its side but before JobScheduler has finished persisting
         // the updated jobs to disk. If JobScheduler hasn't persisted the update to disk,
         // then nothing that happened afterwards should have been persisted either, so there's
         // no concern over activity happening after the migration causing issues.
-        boolean allSyncsMigrated = true;
-        for (int i = pendingJobs.size() - 1; i >= 0; --i) {
-            final JobInfo job = pendingJobs.get(i);
+        // This case is done to fix issues for a subset of test devices.
+        // TODO: remove this attribution check/fix code
+        boolean allSyncsAttributed = true;
+        for (int i = namespacedJobs.size() - 1; i >= 0; --i) {
+            final JobInfo job = namespacedJobs.get(i);
             final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras());
             if (op != null) {
-                // This is a sync. Move it over to SyncManager's namespace.
-                mJobScheduler.schedule(job);
-                jobSchedulerDefaultNamespace.cancel(job.getId());
-                allSyncsMigrated = false;
+                // This is a sync. Make sure it's properly attributed to the app
+                // instead of the system.
+                // Since the job ID stays the same, scheduleAsPackage will replace the scheduled
+                // job, so we don't need to call cancel as well.
+                mJobScheduler.scheduleAsPackage(job,
+                        op.owningPackage, op.target.userId, op.wakeLockName());
+                allSyncsAttributed = false;
             }
         }
-        mSyncStorageEngine.setJobNamespaceMigrated(allSyncsMigrated);
+        mSyncStorageEngine.setJobAttributionFixed(allSyncsAttributed);
     }
 
     private synchronized void verifyJobScheduler() {
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 9f3302d..b890bbd 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -173,6 +173,7 @@
     private volatile boolean mIsClockValid;
 
     private volatile boolean mIsJobNamespaceMigrated;
+    private volatile boolean mIsJobAttributionFixed;
 
     static {
         sAuthorityRenames = new HashMap<String, String>();
@@ -852,6 +853,20 @@
         return mIsJobNamespaceMigrated;
     }
 
+    void setJobAttributionFixed(boolean fixed) {
+        if (mIsJobAttributionFixed == fixed) {
+            return;
+        }
+        mIsJobAttributionFixed = fixed;
+        // This isn't urgent enough to write synchronously. Post it to the handler thread so
+        // SyncManager can move on with whatever it was doing.
+        mHandler.sendEmptyMessageDelayed(MSG_WRITE_STATUS, WRITE_STATUS_DELAY);
+    }
+
+    boolean isJobAttributionFixed() {
+        return mIsJobAttributionFixed;
+    }
+
     public Pair<Long, Long> getBackoff(EndPoint info) {
         synchronized (mAuthorities) {
             AuthorityInfo authority = getAuthorityLocked(info, "getBackoff");
@@ -2120,6 +2135,10 @@
                     mIsJobNamespaceMigrated =
                             proto.readBoolean(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED);
                     break;
+                case (int) SyncStatusProto.IS_JOB_ATTRIBUTION_FIXED:
+                    mIsJobAttributionFixed =
+                            proto.readBoolean(SyncStatusProto.IS_JOB_ATTRIBUTION_FIXED);
+                    break;
                 case ProtoInputStream.NO_MORE_FIELDS:
                     return;
             }
@@ -2389,6 +2408,7 @@
         }
 
         proto.write(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED, mIsJobNamespaceMigrated);
+        proto.write(SyncStatusProto.IS_JOB_ATTRIBUTION_FIXED, mIsJobAttributionFixed);
 
         proto.flush();
     }
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index ba96861..43ee5e2 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -34,6 +34,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.app.TaskStackListener;
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateInfo;
@@ -1235,7 +1236,8 @@
 
     private class OverrideRequestTaskStackListener extends TaskStackListener {
         @Override
-        public void onTaskStackChanged() throws RemoteException {
+        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
+                throws RemoteException {
             synchronized (mLock) {
                 if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) {
                     return;
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
index 2f14998..9008740 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.devicestate;
 
+import android.annotation.DrawableRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Notification;
@@ -103,7 +104,7 @@
             showNotification(
                     info.name, info.activeNotificationTitle,
                     String.format(info.activeNotificationContent, requesterApplicationLabel),
-                    true /* ongoing */
+                    true /* ongoing */, R.drawable.ic_dual_screen
             );
         } else {
             Slog.e(TAG, "Cannot determine the requesting app name when showing state active "
@@ -124,7 +125,8 @@
         }
         showNotification(
                 info.name, info.thermalCriticalNotificationTitle,
-                info.thermalCriticalNotificationContent, false /* ongoing */
+                info.thermalCriticalNotificationContent, false /* ongoing */,
+                R.drawable.ic_thermostat
         );
     }
 
@@ -158,11 +160,12 @@
      * @param ongoing if true, display an ongoing (sticky) notification with a turn off button.
      */
     private void showNotification(
-            @NonNull String name, @NonNull String title, @NonNull String content, boolean ongoing) {
+            @NonNull String name, @NonNull String title, @NonNull String content, boolean ongoing,
+            @DrawableRes int iconRes) {
         final NotificationChannel channel = new NotificationChannel(
                 CHANNEL_ID, name, NotificationManager.IMPORTANCE_HIGH);
         final Notification.Builder builder = new Notification.Builder(mContext, CHANNEL_ID)
-                .setSmallIcon(R.drawable.ic_lock) // TODO(b/266833171) update icons when available.
+                .setSmallIcon(iconRes)
                 .setContentTitle(title)
                 .setContentText(content)
                 .setSubText(name)
diff --git a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
index a921a54..ce29013 100644
--- a/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
+++ b/services/core/java/com/android/server/display/DeviceStateToLayoutMap.java
@@ -22,6 +22,7 @@
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.DisplayAddress;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -114,6 +115,7 @@
                 Slog.i(TAG, "Display layout config not found: " + configFile);
                 return;
             }
+            int leadDisplayId = Display.DEFAULT_DISPLAY;
             for (com.android.server.display.config.layout.Layout l : layouts.getLayout()) {
                 final int state = l.getState().intValue();
                 final Layout layout = createLayout(state);
@@ -123,8 +125,10 @@
                             DisplayAddress.fromPhysicalDisplayId(d.getAddress().longValue()),
                             d.isDefaultDisplay(),
                             d.isEnabled(),
+                            d.getDisplayGroup(),
                             mIdProducer,
-                            d.getBrightnessThrottlingMapId());
+                            d.getBrightnessThrottlingMapId(),
+                            leadDisplayId);
 
                     if (FRONT_STRING.equals(d.getPosition())) {
                         display.setPosition(POSITION_FRONT);
@@ -133,6 +137,7 @@
                     } else {
                         display.setPosition(POSITION_UNKNOWN);
                     }
+                    display.setRefreshRateZoneId(d.getRefreshRateZoneId());
                 }
             }
         } catch (IOException | DatatypeConfigurationException | XmlPullParserException e) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 2af995b..ac9400d 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -33,6 +33,7 @@
 import android.util.Slog;
 import android.util.Spline;
 import android.view.DisplayAddress;
+import android.view.SurfaceControl;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -53,6 +54,7 @@
 import com.android.server.display.config.Point;
 import com.android.server.display.config.RefreshRateConfigs;
 import com.android.server.display.config.RefreshRateRange;
+import com.android.server.display.config.RefreshRateZone;
 import com.android.server.display.config.SdrHdrRatioMap;
 import com.android.server.display.config.SdrHdrRatioPoint;
 import com.android.server.display.config.SensorDetails;
@@ -503,10 +505,10 @@
     /**
      * Array of light sensor lux values to define our levels for auto backlight
      * brightness support.
-
+     *
      * The N + 1 entries of this array define N control points defined in mBrightnessLevelsNits,
      * with first value always being 0 lux
-
+     *
      * The control points must be strictly increasing.  Each control point
      * corresponds to an entry in the brightness backlight values arrays.
      * For example, if lux == level[1] (second element of the levels array)
@@ -515,7 +517,6 @@
      *
      * Spline interpolation is used to determine the auto-brightness
      * backlight values for lux levels between these control points.
-     *
      */
     private float[] mBrightnessLevelsLux;
 
@@ -619,6 +620,10 @@
      */
     private int mDefaultLowBlockingZoneRefreshRate = DEFAULT_LOW_REFRESH_RATE;
 
+    // Refresh rate profiles, currently only for concurrent mode profile and controlled by Layout
+    private final Map<String, SurfaceControl.RefreshRateRange> mRefreshRateZoneProfiles =
+            new HashMap<>();
+
     /**
      * The display uses different gamma curves for different refresh rates. It's hard for panel
      * vendors to tune the curves to have exact same brightness for different refresh rate. So
@@ -1340,6 +1345,23 @@
     }
 
     /**
+     * @return Default refresh rate while the device has high brightness mode enabled for HDR.
+     */
+    public int getDefaultRefreshRateInHbmHdr() {
+        return mContext.getResources().getInteger(
+            R.integer.config_defaultRefreshRateInHbmHdr);
+    }
+
+    /**
+     * @return Default refresh rate while the device has high brightness mode enabled because of
+     * high lux.
+     */
+    public int getDefaultRefreshRateInHbmSunlight() {
+        return mContext.getResources().getInteger(
+            R.integer.config_defaultRefreshRateInHbmSunlight);
+    }
+
+    /**
      * @return Default refresh rate in the higher blocking zone of the associated display
      */
     public int getDefaultHighBlockingZoneRefreshRate() {
@@ -1354,6 +1376,23 @@
     }
 
     /**
+     * @return Refresh rate range for specific profile id or null
+     */
+    @Nullable
+    public SurfaceControl.RefreshRateRange getRefreshRange(@Nullable String id) {
+        if (TextUtils.isEmpty(id)) {
+            return null;
+        }
+        return mRefreshRateZoneProfiles.get(id);
+    }
+
+    @NonNull
+    @VisibleForTesting
+    Map<String, SurfaceControl.RefreshRateRange> getRefreshRangeProfiles() {
+        return mRefreshRateZoneProfiles;
+    }
+
+    /**
      * @return An array of lower display brightness thresholds. This, in combination with lower
      * ambient brightness thresholds help define buckets in which the refresh rate switching is not
      * allowed
@@ -1500,6 +1539,7 @@
                 + ", mDefaultHighBlockingZoneRefreshRate= " + mDefaultHighBlockingZoneRefreshRate
                 + ", mDefaultPeakRefreshRate= " + mDefaultPeakRefreshRate
                 + ", mDefaultRefreshRate= " + mDefaultRefreshRate
+                + ", mRefreshRateZoneProfiles= " + mRefreshRateZoneProfiles
                 + ", mLowDisplayBrightnessThresholds= "
                 + Arrays.toString(mLowDisplayBrightnessThresholds)
                 + ", mLowAmbientBrightnessThresholds= "
@@ -1828,6 +1868,7 @@
         loadDefaultRefreshRate(refreshRateConfigs);
         loadLowerRefreshRateBlockingZones(lowerBlockingZoneConfig);
         loadHigherRefreshRateBlockingZones(higherBlockingZoneConfig);
+        loadRefreshRateZoneProfiles(refreshRateConfigs);
     }
 
     private void loadPeakDefaultRefreshRate(RefreshRateConfigs refreshRateConfigs) {
@@ -1850,6 +1891,21 @@
         }
     }
 
+    /** Loads the refresh rate profiles. */
+    private void loadRefreshRateZoneProfiles(RefreshRateConfigs refreshRateConfigs) {
+        if (refreshRateConfigs == null) {
+            return;
+        }
+        for (RefreshRateZone zone :
+                refreshRateConfigs.getRefreshRateZoneProfiles().getRefreshRateZoneProfile()) {
+            RefreshRateRange range = zone.getRefreshRateRange();
+            mRefreshRateZoneProfiles.put(
+                    zone.getId(),
+                    new SurfaceControl.RefreshRateRange(
+                            range.getMinimum().floatValue(), range.getMaximum().floatValue()));
+        }
+    }
+
     /**
      * Loads the refresh rate configurations pertaining to the upper blocking zones.
      */
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 3759a8b..e200d12 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -142,6 +142,7 @@
 import com.android.server.UiThread;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 import com.android.server.display.DisplayDeviceConfig.SensorData;
+import com.android.server.display.layout.Layout;
 import com.android.server.display.utils.SensorUtils;
 import com.android.server.input.InputManagerInternal;
 import com.android.server.wm.SurfaceAnimationThread;
@@ -245,7 +246,7 @@
     private Display.Mode mUserPreferredMode;
     // HDR conversion mode chosen by user
     @GuardedBy("mSyncRoot")
-    private HdrConversionMode mHdrConversionMode;
+    private HdrConversionMode mHdrConversionMode = null;
 
     // The synchronization root for the display manager.
     // This lock guards most of the display manager's state.
@@ -647,6 +648,7 @@
             updateSettingsLocked();
             updateUserDisabledHdrTypesFromSettingsLocked();
             updateUserPreferredDisplayModeSettingsLocked();
+            updateHdrConversionModeSettingsLocked();
         }
 
         mDisplayModeDirector.setDesiredDisplayModeSpecsListener(
@@ -1664,12 +1666,37 @@
                 return;
             }
 
-            // TODO (b/265793751): Set this DPC as a follower of the default DPC if needed,
-            // clear this DPC's followers if it's not a lead display
+            final int leadDisplayId = display.getLeadDisplayIdLocked();
+            updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
 
             final String uniqueId = device.getUniqueId();
             HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
-            dpc.onDisplayChanged(hbmMetadata);
+            dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
+        }
+    }
+
+    private void updateDisplayPowerControllerLeaderLocked(DisplayPowerControllerInterface dpc,
+            int leadDisplayId) {
+        if (dpc.getLeadDisplayId() == leadDisplayId) {
+            // Lead display hasn't changed, nothing to do.
+            return;
+        }
+
+        // If it has changed, then we need to unregister from the previous leader if there was one.
+        final int prevLeaderId = dpc.getLeadDisplayId();
+        if (prevLeaderId != Layout.NO_LEAD_DISPLAY) {
+            final DisplayPowerControllerInterface prevLeader =
+                    mDisplayPowerControllers.get(prevLeaderId);
+            if (prevLeader != null) {
+                prevLeader.removeDisplayBrightnessFollower(dpc);
+            }
+        }
+
+        // And then, if it's following, register it with the new one.
+        if (leadDisplayId != Layout.NO_LEAD_DISPLAY) {
+            final DisplayPowerControllerInterface newLead =
+                    mDisplayPowerControllers.get(leadDisplayId);
+            newLead.addDisplayBrightnessFollower(dpc);
         }
     }
 
@@ -1733,9 +1760,13 @@
                         + display.getDisplayIdLocked());
                 return;
             }
+
+            final int leadDisplayId = display.getLeadDisplayIdLocked();
+            updateDisplayPowerControllerLeaderLocked(dpc, leadDisplayId);
+
             final String uniqueId = device.getUniqueId();
             HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId);
-            dpc.onDisplayChanged(hbmMetadata);
+            dpc.onDisplayChanged(hbmMetadata, leadDisplayId);
         }
     }
 
@@ -1806,6 +1837,31 @@
         device.setUserPreferredDisplayModeLocked(modeBuilder.build());
     }
 
+    @GuardedBy("mSyncRoot")
+    private void storeHdrConversionModeLocked(HdrConversionMode hdrConversionMode) {
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.HDR_CONVERSION_MODE, hdrConversionMode.getConversionMode());
+        final int preferredHdrOutputType =
+                hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_FORCE
+                        ? hdrConversionMode.getPreferredHdrOutputType()
+                        : Display.HdrCapabilities.HDR_TYPE_INVALID;
+        Settings.Global.putInt(mContext.getContentResolver(),
+                Settings.Global.HDR_FORCE_CONVERSION_TYPE, preferredHdrOutputType);
+    }
+
+    @GuardedBy("mSyncRoot")
+    void updateHdrConversionModeSettingsLocked() {
+        final int conversionMode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.HDR_CONVERSION_MODE, HdrConversionMode.HDR_CONVERSION_SYSTEM);
+        final int preferredHdrOutputType = conversionMode == HdrConversionMode.HDR_CONVERSION_FORCE
+                ? Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.HDR_FORCE_CONVERSION_TYPE,
+                        Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION)
+                : Display.HdrCapabilities.HDR_TYPE_INVALID;
+        mHdrConversionMode = new HdrConversionMode(conversionMode, preferredHdrOutputType);
+        setHdrConversionModeInternal(mHdrConversionMode);
+    }
+
     // If we've never recorded stable device stats for this device before and they aren't
     // explicitly configured, go ahead and record the stable device stats now based on the status
     // of the default display at first boot.
@@ -1962,13 +2018,14 @@
         int[] autoHdrOutputTypes = null;
         synchronized (mSyncRoot) {
             mHdrConversionMode = hdrConversionMode;
+            storeHdrConversionModeLocked(mHdrConversionMode);
 
             // For auto mode, all supported HDR types are allowed except the ones specifically
             // disabled by the user.
             if (hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM) {
                 autoHdrOutputTypes = getEnabledAutoHdrTypesLocked();
             }
-            DisplayControl.setHdrConversionMode(hdrConversionMode.getConversionMode(),
+            mInjector.setHdrConversionMode(hdrConversionMode.getConversionMode(),
                     hdrConversionMode.getPreferredHdrOutputType(), autoHdrOutputTypes);
         }
     }
@@ -1984,7 +2041,7 @@
 
     private @Display.HdrCapabilities.HdrType int[] getSupportedHdrOutputTypesInternal() {
         if (mSupportedHdrOutputType == null) {
-            mSupportedHdrOutputType = DisplayControl.getSupportedHdrOutputTypes();
+            mSupportedHdrOutputType = mInjector.getSupportedHdrOutputTypes();
         }
         return mSupportedHdrOutputType;
     }
@@ -2604,6 +2661,10 @@
                 }
             }
 
+            if (mHdrConversionMode != null) {
+                pw.println("  mHdrConversionMode=" + mHdrConversionMode);
+            }
+
             pw.println();
             final int displayStateCount = mDisplayStates.size();
             pw.println("Display States: size=" + displayStateCount);
@@ -2712,6 +2773,16 @@
         long getDefaultDisplayDelayTimeout() {
             return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
         }
+
+        void setHdrConversionMode(int conversionMode, int preferredHdrOutputType,
+                int[] autoHdrTypes) {
+            DisplayControl.setHdrConversionMode(conversionMode, preferredHdrOutputType,
+                    autoHdrTypes);
+        }
+
+        int[] getSupportedHdrOutputTypes() {
+            return DisplayControl.getSupportedHdrOutputTypes();
+        }
     }
 
     @VisibleForTesting
@@ -4168,6 +4239,23 @@
                         .getHostUsiVersion();
             }
         }
+
+        @Override
+        public IntArray getDisplayGroupIds() {
+            Set<Integer> visitedIds = new ArraySet<>();
+            IntArray displayGroupIds = new IntArray();
+            synchronized (mSyncRoot) {
+                mLogicalDisplayMapper.forEachLocked(logicalDisplay -> {
+                    int groupId = mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(
+                            logicalDisplay.getDisplayIdLocked());
+                    if (!visitedIds.contains(groupId)) {
+                        visitedIds.add(groupId);
+                        displayGroupIds.add(groupId);
+                    }
+                });
+            }
+            return displayGroupIds;
+        }
     }
 
     class DesiredDisplayModeSpecsObserver
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 5f6660b..0a4b5b0 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -123,6 +123,10 @@
     private final DeviceConfigInterface mDeviceConfig;
     private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
 
+    @GuardedBy("mLock")
+    @Nullable
+    private DisplayDeviceConfig mDefaultDisplayDeviceConfig;
+
     // A map from the display ID to the collection of votes and their priority. The latter takes
     // the form of another map from the priority to the vote itself so that each priority is
     // guaranteed to have exactly one vote, which is also easily and efficiently replaceable.
@@ -159,17 +163,18 @@
         mSupportedModesByDisplay = new SparseArray<>();
         mDefaultModeByDisplay = new SparseArray<>();
         mAppRequestObserver = new AppRequestObserver();
-        mDisplayObserver = new DisplayObserver(context, handler);
         mDeviceConfig = injector.getDeviceConfig();
         mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
         mSettingsObserver = new SettingsObserver(context, handler);
         mBrightnessObserver = new BrightnessObserver(context, handler, injector);
+        mDefaultDisplayDeviceConfig = null;
         mUdfpsObserver = new UdfpsObserver();
         final BallotBox ballotBox = (displayId, priority, vote) -> {
             synchronized (mLock) {
                 updateVoteLocked(displayId, priority, vote);
             }
         };
+        mDisplayObserver = new DisplayObserver(context, handler, ballotBox);
         mSensorObserver = new SensorObserver(context, ballotBox, injector);
         mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, ballotBox);
         mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler(),
@@ -701,11 +706,15 @@
      * @param displayDeviceConfig configurations relating to the underlying display device.
      */
     public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) {
-        mSettingsObserver.setRefreshRates(displayDeviceConfig,
-            /* attemptLoadingFromDeviceConfig= */ true);
-        mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
-            /* attemptLoadingFromDeviceConfig= */ true);
-        mBrightnessObserver.reloadLightSensor(displayDeviceConfig);
+        synchronized (mLock) {
+            mDefaultDisplayDeviceConfig = displayDeviceConfig;
+            mSettingsObserver.setRefreshRates(displayDeviceConfig,
+                /* attemptLoadingFromDeviceConfig= */ true);
+            mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
+                /* attemptLoadingFromDeviceConfig= */ true);
+            mBrightnessObserver.reloadLightSensor(displayDeviceConfig);
+            mHbmObserver.setupHdrRefreshRates(displayDeviceConfig);
+        }
     }
 
     /**
@@ -733,7 +742,7 @@
 
     /**
      * Sets the display mode switching type.
-     * @param newType
+     * @param newType new mode switching type
      */
     public void setModeSwitchingType(@DisplayManager.SwitchingType int newType) {
         synchronized (mLock) {
@@ -850,6 +859,18 @@
         notifyDesiredDisplayModeSpecsChangedLocked();
     }
 
+    @GuardedBy("mLock")
+    private float getMaxRefreshRateLocked(int displayId) {
+        Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
+        float maxRefreshRate = 0f;
+        for (Display.Mode mode : modes) {
+            if (mode.getRefreshRate() > maxRefreshRate) {
+                maxRefreshRate = mode.getRefreshRate();
+            }
+        }
+        return maxRefreshRate;
+    }
+
     private void notifyDesiredDisplayModeSpecsChangedLocked() {
         if (mDesiredDisplayModeSpecsListener != null
                 && !mHandler.hasMessages(MSG_REFRESH_RATE_RANGE_CHANGED)) {
@@ -1186,26 +1207,33 @@
         // rest of low priority voters. It votes [0, max(PEAK, MIN)]
         public static final int PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE = 7;
 
+        // To avoid delay in switching between 60HZ -> 90HZ when activating LHBM, set refresh
+        // rate to max value (same as for PRIORITY_UDFPS) on lock screen
+        public static final int PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE = 8;
+
+        // For concurrent displays we want to limit refresh rate on all displays
+        public static final int PRIORITY_LAYOUT_LIMITED_FRAME_RATE = 9;
+
         // LOW_POWER_MODE force the render frame rate to [0, 60HZ] if
         // Settings.Global.LOW_POWER_MODE is on.
-        public static final int PRIORITY_LOW_POWER_MODE = 8;
+        public static final int PRIORITY_LOW_POWER_MODE = 10;
 
         // PRIORITY_FLICKER_REFRESH_RATE_SWITCH votes for disabling refresh rate switching. If the
         // higher priority voters' result is a range, it will fix the rate to a single choice.
         // It's used to avoid refresh rate switches in certain conditions which may result in the
         // user seeing the display flickering when the switches occur.
-        public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 9;
+        public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 11;
 
         // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL.
-        public static final int PRIORITY_SKIN_TEMPERATURE = 10;
+        public static final int PRIORITY_SKIN_TEMPERATURE = 12;
 
         // The proximity sensor needs the refresh rate to be locked in order to function, so this is
         // set to a high priority.
-        public static final int PRIORITY_PROXIMITY = 11;
+        public static final int PRIORITY_PROXIMITY = 13;
 
         // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order
         // to function, so this needs to be the highest priority of all votes.
-        public static final int PRIORITY_UDFPS = 12;
+        public static final int PRIORITY_UDFPS = 14;
 
         // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
         // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
@@ -1322,6 +1350,8 @@
                     return "PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE";
                 case PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE:
                     return "PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE";
+                case PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE:
+                    return "PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE";
                 default:
                     return Integer.toString(priority);
             }
@@ -1657,10 +1687,12 @@
         // calling into us already holding its own lock.
         private final Context mContext;
         private final Handler mHandler;
+        private final BallotBox mBallotBox;
 
-        DisplayObserver(Context context, Handler handler) {
+        DisplayObserver(Context context, Handler handler, BallotBox ballotBox) {
             mContext = context;
             mHandler = handler;
+            mBallotBox = ballotBox;
         }
 
         public void observe() {
@@ -1689,7 +1721,9 @@
 
         @Override
         public void onDisplayAdded(int displayId) {
-            updateDisplayModes(displayId);
+            DisplayInfo displayInfo = getDisplayInfo(displayId);
+            updateDisplayModes(displayId, displayInfo);
+            updateLayoutLimitedFrameRate(displayId, displayInfo);
         }
 
         @Override
@@ -1698,23 +1732,41 @@
                 mSupportedModesByDisplay.remove(displayId);
                 mDefaultModeByDisplay.remove(displayId);
             }
+            updateLayoutLimitedFrameRate(displayId, null);
         }
 
         @Override
         public void onDisplayChanged(int displayId) {
-            updateDisplayModes(displayId);
+            DisplayInfo displayInfo = getDisplayInfo(displayId);
+            updateDisplayModes(displayId, displayInfo);
+            updateLayoutLimitedFrameRate(displayId, displayInfo);
         }
 
-        private void updateDisplayModes(int displayId) {
+        @Nullable
+        private DisplayInfo getDisplayInfo(int displayId) {
             Display d = mContext.getSystemService(DisplayManager.class).getDisplay(displayId);
             if (d == null) {
                 // We can occasionally get a display added or changed event for a display that was
                 // subsequently removed, which means this returns null. Check this case and bail
                 // out early; if it gets re-attached we'll eventually get another call back for it.
-                return;
+                return null;
             }
             DisplayInfo info = new DisplayInfo();
             d.getDisplayInfo(info);
+            return info;
+        }
+
+        private void updateLayoutLimitedFrameRate(int displayId, @Nullable DisplayInfo info) {
+            Vote vote = info != null && info.layoutLimitedRefreshRate != null
+                    ? Vote.forPhysicalRefreshRates(info.layoutLimitedRefreshRate.min,
+                    info.layoutLimitedRefreshRate.max) : null;
+            mBallotBox.vote(displayId, Vote.PRIORITY_LAYOUT_LIMITED_FRAME_RATE, vote);
+        }
+
+        private void updateDisplayModes(int displayId, @Nullable DisplayInfo info) {
+            if (info == null) {
+                return;
+            }
             boolean changed = false;
             synchronized (mLock) {
                 if (!Arrays.equals(mSupportedModesByDisplay.get(displayId), info.supportedModes)) {
@@ -2539,6 +2591,7 @@
 
     private class UdfpsObserver extends IUdfpsRefreshRateRequestCallback.Stub {
         private final SparseBooleanArray mUdfpsRefreshRateEnabled = new SparseBooleanArray();
+        private final SparseBooleanArray mAuthenticationPossible = new SparseBooleanArray();
 
         public void observe() {
             StatusBarManagerInternal statusBar =
@@ -2551,38 +2604,38 @@
         @Override
         public void onRequestEnabled(int displayId) {
             synchronized (mLock) {
-                updateRefreshRateStateLocked(displayId, true /*enabled*/);
+                mUdfpsRefreshRateEnabled.put(displayId, true);
+                updateVoteLocked(displayId, true, Vote.PRIORITY_UDFPS);
             }
         }
 
         @Override
         public void onRequestDisabled(int displayId) {
             synchronized (mLock) {
-                updateRefreshRateStateLocked(displayId, false /*enabled*/);
+                mUdfpsRefreshRateEnabled.put(displayId, false);
+                updateVoteLocked(displayId, false, Vote.PRIORITY_UDFPS);
             }
         }
 
-        private void updateRefreshRateStateLocked(int displayId, boolean enabled) {
-            mUdfpsRefreshRateEnabled.put(displayId, enabled);
-            updateVoteLocked(displayId);
+        @Override
+        public void onAuthenticationPossible(int displayId, boolean isPossible) {
+            synchronized (mLock) {
+                mAuthenticationPossible.put(displayId, isPossible);
+                updateVoteLocked(displayId, isPossible,
+                        Vote.PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE);
+            }
         }
 
-        private void updateVoteLocked(int displayId) {
+        @GuardedBy("mLock")
+        private void updateVoteLocked(int displayId, boolean enabled, int votePriority) {
             final Vote vote;
-            if (mUdfpsRefreshRateEnabled.get(displayId)) {
-                Display.Mode[] modes = mSupportedModesByDisplay.get(displayId);
-                float maxRefreshRate = 0f;
-                for (Display.Mode mode : modes) {
-                    if (mode.getRefreshRate() > maxRefreshRate) {
-                        maxRefreshRate = mode.getRefreshRate();
-                    }
-                }
+            if (enabled) {
+                float maxRefreshRate = DisplayModeDirector.this.getMaxRefreshRateLocked(displayId);
                 vote = Vote.forPhysicalRefreshRates(maxRefreshRate, maxRefreshRate);
             } else {
                 vote = null;
             }
-
-            DisplayModeDirector.this.updateVoteLocked(displayId, Vote.PRIORITY_UDFPS, vote);
+            DisplayModeDirector.this.updateVoteLocked(displayId, votePriority, vote);
         }
 
         void dumpLocked(PrintWriter pw) {
@@ -2593,6 +2646,13 @@
                 final String enabled = mUdfpsRefreshRateEnabled.valueAt(i) ? "enabled" : "disabled";
                 pw.println("      Display " + displayId + ": " + enabled);
             }
+            pw.println("    mAuthenticationPossible: ");
+            for (int i = 0; i < mAuthenticationPossible.size(); i++) {
+                final int displayId = mAuthenticationPossible.keyAt(i);
+                final String isPossible = mAuthenticationPossible.valueAt(i) ? "possible"
+                        : "impossible";
+                pw.println("      Display " + displayId + ": " + isPossible);
+            }
         }
     }
 
@@ -2715,7 +2775,7 @@
      * HBM that are associated with that display. Restrictions are retrieved from
      * DisplayManagerInternal but originate in the display-device-config file.
      */
-    public static class HbmObserver implements DisplayManager.DisplayListener {
+    public class HbmObserver implements DisplayManager.DisplayListener {
         private final BallotBox mBallotBox;
         private final Handler mHandler;
         private final SparseIntArray mHbmMode = new SparseIntArray();
@@ -2735,10 +2795,24 @@
             mDeviceConfigDisplaySettings = displaySettings;
         }
 
-        public void observe() {
-            mRefreshRateInHbmSunlight = mDeviceConfigDisplaySettings.getRefreshRateInHbmSunlight();
-            mRefreshRateInHbmHdr = mDeviceConfigDisplaySettings.getRefreshRateInHbmHdr();
+        /**
+         * Sets up the refresh rate to be used when HDR is enabled
+         */
+        public void setupHdrRefreshRates(DisplayDeviceConfig displayDeviceConfig) {
+            mRefreshRateInHbmHdr = mDeviceConfigDisplaySettings
+                .getRefreshRateInHbmHdr(displayDeviceConfig);
+            mRefreshRateInHbmSunlight = mDeviceConfigDisplaySettings
+                .getRefreshRateInHbmSunlight(displayDeviceConfig);
+        }
 
+        /**
+         * Sets up the HDR refresh rates, and starts observing for the changes in the display that
+         * might impact it
+         */
+        public void observe() {
+            synchronized (mLock) {
+                setupHdrRefreshRates(mDefaultDisplayDeviceConfig);
+            }
             mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
             mInjector.registerDisplayListener(this, mHandler,
                     DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
@@ -2970,26 +3044,33 @@
                     -1);
         }
 
-        public int getRefreshRateInHbmSunlight() {
-            final int defaultRefreshRateInHbmSunlight =
-                    mContext.getResources().getInteger(
-                            R.integer.config_defaultRefreshRateInHbmSunlight);
-
-            final int refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
-                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT,
-                    defaultRefreshRateInHbmSunlight);
-
+        public int getRefreshRateInHbmHdr(DisplayDeviceConfig displayDeviceConfig) {
+            int refreshRate =
+                    (displayDeviceConfig == null) ? mContext.getResources().getInteger(
+                            R.integer.config_defaultRefreshRateInHbmHdr)
+                            : displayDeviceConfig.getDefaultRefreshRateInHbmHdr();
+            try {
+                refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR,
+                    refreshRate);
+            } catch (NullPointerException e) {
+                // Do Nothing
+            }
             return refreshRate;
         }
 
-        public int getRefreshRateInHbmHdr() {
-            final int defaultRefreshRateInHbmHdr =
-                    mContext.getResources().getInteger(R.integer.config_defaultRefreshRateInHbmHdr);
-
-            final int refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
-                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR,
-                    defaultRefreshRateInHbmHdr);
-
+        public int getRefreshRateInHbmSunlight(DisplayDeviceConfig displayDeviceConfig) {
+            int refreshRate =
+                    (displayDeviceConfig == null) ? mContext.getResources()
+                        .getInteger(R.integer.config_defaultRefreshRateInHbmSunlight)
+                        : displayDeviceConfig.getDefaultRefreshRateInHbmSunlight();
+            try {
+                refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT,
+                    refreshRate);
+            } catch (NullPointerException e) {
+                // Do Nothing
+            }
             return refreshRate;
         }
 
@@ -3039,14 +3120,18 @@
                         0).sendToTarget();
             }
 
-            final int refreshRateInHbmSunlight = getRefreshRateInHbmSunlight();
-            mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED,
-                    refreshRateInHbmSunlight, 0)
+            synchronized (mLock) {
+                final int refreshRateInHbmSunlight =
+                        getRefreshRateInHbmSunlight(mDefaultDisplayDeviceConfig);
+                mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED,
+                        refreshRateInHbmSunlight, 0)
                     .sendToTarget();
 
-            final int refreshRateInHbmHdr = getRefreshRateInHbmHdr();
-            mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED, refreshRateInHbmHdr, 0)
+                final int refreshRateInHbmHdr =
+                        getRefreshRateInHbmHdr(mDefaultDisplayDeviceConfig);
+                mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED, refreshRateInHbmHdr, 0)
                     .sendToTarget();
+            }
         }
 
         private int[] getIntArrayProperty(String prop) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 40eec33..1305d63 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -18,6 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
@@ -74,6 +75,7 @@
 import com.android.server.display.brightness.BrightnessReason;
 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
+import com.android.server.display.layout.Layout;
 import com.android.server.display.utils.SensorUtils;
 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
 import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
@@ -195,6 +197,9 @@
     // The ID of the LogicalDisplay tied to this DisplayPowerController.
     private final int mDisplayId;
 
+    // The ID of the display which this display follows for brightness purposes.
+    private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;
+
     // The unique ID of the primary display device currently tied to this logical display
     private String mUniqueDisplayId;
 
@@ -509,8 +514,8 @@
     // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there
     // is one lead display, the additional displays follow the brightness value of the lead display.
     @GuardedBy("mLock")
-    private SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
-            new SparseArray();
+    private final SparseArray<DisplayPowerControllerInterface> mDisplayBrightnessFollowers =
+            new SparseArray<>();
 
     /**
      * Creates the display power controller.
@@ -722,6 +727,11 @@
     }
 
     @Override
+    public int getLeadDisplayId() {
+        return mLeadDisplayId;
+    }
+
+    @Override
     public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
         mHbmController.onAmbientLuxChange(ambientLux);
         if (mAutomaticBrightnessController == null || nits < 0) {
@@ -739,24 +749,20 @@
     }
 
     @Override
-    public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
+    public void addDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
         synchronized (mLock) {
             mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
+            sendUpdatePowerStateLocked();
         }
-        sendUpdatePowerState();
     }
 
     @Override
-    public void clearDisplayBrightnessFollowers() {
-        SparseArray<DisplayPowerControllerInterface> followers;
+    public void removeDisplayBrightnessFollower(@NonNull DisplayPowerControllerInterface follower) {
         synchronized (mLock) {
-            followers = mDisplayBrightnessFollowers.clone();
-            mDisplayBrightnessFollowers.clear();
-        }
-        for (int i = 0; i < followers.size(); i++) {
-            DisplayPowerControllerInterface follower = followers.valueAt(i);
-            follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
-                    /* ambientLux= */ 0);
+            mDisplayBrightnessFollowers.remove(follower.getDisplayId());
+            mHandler.postAtTime(() -> follower.setBrightnessToFollow(
+                    PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
+                    /* ambientLux= */ 0), mClock.uptimeMillis());
         }
     }
 
@@ -851,7 +857,8 @@
      * Make sure DisplayManagerService.mSyncRoot is held when this is called
      */
     @Override
-    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
+    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
+        mLeadDisplayId = leadDisplayId;
         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
         if (device == null) {
             Slog.wtf(mTag, "Display Device is null in DisplayPowerController for display: "
@@ -1011,7 +1018,7 @@
         }
         mBrightnessSettingListener = brightnessValue -> {
             Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         };
 
         mBrightnessSetting.registerListener(mBrightnessSettingListener);
@@ -1040,7 +1047,7 @@
 
         final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
                 R.bool.config_enableIdleScreenBrightnessMode);
-        mInteractiveModeBrightnessMapper = BrightnessMappingStrategy.create(resources,
+        mInteractiveModeBrightnessMapper = mInjector.getInteractiveModeBrightnessMapper(resources,
                 mDisplayDeviceConfig, mDisplayWhiteBalanceController);
         if (isIdleScreenBrightnessEnabled) {
             mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources,
@@ -1065,7 +1072,7 @@
                     mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold();
             float ambientBrighteningMinThreshold =
                     mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold();
-            HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
+            HysteresisLevels ambientBrightnessThresholds = mInjector.getHysteresisLevels(
                     ambientBrighteningThresholds, ambientDarkeningThresholds,
                     ambientBrighteningLevels, ambientDarkeningLevels, ambientDarkeningMinThreshold,
                     ambientBrighteningMinThreshold);
@@ -1083,7 +1090,7 @@
                     mDisplayDeviceConfig.getScreenDarkeningMinThreshold();
             float screenBrighteningMinThreshold =
                     mDisplayDeviceConfig.getScreenBrighteningMinThreshold();
-            HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
+            HysteresisLevels screenBrightnessThresholds = mInjector.getHysteresisLevels(
                     screenBrighteningThresholds, screenDarkeningThresholds,
                     screenBrighteningLevels, screenDarkeningLevels, screenDarkeningMinThreshold,
                     screenBrighteningMinThreshold, true);
@@ -1101,7 +1108,7 @@
                     mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle();
             float[] ambientDarkeningLevelsIdle =
                     mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle();
-            HysteresisLevels ambientBrightnessThresholdsIdle = new HysteresisLevels(
+            HysteresisLevels ambientBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
                     ambientBrighteningThresholdsIdle, ambientDarkeningThresholdsIdle,
                     ambientBrighteningLevelsIdle, ambientDarkeningLevelsIdle,
                     ambientDarkeningMinThresholdIdle, ambientBrighteningMinThresholdIdle);
@@ -1119,7 +1126,7 @@
                     mDisplayDeviceConfig.getScreenBrighteningLevelsIdle();
             float[] screenDarkeningLevelsIdle =
                     mDisplayDeviceConfig.getScreenDarkeningLevelsIdle();
-            HysteresisLevels screenBrightnessThresholdsIdle = new HysteresisLevels(
+            HysteresisLevels screenBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
                     screenBrighteningThresholdsIdle, screenDarkeningThresholdsIdle,
                     screenBrighteningLevelsIdle, screenDarkeningLevelsIdle,
                     screenDarkeningMinThresholdIdle, screenBrighteningMinThresholdIdle);
@@ -1155,8 +1162,8 @@
             if (mAutomaticBrightnessController != null) {
                 mAutomaticBrightnessController.stop();
             }
-            mAutomaticBrightnessController = new AutomaticBrightnessController(this,
-                    handler.getLooper(), mSensorManager, mLightSensor,
+            mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController(
+                    this, handler.getLooper(), mSensorManager, mLightSensor,
                     mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig,
                     PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, dozeScaleFactor,
                     lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
@@ -1257,7 +1264,7 @@
         public void onAnimationEnd() {
             sendUpdatePowerState();
             Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_RAMP_DONE);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         }
     };
 
@@ -2701,6 +2708,7 @@
             pw.println();
             pw.println("Display Power Controller:");
             pw.println("  mDisplayId=" + mDisplayId);
+            pw.println("  mLeadDisplayId=" + mLeadDisplayId);
             pw.println("  mLightSensor=" + mLightSensor);
 
             pw.println();
@@ -2949,7 +2957,8 @@
                 msg.what = MSG_STATSD_HBM_BRIGHTNESS;
                 msg.arg1 = Float.floatToIntBits(brightness);
                 msg.arg2 = mDisplayStatsId;
-                mHandler.sendMessageDelayed(msg, BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
+                mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()
+                        + BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
             }
         }
     }
@@ -3105,7 +3114,7 @@
         @Override
         public void onScreenOn() {
             Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         }
     }
 
@@ -3113,7 +3122,7 @@
         @Override
         public void onScreenOff() {
             Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         }
     }
 
@@ -3195,6 +3204,58 @@
                 FloatProperty<DisplayPowerState> secondProperty) {
             return new DualRampAnimator(dps, firstProperty, secondProperty);
         }
+
+        AutomaticBrightnessController getAutomaticBrightnessController(
+                AutomaticBrightnessController.Callbacks callbacks, Looper looper,
+                SensorManager sensorManager, Sensor lightSensor,
+                BrightnessMappingStrategy interactiveModeBrightnessMapper,
+                int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
+                float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
+                long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
+                boolean resetAmbientLuxAfterWarmUpConfig,
+                HysteresisLevels ambientBrightnessThresholds,
+                HysteresisLevels screenBrightnessThresholds,
+                HysteresisLevels ambientBrightnessThresholdsIdle,
+                HysteresisLevels screenBrightnessThresholdsIdle, Context context,
+                HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
+                BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
+                int ambientLightHorizonLong, float userLux, float userBrightness) {
+            return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
+                    interactiveModeBrightnessMapper, lightSensorWarmUpTime, brightnessMin,
+                    brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate,
+                    brighteningLightDebounceConfig, darkeningLightDebounceConfig,
+                    resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
+                    screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
+                    screenBrightnessThresholdsIdle, context, hbmController, brightnessThrottler,
+                    idleModeBrightnessMapper, ambientLightHorizonShort, ambientLightHorizonLong,
+                    userLux, userBrightness);
+        }
+
+        BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
+                DisplayDeviceConfig displayDeviceConfig,
+                DisplayWhiteBalanceController displayWhiteBalanceController) {
+            return BrightnessMappingStrategy.create(resources,
+                    displayDeviceConfig, displayWhiteBalanceController);
+        }
+
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold) {
+            return new HysteresisLevels(brighteningThresholdsPercentages,
+                    darkeningThresholdsPercentages, brighteningThresholdLevels,
+                    darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold);
+        }
+
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
+            return new HysteresisLevels(brighteningThresholdsPercentages,
+                    darkeningThresholdsPercentages, brighteningThresholdLevels,
+                    darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
+                    potentialOldBrightnessRange);
+        }
     }
 
     static class CachedBrightnessInfo {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 6092ad7..82faa12 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -73,6 +73,7 @@
 import com.android.server.display.brightness.DisplayBrightnessController;
 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
+import com.android.server.display.layout.Layout;
 import com.android.server.display.state.DisplayStateController;
 import com.android.server.display.utils.SensorUtils;
 import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
@@ -179,6 +180,9 @@
     // The ID of the LogicalDisplay tied to this DisplayPowerController2.
     private final int mDisplayId;
 
+    // The ID of the display which this display follows for brightness purposes.
+    private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;
+
     // The unique ID of the primary display device currently tied to this logical display
     private String mUniqueDisplayId;
 
@@ -694,7 +698,8 @@
      * Make sure DisplayManagerService.mSyncRoot lock is held when this is called
      */
     @Override
-    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata) {
+    public void onDisplayChanged(HighBrightnessModeMetadata hbmMetadata, int leadDisplayId) {
+        mLeadDisplayId = leadDisplayId;
         final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
         if (device == null) {
             Slog.wtf(mTag, "Display Device is null in DisplayPowerController2 for display: "
@@ -850,7 +855,7 @@
 
         BrightnessSetting.BrightnessSettingListener brightnessSettingListener = brightnessValue -> {
             Message msg = mHandler.obtainMessage(MSG_UPDATE_BRIGHTNESS, brightnessValue);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         };
         mDisplayBrightnessController
                 .registerBrightnessSettingChangeListener(brightnessSettingListener);
@@ -880,7 +885,7 @@
 
         final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
                 R.bool.config_enableIdleScreenBrightnessMode);
-        mInteractiveModeBrightnessMapper = BrightnessMappingStrategy.create(resources,
+        mInteractiveModeBrightnessMapper = mInjector.getInteractiveModeBrightnessMapper(resources,
                 mDisplayDeviceConfig, mDisplayWhiteBalanceController);
         if (isIdleScreenBrightnessEnabled) {
             mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources,
@@ -905,7 +910,7 @@
                     mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold();
             float ambientBrighteningMinThreshold =
                     mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold();
-            HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels(
+            HysteresisLevels ambientBrightnessThresholds = mInjector.getHysteresisLevels(
                     ambientBrighteningThresholds, ambientDarkeningThresholds,
                     ambientBrighteningLevels, ambientDarkeningLevels, ambientDarkeningMinThreshold,
                     ambientBrighteningMinThreshold);
@@ -923,7 +928,7 @@
                     mDisplayDeviceConfig.getScreenDarkeningMinThreshold();
             float screenBrighteningMinThreshold =
                     mDisplayDeviceConfig.getScreenBrighteningMinThreshold();
-            HysteresisLevels screenBrightnessThresholds = new HysteresisLevels(
+            HysteresisLevels screenBrightnessThresholds = mInjector.getHysteresisLevels(
                     screenBrighteningThresholds, screenDarkeningThresholds,
                     screenBrighteningLevels, screenDarkeningLevels, screenDarkeningMinThreshold,
                     screenBrighteningMinThreshold, true);
@@ -941,7 +946,7 @@
                     mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle();
             float[] ambientDarkeningLevelsIdle =
                     mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle();
-            HysteresisLevels ambientBrightnessThresholdsIdle = new HysteresisLevels(
+            HysteresisLevels ambientBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
                     ambientBrighteningThresholdsIdle, ambientDarkeningThresholdsIdle,
                     ambientBrighteningLevelsIdle, ambientDarkeningLevelsIdle,
                     ambientDarkeningMinThresholdIdle, ambientBrighteningMinThresholdIdle);
@@ -959,7 +964,7 @@
                     mDisplayDeviceConfig.getScreenBrighteningLevelsIdle();
             float[] screenDarkeningLevelsIdle =
                     mDisplayDeviceConfig.getScreenDarkeningLevelsIdle();
-            HysteresisLevels screenBrightnessThresholdsIdle = new HysteresisLevels(
+            HysteresisLevels screenBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
                     screenBrighteningThresholdsIdle, screenDarkeningThresholdsIdle,
                     screenBrighteningLevelsIdle, screenDarkeningLevelsIdle,
                     screenDarkeningMinThresholdIdle, screenBrighteningMinThresholdIdle);
@@ -995,8 +1000,8 @@
             if (mAutomaticBrightnessController != null) {
                 mAutomaticBrightnessController.stop();
             }
-            mAutomaticBrightnessController = new AutomaticBrightnessController(this,
-                    handler.getLooper(), mSensorManager, mLightSensor,
+            mAutomaticBrightnessController = mInjector.getAutomaticBrightnessController(
+                    this, handler.getLooper(), mSensorManager, mLightSensor,
                     mInteractiveModeBrightnessMapper, lightSensorWarmUpTimeConfig,
                     PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, dozeScaleFactor,
                     lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
@@ -1094,7 +1099,7 @@
         public void onAnimationEnd() {
             sendUpdatePowerState();
             Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_RAMP_DONE);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         }
     };
 
@@ -2149,6 +2154,11 @@
     }
 
     @Override
+    public int getLeadDisplayId() {
+        return mLeadDisplayId;
+    }
+
+    @Override
     public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
         mHbmController.onAmbientLuxChange(ambientLux);
         if (mAutomaticBrightnessController == null || nits < 0) {
@@ -2218,21 +2228,17 @@
     public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
         synchronized (mLock) {
             mDisplayBrightnessFollowers.append(follower.getDisplayId(), follower);
+            sendUpdatePowerStateLocked();
         }
-        sendUpdatePowerState();
     }
 
     @Override
-    public void clearDisplayBrightnessFollowers() {
-        SparseArray<DisplayPowerControllerInterface> followers;
+    public void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
         synchronized (mLock) {
-            followers = mDisplayBrightnessFollowers.clone();
-            mDisplayBrightnessFollowers.clear();
-        }
-        for (int i = 0; i < followers.size(); i++) {
-            DisplayPowerControllerInterface follower = followers.valueAt(i);
-            follower.setBrightnessToFollow(PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
-                    /* ambientLux= */ 0);
+            mDisplayBrightnessFollowers.remove(follower.getDisplayId());
+            mHandler.postAtTime(() -> follower.setBrightnessToFollow(
+                    PowerManager.BRIGHTNESS_INVALID_FLOAT, /* nits= */ -1,
+                    /* ambientLux= */ 0), mClock.uptimeMillis());
         }
     }
 
@@ -2242,6 +2248,7 @@
             pw.println();
             pw.println("Display Power Controller:");
             pw.println("  mDisplayId=" + mDisplayId);
+            pw.println("  mLeadDisplayId=" + mLeadDisplayId);
             pw.println("  mLightSensor=" + mLightSensor);
 
             pw.println();
@@ -2458,7 +2465,8 @@
                 msg.what = MSG_STATSD_HBM_BRIGHTNESS;
                 msg.arg1 = Float.floatToIntBits(brightness);
                 msg.arg2 = mDisplayStatsId;
-                mHandler.sendMessageDelayed(msg, BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
+                mHandler.sendMessageAtTime(msg, mClock.uptimeMillis()
+                        + BRIGHTNESS_CHANGE_STATSD_REPORT_INTERVAL_MS);
             }
         }
     }
@@ -2589,7 +2597,7 @@
         @Override
         public void onScreenOn() {
             Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         }
     }
 
@@ -2597,7 +2605,7 @@
         @Override
         public void onScreenOff() {
             Message msg = mHandler.obtainMessage(MSG_SCREEN_OFF_UNBLOCKED, this);
-            mHandler.sendMessage(msg);
+            mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
         }
     }
 
@@ -2671,6 +2679,58 @@
                     looper, nudgeUpdatePowerState,
                     displayId, sensorManager, /* injector= */ null);
         }
+
+        AutomaticBrightnessController getAutomaticBrightnessController(
+                AutomaticBrightnessController.Callbacks callbacks, Looper looper,
+                SensorManager sensorManager, Sensor lightSensor,
+                BrightnessMappingStrategy interactiveModeBrightnessMapper,
+                int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
+                float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
+                long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
+                boolean resetAmbientLuxAfterWarmUpConfig,
+                HysteresisLevels ambientBrightnessThresholds,
+                HysteresisLevels screenBrightnessThresholds,
+                HysteresisLevels ambientBrightnessThresholdsIdle,
+                HysteresisLevels screenBrightnessThresholdsIdle, Context context,
+                HighBrightnessModeController hbmController, BrightnessThrottler brightnessThrottler,
+                BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
+                int ambientLightHorizonLong, float userLux, float userBrightness) {
+            return new AutomaticBrightnessController(callbacks, looper, sensorManager, lightSensor,
+                    interactiveModeBrightnessMapper, lightSensorWarmUpTime, brightnessMin,
+                    brightnessMax, dozeScaleFactor, lightSensorRate, initialLightSensorRate,
+                    brighteningLightDebounceConfig, darkeningLightDebounceConfig,
+                    resetAmbientLuxAfterWarmUpConfig, ambientBrightnessThresholds,
+                    screenBrightnessThresholds, ambientBrightnessThresholdsIdle,
+                    screenBrightnessThresholdsIdle, context, hbmController, brightnessThrottler,
+                    idleModeBrightnessMapper, ambientLightHorizonShort, ambientLightHorizonLong,
+                    userLux, userBrightness);
+        }
+
+        BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
+                DisplayDeviceConfig displayDeviceConfig,
+                DisplayWhiteBalanceController displayWhiteBalanceController) {
+            return BrightnessMappingStrategy.create(resources,
+                    displayDeviceConfig, displayWhiteBalanceController);
+        }
+
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold) {
+            return new HysteresisLevels(brighteningThresholdsPercentages,
+                    darkeningThresholdsPercentages, brighteningThresholdLevels,
+                    darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold);
+        }
+
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
+            return new HysteresisLevels(brighteningThresholdsPercentages,
+                    darkeningThresholdsPercentages, brighteningThresholdLevels,
+                    darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
+                    potentialOldBrightnessRange);
+        }
     }
 
     static class CachedBrightnessInfo {
diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
index 4612ec9..0bc8154 100644
--- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
+++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
@@ -32,13 +32,18 @@
 
     /**
      * Notified when the display is changed.
-     * We use this to apply any changes that might be needed
-     * when displays get swapped on foldable devices.
-     * We also pass the High brightness mode metadata like
-     * remaining time and hbm events for the corresponding
-     * physical display, to update the values correctly.
+     *
+     * We use this to apply any changes that might be needed when displays get swapped on foldable
+     * devices, when layouts change, etc.
+     *
+     * Must be called while holding the SyncRoot lock.
+     *
+     * @param hbmInfo The high brightness mode metadata, like
+     *                remaining time and hbm events, for the corresponding
+     *                physical display, to make sure we stay within the safety margins.
+     * @param leadDisplayId The display who is considered our "leader" for things like brightness.
      */
-    void onDisplayChanged(HighBrightnessModeMetadata hbmInfo);
+    void onDisplayChanged(HighBrightnessModeMetadata hbmInfo, int leadDisplayId);
 
     /**
      * Unregisters all listeners and interrupts all running threads; halting future work.
@@ -169,6 +174,16 @@
     int getDisplayId();
 
     /**
+     * Get the ID of the display that is the leader of this DPC.
+     *
+     * Note that this is different than the display associated with the DPC. The leader is another
+     * display which we follow for things like brightness.
+     *
+     * Must be called while holding the SyncRoot lock.
+     */
+    int getLeadDisplayId();
+
+    /**
      * Set the brightness to follow if this is an additional display in a set of concurrent
      * displays.
      * @param leadDisplayBrightness The brightness of the lead display in the set of concurrent
@@ -187,7 +202,8 @@
     void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower);
 
     /**
-     * Clear all the additional displays following the brightness value of this display.
+     * Removes the given display from the list of brightness followers.
+     * @param follower The DPC to remove from the followers list
      */
-    void clearDisplayBrightnessFollowers();
+    void removeDisplayBrightnessFollower(DisplayPowerControllerInterface follower);
 }
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 4bb1f0e..667c8c8 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -23,6 +23,7 @@
 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;
@@ -77,6 +78,12 @@
     private final int mDisplayId;
     private final int mLayerStack;
 
+    // Indicates which display leads this logical display, in terms of brightness or other
+    // properties.
+    // {@link Layout.NO_LEAD_DISPLAY} means that this display is not lead by any others, and could
+    // be a leader itself.
+    private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY;
+
     private int mDisplayGroupId = Display.INVALID_DISPLAY_GROUP;
 
     /**
@@ -131,6 +138,11 @@
     private final Rect mTempDisplayRect = new Rect();
 
     /**
+     * Name of a display group to which the display is assigned.
+     */
+    private String mDisplayGroupName;
+
+    /**
      * The UID mappings for refresh rate override
      */
     private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides;
@@ -150,12 +162,16 @@
 
     // Indicates the display is part of a transition from one device-state ({@link
     // DeviceStateManager}) to another. Being a "part" of a transition means that either
-    // the {@link mIsEnabled} is changing, or the underlying mPrimiaryDisplayDevice is changing.
+    // the {@link mIsEnabled} is changing, or the underlying mPrimaryDisplayDevice is changing.
     private boolean mIsInTransition;
 
     // Indicates the position of the display, POSITION_UNKNOWN could mean it hasn't been specified,
     // or this is a virtual display etc.
-    private int mPosition = Layout.Display.POSITION_UNKNOWN;
+    private int mDevicePosition = Layout.Display.POSITION_UNKNOWN;
+
+    // Indicates that something other than the primary display device info has changed and needs to
+    // be handled in the next update.
+    private boolean mDirty = false;
 
     /**
      * The ID of the brightness throttling data that should be used. This can change e.g. in
@@ -175,11 +191,14 @@
         mBrightnessThrottlingDataId = DisplayDeviceConfig.DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID;
     }
 
-    public void setPositionLocked(int position) {
-        mPosition = position;
+    public void setDevicePositionLocked(int position) {
+        if (mDevicePosition != position) {
+            mDevicePosition = position;
+            mDirty = true;
+        }
     }
-    public int getPositionLocked() {
-        return mPosition;
+    public int getDevicePositionLocked() {
+        return mDevicePosition;
     }
 
     /**
@@ -337,9 +356,11 @@
         // logical display that they are sharing.  (eg. Adjust size for pixel-perfect
         // mirroring over HDMI.)
         DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
-        if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo)) {
+        if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo) || mDirty) {
             mBaseDisplayInfo.layerStack = mLayerStack;
             mBaseDisplayInfo.flags = 0;
+            // Displays default to moving content to the primary display when removed
+            mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
             }
@@ -437,12 +458,20 @@
             mBaseDisplayInfo.installOrientation = deviceInfo.installOrientation;
             mBaseDisplayInfo.displayShape = deviceInfo.displayShape;
 
-            if (mPosition == Layout.Display.POSITION_REAR) {
+            if (mDevicePosition == Layout.Display.POSITION_REAR) {
+                // A rear display is meant to host a specific experience that is essentially
+                // a presentation to another user or users other than the main user since they
+                // can't actually see that display. Given that, it's a suitable display for
+                // presentations but the content should be destroyed rather than moved to a non-rear
+                // display when the rear display is removed.
                 mBaseDisplayInfo.flags |= Display.FLAG_REAR;
+                mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
+                mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
             }
 
             mPrimaryDisplayDeviceInfo = deviceInfo;
             mInfo.set(null);
+            mDirty = false;
         }
     }
 
@@ -826,12 +855,58 @@
                 brightnessThrottlingDataId;
     }
 
+    /**
+     * Sets the display of which this display is a follower, regarding brightness or other
+     * properties. If set to {@link Layout#NO_LEAD_DISPLAY}, this display does not follow any
+     * others, and has the potential to be a lead display to others.
+     *
+     * A display cannot be a leader or follower of itself, and there cannot be cycles.
+     * A display cannot be both a leader and a follower, ie, there must not be any chains.
+     *
+     * @param displayId logical display id
+     */
+    public void setLeadDisplayLocked(int displayId) {
+        if (mDisplayId != mLeadDisplayId && mDisplayId != displayId) {
+            mLeadDisplayId = displayId;
+        }
+    }
+
+    public int getLeadDisplayIdLocked() {
+        return mLeadDisplayId;
+    }
+
+    /**
+     * Sets the name of display group to which the display is assigned.
+     */
+    public void setDisplayGroupNameLocked(String displayGroupName) {
+        mDisplayGroupName = displayGroupName;
+    }
+
+    /**
+     * Gets the name of display group to which the display is assigned.
+     */
+    public String getDisplayGroupNameLocked() {
+        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);
         pw.println("mIsInTransition=" + mIsInTransition);
         pw.println("mLayerStack=" + mLayerStack);
-        pw.println("mPosition=" + mPosition);
+        pw.println("mPosition=" + mDevicePosition);
         pw.println("mHasContent=" + mHasContent);
         pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}");
         pw.println("mRequestedColorMode=" + mRequestedColorMode);
@@ -844,7 +919,9 @@
         pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing);
         pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides));
         pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids);
+        pw.println("mDisplayGroupName=" + mDisplayGroupName);
         pw.println("mBrightnessThrottlingDataId=" + mBrightnessThrottlingDataId);
+        pw.println("mLeadDisplayId=" + mLeadDisplayId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index a67644b..b48ba65 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -18,6 +18,8 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.server.display.layout.Layout.NO_LEAD_DISPLAY;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -131,6 +133,11 @@
      */
     private final SparseIntArray mDeviceDisplayGroupIds = new SparseIntArray();
 
+    /**
+     * Map of display group ids indexed by display group name.
+     */
+    private final ArrayMap<String, Integer> mDisplayGroupIdsByName = new ArrayMap<>();
+
     private final DisplayDeviceRepository mDisplayDeviceRepo;
     private final DeviceStateToLayoutMap mDeviceStateToLayoutMap;
     private final Listener mListener;
@@ -638,8 +645,9 @@
                         & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0
                         && !nextDeviceInfo.address.equals(deviceInfo.address)) {
                     layout.createDisplayLocked(nextDeviceInfo.address,
-                            /* isDefault= */ true, /* isEnabled= */ true, mIdProducer,
-                            /* brightnessThrottlingMapId= */ null);
+                            /* isDefault= */ true, /* isEnabled= */ true,
+                            Layout.DEFAULT_DISPLAY_GROUP_NAME, mIdProducer,
+                            /* brightnessThrottlingMapId= */ null, DEFAULT_DISPLAY);
                     applyLayoutLocked();
                     return;
                 }
@@ -841,8 +849,7 @@
         final DisplayGroup oldGroup = getDisplayGroupLocked(groupId);
 
         // Get the new display group if a change is needed
-        final DisplayInfo info = display.getDisplayInfoLocked();
-        final boolean needsOwnDisplayGroup = (info.flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0;
+        final boolean needsOwnDisplayGroup = display.needsOwnDisplayGroupLocked();
         final boolean hasOwnDisplayGroup = groupId != Display.DEFAULT_DISPLAY_GROUP;
         final boolean needsDeviceDisplayGroup =
                 !needsOwnDisplayGroup && linkedDeviceUniqueId != null;
@@ -852,8 +859,9 @@
                 || hasOwnDisplayGroup != needsOwnDisplayGroup
                 || hasDeviceDisplayGroup != needsDeviceDisplayGroup) {
             groupId =
-                    assignDisplayGroupIdLocked(
-                            needsOwnDisplayGroup, needsDeviceDisplayGroup, linkedDeviceUniqueId);
+                    assignDisplayGroupIdLocked(needsOwnDisplayGroup,
+                            display.getDisplayGroupNameLocked(), needsDeviceDisplayGroup,
+                            linkedDeviceUniqueId);
         }
 
         // Create a new group if needed
@@ -990,16 +998,25 @@
                 newDisplay.swapDisplaysLocked(oldDisplay);
             }
 
-            newDisplay.setPositionLocked(displayLayout.getPosition());
+            newDisplay.setDevicePositionLocked(displayLayout.getPosition());
+            newDisplay.setLeadDisplayLocked(displayLayout.getLeadDisplayId());
+            setLayoutLimitedRefreshRate(newDisplay, device, displayLayout);
             setEnabledLocked(newDisplay, displayLayout.isEnabled());
             newDisplay.setBrightnessThrottlingDataIdLocked(
                     displayLayout.getBrightnessThrottlingMapId() == null
                             ? DisplayDeviceConfig.DEFAULT_BRIGHTNESS_THROTTLING_DATA_ID
                             : displayLayout.getBrightnessThrottlingMapId());
-        }
 
+            newDisplay.setDisplayGroupNameLocked(displayLayout.getDisplayGroupName());
+        }
     }
 
+    private void setLayoutLimitedRefreshRate(@NonNull LogicalDisplay logicalDisplay,
+            @NonNull DisplayDevice device, @NonNull Layout.Display display) {
+        DisplayDeviceConfig config = device.getDisplayDeviceConfig();
+        DisplayInfo info = logicalDisplay.getDisplayInfoLocked();
+        info.layoutLimitedRefreshRate = config.getRefreshRange(display.getRefreshRateZoneId());
+    }
 
     /**
      * Creates a new logical display for the specified device and display Id and adds it to the list
@@ -1044,8 +1061,8 @@
         }
     }
 
-    private int assignDisplayGroupIdLocked(
-            boolean isOwnDisplayGroup, boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId) {
+    private int assignDisplayGroupIdLocked(boolean isOwnDisplayGroup, String displayGroupName,
+            boolean isDeviceDisplayGroup, Integer linkedDeviceUniqueId) {
         if (isDeviceDisplayGroup && linkedDeviceUniqueId != null) {
             int deviceDisplayGroupId = mDeviceDisplayGroupIds.get(linkedDeviceUniqueId);
             // A value of 0 indicates that no device display group was found.
@@ -1055,7 +1072,13 @@
             }
             return deviceDisplayGroupId;
         }
-        return isOwnDisplayGroup ? mNextNonDefaultGroupId++ : Display.DEFAULT_DISPLAY_GROUP;
+        if (!isOwnDisplayGroup) return Display.DEFAULT_DISPLAY_GROUP;
+        Integer displayGroupId = mDisplayGroupIdsByName.get(displayGroupName);
+        if (displayGroupId == null) {
+            displayGroupId = Integer.valueOf(mNextNonDefaultGroupId++);
+            mDisplayGroupIdsByName.put(displayGroupName, displayGroupId);
+        }
+        return displayGroupId;
     }
 
     private void initializeDefaultDisplayDeviceLocked(DisplayDevice device) {
@@ -1070,7 +1093,8 @@
         }
         final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
         layout.createDisplayLocked(info.address, /* isDefault= */ true, /* isEnabled= */ true,
-                mIdProducer, /* brightnessThrottlingMapId= */ null);
+                Layout.DEFAULT_DISPLAY_GROUP_NAME, mIdProducer,
+                /* brightnessThrottlingMapId= */ null, NO_LEAD_DISPLAY);
     }
 
     private int assignLayerStackLocked(int displayId) {
diff --git a/services/core/java/com/android/server/display/TEST_MAPPING b/services/core/java/com/android/server/display/TEST_MAPPING
index 57c2e01..c4a566f 100644
--- a/services/core/java/com/android/server/display/TEST_MAPPING
+++ b/services/core/java/com/android/server/display/TEST_MAPPING
@@ -16,6 +16,20 @@
                 {"exclude-annotation": "androidx.test.filters.FlakyTest"},
                 {"exclude-annotation": "org.junit.Ignore"}
             ]
+        },
+        {
+            "name": "CtsMediaProjectionTestCases",
+            "options": [
+                {
+                    "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "exclude-annotation": "org.junit.Ignore"
+                }
+            ]
         }
     ]
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index 13fcff3..e3d92a7 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -92,9 +92,9 @@
         // TODO: b/186428377 update brightness setting when display changes
         mBrightnessSetting = brightnessSetting;
         mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+        mScreenBrightnessDefault = BrightnessUtils.clampAbsoluteBrightness(defaultScreenBrightness);
         mCurrentScreenBrightness = getScreenBrightnessSetting();
         mOnBrightnessChangeRunnable = onBrightnessChangeRunnable;
-        mScreenBrightnessDefault = BrightnessUtils.clampAbsoluteBrightness(defaultScreenBrightness);
         mDisplayBrightnessStrategySelector = injector.getDisplayBrightnessStrategySelector(context,
                 displayId);
     }
diff --git a/services/core/java/com/android/server/display/layout/Layout.java b/services/core/java/com/android/server/display/layout/Layout.java
index 01aa97a..f1e885e 100644
--- a/services/core/java/com/android/server/display/layout/Layout.java
+++ b/services/core/java/com/android/server/display/layout/Layout.java
@@ -36,9 +36,15 @@
  * a foldable device is folded, and a second instance for when the device is unfolded.
  */
 public class Layout {
+    public static final String DEFAULT_DISPLAY_GROUP_NAME = "";
+
     private static final String TAG = "Layout";
     private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1;
 
+    // Lead display Id is set to this if this is not a follower display, and therefore
+    // has no lead.
+    public static final int NO_LEAD_DISPLAY = -1;
+
     private final List<Display> mDisplays = new ArrayList<>(2);
 
     /**
@@ -75,13 +81,20 @@
      * @param address Address of the device.
      * @param isDefault Indicates if the device is meant to be the default display.
      * @param isEnabled Indicates if this display is usable and can be switched on
-     * @return The new layout.
+     * @param displayGroupName Name of the display group to which the display is assigned.
+     * @param idProducer Produces the logical display id.
+     * @param brightnessThrottlingMapId Name of which throttling policy should be used.
+     * @param leadDisplayId Display that this one follows (-1 if none).
+     * @exception IllegalArgumentException When a default display owns a display group other than
+     *            DEFAULT_DISPLAY_GROUP.
+     * @return The new Display.
      */
     public Display createDisplayLocked(
             @NonNull DisplayAddress address, boolean isDefault, boolean isEnabled,
-            DisplayIdProducer idProducer, String brightnessThrottlingMapId) {
-        return createDisplayLocked(address, isDefault, isEnabled, idProducer,
-                brightnessThrottlingMapId, POSITION_UNKNOWN);
+            String displayGroupName, DisplayIdProducer idProducer, String brightnessThrottlingMapId,
+            int leadDisplayId) {
+        return createDisplayLocked(address, isDefault, isEnabled, displayGroupName, idProducer,
+                brightnessThrottlingMapId, POSITION_UNKNOWN, leadDisplayId);
     }
 
     /**
@@ -90,12 +103,19 @@
      * @param address Address of the device.
      * @param isDefault Indicates if the device is meant to be the default display.
      * @param isEnabled Indicates if this display is usable and can be switched on
+     * @param displayGroupName Name of the display group to which the display is assigned.
+     * @param idProducer Produces the logical display id.
+     * @param brightnessThrottlingMapId Name of which throttling policy should be used.
      * @param position Indicates the position this display is facing in this layout.
-     * @return The new layout.
+     * @param leadDisplayId Display that this one follows (-1 if none).
+     * @exception IllegalArgumentException When a default display owns a display group other than
+     *            DEFAULT_DISPLAY_GROUP.
+     * @return The new Display.
      */
     public Display createDisplayLocked(
             @NonNull DisplayAddress address, boolean isDefault, boolean isEnabled,
-            DisplayIdProducer idProducer, String brightnessThrottlingMapId, int position) {
+            String displayGroupName, DisplayIdProducer idProducer, String brightnessThrottlingMapId,
+            int position, int leadDisplayId) {
         if (contains(address)) {
             Slog.w(TAG, "Attempting to add second definition for display-device: " + address);
             return null;
@@ -111,9 +131,15 @@
         // Note that the logical display ID is saved into the layout, so when switching between
         // different layouts, a logical display can be destroyed and later recreated with the
         // same logical display ID.
+        if (displayGroupName == null) {
+            displayGroupName = DEFAULT_DISPLAY_GROUP_NAME;
+        }
+        if (isDefault && !displayGroupName.equals(DEFAULT_DISPLAY_GROUP_NAME)) {
+            throw new IllegalArgumentException("Default display should own DEFAULT_DISPLAY_GROUP");
+        }
         final int logicalDisplayId = idProducer.getId(isDefault);
-        final Display display = new Display(address, logicalDisplayId, isEnabled,
-                brightnessThrottlingMapId, position);
+        final Display display = new Display(address, logicalDisplayId, isEnabled, displayGroupName,
+                brightnessThrottlingMapId, position, leadDisplayId);
 
         mDisplays.add(display);
         return display;
@@ -209,6 +235,9 @@
         // Indicates if this display is usable and can be switched on
         private final boolean mIsEnabled;
 
+        // Name of display group to which the display is assigned
+        private final String mDisplayGroupName;
+
         // The direction the display faces
         // {@link DeviceStateToLayoutMap.POSITION_FRONT} or
         // {@link DeviceStateToLayoutMap.POSITION_REAR}.
@@ -221,13 +250,29 @@
         @Nullable
         private final String mBrightnessThrottlingMapId;
 
+        // The ID of the lead display that this display will follow in a layout. -1 means no lead.
+        private int mLeadDisplayId;
+
+        // Refresh rate zone id for specific layout
+        @Nullable
+        private String mRefreshRateZoneId;
+
         Display(@NonNull DisplayAddress address, int logicalDisplayId, boolean isEnabled,
-                String brightnessThrottlingMapId, int position) {
+                @NonNull String displayGroupName, String brightnessThrottlingMapId, int position,
+                int leadDisplayId) {
             mAddress = address;
             mLogicalDisplayId = logicalDisplayId;
             mIsEnabled = isEnabled;
+            mDisplayGroupName = displayGroupName;
             mPosition = position;
             mBrightnessThrottlingMapId = brightnessThrottlingMapId;
+
+            if (leadDisplayId == mLogicalDisplayId) {
+                mLeadDisplayId = NO_LEAD_DISPLAY;
+            } else {
+                mLeadDisplayId = leadDisplayId;
+            }
+
         }
 
         @Override
@@ -235,9 +280,12 @@
             return "{"
                     + "dispId: " + mLogicalDisplayId
                     + "(" + (mIsEnabled ? "ON" : "OFF") + ")"
+                    + ", displayGroupName: " + mDisplayGroupName
                     + ", addr: " + mAddress
                     +  ((mPosition == POSITION_UNKNOWN) ? "" : ", position: " + mPosition)
                     + ", brightnessThrottlingMapId: " + mBrightnessThrottlingMapId
+                    + ", mRefreshRateZoneId: " + mRefreshRateZoneId
+                    + ", mLeadDisplayId: " + mLeadDisplayId
                     + "}";
         }
 
@@ -252,9 +300,12 @@
             return otherDisplay.mIsEnabled == this.mIsEnabled
                     && otherDisplay.mPosition == this.mPosition
                     && otherDisplay.mLogicalDisplayId == this.mLogicalDisplayId
+                    && this.mDisplayGroupName.equals(otherDisplay.mDisplayGroupName)
                     && this.mAddress.equals(otherDisplay.mAddress)
                     && Objects.equals(mBrightnessThrottlingMapId,
-                    otherDisplay.mBrightnessThrottlingMapId);
+                    otherDisplay.mBrightnessThrottlingMapId)
+                    && Objects.equals(otherDisplay.mRefreshRateZoneId, this.mRefreshRateZoneId)
+                    && this.mLeadDisplayId == otherDisplay.mLeadDisplayId;
         }
 
         @Override
@@ -263,8 +314,11 @@
             result = 31 * result + Boolean.hashCode(mIsEnabled);
             result = 31 * result + mPosition;
             result = 31 * result + mLogicalDisplayId;
+            result = 31 * result + mDisplayGroupName.hashCode();
             result = 31 * result + mAddress.hashCode();
             result = 31 * result + mBrightnessThrottlingMapId.hashCode();
+            result = 31 * result + Objects.hashCode(mRefreshRateZoneId);
+            result = 31 * result + mLeadDisplayId;
             return result;
         }
 
@@ -280,6 +334,23 @@
             return mIsEnabled;
         }
 
+        public String getDisplayGroupName() {
+            return mDisplayGroupName;
+        }
+
+        public void setRefreshRateZoneId(@Nullable String refreshRateZoneId) {
+            mRefreshRateZoneId = refreshRateZoneId;
+        }
+
+        @Nullable
+        public String getRefreshRateZoneId() {
+            return mRefreshRateZoneId;
+        }
+
+        /**
+         * Sets the position that this display is facing.
+         * @param position the display is facing.
+         */
         public void setPosition(int position) {
             mPosition = position;
         }
@@ -291,8 +362,31 @@
             return mBrightnessThrottlingMapId;
         }
 
+        /**
+         *
+         * @return the position that this display is facing.
+         */
         public int getPosition() {
             return mPosition;
         }
+
+        /**
+         * Set the display that this display should follow certain properties of, for example,
+         * brightness
+         * @param displayId of the lead display.
+         */
+        public void setLeadDisplay(int displayId) {
+            if (displayId != mLogicalDisplayId) {
+                mLeadDisplayId = displayId;
+            }
+        }
+
+        /**
+         *
+         * @return logical displayId of the display that this one follows.
+         */
+        public int getLeadDisplayId() {
+            return mLeadDisplayId;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index d7306b7..3bc4b54 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -294,8 +294,6 @@
                         new int[] {ACTIVITY_TYPE_DREAM});
 
                 mListener.onDreamStopped(dream.mToken);
-            } else if (dream.mCanDoze && !mCurrentDream.mCanDoze) {
-                mListener.stopDozing(dream.mToken);
             }
 
         } finally {
@@ -322,7 +320,7 @@
         try {
             service.asBinder().linkToDeath(mCurrentDream, 0);
             service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze,
-                    mCurrentDream.mDreamingStartedCallback);
+                    mCurrentDream.mIsPreviewMode, mCurrentDream.mDreamingStartedCallback);
         } catch (RemoteException ex) {
             Slog.e(TAG, "The dream service died unexpectedly.", ex);
             stopDream(true /*immediate*/, "attach failed");
@@ -343,7 +341,6 @@
      */
     public interface Listener {
         void onDreamStopped(Binder token);
-        void stopDozing(Binder token);
     }
 
     private final class DreamRecord implements DeathRecipient, ServiceConnection {
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index d9cdba7..7802b9d 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -72,6 +72,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.input.InputManagerInternal;
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.wm.ActivityInterceptorCallback;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
@@ -499,12 +500,7 @@
         }
 
         synchronized (mLock) {
-            if (mCurrentDream == null) {
-                return;
-            }
-
-            final boolean sameDream = mCurrentDream.token == token;
-            if ((sameDream && mCurrentDream.isDozing) || (!sameDream && !mCurrentDream.isDozing)) {
+            if (mCurrentDream != null && mCurrentDream.token == token && mCurrentDream.isDozing) {
                 mCurrentDream.isDozing = false;
                 mDozeWakeLock.release();
                 mPowerManagerInternal.setDozeOverrideFromDreamManager(
@@ -639,8 +635,10 @@
     }
 
     private boolean dreamsEnabledForUser(int userId) {
-        // TODO(b/257333623): Support non-system Dock Users in HSUM.
-        return !mDreamsOnlyEnabledForDockUser || (userId == UserHandle.USER_SYSTEM);
+        if (!mDreamsOnlyEnabledForDockUser) return true;
+        if (userId < 0) return false;
+        final int mainUserId = LocalServices.getService(UserManagerInternal.class).getMainUserId();
+        return userId == mainUserId;
     }
 
     private ServiceInfo getServiceInfo(ComponentName name) {
@@ -668,6 +666,10 @@
 
         Slog.i(TAG, "Entering dreamland.");
 
+        if (mCurrentDream != null && mCurrentDream.isDozing) {
+            stopDozingInternal(mCurrentDream.token);
+        }
+
         mCurrentDream = new DreamRecord(name, userId, isPreviewMode, canDoze);
 
         if (!mCurrentDream.name.equals(mAmbientDisplayComponent)) {
@@ -773,11 +775,6 @@
                 }
             }
         }
-
-        @Override
-        public void stopDozing(Binder token) {
-            stopDozingInternal(token);
-        }
     };
 
     private final ContentObserver mDozeEnabledObserver = new ContentObserver(null) {
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 6d1af3b..e21ec72 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -627,11 +627,14 @@
     })
     @interface HpdSignalType {}
 
-    static final String DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE = "soundbar_mode";
+    static final String DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE = "enable_soundbar_mode";
     static final String DEVICE_CONFIG_FEATURE_FLAG_ENABLE_EARC_TX = "enable_earc_tx";
+    static final String DEVICE_CONFIG_FEATURE_FLAG_TRANSITION_ARC_TO_EARC_TX =
+            "transition_arc_to_earc_tx";
     @StringDef({
             DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE,
-            DEVICE_CONFIG_FEATURE_FLAG_ENABLE_EARC_TX
+            DEVICE_CONFIG_FEATURE_FLAG_ENABLE_EARC_TX,
+            DEVICE_CONFIG_FEATURE_FLAG_TRANSITION_ARC_TO_EARC_TX
     })
     @interface FeatureFlag {}
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 6303bdc..9eedc4e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1261,7 +1261,8 @@
     void launchRoutingControl(boolean routingForBootup) {
         assertRunOnServiceThread();
         // Seq #24
-        if (getActivePortId() != Constants.INVALID_PORT_ID) {
+        if (getActivePortId() != Constants.INVALID_PORT_ID
+                && getActivePortId() != Constants.CEC_SWITCH_HOME) {
             if (!routingForBootup && !isProhibitMode()) {
                 int newPath = mService.portIdToPath(getActivePortId());
                 setActivePath(newPath);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 14b9121..3563938 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -458,6 +458,9 @@
     private boolean mEarcTxFeatureFlagEnabled = false;
 
     @ServiceThreadOnly
+    private boolean mTransitionFromArcToEarcTxEnabled = false;
+
+    @ServiceThreadOnly
     private int mActivePortId = Constants.INVALID_PORT_ID;
 
     // Set to true while the input change by MHL is allowed.
@@ -675,6 +678,8 @@
                 Constants.DEVICE_CONFIG_FEATURE_FLAG_SOUNDBAR_MODE, false);
         mEarcTxFeatureFlagEnabled = mDeviceConfig.getBoolean(
                 Constants.DEVICE_CONFIG_FEATURE_FLAG_ENABLE_EARC_TX, false);
+        mTransitionFromArcToEarcTxEnabled = mDeviceConfig.getBoolean(
+                Constants.DEVICE_CONFIG_FEATURE_FLAG_TRANSITION_ARC_TO_EARC_TX, false);
 
         synchronized (mLock) {
             mEarcEnabled = (mHdmiCecConfig.getIntValue(
@@ -886,6 +891,16 @@
                                 ? SOUNDBAR_MODE_ENABLED : SOUNDBAR_MODE_DISABLED);
                     }
                 }, mServiceThreadExecutor);
+
+        mDeviceConfig.addOnPropertiesChangedListener(getContext().getMainExecutor(),
+                new DeviceConfig.OnPropertiesChangedListener() {
+                    @Override
+                    public void onPropertiesChanged(DeviceConfig.Properties properties) {
+                        mTransitionFromArcToEarcTxEnabled = properties.getBoolean(
+                                Constants.DEVICE_CONFIG_FEATURE_FLAG_TRANSITION_ARC_TO_EARC_TX,
+                                false);
+                    }
+                });
     }
     /** Returns true if the device screen is off */
     boolean isScreenOff() {
@@ -1618,6 +1633,11 @@
     }
 
     void enableAudioReturnChannel(int portId, boolean enabled) {
+        if (!mTransitionFromArcToEarcTxEnabled && enabled && mEarcController != null) {
+            // If the feature flag is set to false, prevent eARC from establishing if ARC is already
+            // established.
+            setEarcEnabledInHal(false, false);
+        }
         mCecController.enableAudioReturnChannel(portId, enabled);
     }
 
@@ -2481,6 +2501,7 @@
                         Slog.w(TAG, "Local tv device not available to change arc mode.");
                         return;
                     }
+                    tv.startArcAction(enabled);
                 }
             });
         }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e2caeec..172aa20 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -32,7 +32,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.database.ContentObserver;
 import android.graphics.PointF;
 import android.hardware.SensorPrivacyManager;
 import android.hardware.SensorPrivacyManager.Sensors;
@@ -78,8 +77,6 @@
 import android.os.vibrator.StepSegment;
 import android.os.vibrator.VibrationEffectSegment;
 import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
@@ -147,8 +144,6 @@
     private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
     private static final String PORT_ASSOCIATIONS_PATH = "etc/input-port-associations.xml";
 
-    // Feature flag name for the deep press feature
-    private static final String DEEP_PRESS_ENABLED = "deep_press_enabled";
     // Feature flag name for the strategy to be used in VelocityTracker
     private static final String VELOCITYTRACKER_STRATEGY_PROPERTY = "velocitytracker_strategy";
 
@@ -307,6 +302,9 @@
     @GuardedBy("mInputMonitors")
     final Map<IBinder, GestureMonitorSpyWindow> mInputMonitors = new HashMap<>();
 
+    // Watches for settings changes and updates the native side appropriately.
+    private final InputSettingsObserver mSettingsObserver;
+
     // Manages Keyboard layouts for Physical keyboards
     private final KeyboardLayoutManager mKeyboardLayoutManager;
 
@@ -428,6 +426,7 @@
         mContext = injector.getContext();
         mHandler = new InputManagerHandler(injector.getLooper());
         mNative = injector.getNativeService(this);
+        mSettingsObserver = new InputSettingsObserver(mContext, mHandler, mNative);
         mKeyboardLayoutManager = new KeyboardLayoutManager(mContext, mNative, mDataStore,
                 injector.getLooper());
         mBatteryController = new BatteryController(mContext, mNative, injector.getLooper());
@@ -493,39 +492,7 @@
         // Add ourselves to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
 
-        registerMousePointerSpeedSettingObserver();
-        registerTouchpadPointerSpeedSettingObserver();
-        registerTouchpadNaturalScrollingEnabledObserver();
-        registerTouchpadTapToClickEnabledObserver();
-        registerTouchpadRightClickZoneEnabledObserver();
-        registerShowTouchesSettingObserver();
-        registerAccessibilityLargePointerSettingObserver();
-        registerLongPressTimeoutObserver();
-        registerMaximumObscuringOpacityForTouchSettingObserver();
-
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                updateMousePointerSpeedFromSettings();
-                updateTouchpadPointerSpeedFromSettings();
-                updateTouchpadNaturalScrollingEnabledFromSettings();
-                updateTouchpadTapToClickEnabledFromSettings();
-                updateTouchpadRightClickZoneEnabledFromSettings();
-                updateShowTouchesFromSettings();
-                updateAccessibilityLargePointerFromSettings();
-                updateDeepPressStatusFromSettings("user switched");
-            }
-        }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
-
-        updateMousePointerSpeedFromSettings();
-        updateTouchpadPointerSpeedFromSettings();
-        updateTouchpadNaturalScrollingEnabledFromSettings();
-        updateTouchpadTapToClickEnabledFromSettings();
-        updateTouchpadRightClickZoneEnabledFromSettings();
-        updateShowTouchesFromSettings();
-        updateAccessibilityLargePointerFromSettings();
-        updateDeepPressStatusFromSettings("just booted");
-        updateMaximumObscuringOpacityForTouchFromSettings();
+        mSettingsObserver.registerAndUpdate();
     }
 
     // TODO(BT) Pass in parameter for bluetooth system
@@ -1349,11 +1316,6 @@
         setPointerSpeedUnchecked(speed);
     }
 
-    private void updateMousePointerSpeedFromSettings() {
-        int speed = getMousePointerSpeedSetting();
-        setPointerSpeedUnchecked(speed);
-    }
-
     private void setPointerSpeedUnchecked(int speed) {
         speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
                 InputManager.MAX_POINTER_SPEED);
@@ -1370,194 +1332,6 @@
                 properties -> properties.pointerIconVisible = visible);
     }
 
-    private void registerMousePointerSpeedSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateMousePointerSpeedFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private int getMousePointerSpeedSetting() {
-        int speed = InputManager.DEFAULT_POINTER_SPEED;
-        try {
-            speed = Settings.System.getIntForUser(mContext.getContentResolver(),
-                    Settings.System.POINTER_SPEED, UserHandle.USER_CURRENT);
-        } catch (SettingNotFoundException ignored) {
-        }
-        return speed;
-    }
-
-    private void registerTouchpadPointerSpeedSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.TOUCHPAD_POINTER_SPEED), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateTouchpadPointerSpeedFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateTouchpadPointerSpeedFromSettings() {
-        int speed = Settings.System.getIntForUser(mContext.getContentResolver(),
-                Settings.System.TOUCHPAD_POINTER_SPEED, InputManager.DEFAULT_POINTER_SPEED,
-                UserHandle.USER_CURRENT);
-        speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
-                InputManager.MAX_POINTER_SPEED);
-        mNative.setTouchpadPointerSpeed(speed);
-    }
-
-    private void registerTouchpadNaturalScrollingEnabledObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.TOUCHPAD_NATURAL_SCROLLING), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateTouchpadNaturalScrollingEnabledFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateTouchpadNaturalScrollingEnabledFromSettings() {
-        int setting = Settings.System.getIntForUser(mContext.getContentResolver(),
-                Settings.System.TOUCHPAD_NATURAL_SCROLLING, 0, UserHandle.USER_CURRENT);
-        mNative.setTouchpadNaturalScrollingEnabled(setting != 0);
-    }
-
-    private void registerTouchpadTapToClickEnabledObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.TOUCHPAD_TAP_TO_CLICK), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateTouchpadTapToClickEnabledFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateTouchpadTapToClickEnabledFromSettings() {
-        int setting = Settings.System.getIntForUser(mContext.getContentResolver(),
-                Settings.System.TOUCHPAD_TAP_TO_CLICK, 0, UserHandle.USER_CURRENT);
-        mNative.setTouchpadTapToClickEnabled(setting != 0);
-    }
-
-    private void registerTouchpadRightClickZoneEnabledObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateTouchpadRightClickZoneEnabledFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateTouchpadRightClickZoneEnabledFromSettings() {
-        int setting = Settings.System.getIntForUser(mContext.getContentResolver(),
-                Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, 0, UserHandle.USER_CURRENT);
-        mNative.setTouchpadRightClickZoneEnabled(setting != 0);
-    }
-
-    private void updateShowTouchesFromSettings() {
-        int setting = getShowTouchesSetting(0);
-        mNative.setShowTouches(setting != 0);
-    }
-
-    private void registerShowTouchesSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateShowTouchesFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateAccessibilityLargePointerFromSettings() {
-        final int accessibilityConfig = Settings.Secure.getIntForUser(
-                mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
-                0, UserHandle.USER_CURRENT);
-        PointerIcon.setUseLargeIcons(accessibilityConfig == 1);
-        mNative.reloadPointerIcons();
-    }
-
-    private void registerAccessibilityLargePointerSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateAccessibilityLargePointerFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateDeepPressStatusFromSettings(String reason) {
-        // Not using ViewConfiguration.getLongPressTimeout here because it may return a stale value
-        final int timeout = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.LONG_PRESS_TIMEOUT, ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT,
-                UserHandle.USER_CURRENT);
-        final boolean featureEnabledFlag =
-                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
-                        DEEP_PRESS_ENABLED, true /* default */);
-        final boolean enabled =
-                featureEnabledFlag && timeout <= ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT;
-        Log.i(TAG,
-                (enabled ? "Enabling" : "Disabling") + " motion classifier because " + reason
-                + ": feature " + (featureEnabledFlag ? "enabled" : "disabled")
-                + ", long press timeout = " + timeout);
-        mNative.setMotionClassifierEnabled(enabled);
-    }
-
-    private void registerLongPressTimeoutObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LONG_PRESS_TIMEOUT), true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateDeepPressStatusFromSettings("timeout changed");
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void registerMaximumObscuringOpacityForTouchSettingObserver() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH),
-                /* notifyForDescendants */ true,
-                new ContentObserver(mHandler) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        updateMaximumObscuringOpacityForTouchFromSettings();
-                    }
-                }, UserHandle.USER_ALL);
-    }
-
-    private void updateMaximumObscuringOpacityForTouchFromSettings() {
-        InputManager im = Objects.requireNonNull(mContext.getSystemService(InputManager.class));
-        final float opacity = im.getMaximumObscuringOpacityForTouch();
-        if (opacity < 0 || opacity > 1) {
-            Log.e(TAG, "Invalid maximum obscuring opacity " + opacity
-                    + ", it should be >= 0 and <= 1, rejecting update.");
-            return;
-        }
-        mNative.setMaximumObscuringOpacityForTouch(opacity);
-    }
-
-    private int getShowTouchesSetting(int defaultValue) {
-        int result = defaultValue;
-        try {
-            result = Settings.System.getIntForUser(mContext.getContentResolver(),
-                    Settings.System.SHOW_TOUCHES, UserHandle.USER_CURRENT);
-        } catch (SettingNotFoundException snfe) {
-        }
-        return result;
-    }
-
     /**
      * Update the display on which the mouse pointer is shown.
      *
@@ -2974,6 +2748,13 @@
         return null;
     }
 
+    // Native callback.
+    @SuppressWarnings("unused")
+    private boolean isStylusPointerIconEnabled() {
+        return Objects.requireNonNull(mContext.getSystemService(InputManager.class))
+                .isStylusPointerIconEnabled();
+    }
+
     private static class PointerDisplayIdChangedArgs {
         final int mPointerDisplayId;
         final float mXPosition;
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
new file mode 100644
index 0000000..a113d01
--- /dev/null
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.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.server.input;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.hardware.input.InputManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.PointerIcon;
+import android.view.ViewConfiguration;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+/** Observes settings changes and propagates them to the native side. */
+class InputSettingsObserver extends ContentObserver {
+    static final String TAG = "InputManager";
+
+    /** Feature flag name for the deep press feature */
+    private static final String DEEP_PRESS_ENABLED = "deep_press_enabled";
+
+    private final Context mContext;
+    private final Handler mHandler;
+    private final NativeInputManagerService mNative;
+    private final Map<Uri, Consumer<String /* reason*/>> mObservers;
+
+    InputSettingsObserver(Context context, Handler handler, NativeInputManagerService nativeIms) {
+        super(handler);
+        mContext = context;
+        mHandler = handler;
+        mNative = nativeIms;
+        mObservers = Map.ofEntries(
+            Map.entry(Settings.System.getUriFor(Settings.System.POINTER_SPEED),
+                    (reason) -> updateMousePointerSpeed()),
+            Map.entry(Settings.System.getUriFor(Settings.System.TOUCHPAD_POINTER_SPEED),
+                    (reason) -> updateTouchpadPointerSpeed()),
+            Map.entry(Settings.System.getUriFor(Settings.System.TOUCHPAD_NATURAL_SCROLLING),
+                    (reason) -> updateTouchpadNaturalScrollingEnabled()),
+            Map.entry(Settings.System.getUriFor(Settings.System.TOUCHPAD_TAP_TO_CLICK),
+                    (reason) -> updateTouchpadTapToClickEnabled()),
+            Map.entry(Settings.System.getUriFor(Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE),
+                    (reason) -> updateTouchpadRightClickZoneEnabled()),
+            Map.entry(Settings.System.getUriFor(Settings.System.SHOW_TOUCHES),
+                    (reason) -> updateShowTouches()),
+            Map.entry(Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON),
+                    (reason) -> updateAccessibilityLargePointer()),
+            Map.entry(Settings.Secure.getUriFor(Settings.Secure.LONG_PRESS_TIMEOUT),
+                    (reason) -> updateDeepPressStatus(reason)),
+            Map.entry(
+                    Settings.Global.getUriFor(Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH),
+                    (reason) -> updateMaximumObscuringOpacityForTouch()));
+    }
+
+    /**
+     * Registers observers for input-related settings and updates the input subsystem with their
+     * current values.
+     */
+    public void registerAndUpdate() {
+        for (Uri uri : mObservers.keySet()) {
+            mContext.getContentResolver().registerContentObserver(
+                    uri, true /* notifyForDescendants */, this, UserHandle.USER_ALL);
+        }
+
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                for (Consumer<String> observer : mObservers.values()) {
+                    observer.accept("user switched");
+                }
+            }
+        }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler);
+
+        for (Consumer<String> observer : mObservers.values()) {
+            observer.accept("just booted");
+        }
+    }
+
+    @Override
+    public void onChange(boolean selfChange, Uri uri) {
+        mObservers.get(uri).accept("setting changed");
+    }
+
+    private boolean getBoolean(String settingName, boolean defaultValue) {
+        final int setting = Settings.System.getIntForUser(mContext.getContentResolver(),
+                settingName, defaultValue ? 1 : 0, UserHandle.USER_CURRENT);
+        return setting != 0;
+    }
+
+    private int getPointerSpeedValue(String settingName) {
+        int speed = Settings.System.getIntForUser(mContext.getContentResolver(),
+                settingName, InputManager.DEFAULT_POINTER_SPEED, UserHandle.USER_CURRENT);
+        return Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
+                InputManager.MAX_POINTER_SPEED);
+    }
+
+    private void updateMousePointerSpeed() {
+        mNative.setPointerSpeed(getPointerSpeedValue(Settings.System.POINTER_SPEED));
+    }
+
+    private void updateTouchpadPointerSpeed() {
+        mNative.setTouchpadPointerSpeed(
+                getPointerSpeedValue(Settings.System.TOUCHPAD_POINTER_SPEED));
+    }
+
+    private void updateTouchpadNaturalScrollingEnabled() {
+        mNative.setTouchpadNaturalScrollingEnabled(
+                getBoolean(Settings.System.TOUCHPAD_NATURAL_SCROLLING, true));
+    }
+
+    private void updateTouchpadTapToClickEnabled() {
+        mNative.setTouchpadTapToClickEnabled(
+                getBoolean(Settings.System.TOUCHPAD_TAP_TO_CLICK, true));
+    }
+
+    private void updateTouchpadRightClickZoneEnabled() {
+        mNative.setTouchpadRightClickZoneEnabled(
+                getBoolean(Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, false));
+    }
+
+    private void updateShowTouches() {
+        mNative.setShowTouches(getBoolean(Settings.System.SHOW_TOUCHES, false));
+    }
+
+    private void updateAccessibilityLargePointer() {
+        final int accessibilityConfig = Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
+                0, UserHandle.USER_CURRENT);
+        PointerIcon.setUseLargeIcons(accessibilityConfig == 1);
+        mNative.reloadPointerIcons();
+    }
+
+    private void updateDeepPressStatus(String reason) {
+        // Not using ViewConfiguration.getLongPressTimeout here because it may return a stale value
+        final int timeout = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LONG_PRESS_TIMEOUT, ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT,
+                UserHandle.USER_CURRENT);
+        final boolean featureEnabledFlag =
+                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
+                        DEEP_PRESS_ENABLED, true /* default */);
+        final boolean enabled =
+                featureEnabledFlag && timeout <= ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT;
+        Log.i(TAG,
+                (enabled ? "Enabling" : "Disabling") + " motion classifier because " + reason
+                + ": feature " + (featureEnabledFlag ? "enabled" : "disabled")
+                + ", long press timeout = " + timeout);
+        mNative.setMotionClassifierEnabled(enabled);
+    }
+
+    private void updateMaximumObscuringOpacityForTouch() {
+        InputManager im = Objects.requireNonNull(mContext.getSystemService(InputManager.class));
+        final float opacity = im.getMaximumObscuringOpacityForTouch();
+        if (opacity < 0 || opacity > 1) {
+            Log.e(TAG, "Invalid maximum obscuring opacity " + opacity
+                    + ", it should be >= 0 and <= 1, rejecting update.");
+            return;
+        }
+        mNative.setMaximumObscuringOpacityForTouch(opacity);
+    }
+}
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 298f6ad..9f7ff31 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -130,14 +130,14 @@
             @ImeVisibilityStateComputer.VisibilityState int state, int reason) {
         switch (state) {
             case STATE_SHOW_IME:
-                ImeTracker.get().onProgress(statsToken,
+                ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
                 // Send to window manager to show IME after IME layout finishes.
                 mWindowManagerInternal.showImePostLayout(windowToken, statsToken);
                 break;
             case STATE_HIDE_IME:
                 if (mService.mCurFocusedWindowClient != null) {
-                    ImeTracker.get().onProgress(statsToken,
+                    ImeTracker.forLogging().onProgress(statsToken,
                             ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
                     // IMMS only knows of focused window, not the actual IME target.
                     // e.g. it isn't aware of any window that has both
@@ -148,7 +148,7 @@
                     mWindowManagerInternal.hideIme(windowToken,
                             mService.mCurFocusedWindowClient.mSelfReportedDisplayId, statsToken);
                 } else {
-                    ImeTracker.get().onFailed(statsToken,
+                    ImeTracker.forLogging().onFailed(statsToken,
                             ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
                 }
                 break;
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index eaca842..ceb9706 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -183,10 +183,10 @@
      */
     boolean onImeShowFlags(@NonNull ImeTracker.Token statsToken, int showFlags) {
         if (mPolicy.mA11yRequestingNoSoftKeyboard || mPolicy.mImeHiddenByDisplayPolicy) {
-            ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
+            ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
             return false;
         }
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
         if ((showFlags & InputMethodManager.SHOW_FORCED) != 0) {
             mRequestedShowExplicitly = true;
             mShowForced = true;
@@ -207,15 +207,15 @@
         if ((hideFlags & InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
                 && (mRequestedShowExplicitly || mShowForced)) {
             if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
-            ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
+            ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
             return false;
         }
         if (mShowForced && (hideFlags & InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
             if (DEBUG) Slog.v(TAG, "Not hiding: forced show not cancelled by not-always hide");
-            ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
+            ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
             return false;
         }
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 27daceb..c7e4cd2 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2293,7 +2293,7 @@
             mCurClient.mSessionRequestedForAccessibility = false;
             mCurClient = null;
             mCurVirtualDisplayToScreenMatrix = null;
-            ImeTracker.get().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+            ImeTracker.forLogging().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
             mCurStatsToken = null;
 
             mMenuController.hideInputMethodMenuLocked();
@@ -3279,7 +3279,8 @@
                 "InputMethodManagerService#showSoftInput");
         synchronized (ImfLock.class) {
             if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken)) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
+                ImeTracker.forLogging().onFailed(
+                        statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
                 return false;
             }
             final long ident = Binder.clearCallingIdentity();
@@ -3375,7 +3376,7 @@
             // TODO(b/261565259): to avoid using null, add package name in ClientState
             final String packageName = (mCurEditorInfo != null) ? mCurEditorInfo.packageName : null;
             final int uid = mCurClient != null ? mCurClient.mUid : -1;
-            statsToken = ImeTracker.get().onRequestShow(packageName, uid,
+            statsToken = ImeTracker.forLogging().onRequestShow(packageName, uid,
                     ImeTracker.ORIGIN_SERVER_START_INPUT, reason);
         }
 
@@ -3384,19 +3385,19 @@
         }
 
         if (!mSystemReady) {
-            ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
+            ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
             return false;
         }
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
 
         mVisibilityStateComputer.requestImeVisibility(windowToken, true);
 
         // Ensure binding the connection when IME is going to show.
         mBindingController.setCurrentMethodVisible();
         final IInputMethodInvoker curMethod = getCurMethodLocked();
-        ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+        ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
         if (curMethod != null) {
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
             mCurStatsToken = null;
 
             if (lastClickToolType != MotionEvent.TOOL_TYPE_UNKNOWN) {
@@ -3407,7 +3408,7 @@
             mVisibilityStateComputer.setInputShown(true);
             return true;
         } else {
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
             mCurStatsToken = statsToken;
         }
         return false;
@@ -3423,9 +3424,10 @@
         synchronized (ImfLock.class) {
             if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken)) {
                 if (isInputShown()) {
-                    ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
+                    ImeTracker.forLogging().onFailed(
+                            statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
                 } else {
-                    ImeTracker.get().onCancelled(statsToken,
+                    ImeTracker.forLogging().onCancelled(statsToken,
                             ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
                 }
                 return false;
@@ -3458,7 +3460,7 @@
             } else {
                 uid = -1;
             }
-            statsToken = ImeTracker.get().onRequestHide(packageName, uid,
+            statsToken = ImeTracker.forLogging().onRequestHide(packageName, uid,
                     ImeTracker.ORIGIN_SERVER_HIDE_INPUT, reason);
         }
 
@@ -3484,15 +3486,15 @@
             // delivered to the IME process as an IPC.  Hence the inconsistency between
             // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
             // the final state.
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
             mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason);
         } else {
-            ImeTracker.get().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
+            ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
         }
         mBindingController.setCurrentMethodNotVisible();
         mVisibilityStateComputer.clearImeShowFlags();
         // Cancel existing statsToken for show IME as we got a hide request.
-        ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+        ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
         mCurStatsToken = null;
         return shouldHideSoftInput;
     }
@@ -3764,16 +3766,16 @@
             // be made before input is started in it.
             final ClientState cs = mClients.get(client.asBinder());
             if (cs == null) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
+                ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
                 throw new IllegalArgumentException("unknown client " + client.asBinder());
             }
-            ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
+            ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
             if (!isImeClientFocused(mCurFocusedWindow, cs)) {
                 Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
                 return false;
             }
         }
-        ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
+        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
         return true;
     }
 
@@ -4550,7 +4552,8 @@
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
         synchronized (ImfLock.class) {
             if (!calledWithValidTokenLocked(token)) {
-                ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
+                ImeTracker.forLogging().onFailed(statsToken,
+                        ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
                 return;
             }
             final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(windowToken);
@@ -4588,6 +4591,13 @@
             Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid()
                     + " token: " + token);
             return;
+        } else {
+            // Called with current IME's token.
+            if (mMethodMap.get(id) != null
+                    && mSettings.getEnabledInputMethodListWithFilterLocked(
+                            (info) -> info.getId().equals(id)).isEmpty()) {
+                throw new IllegalStateException("Requested IME is not enabled: " + id);
+            }
         }
 
         final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/location/altitude/AltitudeService.java b/services/core/java/com/android/server/location/altitude/AltitudeService.java
new file mode 100644
index 0000000..b321e4d
--- /dev/null
+++ b/services/core/java/com/android/server/location/altitude/AltitudeService.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location.altitude;
+
+import android.content.Context;
+import android.frameworks.location.altitude.AddMslAltitudeToLocationRequest;
+import android.frameworks.location.altitude.AddMslAltitudeToLocationResponse;
+import android.frameworks.location.altitude.IAltitudeService;
+import android.location.Location;
+import android.location.altitude.AltitudeConverter;
+import android.os.RemoteException;
+
+import com.android.server.SystemService;
+
+import java.io.IOException;
+
+/**
+ * Manages altitude information exchange through the HAL, e.g., geoid height requests such that
+ * vendors can perform altitude conversions.
+ *
+ * @hide
+ */
+public class AltitudeService extends IAltitudeService.Stub {
+
+    private final AltitudeConverter mAltitudeConverter = new AltitudeConverter();
+    private final Context mContext;
+
+    /** @hide */
+    public AltitudeService(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public AddMslAltitudeToLocationResponse addMslAltitudeToLocation(
+            AddMslAltitudeToLocationRequest request) throws RemoteException {
+        Location location = new Location("");
+        location.setLatitude(request.latitudeDegrees);
+        location.setLongitude(request.longitudeDegrees);
+        location.setAltitude(request.altitudeMeters);
+        location.setVerticalAccuracyMeters(request.verticalAccuracyMeters);
+        try {
+            mAltitudeConverter.addMslAltitudeToLocation(mContext, location);
+        } catch (IOException e) {
+            throw new RemoteException(e);
+        }
+
+        AddMslAltitudeToLocationResponse response = new AddMslAltitudeToLocationResponse();
+        response.mslAltitudeMeters = location.getMslAltitudeMeters();
+        response.mslAltitudeAccuracyMeters = location.getMslAltitudeAccuracyMeters();
+        return response;
+    }
+
+    @Override
+    public String getInterfaceHash() {
+        return IAltitudeService.HASH;
+    }
+
+    @Override
+    public int getInterfaceVersion() {
+        return IAltitudeService.VERSION;
+    }
+
+    /** @hide */
+    public static class Lifecycle extends SystemService {
+
+        private static final String SERVICE_NAME = IAltitudeService.DESCRIPTOR + "/default";
+
+        private AltitudeService mService;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onStart() {
+            mService = new AltitudeService(getContext());
+            publishBinderService(SERVICE_NAME, mService);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 50febba..925ab65 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -2105,6 +2105,11 @@
     @Override
     protected boolean registerWithService(ProviderRequest request,
             Collection<Registration> registrations) {
+        if (!request.isActive()) {
+            // the default request is already an empty request, no need to register this
+            return true;
+        }
+
         return reregisterWithService(ProviderRequest.EMPTY_REQUEST, request, registrations);
     }
 
@@ -2179,6 +2184,9 @@
         }
 
         EVENT_LOG.logProviderUpdateRequest(mName, request);
+        if (D) {
+            Log.d(TAG, mName + " provider request changed to " + request);
+        }
         mProvider.getController().setRequest(request);
 
         FgThread.getHandler().post(() -> {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ebc18bc..149a915 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
 import static android.Manifest.permission.MANAGE_BIOMETRIC;
-import static android.Manifest.permission.READ_CONTACTS;
 import static android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS;
 import static android.Manifest.permission.SET_INITIAL_LOCK;
 import static android.app.admin.DevicePolicyManager.DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT;
@@ -29,7 +28,7 @@
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.UserHandle.USER_ALL;
-import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION;
+import static android.os.UserHandle.USER_SYSTEM;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
@@ -57,6 +56,8 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.RemoteLockscreenValidationResult;
+import android.app.StartLockscreenValidationRequest;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.admin.DeviceStateCache;
@@ -70,6 +71,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.database.sqlite.SQLiteDatabase;
 import android.hardware.authsecret.IAuthSecret;
@@ -96,7 +98,6 @@
 import android.os.storage.StorageManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
-import android.provider.Settings.Secure;
 import android.security.AndroidKeyStoreMaintenance;
 import android.security.Authorization;
 import android.security.KeyStore;
@@ -110,12 +111,12 @@
 import android.security.keystore2.AndroidKeyStoreLoadStoreParameter;
 import android.security.keystore2.AndroidKeyStoreProvider;
 import android.service.gatekeeper.IGateKeeperService;
+import android.service.notification.StatusBarNotification;
 import android.system.keystore2.Domain;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.EventLog;
-import android.util.FeatureFlagUtils;
 import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -218,6 +219,8 @@
     private static final String PROFILE_KEY_NAME_ENCRYPT = "profile_key_name_encrypt_";
     private static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_";
 
+    private static final int HEADLESS_VENDOR_AUTH_SECRET_LENGTH = 32;
+
     // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
     // Do not call into ActivityManager while holding mSpManager lock.
     private final Object mSeparateChallengeLock = new Object();
@@ -266,6 +269,13 @@
     @VisibleForTesting
     protected boolean mHasSecureLockScreen;
 
+    @VisibleForTesting
+    protected final Object mHeadlessAuthSecretLock = new Object();
+
+    @VisibleForTesting
+    @GuardedBy("mHeadlessAuthSecretLock")
+    protected byte[] mAuthSecret;
+
     protected IGateKeeperService mGateKeeperService;
     protected IAuthSecret mAuthSecretService;
 
@@ -562,6 +572,15 @@
                 java.security.KeyStore ks) {
             return new ManagedProfilePasswordCache(ks, getUserManager());
         }
+
+        public boolean isHeadlessSystemUserMode() {
+            return UserManager.isHeadlessSystemUserMode();
+        }
+
+        public boolean isMainUserPermanentAdmin() {
+            return Resources.getSystem()
+                    .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin);
+        }
     }
 
     public LockSettingsService(Context context) {
@@ -581,6 +600,7 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_ADDED);
         filter.addAction(Intent.ACTION_USER_STARTING);
+        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
         injector.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter,
                 null, null);
 
@@ -602,6 +622,20 @@
         LocalServices.addService(LockSettingsInternal.class, new LocalService());
     }
 
+    private void updateActivatedEncryptionNotifications(String reason) {
+        for (UserInfo userInfo : mUserManager.getUsers()) {
+            Context userContext = mContext.createContextAsUser(UserHandle.of(userInfo.id), 0);
+            NotificationManager nm = (NotificationManager)
+                    userContext.getSystemService(Context.NOTIFICATION_SERVICE);
+            for (StatusBarNotification notification : nm.getActiveNotifications()) {
+                if (notification.getId() == SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION) {
+                    maybeShowEncryptionNotificationForUser(userInfo.id, reason);
+                    break;
+                }
+            }
+        }
+    }
+
     /**
      * If the account is credential-encrypted, show notification requesting the user to unlock the
      * device.
@@ -799,6 +833,8 @@
             } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
                 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                 mStorage.prefetchUser(userHandle);
+            } else if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+                updateActivatedEncryptionNotifications("locale changed");
             }
         }
     };
@@ -814,7 +850,6 @@
                 .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
         migrateOldData();
         getGateKeeperService();
-        mSpManager.initWeaverService();
         getAuthSecretHal();
         mDeviceProvisionedObserver.onSystemReady();
 
@@ -1048,27 +1083,21 @@
         mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsHave");
     }
 
-    private final void checkReadPermission(String requestedKey, int userId) {
-        final int callingUid = Binder.getCallingUid();
+    private static final String[] UNPROTECTED_SETTINGS = {
+        // These three LOCK_PATTERN_* settings have traditionally been readable via the public API
+        // android.provider.Settings.{System,Secure}.getString() without any permission.
+        Settings.Secure.LOCK_PATTERN_ENABLED,
+        Settings.Secure.LOCK_PATTERN_VISIBLE,
+        Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED,
+    };
 
-        for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_CONTACTS_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + READ_CONTACTS + " to read "
-                        + requestedKey + " for user " + userId);
-            }
+    private final void checkDatabaseReadPermission(String requestedKey, int userId) {
+        if (ArrayUtils.contains(UNPROTECTED_SETTINGS, requestedKey)) {
+            return;
         }
-
-        for (int i = 0; i < READ_PASSWORD_PROTECTED_SETTINGS.length; i++) {
-            String key = READ_PASSWORD_PROTECTED_SETTINGS[i];
-            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(PERMISSION)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("uid=" + callingUid
-                        + " needs permission " + PERMISSION + " to read "
-                        + requestedKey + " for user " + userId);
-            }
+        if (!hasPermission(PERMISSION)) {
+            throw new SecurityException("uid=" + getCallingUid() + " needs permission "
+                    + PERMISSION + " to read " + requestedKey + " for user " + userId);
         }
     }
 
@@ -1097,7 +1126,7 @@
 
     @Override
     public boolean getSeparateProfileChallengeEnabled(int userId) {
-        checkReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
+        checkDatabaseReadPermission(SEPARATE_PROFILE_CHALLENGE_KEY, userId);
         return getSeparateProfileChallengeEnabledInternal(userId);
     }
 
@@ -1178,7 +1207,7 @@
 
     @Override
     public boolean getBoolean(String key, boolean defaultValue, int userId) {
-        checkReadPermission(key, userId);
+        checkDatabaseReadPermission(key, userId);
         if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
             return getCredentialTypeInternal(userId) == CREDENTIAL_TYPE_PATTERN;
         }
@@ -1187,13 +1216,13 @@
 
     @Override
     public long getLong(String key, long defaultValue, int userId) {
-        checkReadPermission(key, userId);
+        checkDatabaseReadPermission(key, userId);
         return mStorage.getLong(key, defaultValue, userId);
     }
 
     @Override
     public String getString(String key, String defaultValue, int userId) {
-        checkReadPermission(key, userId);
+        checkDatabaseReadPermission(key, userId);
         return mStorage.getString(key, defaultValue, userId);
     }
 
@@ -1679,7 +1708,7 @@
                 throw new IllegalStateException("password change failed");
             }
 
-            onSyntheticPasswordKnown(userId, sp);
+            onSyntheticPasswordUnlocked(userId, sp);
             setLockCredentialWithSpLocked(credential, sp, userId);
             sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent);
             return true;
@@ -1690,8 +1719,7 @@
         if (newCredential.isPattern()) {
             setBoolean(LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, true, userHandle);
         }
-        if (DeviceConfig.getBoolean(NAMESPACE_AUTO_PIN_CONFIRMATION,
-                "enable_auto_pin_confirmation", /* defaultValue= */ false)) {
+        if (LockPatternUtils.isAutoPinConfirmFeatureAvailable()) {
             if (newCredential.isPin()) {
                 setLong(LockPatternUtils.PIN_LENGTH, newCredential.size(), userHandle);
             }
@@ -1991,7 +2019,7 @@
                 Slogf.wtf(TAG, "Failed to unwrap synthetic password for unsecured user %d", userId);
                 return;
             }
-            onSyntheticPasswordKnown(userId, result.syntheticPassword);
+            onSyntheticPasswordUnlocked(userId, result.syntheticPassword);
             unlockUserKey(userId, result.syntheticPassword);
         }
     }
@@ -2515,39 +2543,20 @@
     /**
      * Starts a session to verify lock screen credentials provided by a remote device.
      */
-    public void startRemoteLockscreenValidation() {
-        if (!FeatureFlagUtils.isEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API)) {
-            throw new UnsupportedOperationException("Under development");
-        }
-        mRecoverableKeyStoreManager.startRemoteLockscreenValidation();
+    @NonNull
+    public StartLockscreenValidationRequest startRemoteLockscreenValidation() {
+        return mRecoverableKeyStoreManager.startRemoteLockscreenValidation(this);
     }
 
     /**
-     * Verifies credentials guess from a remote device.
+     * Verifies encrypted credentials guess from a remote device.
      */
-    public void validateRemoteLockscreen(@NonNull byte[] encryptedCredential) {
-        if (!FeatureFlagUtils.isEnabled(mContext,
-                FeatureFlagUtils.SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API)) {
-            throw new UnsupportedOperationException("Under development");
-        }
-        mRecoverableKeyStoreManager.validateRemoteLockscreen(encryptedCredential);
+    @NonNull
+    public RemoteLockscreenValidationResult
+            validateRemoteLockscreen(@NonNull byte[] encryptedCredential) {
+        return mRecoverableKeyStoreManager.validateRemoteLockscreen(encryptedCredential, this);
     }
 
-    // Reading these settings needs the contacts permission
-    private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] {
-            Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
-            Secure.LOCK_SCREEN_OWNER_INFO
-    };
-
-    // Reading these settings needs the same permission as checking the password
-    private static final String[] READ_PASSWORD_PROTECTED_SETTINGS = new String[] {
-            LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
-            LockPatternUtils.PASSWORD_HISTORY_KEY,
-            LockPatternUtils.PASSWORD_TYPE_KEY,
-            SEPARATE_PROFILE_CHALLENGE_KEY
-    };
-
     private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
         @Override
         public void binderDied() {
@@ -2584,43 +2593,112 @@
         }
     }
 
-    private void onSyntheticPasswordKnown(@UserIdInt int userId, SyntheticPassword sp) {
+    private void onSyntheticPasswordCreated(@UserIdInt int userId, SyntheticPassword sp) {
+        onSyntheticPasswordKnown(userId, sp, true);
+    }
+
+    private void onSyntheticPasswordUnlocked(@UserIdInt int userId, SyntheticPassword sp) {
+        onSyntheticPasswordKnown(userId, sp, false);
+    }
+
+    private void onSyntheticPasswordKnown(
+            @UserIdInt int userId, SyntheticPassword sp, boolean justCreated) {
         if (mInjector.isGsiRunning()) {
             Slog.w(TAG, "Running in GSI; skipping calls to AuthSecret and RebootEscrow");
             return;
         }
 
-        mRebootEscrowManager.callToRebootEscrowIfNeeded(userId, sp.getVersion(),
-                sp.getSyntheticPassword());
-
-        callToAuthSecretIfNeeded(userId, sp);
+        mRebootEscrowManager.callToRebootEscrowIfNeeded(
+                userId, sp.getVersion(), sp.getSyntheticPassword());
+        callToAuthSecretIfNeeded(userId, sp, justCreated);
     }
 
-    private void callToAuthSecretIfNeeded(@UserIdInt int userId, SyntheticPassword sp) {
-        // If the given user is the primary user, pass the auth secret to the HAL.  Only the system
-        // user can be primary.  Check for the system user ID before calling getUserInfo(), as other
-        // users may still be under construction.
+    /**
+     * Handles generation, storage, and sending of the vendor auth secret. Here we try to retrieve
+     * the auth secret to send it to the auth secret HAL, generate a fresh secret if need be, store
+     * it encrypted on disk so that the given user can unlock it in future, and stash it in memory
+     * so that when future users are created they can also unlock it.
+     *
+     * <p>Called whenever the SP of a user is available, except in GSI.
+     */
+    private void callToAuthSecretIfNeeded(
+            @UserIdInt int userId, SyntheticPassword sp, boolean justCreated) {
         if (mAuthSecretService == null) {
+            // If there's no IAuthSecret service, we don't need to maintain a auth secret
             return;
         }
-        if (userId == UserHandle.USER_SYSTEM &&
-                mUserManager.getUserInfo(userId).isPrimary()) {
-            final byte[] secret = sp.deriveVendorAuthSecret();
-            try {
-                mAuthSecretService.setPrimaryUserCredential(secret);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Failed to pass primary user secret to AuthSecret HAL", e);
+        // User may be partially created, so use the internal user manager interface
+        final UserManagerInternal userManagerInternal = mInjector.getUserManagerInternal();
+        final UserInfo userInfo = userManagerInternal.getUserInfo(userId);
+        if (userInfo == null) {
+            // User may be partially deleted, skip this.
+            return;
+        }
+        final byte[] authSecret;
+        if (!mInjector.isHeadlessSystemUserMode()) {
+            // On non-headless systems, the auth secret is derived from user 0's
+            // SP, and only user 0 passes it to the HAL.
+            if (userId != USER_SYSTEM) {
+                return;
             }
+            authSecret = sp.deriveVendorAuthSecret();
+        } else if (!mInjector.isMainUserPermanentAdmin() || !userInfo.isFull()) {
+            // Only full users can receive or pass on the auth secret.
+            // If there is no main permanent admin user, we don't try to create or send
+            // an auth secret, since there may sometimes be no full users.
+            return;
+        } else if (justCreated) {
+            if (userInfo.isMain()) {
+                // The first user is just being created, so we create a new auth secret
+                // at the same time.
+                Slog.i(TAG, "Generating new vendor auth secret and storing for user: " + userId);
+                authSecret = SecureRandomUtils.randomBytes(HEADLESS_VENDOR_AUTH_SECRET_LENGTH);
+                // Store it in memory, for when new users are created.
+                synchronized (mHeadlessAuthSecretLock) {
+                    mAuthSecret = authSecret;
+                }
+            } else {
+                // A new user is being created. Another user should already have logged in at
+                // this point, and therefore the auth secret should be stored in memory.
+                synchronized (mHeadlessAuthSecretLock) {
+                    authSecret = mAuthSecret;
+                }
+                if (authSecret == null) {
+                    Slog.e(TAG, "Creating non-main user " + userId
+                            + " but vendor auth secret is not in memory");
+                    return;
+                }
+            }
+            // Store the auth secret encrypted using the user's SP (which was just created).
+            mSpManager.writeVendorAuthSecret(authSecret, sp, userId);
+        } else {
+            // The user already exists, so the auth secret should be stored encrypted
+            // with that user's SP.
+            authSecret = mSpManager.readVendorAuthSecret(sp, userId);
+            if (authSecret == null) {
+                Slog.e(TAG, "Unable to read vendor auth secret for user: " + userId);
+                return;
+            }
+            // Store it in memory, for when new users are created.
+            synchronized (mHeadlessAuthSecretLock) {
+                mAuthSecret = authSecret;
+            }
+        }
+        Slog.i(TAG, "Sending vendor auth secret to IAuthSecret HAL as user: " + userId);
+        try {
+            mAuthSecretService.setPrimaryUserCredential(authSecret);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed to send vendor auth secret to IAuthSecret HAL", e);
         }
     }
 
     /**
      * Creates the synthetic password (SP) for the given user, protects it with an empty LSKF, and
      * protects the user's CE key with a key derived from the SP.
-     * <p>
-     * This is called just once in the lifetime of the user: at user creation time (possibly delayed
-     * until the time when Weaver is guaranteed to be available), or when upgrading from Android 13
-     * or earlier where users with no LSKF didn't necessarily have an SP.
+     *
+     * <p>This is called just once in the lifetime of the user: at user creation time (possibly
+     * delayed until the time when Weaver is guaranteed to be available), or when upgrading from
+     * Android 13 or earlier where users with no LSKF didn't necessarily have an SP.
      */
     @VisibleForTesting
     SyntheticPassword initializeSyntheticPassword(int userId) {
@@ -2635,7 +2713,7 @@
                     LockscreenCredential.createNone(), sp, userId);
             setCurrentLskfBasedProtectorId(protectorId, userId);
             setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
-            onSyntheticPasswordKnown(userId, sp);
+            onSyntheticPasswordCreated(userId, sp);
             return sp;
         }
     }
@@ -2702,7 +2780,7 @@
         }
         mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
 
-        onSyntheticPasswordKnown(userId, sp);
+        onSyntheticPasswordUnlocked(userId, sp);
     }
 
     private void setDeviceUnlockedForUser(int userId) {
@@ -2990,7 +3068,7 @@
                     + "verification.");
             return false;
         }
-        onSyntheticPasswordKnown(userId, result.syntheticPassword);
+        onSyntheticPasswordUnlocked(userId, result.syntheticPassword);
         setLockCredentialWithSpLocked(credential, result.syntheticPassword, userId);
         return true;
     }
@@ -3361,10 +3439,10 @@
                     Slog.w(TAG, "Querying password metrics for unified challenge profile: "
                             + userHandle);
                 }
+                return LockSettingsService.this.getUserPasswordMetrics(userHandle);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
-            return LockSettingsService.this.getUserPasswordMetrics(userHandle);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index ea000a0..dee26e38 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -21,6 +21,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.admin.PasswordMetrics;
 import android.content.Context;
 import android.content.pm.UserInfo;
@@ -93,6 +94,9 @@
  *                     while the LSKF is nonempty.
  *     SP_E0_NAME, SP_P1_NAME: Information needed to create and use escrow token-based protectors.
  *                             Deleted when escrow token support is disabled for the user.
+ *     VENDOR_AUTH_SECRET_NAME: A copy of the secret passed using the IAuthSecret interface,
+ *                              encrypted using a secret derived from the SP using
+ *                              PERSONALIZATION_AUTHSECRET_ENCRYPTION_KEY.
  *
  *     For each protector, stored under the corresponding protector ID:
  *       SP_BLOB_NAME: The encrypted SP secret (the SP itself or the P0 value).  Always exists.
@@ -120,6 +124,7 @@
     private static final String PASSWORD_DATA_NAME = "pwd";
     private static final String WEAVER_SLOT_NAME = "weaver";
     private static final String PASSWORD_METRICS_NAME = "metrics";
+    private static final String VENDOR_AUTH_SECRET_NAME = "vendor_auth_secret";
 
     // used for files associated with the SP itself, not with a particular protector
     public static final long NULL_PROTECTOR_ID = 0L;
@@ -158,6 +163,8 @@
     private static final byte[] PERSONALIZATION_SP_GK_AUTH = "sp-gk-authentication".getBytes();
     private static final byte[] PERSONALIZATION_FBE_KEY = "fbe-key".getBytes();
     private static final byte[] PERSONALIZATION_AUTHSECRET_KEY = "authsecret-hal".getBytes();
+    private static final byte[] PERSONALIZATION_AUTHSECRET_ENCRYPTION_KEY =
+            "vendor-authsecret-encryption-key".getBytes();
     private static final byte[] PERSONALIZATION_SP_SPLIT = "sp-split".getBytes();
     private static final byte[] PERSONALIZATION_PASSWORD_HASH = "pw-hash".getBytes();
     private static final byte[] PERSONALIZATION_E0 = "e0-encryption".getBytes();
@@ -249,6 +256,10 @@
             return deriveSubkey(PERSONALIZATION_PASSWORD_METRICS);
         }
 
+        public byte[] deriveVendorAuthSecretEncryptionKey() {
+            return deriveSubkey(PERSONALIZATION_AUTHSECRET_ENCRYPTION_KEY);
+        }
+
         /**
          * Assigns escrow data to this synthetic password. This is a prerequisite to call
          * {@link SyntheticPassword#recreateFromEscrow}.
@@ -499,40 +510,35 @@
         return null;
     }
 
-    public synchronized void initWeaverService() {
+    private synchronized boolean isWeaverAvailable() {
         if (mWeaver != null) {
-            return;
+            return true;
         }
 
+        // Re-initialize weaver in case there was a transient error preventing access to it.
         IWeaver weaver = getWeaverService();
         if (weaver == null) {
-            return;
+            return false;
         }
 
-        // Get the config
-        WeaverConfig weaverConfig = null;
+        final WeaverConfig weaverConfig;
         try {
             weaverConfig = weaver.getConfig();
         } catch (RemoteException | ServiceSpecificException e) {
             Slog.e(TAG, "Failed to get weaver config", e);
+            return false;
         }
         if (weaverConfig == null || weaverConfig.slots <= 0) {
-            Slog.e(TAG, "Failed to initialize weaver config");
-            return;
+            Slog.e(TAG, "Invalid weaver config");
+            return false;
         }
 
         mWeaver = weaver;
         mWeaverConfig = weaverConfig;
         mPasswordSlotManager.refreshActiveSlots(getUsedWeaverSlots());
         Slog.i(TAG, "Weaver service initialized");
-    }
 
-    private synchronized boolean isWeaverAvailable() {
-        if (mWeaver == null) {
-            //Re-initializing weaver in case there was a transient error preventing access to it.
-            initWeaverService();
-        }
-        return mWeaver != null && mWeaverConfig.slots > 0;
+        return true;
     }
 
     /**
@@ -1737,4 +1743,25 @@
             mListeners.finishBroadcast();
         }
     }
+
+    public void writeVendorAuthSecret(
+            @NonNull final byte[] vendorAuthSecret,
+            @NonNull final SyntheticPassword sp,
+            @UserIdInt final int userId) {
+        final byte[] encrypted =
+                SyntheticPasswordCrypto.encrypt(
+                        sp.deriveVendorAuthSecretEncryptionKey(), new byte[0], vendorAuthSecret);
+        saveState(VENDOR_AUTH_SECRET_NAME, encrypted, NULL_PROTECTOR_ID, userId);
+        syncState(userId);
+    }
+
+    public @Nullable byte[] readVendorAuthSecret(
+            @NonNull final SyntheticPassword sp, @UserIdInt final int userId) {
+        final byte[] encrypted = loadState(VENDOR_AUTH_SECRET_NAME, NULL_PROTECTOR_ID, userId);
+        if (encrypted == null) {
+            return null;
+        }
+        return SyntheticPasswordCrypto.decrypt(
+                sp.deriveVendorAuthSecretEncryptionKey(), new byte[0], encrypted);
+    }
 }
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index b437421..c08958b 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -28,7 +28,10 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.KeyguardManager;
 import android.app.PendingIntent;
+import android.app.RemoteLockscreenValidationResult;
+import android.app.StartLockscreenValidationRequest;
 import android.content.Context;
 import android.os.Binder;
 import android.os.RemoteException;
@@ -40,11 +43,17 @@
 import android.security.keystore.recovery.RecoveryController;
 import android.security.keystore.recovery.WrappedApplicationKey;
 import android.util.ArrayMap;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView;
+import com.android.internal.widget.LockscreenCredential;
+import com.android.internal.widget.VerifyCredentialResponse;
 import com.android.security.SecureBox;
+import com.android.server.locksettings.LockSettingsService;
 import com.android.server.locksettings.recoverablekeystore.certificate.CertParsingException;
 import com.android.server.locksettings.recoverablekeystore.certificate.CertUtils;
 import com.android.server.locksettings.recoverablekeystore.certificate.CertValidationException;
@@ -55,8 +64,11 @@
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
+import com.android.server.locksettings.recoverablekeystore.storage.RemoteLockscreenValidationSessionStorage;
+import com.android.server.locksettings.recoverablekeystore.storage.RemoteLockscreenValidationSessionStorage.LockscreenVerificationSession;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.security.InvalidKeyException;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
@@ -89,6 +101,7 @@
 public class RecoverableKeyStoreManager {
     private static final String TAG = "RecoverableKeyStoreMgr";
     private static final long SYNC_DELAY_MILLIS = 2000;
+    private static final int INVALID_REMOTE_GUESS_LIMIT = 5;
 
     private static RecoverableKeyStoreManager mInstance;
 
@@ -103,6 +116,9 @@
     private final ApplicationKeyStorage mApplicationKeyStorage;
     private final TestOnlyInsecureCertificateHelper mTestCertHelper;
     private final CleanupManager mCleanupManager;
+    // only set if SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API is enabled.
+    @Nullable private final RemoteLockscreenValidationSessionStorage
+            mRemoteLockscreenValidationSessionStorage;
 
     /**
      * Returns a new or existing instance.
@@ -112,7 +128,18 @@
     public static synchronized RecoverableKeyStoreManager
             getInstance(Context context) {
         if (mInstance == null) {
-            RecoverableKeyStoreDb db = RecoverableKeyStoreDb.newInstance(context);
+            RecoverableKeyStoreDb db;
+            RemoteLockscreenValidationSessionStorage lockscreenCheckSessions;
+            if (FeatureFlagUtils.isEnabled(context,
+                    FeatureFlagUtils.SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API)) {
+                // TODO(b/254335492): Remove flag check when feature is launched.
+                db = RecoverableKeyStoreDb.newInstance(context, 7);
+                lockscreenCheckSessions = new RemoteLockscreenValidationSessionStorage();
+            } else {
+                db = RecoverableKeyStoreDb.newInstance(context);
+                lockscreenCheckSessions = null;
+            }
+
             PlatformKeyManager platformKeyManager;
             ApplicationKeyStorage applicationKeyStorage;
             try {
@@ -142,7 +169,8 @@
                     platformKeyManager,
                     applicationKeyStorage,
                     new TestOnlyInsecureCertificateHelper(),
-                    cleanupManager);
+                    cleanupManager,
+                    lockscreenCheckSessions);
         }
         return mInstance;
     }
@@ -158,7 +186,8 @@
             PlatformKeyManager platformKeyManager,
             ApplicationKeyStorage applicationKeyStorage,
             TestOnlyInsecureCertificateHelper testOnlyInsecureCertificateHelper,
-            CleanupManager cleanupManager) {
+            CleanupManager cleanupManager,
+            RemoteLockscreenValidationSessionStorage remoteLockscreenValidationSessionStorage) {
         mContext = context;
         mDatabase = recoverableKeyStoreDb;
         mRecoverySessionStorage = recoverySessionStorage;
@@ -177,6 +206,7 @@
             Log.wtf(TAG, "AES keygen algorithm not available. AOSP must support this.", e);
             throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
         }
+        mRemoteLockscreenValidationSessionStorage = remoteLockscreenValidationSessionStorage;
     }
 
     /**
@@ -969,32 +999,155 @@
     /**
      * Starts a session to verify lock screen credentials provided by a remote device.
      */
-    public void startRemoteLockscreenValidation() {
+    public StartLockscreenValidationRequest startRemoteLockscreenValidation(
+            LockSettingsService lockSettingsService) {
+        if (mRemoteLockscreenValidationSessionStorage == null) {
+            throw new UnsupportedOperationException("Under development");
+        }
         checkVerifyRemoteLockscreenPermission();
-        // TODO(b/254335492): Create session in memory
-        return;
+        int userId = UserHandle.getCallingUserId();
+        int savedCredentialType;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            savedCredentialType = lockSettingsService.getCredentialType(userId);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        int keyguardCredentialsType = lockPatternUtilsToKeyguardType(savedCredentialType);
+        LockscreenVerificationSession session =
+                mRemoteLockscreenValidationSessionStorage.startSession(userId);
+        PublicKey publicKey = session.getKeyPair().getPublic();
+        byte[] encodedPublicKey = SecureBox.encodePublicKey(publicKey);
+        int badGuesses = mDatabase.getBadRemoteGuessCounter(userId);
+        int remainingAttempts = Math.max(INVALID_REMOTE_GUESS_LIMIT - badGuesses, 0);
+        // TODO(b/254335492): Schedule task to remove inactive session
+        return new StartLockscreenValidationRequest.Builder()
+                .setLockscreenUiType(keyguardCredentialsType)
+                .setRemainingAttempts(remainingAttempts)
+                .setSourcePublicKey(encodedPublicKey)
+                .build();
     }
 
     /**
      * Verifies encrypted credentials guess from a remote device.
      */
-    public void validateRemoteLockscreen(@NonNull byte[] encryptedCredential) {
+    public synchronized RemoteLockscreenValidationResult validateRemoteLockscreen(
+            @NonNull byte[] encryptedCredential,
+            LockSettingsService lockSettingsService) {
         checkVerifyRemoteLockscreenPermission();
-        // TODO(b/254335492): Decrypt and verify credentials
-        return;
+        int userId = UserHandle.getCallingUserId();
+        LockscreenVerificationSession session =
+                mRemoteLockscreenValidationSessionStorage.get(userId);
+        int badGuesses = mDatabase.getBadRemoteGuessCounter(userId);
+        int remainingAttempts = INVALID_REMOTE_GUESS_LIMIT - badGuesses;
+        if (remainingAttempts <= 0) {
+            return new RemoteLockscreenValidationResult.Builder()
+                .setResultCode(RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS)
+                .build();
+        }
+        if (session == null) {
+            throw new IllegalStateException("There is no active lock screen check session");
+        }
+        byte[] decryptedCredentials;
+        try {
+            decryptedCredentials = SecureBox.decrypt(
+                session.getKeyPair().getPrivate(),
+                /* sharedSecret= */ null,
+                LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
+                encryptedCredential);
+        } catch (NoSuchAlgorithmException e) {
+            Log.wtf(TAG, "Missing SecureBox algorithm. AOSP required to support this.", e);
+            throw new IllegalStateException(e);
+        } catch (InvalidKeyException e) {
+            Log.e(TAG, "Got InvalidKeyException during lock screen credentials decryption");
+            throw new IllegalStateException(e);
+        } catch (AEADBadTagException e) {
+            throw new IllegalStateException("Could not decrypt credentials guess", e);
+        }
+        int savedCredentialType;
+        final long token = Binder.clearCallingIdentity();
+        try {
+            savedCredentialType = lockSettingsService.getCredentialType(userId);
+            int keyguardCredentialsType = lockPatternUtilsToKeyguardType(savedCredentialType);
+            try (LockscreenCredential credential =
+                    createLockscreenCredential(keyguardCredentialsType, decryptedCredentials)) {
+                // TODO(b/254335492): remove decryptedCredentials
+                VerifyCredentialResponse verifyResponse =
+                        lockSettingsService.verifyCredential(credential, userId, 0);
+                return handleVerifyCredentialResponse(verifyResponse, userId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private RemoteLockscreenValidationResult handleVerifyCredentialResponse(
+            VerifyCredentialResponse response, int userId) {
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+            mDatabase.setBadRemoteGuessCounter(userId, 0);
+            mRemoteLockscreenValidationSessionStorage.finishSession(userId);
+            return new RemoteLockscreenValidationResult.Builder()
+                    .setResultCode(RemoteLockscreenValidationResult.RESULT_GUESS_VALID)
+                    .build();
+        }
+        if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
+            long timeout = (long) response.getTimeout();
+            return new RemoteLockscreenValidationResult.Builder()
+                    .setResultCode(RemoteLockscreenValidationResult.RESULT_LOCKOUT)
+                    .setTimeoutMillis(timeout)
+                    .build();
+        }
+        // Invalid guess
+        int badGuesses = mDatabase.getBadRemoteGuessCounter(userId);
+        mDatabase.setBadRemoteGuessCounter(userId, badGuesses + 1);
+        return new RemoteLockscreenValidationResult.Builder()
+                .setResultCode(RemoteLockscreenValidationResult.RESULT_GUESS_INVALID)
+                .build();
+    }
+
+    private LockscreenCredential createLockscreenCredential(
+            int lockType, byte[] password) {
+        switch (lockType) {
+            case KeyguardManager.PASSWORD:
+                CharSequence passwordStr = new String(password, StandardCharsets.UTF_8);
+                return LockscreenCredential.createPassword(passwordStr);
+            case KeyguardManager.PIN:
+                CharSequence pinStr = new String(password);
+                return LockscreenCredential.createPin(pinStr);
+            case KeyguardManager.PATTERN:
+                List<LockPatternView.Cell> pattern =
+                        LockPatternUtils.byteArrayToPattern(password);
+                return LockscreenCredential.createPattern(pattern);
+            default:
+                throw new IllegalStateException("Lockscreen is not set");
+        }
     }
 
     private void checkVerifyRemoteLockscreenPermission() {
-        // TODO(b/254335492): Check new system permission
         mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.RECOVER_KEYSTORE,
+                Manifest.permission.CHECK_REMOTE_LOCKSCREEN,
                 "Caller " + Binder.getCallingUid()
-                        + " doesn't have verifyRemoteLockscreen permission.");
+                        + " doesn't have CHECK_REMOTE_LOCKSCREEN permission.");
         int userId = UserHandle.getCallingUserId();
         int uid = Binder.getCallingUid();
         mCleanupManager.registerRecoveryAgent(userId, uid);
     }
 
+    private int lockPatternUtilsToKeyguardType(int credentialsType) {
+        switch(credentialsType) {
+            case LockPatternUtils.CREDENTIAL_TYPE_NONE:
+                throw new IllegalStateException("Screen lock is not set");
+            case LockPatternUtils.CREDENTIAL_TYPE_PATTERN:
+                return KeyguardManager.PATTERN;
+            case LockPatternUtils.CREDENTIAL_TYPE_PIN:
+                return KeyguardManager.PIN;
+            case LockPatternUtils.CREDENTIAL_TYPE_PASSWORD:
+                return KeyguardManager.PASSWORD;
+            default:
+                throw new IllegalStateException("Screen lock is not set");
+        }
+    }
+
     private void checkRecoverKeyStorePermission() {
         mContext.enforceCallingOrSelfPermission(
                 Manifest.permission.RECOVER_KEYSTORE,
diff --git a/services/core/java/com/android/server/media/projection/TEST_MAPPING b/services/core/java/com/android/server/media/projection/TEST_MAPPING
index a792498..4324930 100644
--- a/services/core/java/com/android/server/media/projection/TEST_MAPPING
+++ b/services/core/java/com/android/server/media/projection/TEST_MAPPING
@@ -13,6 +13,20 @@
           "exclude-annotation": "org.junit.Ignore"
         }
       ]
+    },
+    {
+      "name": "CtsMediaProjectionTestCases",
+      "options": [
+        {
+          "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
     }
   ]
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 14ae2a7..c1b3834 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -24,6 +24,7 @@
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.Notification.FLAG_INSISTENT;
 import static android.app.Notification.FLAG_NO_CLEAR;
+import static android.app.Notification.FLAG_NO_DISMISS;
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
@@ -113,6 +114,7 @@
 import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING;
 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
@@ -270,6 +272,7 @@
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.logging.InstanceId;
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.logging.MetricsLogger;
@@ -576,6 +579,8 @@
     private float mInCallNotificationVolume;
     private Binder mCallNotificationToken = null;
 
+    private SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver;
+
     // used as a mutex for access to all active notifications & listeners
     final Object mNotificationLock = new Object();
     @GuardedBy("mNotificationLock")
@@ -640,6 +645,7 @@
     private NotificationUsageStats mUsageStats;
     private boolean mLockScreenAllowSecureNotifications = true;
     boolean mAllowFgsDismissal = false;
+    boolean mSystemExemptFromDismissal = false;
 
     private static final int MY_UID = Process.myUid();
     private static final int MY_PID = Process.myPid();
@@ -1201,10 +1207,14 @@
                     id = r.getSbn().getId();
                 }
             }
-            int mustNotHaveFlags = FLAG_ONGOING_EVENT;
-            cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
-                    mustNotHaveFlags,
-                    true, userId, REASON_CANCEL, nv.rank, nv.count,null);
+
+            int mustNotHaveFlags = mFlagResolver.isEnabled(ALLOW_DISMISS_ONGOING)
+                    ? FLAG_NO_DISMISS : FLAG_ONGOING_EVENT;
+            cancelNotification(callingUid, callingPid, pkg, tag, id,
+                    /* mustHaveFlags= */ 0,
+                    /* mustNotHaveFlags= */ mustNotHaveFlags,
+                    /* sendDelete= */ true,
+                    userId, REASON_CANCEL, nv.rank, nv.count, /* listener= */ null);
             nv.recycle();
         }
 
@@ -2210,7 +2220,8 @@
             TelephonyManager telephonyManager, ActivityManagerInternal ami,
             MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper,
             UsageStatsManagerInternal usageStatsManagerInternal,
-            TelecomManager telecomManager, NotificationChannelLogger channelLogger) {
+            TelecomManager telecomManager, NotificationChannelLogger channelLogger,
+            SystemUiSystemPropertiesFlags.FlagResolver flagResolver) {
         mHandler = handler;
         Resources resources = getContext().getResources();
         mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
@@ -2408,6 +2419,8 @@
         mMsgPkgsAllowedAsConvos = Set.of(getStringArrayResource(
                 com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos));
 
+        mFlagResolver = flagResolver;
+
         mStatsManager = statsManager;
 
         mToastRateLimiter = toastRateLimiter;
@@ -2539,7 +2552,7 @@
                         AppGlobals.getPermissionManager()),
                 LocalServices.getService(UsageStatsManagerInternal.class),
                 getContext().getSystemService(TelecomManager.class),
-                new NotificationChannelLoggerImpl());
+                new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver());
 
         publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
                 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
@@ -2588,6 +2601,10 @@
         mAllowFgsDismissal = DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
                 SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED, true);
+        mSystemExemptFromDismissal = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
+                /* name= */ "application_exemptions",
+                /* defaultValue= */ true);
         DeviceConfig.addOnPropertiesChangedListener(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
                 new HandlerExecutor(mHandler),
@@ -6505,7 +6522,7 @@
 
         // Fix the notification as best we can.
         try {
-            fixNotification(notification, pkg, tag, id, userId);
+            fixNotification(notification, pkg, tag, id, userId, notificationUid);
         } catch (Exception e) {
             if (notification.isForegroundService()) {
                 throw new SecurityException("Invalid FGS notification", e);
@@ -6683,23 +6700,48 @@
 
     @VisibleForTesting
     protected void fixNotification(Notification notification, String pkg, String tag, int id,
-            int userId) throws NameNotFoundException, RemoteException {
+            @UserIdInt int userId, int notificationUid) throws NameNotFoundException,
+            RemoteException {
         final ApplicationInfo ai = mPackageManagerClient.getApplicationInfoAsUser(
                 pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                 (userId == UserHandle.USER_ALL) ? USER_SYSTEM : userId);
         Notification.addFieldsFromContext(ai, notification);
 
-        int canColorize = mPackageManagerClient.checkPermission(
-                android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, pkg);
+        // Only notifications that can be non-dismissible can have the flag FLAG_NO_DISMISS
+        if (mFlagResolver.isEnabled(ALLOW_DISMISS_ONGOING)) {
+            if (((notification.flags & FLAG_ONGOING_EVENT) > 0)
+                    && canBeNonDismissible(ai, notification)) {
+                notification.flags |= FLAG_NO_DISMISS;
+            } else {
+                notification.flags &= ~FLAG_NO_DISMISS;
+            }
+        }
+
+        int canColorize = getContext().checkPermission(
+                android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, -1, notificationUid);
+
         if (canColorize == PERMISSION_GRANTED) {
             notification.flags |= Notification.FLAG_CAN_COLORIZE;
         } else {
             notification.flags &= ~Notification.FLAG_CAN_COLORIZE;
         }
 
+        if (notification.extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, false)) {
+            int hasShowDuringSetupPerm = getContext().checkPermission(
+                    android.Manifest.permission.NOTIFICATION_DURING_SETUP, -1, notificationUid);
+            if (hasShowDuringSetupPerm != PERMISSION_GRANTED) {
+                notification.extras.remove(Notification.EXTRA_ALLOW_DURING_SETUP);
+                if (DBG) {
+                    Slog.w(TAG, "warning: pkg " + pkg + " attempting to show during setup"
+                            + " without holding perm "
+                            + Manifest.permission.NOTIFICATION_DURING_SETUP);
+                }
+            }
+        }
+
         if (notification.fullScreenIntent != null && ai.targetSdkVersion >= Build.VERSION_CODES.Q) {
-            int fullscreenIntentPermission = mPackageManagerClient.checkPermission(
-                    android.Manifest.permission.USE_FULL_SCREEN_INTENT, pkg);
+            int fullscreenIntentPermission = getContext().checkPermission(
+                    android.Manifest.permission.USE_FULL_SCREEN_INTENT, -1, notificationUid);
             if (fullscreenIntentPermission != PERMISSION_GRANTED) {
                 notification.fullScreenIntent = null;
                 Slog.w(TAG, "Package " + pkg +
@@ -6744,8 +6786,8 @@
 
         // Ensure MediaStyle has correct permissions for remote device extras
         if (notification.isStyle(Notification.MediaStyle.class)) {
-            int hasMediaContentControlPermission = mPackageManager.checkPermission(
-                    android.Manifest.permission.MEDIA_CONTENT_CONTROL, pkg, userId);
+            int hasMediaContentControlPermission = getContext().checkPermission(
+                    android.Manifest.permission.MEDIA_CONTENT_CONTROL, -1, notificationUid);
             if (hasMediaContentControlPermission != PERMISSION_GRANTED) {
                 notification.extras.remove(Notification.EXTRA_MEDIA_REMOTE_DEVICE);
                 notification.extras.remove(Notification.EXTRA_MEDIA_REMOTE_ICON);
@@ -6759,8 +6801,8 @@
 
         // Ensure only allowed packages have a substitute app name
         if (notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) {
-            int hasSubstituteAppNamePermission = mPackageManager.checkPermission(
-                    permission.SUBSTITUTE_NOTIFICATION_APP_NAME, pkg, userId);
+            int hasSubstituteAppNamePermission = getContext().checkPermission(
+                    permission.SUBSTITUTE_NOTIFICATION_APP_NAME, -1, notificationUid);
             if (hasSubstituteAppNamePermission != PERMISSION_GRANTED) {
                 notification.extras.remove(Notification.EXTRA_SUBSTITUTE_APP_NAME);
                 if (DBG) {
@@ -6775,6 +6817,31 @@
         checkRemoteViews(pkg, tag, id, notification);
     }
 
+    /**
+     * Whether a notification can be non-dismissible.
+     * A notification should be dismissible, unless it's exempted for some reason.
+     */
+    private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) {
+        // Check if the app is on the system partition, or an update to an app on the system
+        // partition.
+        boolean isSystemAppExempt = (ai.flags
+                & (ApplicationInfo.FLAG_UPDATED_SYSTEM_APP | ApplicationInfo.FLAG_SYSTEM)) > 0;
+        return isSystemAppExempt || notification.isMediaNotification() || isEnterpriseExempted(ai);
+    }
+
+    private boolean isEnterpriseExempted(ApplicationInfo ai) {
+        // Check if the app is an organization admin app
+        // TODO(b/234609037): Replace with new DPM APIs to check if organization admin
+        if (mDpm != null && (mDpm.isActiveProfileOwner(ai.uid)
+                || mDpm.isActiveDeviceOwner(ai.uid))) {
+            return true;
+        }
+        // Check if an app has been given system exemption
+        return mSystemExemptFromDismissal && mAppOps.checkOpNoThrow(
+                AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, ai.uid,
+                ai.packageName) == AppOpsManager.MODE_ALLOWED;
+    }
+
     private void checkRemoteViews(String pkg, String tag, int id, Notification notification) {
         if (removeRemoteView(pkg, tag, id, notification.contentView)) {
             notification.contentView = null;
@@ -8003,6 +8070,13 @@
                             }
                         }
                     }
+
+                    // Try to start flash notification event whenever an audible and non-suppressed
+                    // notification is received
+                    mAccessibilityManager.startFlashNotificationEvent(getContext(),
+                            AccessibilityManager.FLASH_REASON_NOTIFICATION,
+                            record.getSbn().getPackageName());
+
                 } else if ((record.getFlags() & Notification.FLAG_INSISTENT) != 0) {
                     hasValidSound = false;
                 }
@@ -8619,7 +8693,8 @@
                         r.getImportance(),
                         r.getRankingScore(),
                         r.isConversation(),
-                        r.getProposedImportance());
+                        r.getProposedImportance(),
+                        r.hasSensitiveContent());
                 extractorDataBefore.put(r.getKey(), extractorData);
                 mRankingHelper.extractSignals(r);
             }
@@ -9915,7 +9990,8 @@
                             ? RANKING_UNCHANGED
                             : (record.getRankingScore() > 0 ?  RANKING_PROMOTED : RANKING_DEMOTED),
                     record.getNotification().isBubbleNotification(),
-                    record.getProposedImportance()
+                    record.getProposedImportance(),
+                    record.hasSensitiveContent()
             );
             rankings.add(ranking);
         }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 91b5afe..2ea6c40 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -211,6 +211,7 @@
     // are sorted.
     private boolean mPendingLogUpdate = false;
     private int mProposedImportance = IMPORTANCE_UNSPECIFIED;
+    private boolean mSensitiveContent = false;
 
     public NotificationRecord(Context context, StatusBarNotification sbn,
             NotificationChannel channel) {
@@ -503,6 +504,7 @@
         pw.println(prefix + "mProposedImportance="
                 + NotificationListenerService.Ranking.importanceToString(mProposedImportance));
         pw.println(prefix + "mIsAppImportanceLocked=" + mIsAppImportanceLocked);
+        pw.println(prefix + "mSensitiveContent=" + mSensitiveContent);
         pw.println(prefix + "mIntercept=" + mIntercept);
         pw.println(prefix + "mHidden==" + mHidden);
         pw.println(prefix + "mGlobalSortKey=" + mGlobalSortKey);
@@ -747,6 +749,12 @@
                             Adjustment.KEY_IMPORTANCE_PROPOSAL,
                             Integer.toString(mProposedImportance));
                 }
+                if (signals.containsKey(Adjustment.KEY_SENSITIVE_CONTENT)) {
+                    mSensitiveContent = signals.getBoolean(Adjustment.KEY_SENSITIVE_CONTENT);
+                    EventLogTags.writeNotificationAdjusted(getKey(),
+                            Adjustment.KEY_SENSITIVE_CONTENT,
+                            Boolean.toString(mSensitiveContent));
+                }
                 if (!signals.isEmpty() && adjustment.getIssuer() != null) {
                     mAdjustmentIssuer = adjustment.getIssuer();
                 }
@@ -883,6 +891,13 @@
         return mProposedImportance;
     }
 
+    /**
+     * @return true if the notification contains sensitive content detected by the assistant.
+     */
+    public boolean hasSensitiveContent() {
+        return mSensitiveContent;
+    }
+
     public float getRankingScore() {
         return mRankingScore;
     }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java b/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java
index 6dc9029..3f4f7d3 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordExtractorData.java
@@ -46,6 +46,7 @@
     private final float mRankingScore;
     private final boolean mIsConversation;
     private final int mProposedImportance;
+    private final boolean mSensitiveContent;
 
     NotificationRecordExtractorData(int position, int visibility, boolean showBadge,
             boolean allowBubble, boolean isBubble, NotificationChannel channel, String groupKey,
@@ -53,7 +54,7 @@
             Integer userSentiment, Integer suppressVisually,
             ArrayList<Notification.Action> systemSmartActions,
             ArrayList<CharSequence> smartReplies, int importance, float rankingScore,
-            boolean isConversation, int proposedImportance) {
+            boolean isConversation, int proposedImportance, boolean sensitiveContent) {
         mPosition = position;
         mVisibility = visibility;
         mShowBadge = showBadge;
@@ -71,6 +72,7 @@
         mRankingScore = rankingScore;
         mIsConversation = isConversation;
         mProposedImportance = proposedImportance;
+        mSensitiveContent = sensitiveContent;
     }
 
     // Returns whether the provided NotificationRecord differs from the cached data in any way.
@@ -90,7 +92,8 @@
                 || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
                 || !Objects.equals(mSmartReplies, r.getSmartReplies())
                 || mImportance != r.getImportance()
-                || mProposedImportance != r.getProposedImportance();
+                || mProposedImportance != r.getProposedImportance()
+                || mSensitiveContent != r.hasSensitiveContent();
     }
 
     // Returns whether the NotificationRecord has a change from this data for which we should
@@ -113,6 +116,7 @@
                 || mImportance != r.getImportance()
                 || !r.rankingScoreMatches(mRankingScore)
                 || mIsConversation != r.isConversation()
-                || mProposedImportance != r.getProposedImportance();
+                || mProposedImportance != r.getProposedImportance()
+                || mSensitiveContent != r.hasSensitiveContent();
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 4031c83..25d619d 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -473,4 +473,15 @@
         }
         return (r.getSbn().getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
     }
+
+    /**
+     * @param r NotificationRecord
+     * @return Whether the notification is a non-dismissible notification.
+     */
+    static boolean isNonDismissible(@NonNull NotificationRecord r) {
+        if (r.getSbn() == null || r.getSbn().getNotification() == null) {
+            return false;
+        }
+        return (r.getNotification().flags & Notification.FLAG_NO_DISMISS) != 0;
+    }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index 17c6c46..9a1f19d 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -86,7 +86,9 @@
                 /* bool is_foreground_service = 23 */
                 NotificationRecordLogger.isForegroundService(p.r),
                 /* optional int64 timeout_millis = 24 */
-                p.r.getSbn().getNotification().getTimeoutAfter()
+                p.r.getSbn().getNotification().getTimeoutAfter(),
+                /* bool is_nondismissible = 25 */
+                NotificationRecordLogger.isNonDismissible(p.r)
         );
     }
 
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 062f0fc..d471c8a 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -301,7 +301,7 @@
                     && shellPkgName.equals(overlayInfo.packageName));
 
             initIfNeeded();
-            onSwitchUser(UserHandle.USER_SYSTEM);
+            onStartUser(UserHandle.USER_SYSTEM);
 
             publishBinderService(Context.OVERLAY_SERVICE, mService);
             publishLocalService(OverlayManagerService.class, this);
@@ -324,7 +324,7 @@
                 final UserInfo userInfo = users.get(i);
                 if (!userInfo.supportsSwitchTo() && userInfo.id != UserHandle.USER_SYSTEM) {
                     // Initialize any users that can't be switched to, as their state would
-                    // never be setup in onSwitchUser(). We will switch to the system user right
+                    // never be setup in onStartUser(). We will switch to the system user right
                     // after this, and its state will be setup there.
                     updatePackageManagerLocked(mImpl.updateOverlaysForUser(users.get(i).id));
                 }
@@ -333,13 +333,13 @@
     }
 
     @Override
-    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
-        onSwitchUser(to.getUserIdentifier());
+    public void onUserStarting(TargetUser user) {
+        onStartUser(user.getUserIdentifier());
     }
 
-    private void onSwitchUser(@UserIdInt int newUserId) {
+    private void onStartUser(@UserIdInt int newUserId) {
         try {
-            traceBegin(TRACE_TAG_RRO, "OMS#onSwitchUser " + newUserId);
+            traceBegin(TRACE_TAG_RRO, "OMS#onStartUser " + newUserId);
             // ensure overlays in the settings are up-to-date, and propagate
             // any asset changes to the rest of the system
             synchronized (mLock) {
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java b/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
index e149b04..b5c0417 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentResolverEngine.java
@@ -37,6 +37,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper;
 import com.android.server.LocalServices;
 import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
@@ -61,6 +62,8 @@
     private final Context mContext;
     private final UserManagerInternal mUserManagerInternal;
 
+    private AppCloningDeviceConfigHelper mAppCloningDeviceConfigHelper;
+
     public CrossProfileIntentResolverEngine(UserManagerService userManager,
             DomainVerificationManagerInternal domainVerificationManager,
             DefaultAppProvider defaultAppProvider, Context context) {
@@ -250,7 +253,12 @@
          * We would return NoFilteringResolver only if it is allowed(feature flag is set).
          */
         if (shouldUseNoFilteringResolver(sourceUserId, targetUserId)) {
-            if (NoFilteringResolver.isIntentRedirectionAllowed(mContext, resolveForStart, flags)) {
+            if (mAppCloningDeviceConfigHelper == null) {
+                //lazy initialization of helper till required, to improve performance.
+                mAppCloningDeviceConfigHelper = AppCloningDeviceConfigHelper.getInstance(mContext);
+            }
+            if (NoFilteringResolver.isIntentRedirectionAllowed(mContext,
+                    mAppCloningDeviceConfigHelper, resolveForStart, flags)) {
                 return new NoFilteringResolver(computer.getComponentResolver(),
                         mUserManager);
             } else {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 225d2a4..a119a3c 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -35,6 +35,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ApplicationExitInfo;
 import android.app.ApplicationPackageManager;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -237,7 +238,7 @@
         synchronized (mPm.mInstallLock) {
             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
             try (PackageFreezer freezer = mPm.freezePackageForDelete(packageName, freezeUser,
-                    deleteFlags, "deletePackageX")) {
+                    deleteFlags, "deletePackageX", ApplicationExitInfo.REASON_OTHER)) {
                 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
                         deleteFlags | PackageManager.DELETE_CHATTY, info, true);
             }
@@ -262,7 +263,7 @@
             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
             info.sendPackageRemovedBroadcasts(killApp, removedBySystem);
             info.sendSystemPackageUpdatedBroadcasts();
-            PackageMetrics.onUninstallSucceeded(info, deleteFlags, userId);
+            PackageMetrics.onUninstallSucceeded(info, deleteFlags, removeUser);
         }
 
         // Force a gc to clear up things.
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index de37080..d8bfa59 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -40,8 +40,10 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppGlobals;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ResolveInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.dex.ArtManager;
@@ -1019,7 +1021,15 @@
                 pm.getDexOptHelper().new DexoptDoneHandler());
         LocalManagerRegistry.addManager(ArtManagerLocal.class, artManager);
 
-        artManager.scheduleBackgroundDexoptJob();
+        // Schedule the background job when boot is complete. This decouples us from when
+        // JobSchedulerService is initialized.
+        systemContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                context.unregisterReceiver(this);
+                artManager.scheduleBackgroundDexoptJob();
+            }
+        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/InstallArgs.java b/services/core/java/com/android/server/pm/InstallArgs.java
index 9cf9122..6de7f07 100644
--- a/services/core/java/com/android/server/pm/InstallArgs.java
+++ b/services/core/java/com/android/server/pm/InstallArgs.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.SigningDetails;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 
 import com.android.internal.util.Preconditions;
 
@@ -47,7 +48,8 @@
     final String mVolumeUuid;
     final UserHandle mUser;
     final String mAbiOverride;
-    final String[] mInstallGrantPermissions;
+    @NonNull
+    final ArrayMap<String, Integer> mPermissionStates;
     final List<String> mAllowlistedRestrictedPermissions;
     final int mAutoRevokePermissionsMode;
     /** If non-null, drop an async trace when the install completes */
@@ -68,8 +70,8 @@
 
     InstallArgs(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer,
             int installFlags, InstallSource installSource, String volumeUuid,
-            UserHandle user, String[] instructionSets,
-            String abiOverride, String[] installGrantPermissions,
+            UserHandle user, String[] instructionSets, String abiOverride,
+            @NonNull ArrayMap<String, Integer> permissionStates,
             List<String> allowlistedRestrictedPermissions,
             int autoRevokePermissionsMode, String traceMethod, int traceCookie,
             SigningDetails signingDetails, int installReason, int installScenario,
@@ -84,7 +86,7 @@
         mUser = user;
         mInstructionSets = instructionSets;
         mAbiOverride = abiOverride;
-        mInstallGrantPermissions = installGrantPermissions;
+        mPermissionStates = permissionStates;
         mAllowlistedRestrictedPermissions = allowlistedRestrictedPermissions;
         mAutoRevokePermissionsMode = autoRevokePermissionsMode;
         mTraceMethod = traceMethod;
@@ -103,8 +105,8 @@
      * when cleaning up old installs, or used as a move source.
      */
     InstallArgs(String codePath, String[] instructionSets) {
-        this(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
-                null, null, instructionSets, null, null, null, MODE_DEFAULT, null, 0,
+        this(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY, null, null,
+                instructionSets, null, new ArrayMap<>(), null, MODE_DEFAULT, null, 0,
                 SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN,
                 PackageManager.INSTALL_SCENARIO_DEFAULT, false, DataLoaderType.NONE,
                 PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED, false);
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 0d5392b..9ec68da 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -100,7 +100,9 @@
 import android.annotation.UserIdInt;
 import android.apex.ApexInfo;
 import android.app.AppOpsManager;
+import android.app.ApplicationExitInfo;
 import android.app.ApplicationPackageManager;
+import android.app.BroadcastOptions;
 import android.app.backup.IBackupManager;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -489,8 +491,10 @@
             if (pkg.getStaticSharedLibraryName() == null || isReplace) {
                 for (int i = 0; i < clientLibPkgs.size(); i++) {
                     AndroidPackage clientPkg = clientLibPkgs.get(i);
-                    mPm.killApplication(clientPkg.getPackageName(),
-                            clientPkg.getUid(), "update lib");
+                    String packageName = clientPkg.getPackageName();
+                    mPm.killApplication(packageName,
+                            clientPkg.getUid(), "update lib",
+                            ApplicationExitInfo.REASON_DEPENDENCY_DIED);
                 }
             }
         }
@@ -687,7 +691,10 @@
         fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
                 PackageManager.installStatusToPublicStatus(returnCode));
         try {
-            target.sendIntent(context, 0, fillIn, null, null);
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+            target.sendIntent(context, 0, fillIn, null /* onFinished*/, null /* handler */,
+                    null /* requiredPermission */, options.toBundle());
         } catch (IntentSender.SendIntentException ignored) {
         }
     }
@@ -1538,7 +1545,8 @@
         }
 
         final PackageFreezer freezer =
-                freezePackageForInstall(pkgName, installFlags, "installPackageLI");
+                freezePackageForInstall(pkgName, UserHandle.USER_ALL, installFlags,
+                        "installPackageLI", ApplicationExitInfo.REASON_PACKAGE_UPDATED);
         boolean shouldCloseFreezerBeforeReturn = true;
         try {
             final PackageState oldPackageState;
@@ -1987,17 +1995,12 @@
         }
     }
 
-    private PackageFreezer freezePackageForInstall(String packageName, int installFlags,
-            String killReason) {
-        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
-    }
-
     private PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
-            String killReason) {
+            String killReason, int exitInfoReason) {
         if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
             return new PackageFreezer(mPm);
         } else {
-            return mPm.freezePackage(packageName, userId, killReason);
+            return mPm.freezePackage(packageName, userId, killReason, exitInfoReason);
         }
     }
 
@@ -2280,14 +2283,23 @@
                 final PermissionManagerServiceInternal.PackageInstalledParams.Builder
                         permissionParamsBuilder =
                         new PermissionManagerServiceInternal.PackageInstalledParams.Builder();
-                final boolean grantPermissions = (installRequest.getInstallFlags()
-                        & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
-                if (grantPermissions) {
-                    final List<String> grantedPermissions =
-                            installRequest.getInstallGrantPermissions() != null
-                                    ? Arrays.asList(installRequest.getInstallGrantPermissions())
-                                    : pkg.getRequestedPermissions();
-                    permissionParamsBuilder.setGrantedPermissions(grantedPermissions);
+                final boolean grantRequestedPermissions = (installRequest.getInstallFlags()
+                        & PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS) != 0;
+                if (grantRequestedPermissions) {
+                    var permissionStates = new ArrayMap<String, Integer>();
+                    var requestedPermissions = pkg.getRequestedPermissions();
+                    for (int index = 0; index < requestedPermissions.size(); index++) {
+                        var permissionName = requestedPermissions.get(index);
+                        permissionStates.put(permissionName,
+                                PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED);
+                    }
+                    permissionParamsBuilder.setPermissionStates(permissionStates);
+                } else {
+                    var permissionStates = installRequest.getPermissionStates();
+                    if (permissionStates != null) {
+                        permissionParamsBuilder
+                                .setPermissionStates(permissionStates);
+                    }
                 }
                 final boolean allowlistAllRestrictedPermissions =
                         (installRequest.getInstallFlags()
@@ -2566,15 +2578,19 @@
                     if (disabledPs != null) {
                         dataOwnerPkg = disabledPs.getPkg();
                     }
-                    try {
-                        PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite);
-                    } catch (PackageManagerException e) {
-                        String errorMsg = "System app: " + packageName + " cannot be downgraded to"
-                                + " older than its preloaded version on the system image. "
-                                + e.getMessage();
-                        Slog.w(TAG, errorMsg);
-                        return Pair.create(
-                                PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
+                    if (!Build.IS_DEBUGGABLE && !dataOwnerPkg.isDebuggable()) {
+                        // Only restrict non-debuggable builds and non-debuggable version of the app
+                        try {
+                            PackageManagerServiceUtils.checkDowngrade(dataOwnerPkg, pkgLite);
+                        } catch (PackageManagerException e) {
+                            String errorMsg =
+                                    "System app: " + packageName + " cannot be downgraded to"
+                                            + " older than its preloaded version on the system"
+                                            + " image. " + e.getMessage();
+                            Slog.w(TAG, errorMsg);
+                            return Pair.create(
+                                    PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
+                        }
                     }
                 }
             }
@@ -3125,7 +3141,9 @@
         synchronized (mPm.mInstallLock) {
             final AndroidPackage pkg;
             try (PackageFreezer freezer =
-                         mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
+                         mPm.freezePackage(stubPkg.getPackageName(), UserHandle.USER_ALL,
+                                 "setEnabledSetting",
+                                 ApplicationExitInfo.REASON_PACKAGE_UPDATED)) {
                 pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
                 mAppDataHelper.prepareAppDataAfterInstallLIF(pkg);
                 synchronized (mPm.mLock) {
@@ -3147,7 +3165,9 @@
             } catch (PackageManagerException e) {
                 // Whoops! Something went very wrong; roll back to the stub and disable the package
                 try (PackageFreezer freezer =
-                             mPm.freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
+                             mPm.freezePackage(stubPkg.getPackageName(), UserHandle.USER_ALL,
+                                     "setEnabledSetting",
+                                     ApplicationExitInfo.REASON_PACKAGE_UPDATED)) {
                     synchronized (mPm.mLock) {
                         // NOTE: Ensure the system package is enabled; even for a compressed stub.
                         // If we don't, installing the system package fails during scan
@@ -4203,8 +4223,8 @@
                         "System package signature mismatch;"
                                 + " name: " + pkgSetting.getPackageName());
                 try (@SuppressWarnings("unused") PackageFreezer freezer = mPm.freezePackage(
-                        parsedPackage.getPackageName(),
-                        "scanPackageInternalLI")) {
+                        parsedPackage.getPackageName(), UserHandle.USER_ALL,
+                        "scanPackageInternalLI", ApplicationExitInfo.REASON_OTHER)) {
                     DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm);
                     deletePackageHelper.deletePackageLIF(parsedPackage.getPackageName(), null, true,
                             mPm.mUserManager.getUserIds(), 0, null, false);
diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java
index a9c5773..1516384 100644
--- a/services/core/java/com/android/server/pm/InstallRequest.java
+++ b/services/core/java/com/android/server/pm/InstallRequest.java
@@ -39,6 +39,7 @@
 import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.ExceptionUtils;
 import android.util.Slog;
 
@@ -131,11 +132,10 @@
         mInstallArgs = new InstallArgs(params.mOriginInfo, params.mMoveInfo, params.mObserver,
                 params.mInstallFlags, params.mInstallSource, params.mVolumeUuid,
                 params.getUser(), null /*instructionSets*/, params.mPackageAbiOverride,
-                params.mGrantedRuntimePermissions, params.mAllowlistedRestrictedPermissions,
-                params.mAutoRevokePermissionsMode,
-                params.mTraceMethod, params.mTraceCookie, params.mSigningDetails,
-                params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride,
-                params.mDataLoaderType, params.mPackageSource,
+                params.mPermissionStates, params.mAllowlistedRestrictedPermissions,
+                params.mAutoRevokePermissionsMode, params.mTraceMethod, params.mTraceCookie,
+                params.mSigningDetails, params.mInstallReason, params.mInstallScenario,
+                params.mForceQueryableOverride, params.mDataLoaderType, params.mPackageSource,
                 params.mApplicationEnabledSettingPersistent);
         mPackageMetrics = new PackageMetrics(this);
         mIsInstallInherit = params.mIsInherit;
@@ -384,8 +384,8 @@
     }
 
     @Nullable
-    public String[] getInstallGrantPermissions() {
-        return mInstallArgs == null ? null : mInstallArgs.mInstallGrantPermissions;
+    public ArrayMap<String, Integer> getPermissionStates() {
+        return mInstallArgs == null ? null : mInstallArgs.mPermissionStates;
     }
 
     @Nullable
diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java
index 43c0e05..f989f6f 100644
--- a/services/core/java/com/android/server/pm/InstallingSession.java
+++ b/services/core/java/com/android/server/pm/InstallingSession.java
@@ -44,6 +44,7 @@
 import android.os.Environment;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Slog;
@@ -73,7 +74,8 @@
     final String mVolumeUuid;
     int mRet;
     final String mPackageAbiOverride;
-    final String[] mGrantedRuntimePermissions;
+    @NonNull
+    final ArrayMap<String, Integer> mPermissionStates;
     final List<String> mAllowlistedRestrictedPermissions;
     final int mAutoRevokePermissionsMode;
     final SigningDetails mSigningDetails;
@@ -116,7 +118,7 @@
         mVolumeUuid = volumeUuid;
         mPackageAbiOverride = packageAbiOverride;
 
-        mGrantedRuntimePermissions = null;
+        mPermissionStates = new ArrayMap<>();
         mAllowlistedRestrictedPermissions = null;
         mAutoRevokePermissionsMode = MODE_DEFAULT;
         mSigningDetails = SigningDetails.UNKNOWN;
@@ -151,7 +153,7 @@
         mInstallSource = installSource;
         mVolumeUuid = sessionParams.volumeUuid;
         mPackageAbiOverride = sessionParams.abiOverride;
-        mGrantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
+        mPermissionStates = sessionParams.getFinalPermissionStates();
         mAllowlistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
         mAutoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
         mSigningDetails = signingDetails;
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index c5bcddc..6b9be25 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1116,12 +1116,16 @@
 
             // Flag for bubble
             ActivityOptions options = ActivityOptions.fromBundle(startActivityOptions);
-            if (options != null && options.isApplyActivityFlagsForBubbles()) {
-                // Flag for bubble to make behaviour match documentLaunchMode=always.
-                intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
-                intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
+            if (options != null) {
+                if (options.isApplyActivityFlagsForBubbles()) {
+                    // Flag for bubble to make behaviour match documentLaunchMode=always.
+                    intents[0].addFlags(FLAG_ACTIVITY_NEW_DOCUMENT);
+                    intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
+                }
+                if (options.isApplyMultipleTaskFlagForShortcut()) {
+                    intents[0].addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
+                }
             }
-
             intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             intents[0].setSourceBounds(sourceBounds);
 
diff --git a/services/core/java/com/android/server/pm/MovePackageHelper.java b/services/core/java/com/android/server/pm/MovePackageHelper.java
index 52adc0d..bec5a9a 100644
--- a/services/core/java/com/android/server/pm/MovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/MovePackageHelper.java
@@ -28,6 +28,7 @@
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.TAG;
 
+import android.app.ApplicationExitInfo;
 import android.content.Intent;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageMoveObserver;
@@ -145,7 +146,8 @@
 
         final PackageFreezer freezer;
         synchronized (mPm.mLock) {
-            freezer = mPm.freezePackage(packageName, "movePackageInternal");
+            freezer = mPm.freezePackage(packageName, UserHandle.USER_ALL,
+                    "movePackageInternal", ApplicationExitInfo.REASON_USER_REQUESTED);
         }
 
         final Bundle extras = new Bundle();
diff --git a/services/core/java/com/android/server/pm/NoFilteringResolver.java b/services/core/java/com/android/server/pm/NoFilteringResolver.java
index 999706a..3923890 100644
--- a/services/core/java/com/android/server/pm/NoFilteringResolver.java
+++ b/services/core/java/com/android/server/pm/NoFilteringResolver.java
@@ -22,8 +22,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Binder;
-import android.provider.DeviceConfig;
 
+import com.android.internal.config.appcloning.AppCloningDeviceConfigHelper;
 import com.android.server.pm.pkg.PackageStateInternal;
 import com.android.server.pm.resolution.ComponentResolverApi;
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
@@ -49,18 +49,19 @@
             "allow_intent_redirection_for_clone_profile";
 
     /**
-     * Returns true if intent redirection for clone profile feature flag is set
-     * and if its query, then check if calling user have necessary permission
+     * Returns true if intent redirection for clone profile feature flag
+     * (enable_app_cloning_building_blocks) is set and if its query,
+     * then check if calling user have necessary permission
      * (android.permission.QUERY_CLONED_APPS) as well as required flag
      * (PackageManager.MATCH_CLONE_PROFILE) bit set.
      * @return true if resolver would be used for cross profile resolution.
      */
     public static boolean isIntentRedirectionAllowed(Context context,
-            boolean resolveForStart, long flags) {
+            AppCloningDeviceConfigHelper appCloningDeviceConfigHelper, boolean resolveForStart,
+            long flags) {
         final long token = Binder.clearCallingIdentity();
         try {
-            return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_APP_CLONING,
-                    FLAG_ALLOW_INTENT_REDIRECTION_FOR_CLONE_PROFILE, false /* defaultValue */)
+            return appCloningDeviceConfigHelper.getEnableAppCloningBuildingBlocks()
                     && (resolveForStart || (((flags & PackageManager.MATCH_CLONE_PROFILE) != 0)
                     && hasPermission(context, Manifest.permission.QUERY_CLONED_APPS)));
         } finally {
diff --git a/services/core/java/com/android/server/pm/PackageFreezer.java b/services/core/java/com/android/server/pm/PackageFreezer.java
index 1e0a1f2..841b66e 100644
--- a/services/core/java/com/android/server/pm/PackageFreezer.java
+++ b/services/core/java/com/android/server/pm/PackageFreezer.java
@@ -51,7 +51,7 @@
     }
 
     PackageFreezer(String packageName, int userId, String killReason,
-            PackageManagerService pm) {
+            PackageManagerService pm, int exitInfoReason) {
         mPm = pm;
         mPackageName = packageName;
         final PackageSetting ps;
@@ -62,7 +62,8 @@
             ps = mPm.mSettings.getPackageLPr(mPackageName);
         }
         if (ps != null) {
-            mPm.killApplication(ps.getPackageName(), ps.getAppId(), userId, killReason);
+            mPm.killApplication(ps.getPackageName(), ps.getAppId(), userId, killReason,
+                    exitInfoReason);
         }
         mCloseGuard.open("close");
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 6546f6a..ed9d370 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -28,6 +28,7 @@
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PackageDeleteObserver;
@@ -87,6 +88,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.InstallLocationUtils;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
@@ -121,6 +123,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Random;
+import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.CompletableFuture;
@@ -169,6 +172,10 @@
     private static final int ADB_DEV_MODE = PackageManager.INSTALL_FROM_ADB
             | PackageManager.INSTALL_ALLOW_TEST;
 
+    private static final Set<String> ALLOWED_PERMISSION_STATE_NAMES = Set.of(
+            Manifest.permission.USE_FULL_SCREEN_INTENT
+    );
+
     private final Context mContext;
     private final PackageManagerService mPm;
     private final ApexManager mApexManager;
@@ -784,13 +791,31 @@
         mBypassNextAllowedApexUpdateCheck = false;
 
         if (!params.isMultiPackage) {
+            var hasInstallGrantRuntimePermissions = mContext.checkCallingOrSelfPermission(
+                    Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
+                    == PackageManager.PERMISSION_GRANTED;
+
             // Only system components can circumvent runtime permissions when installing.
-            if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
-                    && mContext.checkCallingOrSelfPermission(Manifest.permission
-                    .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
+            if ((params.installFlags & PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS) != 0
+                    && !hasInstallGrantRuntimePermissions) {
                 throw new SecurityException("You need the "
-                        + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
-                        + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
+                        + Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
+                        + " permission to use the"
+                        + " PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS flag");
+            }
+
+            var permissionStates = params.getFinalPermissionStates();
+            if (!permissionStates.isEmpty()) {
+                if (!hasInstallGrantRuntimePermissions) {
+                    for (int index = 0; index < permissionStates.size(); index++) {
+                        var permissionName = permissionStates.keyAt(index);
+                        if (!ALLOWED_PERMISSION_STATE_NAMES.contains(permissionName)) {
+                            throw new SecurityException("You need the "
+                                    + Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
+                                    + " permission to grant runtime permissions for a session");
+                        }
+                    }
+                }
             }
 
             // Defensively resize giant app icons
@@ -1314,7 +1339,10 @@
             intent.putExtra(PackageInstaller.EXTRA_INSTALL_CONSTRAINTS, constraints);
             intent.putExtra(PackageInstaller.EXTRA_INSTALL_CONSTRAINTS_RESULT, result);
             try {
-                callback.sendIntent(mContext, 0, intent, null, null);
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+                callback.sendIntent(mContext, 0, intent, null /* onFinished*/,
+                        null /* handler */, null /* requiredPermission */, options.toBundle());
             } catch (SendIntentException ignore) {
             }
         });
@@ -1477,7 +1505,10 @@
                     PackageInstaller.STATUS_PENDING_USER_ACTION);
             fillIn.putExtra(Intent.EXTRA_INTENT, intent);
             try {
-                mTarget.sendIntent(mContext, 0, fillIn, null, null);
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+                mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
+                        null /* handler */, null /* requiredPermission */, options.toBundle());
             } catch (SendIntentException ignored) {
             }
         }
@@ -1502,7 +1533,10 @@
                     PackageManager.deleteStatusToString(returnCode, msg));
             fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
             try {
-                mTarget.sendIntent(mContext, 0, fillIn, null, null);
+                final BroadcastOptions options = BroadcastOptions.makeBasic();
+                options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+                mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
+                        null /* handler */, null /* requiredPermission */, options.toBundle());
             } catch (SendIntentException ignored) {
             }
         }
@@ -1769,7 +1803,8 @@
         mSilentUpdatePolicy.dump(pw);
     }
 
-    class InternalCallback {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public class InternalCallback {
         public void onSessionBadgingChanged(PackageInstallerSession session) {
             mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId);
             mSettingsWriteRequest.schedule();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 47e18f1..3ad3af3e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -59,6 +59,7 @@
 import android.annotation.Nullable;
 import android.annotation.WorkerThread;
 import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.admin.DevicePolicyEventLogger;
@@ -219,6 +220,8 @@
     static final String TAG_SESSION_CHECKSUM = "sessionChecksum";
     static final String TAG_SESSION_CHECKSUM_SIGNATURE = "sessionChecksumSignature";
     private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission";
+    private static final String TAG_GRANT_PERMISSION = "grant-permission";
+    private static final String TAG_DENY_PERMISSION = "deny-permission";
     private static final String TAG_WHITELISTED_RESTRICTED_PERMISSION =
             "whitelisted-restricted-permission";
     private static final String TAG_AUTO_REVOKE_PERMISSIONS_MODE =
@@ -1145,7 +1148,7 @@
             if (!scrubData) {
                 info.referrerUri = params.referrerUri;
             }
-            info.grantedRuntimePermissions = params.grantedRuntimePermissions;
+            info.grantedRuntimePermissions = params.getLegacyGrantedRuntimePermissions();
             info.whitelistedRestrictedPermissions = params.whitelistedRestrictedPermissions;
             info.autoRevokePermissionsMode = params.autoRevokePermissionsMode;
             info.installFlags = params.installFlags;
@@ -1520,7 +1523,10 @@
     public ParcelFileDescriptor getAppMetadataFd() {
         assertCallerIsOwnerOrRoot();
         synchronized (mLock) {
-            assertPreparedAndNotCommittedOrDestroyedLocked("openRead");
+            assertPreparedAndNotCommittedOrDestroyedLocked("getAppMetadataFd");
+            if (getStagedAppMetadataFile() == null) {
+                return null;
+            }
             try {
                 return openReadInternalLocked(APP_METADATA_FILE_NAME);
             } catch (IOException e) {
@@ -1529,6 +1535,14 @@
         }
     }
 
+    @Override
+    public void removeAppMetadata() {
+        File file = getStagedAppMetadataFile();
+        if (file != null) {
+            file.delete();
+        }
+    }
+
     private static long getAppMetadataSizeLimit() {
         final long token = Binder.clearCallingIdentity();
         try {
@@ -3995,7 +4009,14 @@
                 return;
             }
         }
-        r.run();
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            // This will call into StagingManager which might trigger external callbacks
+            r.run();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
@@ -4495,8 +4516,10 @@
         intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_SUCCESS);
         intent.putExtra(PackageInstaller.EXTRA_PRE_APPROVAL, true);
         try {
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.setPendingIntentBackgroundActivityLaunchAllowed(false);
             target.sendIntent(mContext, 0 /* code */, intent, null /* onFinished */,
-                    null /* handler */);
+                    null /* handler */, null /* requiredPermission */, options.toBundle());
         } catch (IntentSender.SendIntentException ignored) {
         }
     }
@@ -4763,7 +4786,10 @@
                 PackageInstaller.ACTION_CONFIRM_PRE_APPROVAL.equals(intent.getAction()));
         fillIn.putExtra(Intent.EXTRA_INTENT, intent);
         try {
-            target.sendIntent(context, 0, fillIn, null, null);
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+            target.sendIntent(context, 0, fillIn, null /* onFinished */,
+                    null /* handler */, null /* requiredPermission */, options.toBundle());
         } catch (IntentSender.SendIntentException ignored) {
         }
     }
@@ -4805,7 +4831,10 @@
             }
         }
         try {
-            target.sendIntent(context, 0, fillIn, null, null);
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+            target.sendIntent(context, 0, fillIn, null /* onFinished */,
+                    null /* handler */, null /* requiredPermission */, options.toBundle());
         } catch (IntentSender.SendIntentException ignored) {
         }
     }
@@ -4839,20 +4868,17 @@
             intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
         }
         try {
-            target.sendIntent(context, 0, intent, null, null);
+            final BroadcastOptions options = BroadcastOptions.makeBasic();
+            options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+            target.sendIntent(context, 0, intent, null /* onFinished */,
+                    null /* handler */, null /* requiredPermission */, options.toBundle());
         } catch (IntentSender.SendIntentException ignored) {
         }
     }
 
-    private static void writeGrantedRuntimePermissionsLocked(TypedXmlSerializer out,
-            String[] grantedRuntimePermissions) throws IOException {
-        if (grantedRuntimePermissions != null) {
-            for (String permission : grantedRuntimePermissions) {
-                out.startTag(null, TAG_GRANTED_RUNTIME_PERMISSION);
-                writeStringAttribute(out, ATTR_NAME, permission);
-                out.endTag(null, TAG_GRANTED_RUNTIME_PERMISSION);
-            }
-        }
+    private static void writePermissionsLocked(@NonNull TypedXmlSerializer out,
+            @NonNull SessionParams params) throws IOException {
+        params.writePermissionStateXml(out, TAG_GRANT_PERMISSION, TAG_DENY_PERMISSION, ATTR_NAME);
     }
 
     private static void writeWhitelistedRestrictedPermissionsLocked(@NonNull TypedXmlSerializer out,
@@ -4960,7 +4986,7 @@
                         params.dataLoaderParams.getArguments());
             }
 
-            writeGrantedRuntimePermissionsLocked(out, params.grantedRuntimePermissions);
+            writePermissionsLocked(out, params);
             writeWhitelistedRestrictedPermissionsLocked(out,
                     params.whitelistedRestrictedPermissions);
             writeAutoRevokePermissionsMode(out, params.autoRevokePermissionsMode);
@@ -5144,7 +5170,9 @@
 
         // Store the current depth. We should stop parsing when we reach an end tag at the same
         // depth.
-        List<String> grantedRuntimePermissions = new ArrayList<>();
+        List<String> legacyGrantedRuntimePermissions = new ArrayList<>();
+        ArraySet<String> grantPermissions = new ArraySet<>();
+        ArraySet<String> denyPermissions = new ArraySet<>();
         List<String> whitelistedRestrictedPermissions = new ArrayList<>();
         int autoRevokePermissionsMode = MODE_DEFAULT;
         IntArray childSessionIds = new IntArray();
@@ -5158,51 +5186,59 @@
             if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                 continue;
             }
-            if (TAG_GRANTED_RUNTIME_PERMISSION.equals(in.getName())) {
-                grantedRuntimePermissions.add(readStringAttribute(in, ATTR_NAME));
-            }
-            if (TAG_WHITELISTED_RESTRICTED_PERMISSION.equals(in.getName())) {
-                whitelistedRestrictedPermissions.add(readStringAttribute(in, ATTR_NAME));
+            switch (in.getName()) {
+                case TAG_GRANTED_RUNTIME_PERMISSION:
+                    legacyGrantedRuntimePermissions.add(readStringAttribute(in, ATTR_NAME));
+                    break;
+                case TAG_GRANT_PERMISSION:
+                    grantPermissions.add(readStringAttribute(in, ATTR_NAME));
+                    break;
+                case TAG_DENY_PERMISSION:
+                    denyPermissions.add(readStringAttribute(in, ATTR_NAME));
+                    break;
+                case TAG_WHITELISTED_RESTRICTED_PERMISSION:
+                    whitelistedRestrictedPermissions.add(readStringAttribute(in, ATTR_NAME));
+                    break;
+                case TAG_AUTO_REVOKE_PERMISSIONS_MODE:
+                    autoRevokePermissionsMode = in.getAttributeInt(null, ATTR_MODE);
+                    break;
+                case TAG_CHILD_SESSION:
+                    childSessionIds.add(in.getAttributeInt(null, ATTR_SESSION_ID,
+                            SessionInfo.INVALID_ID));
+                    break;
+                case TAG_SESSION_FILE:
+                    files.add(new InstallationFile(
+                            in.getAttributeInt(null, ATTR_LOCATION, 0),
+                            readStringAttribute(in, ATTR_NAME),
+                            in.getAttributeLong(null, ATTR_LENGTH_BYTES, -1),
+                            readByteArrayAttribute(in, ATTR_METADATA),
+                            readByteArrayAttribute(in, ATTR_SIGNATURE)));
+                    break;
+                case TAG_SESSION_CHECKSUM:
+                    final String fileName = readStringAttribute(in, ATTR_NAME);
+                    final Checksum checksum = new Checksum(
+                            in.getAttributeInt(null, ATTR_CHECKSUM_KIND, 0),
+                            readByteArrayAttribute(in, ATTR_CHECKSUM_VALUE));
 
-            }
-            if (TAG_AUTO_REVOKE_PERMISSIONS_MODE.equals(in.getName())) {
-                autoRevokePermissionsMode = in.getAttributeInt(null, ATTR_MODE);
-            }
-            if (TAG_CHILD_SESSION.equals(in.getName())) {
-                childSessionIds.add(in.getAttributeInt(null, ATTR_SESSION_ID,
-                        SessionInfo.INVALID_ID));
-            }
-            if (TAG_SESSION_FILE.equals(in.getName())) {
-                files.add(new InstallationFile(
-                        in.getAttributeInt(null, ATTR_LOCATION, 0),
-                        readStringAttribute(in, ATTR_NAME),
-                        in.getAttributeLong(null, ATTR_LENGTH_BYTES, -1),
-                        readByteArrayAttribute(in, ATTR_METADATA),
-                        readByteArrayAttribute(in, ATTR_SIGNATURE)));
-            }
-            if (TAG_SESSION_CHECKSUM.equals(in.getName())) {
-                final String fileName = readStringAttribute(in, ATTR_NAME);
-                final Checksum checksum = new Checksum(
-                        in.getAttributeInt(null, ATTR_CHECKSUM_KIND, 0),
-                        readByteArrayAttribute(in, ATTR_CHECKSUM_VALUE));
-
-                List<Checksum> fileChecksums = checksums.get(fileName);
-                if (fileChecksums == null) {
-                    fileChecksums = new ArrayList<>();
-                    checksums.put(fileName, fileChecksums);
-                }
-                fileChecksums.add(checksum);
-            }
-            if (TAG_SESSION_CHECKSUM_SIGNATURE.equals(in.getName())) {
-                final String fileName = readStringAttribute(in, ATTR_NAME);
-                final byte[] signature = readByteArrayAttribute(in, ATTR_SIGNATURE);
-                signatures.put(fileName, signature);
+                    List<Checksum> fileChecksums = checksums.get(fileName);
+                    if (fileChecksums == null) {
+                        fileChecksums = new ArrayList<>();
+                        checksums.put(fileName, fileChecksums);
+                    }
+                    fileChecksums.add(checksum);
+                    break;
+                case TAG_SESSION_CHECKSUM_SIGNATURE:
+                    final String fileName1 = readStringAttribute(in, ATTR_NAME);
+                    final byte[] signature = readByteArrayAttribute(in, ATTR_SIGNATURE);
+                    signatures.put(fileName1, signature);
+                    break;
             }
         }
 
-        if (grantedRuntimePermissions.size() > 0) {
-            params.grantedRuntimePermissions =
-                    grantedRuntimePermissions.toArray(EmptyArray.STRING);
+        if (legacyGrantedRuntimePermissions.size() > 0) {
+            params.setPermissionStates(legacyGrantedRuntimePermissions, Collections.emptyList());
+        } else {
+            params.setPermissionStates(grantPermissions, denyPermissions);
         }
 
         if (whitelistedRestrictedPermissions.size() > 0) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5d41b4c..382be45 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -55,7 +55,9 @@
 import android.annotation.WorkerThread;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
+import android.app.ApplicationExitInfo;
 import android.app.ApplicationPackageManager;
+import android.app.BroadcastOptions;
 import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.app.admin.SecurityLog;
@@ -187,7 +189,6 @@
 import com.android.permission.persistence.RuntimePermissionsPersistence;
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
-import com.android.server.IntentResolver;
 import com.android.server.LocalManagerRegistry;
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
@@ -3049,12 +3050,12 @@
         onChanged();
     }
 
-    void killApplication(String pkgName, @AppIdInt int appId, String reason) {
-        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
+    void killApplication(String pkgName, @AppIdInt int appId, String reason, int exitInfoReason) {
+        killApplication(pkgName, appId, UserHandle.USER_ALL, reason, exitInfoReason);
     }
 
     void killApplication(String pkgName, @AppIdInt int appId,
-            @UserIdInt int userId, String reason) {
+            @UserIdInt int userId, String reason, int exitInfoReason) {
         // Request the ActivityManager to kill the process(only for existing packages)
         // so that we do not end up in a confused state while the user is still using the older
         // version of the application while the new one gets installed.
@@ -3063,7 +3064,7 @@
             IActivityManager am = ActivityManager.getService();
             if (am != null) {
                 try {
-                    am.killApplication(pkgName, appId, userId, reason);
+                    am.killApplication(pkgName, appId, userId, reason, exitInfoReason);
                 } catch (RemoteException e) {
                 }
             }
@@ -4337,25 +4338,17 @@
         }
     }
 
-    public PackageFreezer freezePackage(String packageName, String killReason) {
-        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
-    }
-
-    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
-        return new PackageFreezer(packageName, userId, killReason, this);
-    }
-
-    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
-            String killReason) {
-        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
+    public PackageFreezer freezePackage(String packageName, int userId, String killReason,
+            int exitInfoReason) {
+        return new PackageFreezer(packageName, userId, killReason, this, exitInfoReason);
     }
 
     public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
-            String killReason) {
+            String killReason, int exitInfoReason) {
         if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
             return new PackageFreezer(this);
         } else {
-            return freezePackage(packageName, userId, killReason);
+            return freezePackage(packageName, userId, killReason, exitInfoReason);
         }
     }
 
@@ -4659,7 +4652,9 @@
             final Computer snapshot = snapshotComputer();
             final AndroidPackage pkg = snapshot.getPackage(packageName);
             try (PackageFreezer ignored =
-                            freezePackage(packageName, "clearApplicationProfileData")) {
+                            freezePackage(packageName, UserHandle.USER_ALL,
+                                    "clearApplicationProfileData",
+                                    ApplicationExitInfo.REASON_OTHER)) {
                 synchronized (mInstallLock) {
                     mAppDataHelper.clearAppProfilesLIF(pkg);
                 }
@@ -4700,8 +4695,9 @@
                 public void run() {
                     mHandler.removeCallbacks(this);
                     final boolean succeeded;
-                    try (PackageFreezer freezer = freezePackage(packageName,
-                            "clearApplicationUserData")) {
+                    try (PackageFreezer freezer = freezePackage(packageName, UserHandle.USER_ALL,
+                            "clearApplicationUserData",
+                            ApplicationExitInfo.REASON_USER_REQUESTED)) {
                         synchronized (mInstallLock) {
                             succeeded = clearApplicationUserDataLIF(snapshotComputer(), packageName,
                                     userId);
@@ -4778,7 +4774,7 @@
                 ArraySet<CrossProfileIntentFilter> set =
                         new ArraySet<>(resolver.filterSet());
                 for (CrossProfileIntentFilter filter : set) {
-                    if (IntentResolver.filterEquals(filter.mFilter, intentFilter)
+                    if (IntentFilter.filterEquals(filter.mFilter, intentFilter)
                             && filter.getOwnerPackage().equals(ownerPackage)
                             && filter.getTargetUserId() == targetUserId
                             && filter.getFlags() == flags) {
@@ -4948,7 +4944,11 @@
                 }
                 if (pi != null) {
                     try {
-                        pi.sendIntent(null, success ? 1 : 0, null, null, null);
+                        final BroadcastOptions options = BroadcastOptions.makeBasic();
+                        options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+                        pi.sendIntent(null, success ? 1 : 0, null /* intent */,
+                                null /* onFinished*/, null /* handler */,
+                                null /* requiredPermission */, options.toBundle());
                     } catch (SendIntentException e) {
                         Slog.w(TAG, e);
                     }
@@ -5771,7 +5771,8 @@
                         newSnapshot.getPackageStateInternal(packageName);
 
                 if (hidden) {
-                    killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg");
+                    killApplication(packageName, newPackageState.getAppId(), userId, "hiding pkg",
+                            ApplicationExitInfo.REASON_OTHER);
                     sendApplicationHiddenForUser(packageName, newPackageState, userId);
                 } else {
                     sendPackageAddedForUser(newSnapshot, packageName, newPackageState, userId,
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 8beb0b6..d322fa2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3069,7 +3069,7 @@
                 getOutPrintWriter().printf("Success: user %d is already being removed\n", userId);
                 return 0;
             case UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN:
-                getOutPrintWriter().printf("Error: user %d is a permanent admin main user\n",
+                getErrPrintWriter().printf("Error: user %d is a permanent admin main user\n",
                         userId);
                 return 1;
             default:
@@ -3123,12 +3123,7 @@
                 translateUserId(userId, UserHandle.USER_NULL, "runSetUserRestriction");
         final IUserManager um = IUserManager.Stub.asInterface(
                 ServiceManager.getService(Context.USER_SERVICE));
-        try {
-            um.setUserRestriction(restriction, value, translatedUserId);
-        } catch (IllegalArgumentException e) {
-            getErrPrintWriter().println(e.getMessage());
-            return 1;
-        }
+        um.setUserRestriction(restriction, value, translatedUserId);
         return 0;
     }
 
@@ -3198,7 +3193,8 @@
                     sessionParams.installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
                     break;
                 case "-g":
-                    sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
+                    sessionParams.installFlags |=
+                            PackageManager.INSTALL_GRANT_ALL_REQUESTED_PERMISSIONS;
                     break;
                 case "--restrict-permissions":
                     sessionParams.installFlags &=
diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index d4c1256..c4ad20e 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -41,7 +41,7 @@
 import java.util.stream.Stream;
 
 /**
- * Metrics class for reporting stats to logging infrastructures like Westworld
+ * Metrics class for reporting stats to logging infrastructures like statsd
  */
 final class PackageMetrics {
     public static final int STEP_PREPARE = 1;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 9c91879..6541b40 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -98,7 +98,6 @@
 import com.android.modules.utils.TypedXmlSerializer;
 import com.android.permission.persistence.RuntimePermissionsPersistence;
 import com.android.permission.persistence.RuntimePermissionsState;
-import com.android.server.IntentResolver;
 import com.android.server.LocalServices;
 import com.android.server.backup.PreferredActivityBackupHelper;
 import com.android.server.pm.Installer.InstallerException;
@@ -120,7 +119,7 @@
 import com.android.server.pm.verify.domain.DomainVerificationLegacySettings;
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
 import com.android.server.pm.verify.domain.DomainVerificationPersistence;
-import com.android.server.security.FileIntegrityLocal;
+import com.android.server.security.FileIntegrity;
 import com.android.server.utils.Slogf;
 import com.android.server.utils.Snappable;
 import com.android.server.utils.SnapshotCache;
@@ -2714,8 +2713,8 @@
             }
 
             try {
-                FileIntegrityLocal.setUpFsVerity(mSettingsFilename.getAbsolutePath());
-                FileIntegrityLocal.setUpFsVerity(mSettingsReserveCopyFilename.getAbsolutePath());
+                FileIntegrity.setUpFsVerity(mSettingsFilename);
+                FileIntegrity.setUpFsVerity(mSettingsReserveCopyFilename);
             } catch (IOException e) {
                 Slog.e(TAG, "Failed to verity-protect settings", e);
             }
@@ -6307,7 +6306,7 @@
         boolean changed = false;
         while (it.hasNext()) {
             PersistentPreferredActivity ppa = it.next();
-            if (IntentResolver.filterEquals(ppa.getIntentFilter(), filter)) {
+            if (IntentFilter.filterEquals(ppa.getIntentFilter(), filter)) {
                 ppir.removeFilter(ppa);
                 changed = true;
                 break;
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index 23156d1..7684a49 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -27,6 +27,7 @@
 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
 
 import android.annotation.NonNull;
+import android.app.ApplicationExitInfo;
 import android.app.ResourcesManager;
 import android.content.pm.PackageManager;
 import android.content.pm.PackagePartitions;
@@ -153,7 +154,8 @@
         }
 
         for (PackageStateInternal ps : packages) {
-            freezers.add(mPm.freezePackage(ps.getPackageName(), "loadPrivatePackagesInner"));
+            freezers.add(mPm.freezePackage(ps.getPackageName(), UserHandle.USER_ALL,
+                    "loadPrivatePackagesInner", ApplicationExitInfo.REASON_OTHER));
             synchronized (mPm.mInstallLock) {
                 final AndroidPackage pkg;
                 try {
@@ -256,7 +258,8 @@
                     final PackageRemovedInfo outInfo = new PackageRemovedInfo(mPm);
 
                     try (PackageFreezer freezer = mPm.freezePackageForDelete(ps.getPackageName(),
-                            deleteFlags, "unloadPrivatePackagesInner")) {
+                             UserHandle.USER_ALL, deleteFlags,
+                            "unloadPrivatePackagesInner", ApplicationExitInfo.REASON_OTHER)) {
                         if (mDeletePackageHelper.deletePackageLIF(ps.getPackageName(), null, false,
                                 userIds, deleteFlags, outInfo, false)) {
                             unloaded.add(pkg);
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 26a990c..3cbaebe 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -64,11 +64,12 @@
     })
     public @interface UserAssignmentResult {}
 
-    private static final String PREFIX_USER_START_MODE = "USER_START_MODE_";
+    // TODO(b/248408342): Move keep annotation to the method referencing these fields reflectively.
+    @Keep public static final int USER_START_MODE_FOREGROUND = 1;
+    @Keep public static final int USER_START_MODE_BACKGROUND = 2;
+    @Keep public static final int USER_START_MODE_BACKGROUND_VISIBLE = 3;
 
-    /**
-     * Type used to indicate how a user started.
-     */
+    private static final String PREFIX_USER_START_MODE = "USER_START_MODE_";
     @IntDef(flag = false, prefix = {PREFIX_USER_START_MODE}, value = {
             USER_START_MODE_FOREGROUND,
             USER_START_MODE_BACKGROUND,
@@ -76,32 +77,6 @@
     })
     public @interface UserStartMode {}
 
-    // TODO(b/248408342): Move keep annotations below to the method referencing these fields
-    // reflectively.
-
-    /** (Full) user started on foreground (a.k.a. "current user"). */
-    @Keep public static final int USER_START_MODE_FOREGROUND = 1;
-
-    /**
-     * User (full or profile) started on background and is
-     * {@link UserManager#isUserVisible() invisible}.
-     *
-     * <p>This is the "traditional" way of starting a background user, and can be used to start
-     * profiles as well, although starting an invisible profile is not common from the System UI
-     * (it could be done through APIs or adb, though).
-     */
-    @Keep public static final int USER_START_MODE_BACKGROUND = 2;
-
-    /**
-     * User (full or profile) started on background and is
-     * {@link UserManager#isUserVisible() visible}.
-     *
-     * <p>This is the "traditional" way of starting a profile (i.e., when the profile of the current
-     * user is the current foreground user), but it can also be used to start a full user associated
-     * with a display (which is the case on automotives with passenger displays).
-     */
-    @Keep public static final int USER_START_MODE_BACKGROUND_VISIBLE = 3;
-
     public interface UserRestrictionsListener {
         /**
          * Called when a user restriction changes.
@@ -553,11 +528,12 @@
      * switched to.
      *
      * <p>Otherwise, in {@link UserManager#isHeadlessSystemUserMode() headless system user mode},
-     * this will be the user who was last in the foreground on this device. If there is no
-     * switchable user on the device, a new user will be created and its id will be returned.
+     * this will be the user who was last in the foreground on this device.
      *
-     * <p>In non-headless system user mode, the return value will be {@link UserHandle#USER_SYSTEM}.
+     * <p>In non-headless system user mode, the return value will be
+     * {@link android.os.UserHandle#USER_SYSTEM}.
+
+     * @throws UserManager.CheckedUserOperationException if no switchable user can be found
      */
-    public abstract @UserIdInt int getBootUser()
-            throws UserManager.CheckedUserOperationException;
+    public abstract @UserIdInt int getBootUser() throws UserManager.CheckedUserOperationException;
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 762d1f6..372b580 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2810,8 +2810,9 @@
         }
 
         if (!userExists(userId)) {
-            throw new IllegalArgumentException("Cannot set user restriction. "
-                    + "User with this id does not exist");
+            Slogf.w(LOG_TAG, "Cannot set user restriction %s. User with id %d does not exist",
+                    key, userId);
+            return;
         }
         synchronized (mRestrictionsLock) {
             // Note we can't modify Bundles stored in mBaseUserRestrictions directly, so create
@@ -5049,6 +5050,8 @@
         //...then external ones
         Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
         addedIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        // In HSUM, MainUser might be created before PHASE_ACTIVITY_MANAGER_READY has been sent.
+        addedIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
         // Also, add the UserHandle for mainline modules which can't use the @hide
         // EXTRA_USER_HANDLE.
@@ -6758,18 +6761,6 @@
         return mLocalService.isUserInitialized(userId);
     }
 
-    /**
-     * Creates a new user, intended to be the initial user on a device in headless system user mode.
-     */
-    private UserInfo createInitialUserForHsum() throws UserManager.CheckedUserOperationException {
-        final int flags = UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN;
-
-        // Null name will be replaced with "Owner" on-demand to allow for localisation.
-        return createUserInternalUnchecked(/* name= */ null, UserManager.USER_TYPE_FULL_SECONDARY,
-                flags, UserHandle.USER_NULL, /* preCreate= */ false,
-                /* disallowedPackages= */ null, /* token= */ null);
-    }
-
     private class LocalService extends UserManagerInternal {
         @Override
         public void setDevicePolicyUserRestrictions(@UserIdInt int originatingUserId,
@@ -7249,15 +7240,9 @@
                         }
                     }
                 }
-                // No switchable users. Create the initial user.
-                final UserInfo newInitialUser = createInitialUserForHsum();
-                if (newInitialUser == null) {
-                    throw new UserManager.CheckedUserOperationException(
-                            "Initial user creation failed", USER_OPERATION_ERROR_UNKNOWN);
-                }
-                Slogf.i(LOG_TAG,
-                        "No switchable users. Boot user is new user %d", newInitialUser.id);
-                return newInitialUser.id;
+                // No switchable users found. Uh oh!
+                throw new UserManager.CheckedUserOperationException(
+                        "No switchable users found", USER_OPERATION_ERROR_UNKNOWN);
             }
             // Not HSUM, return system user.
             return UserHandle.USER_SYSTEM;
@@ -7437,14 +7422,14 @@
 
     /**
      * Returns true, when user has {@link UserInfo#FLAG_MAIN} and system property
-     * {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
+     * {@link com.android.internal.R.bool#config_isMainUserPermanentAdmin} is true.
      */
     private boolean isNonRemovableMainUser(UserInfo userInfo) {
         return userInfo.isMain() && isMainUserPermanentAdmin();
     }
 
     /**
-     * Returns true, when {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
+     * Returns true if {@link com.android.internal.R.bool#config_isMainUserPermanentAdmin} is true.
      * If the main user is a permanent admin user it can't be deleted
      * or downgraded to non-admin status.
      */
diff --git a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
index 50a1d90..eed2a78 100644
--- a/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
+++ b/services/core/java/com/android/server/pm/UserManagerServiceShellCommand.java
@@ -111,11 +111,19 @@
         pw.println("    It returns the effective mode, even when using emulation");
         pw.println("    (to get the real mode as well, use -v or --verbose)");
         pw.println();
+        pw.println("  is-visible-background-users-supported [-v | --verbose]");
+        pw.println("    Checks whether the device allows users to be start visible on background.");
+        pw.println("    It returns the effective mode, even when using emulation");
+        pw.println("    (to get the real mode as well, use -v or --verbose)");
+        pw.println();
         pw.println("  is-user-visible [--display DISPLAY_ID] <USER_ID>");
         pw.println("    Checks if the given user is visible in the given display.");
         pw.println("    If the display option is not set, it uses the user's context to check");
         pw.println("    (so it emulates what apps would get from UserManager.isUserVisible())");
         pw.println();
+        pw.println("  get-main-user ");
+        pw.println("    Displays main user id or message if there is no main user");
+        pw.println();
     }
 
     @Override
@@ -134,10 +142,14 @@
                     return runSetSystemUserModeEmulation();
                 case "is-headless-system-user-mode":
                     return runIsHeadlessSystemUserMode();
+                case "is-visible-background-users-supported":
+                    return runIsVisibleBackgroundUserSupported();
                 case "is-visible-background-users-on-default-display-supported":
                     return runIsVisibleBackgroundUserOnDefaultDisplaySupported();
                 case "is-user-visible":
                     return runIsUserVisible();
+                case "get-main-user":
+                    return runGetMainUserId();
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -418,6 +430,7 @@
         } else {
             isVisible = getUserManagerForUser(userId).isUserVisible();
         }
+        // NOTE: do not change output below (or command name / args), as it's used by ITestDevice
         pw.println(isVisible);
         return 0;
     }
@@ -450,6 +463,35 @@
         return 0;
     }
 
+    private int runIsVisibleBackgroundUserSupported() {
+        PrintWriter pw = getOutPrintWriter();
+
+        boolean verbose = false;
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-v":
+                case "--verbose":
+                    verbose = true;
+                    break;
+                default:
+                    pw.println("Invalid option: " + opt);
+                    return -1;
+            }
+        }
+
+        boolean effective = UserManager.isVisibleBackgroundUsersEnabled();
+        if (!verbose) {
+            // NOTE: do not change output below, as it's used by ITestDevice
+            // (it's ok to change the verbose option though)
+            pw.println(effective);
+        } else {
+            pw.printf("effective=%b real=%b\n", effective, Resources.getSystem()
+                    .getBoolean(R.bool.config_multiuserVisibleBackgroundUsers));
+        }
+        return 0;
+    }
+
     private int runIsVisibleBackgroundUserOnDefaultDisplaySupported() {
         PrintWriter pw = getOutPrintWriter();
 
@@ -479,6 +521,17 @@
         return 0;
     }
 
+    private int runGetMainUserId() {
+        PrintWriter pw = getOutPrintWriter();
+        final int mainUserId = mService.getMainUserId();
+        if (mainUserId == UserHandle.USER_NULL) {
+            pw.println("Couldn't get main user.");
+            return 1;
+        }
+        pw.println("Main user id: " + mainUserId);
+        return 0;
+    }
+
     /**
      * Gets the {@link UserManager} associated with the context of the given user.
      */
diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
index fe8a500..3f7502b 100644
--- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java
+++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
@@ -42,7 +42,6 @@
 import android.util.EventLog;
 import android.util.IndentingPrintWriter;
 import android.util.IntArray;
-import android.util.Log;
 import android.util.SparseIntArray;
 import android.view.Display;
 
@@ -56,8 +55,6 @@
 import com.android.server.utils.Slogf;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -80,11 +77,11 @@
  */
 public final class UserVisibilityMediator implements Dumpable {
 
-    private static final String TAG = UserVisibilityMediator.class.getSimpleName();
-
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
     private static final boolean VERBOSE = false; // DO NOT SUBMIT WITH TRUE
 
+    private static final String TAG = UserVisibilityMediator.class.getSimpleName();
+
     private static final String PREFIX_SECONDARY_DISPLAY_MAPPING = "SECONDARY_DISPLAY_MAPPING_";
     public static final int SECONDARY_DISPLAY_MAPPING_NEEDED = 1;
     public static final int SECONDARY_DISPLAY_MAPPING_NOT_NEEDED = 2;
@@ -101,7 +98,7 @@
     })
     public @interface SecondaryDisplayMappingStatus {}
 
-    // TODO(b/266158156): might need to change this if boot logic is refactored for HSUM devices
+    // TODO(b/242195409): might need to change this if boot logic is refactored for HSUM devices
     @VisibleForTesting
     static final int INITIAL_CURRENT_USER_ID = USER_SYSTEM;
 
@@ -135,23 +132,10 @@
     private final SparseIntArray mExtraDisplaysAssignedToUsers;
 
     /**
-     * Mapping of each user that started visible (key) to its profile group id (value).
-     *
-     * <p>It's used to determine not just if the user is visible, but also
-     * {@link #isProfile(int, int) if it's a profile}.
+     * Mapping from each started user to its profile group.
      */
     @GuardedBy("mLock")
-    private final SparseIntArray mStartedVisibleProfileGroupIds = new SparseIntArray();
-
-    /**
-     * List of profiles that have explicitly started invisible.
-     *
-     * <p>Only used for debugging purposes (and set when {@link #DBG} is {@code true}), hence we
-     * don't care about autoboxing.
-     */
-    @GuardedBy("mLock")
-    @Nullable
-    private final List<Integer> mStartedInvisibleProfileUserIds;
+    private final SparseIntArray mStartedProfileGroupIds = new SparseIntArray();
 
     /**
      * Handler user to call listeners
@@ -180,14 +164,9 @@
             mUsersAssignedToDisplayOnStart = null;
             mExtraDisplaysAssignedToUsers = null;
         }
-        mStartedInvisibleProfileUserIds = DBG ? new ArrayList<>(4) : null;
         mHandler = handler;
-        // TODO(b/266158156): might need to change this if boot logic is refactored for HSUM devices
-        mStartedVisibleProfileGroupIds.put(INITIAL_CURRENT_USER_ID, INITIAL_CURRENT_USER_ID);
-
-        if (DBG) {
-            Slogf.i(TAG, "UserVisibilityMediator created with DBG on");
-        }
+        // TODO(b/242195409): might need to change this if boot logic is refactored for HSUM devices
+        mStartedProfileGroupIds.put(INITIAL_CURRENT_USER_ID, INITIAL_CURRENT_USER_ID);
     }
 
     /**
@@ -198,8 +177,6 @@
             int displayId) {
         Preconditions.checkArgument(!isSpecialUserId(userId), "user id cannot be generic: %d",
                 userId);
-        validateUserStartMode(userStartMode);
-
         // This method needs to perform 4 actions:
         //
         // 1. Check if the user can be started given the provided arguments
@@ -247,29 +224,14 @@
 
             visibleUsersBefore = getVisibleUsers();
 
-            // Set current user / started users state
-            switch (userStartMode) {
-                case USER_START_MODE_FOREGROUND:
-                    mCurrentUserId = userId;
-                    // Fallthrough
-                case USER_START_MODE_BACKGROUND_VISIBLE:
-                    if (DBG) {
-                        Slogf.d(TAG, "adding visible user / profile group id mapping (%d -> %d)",
-                                userId, profileGroupId);
-                    }
-                    mStartedVisibleProfileGroupIds.put(userId, profileGroupId);
-                    break;
-                case USER_START_MODE_BACKGROUND:
-                    if (mStartedInvisibleProfileUserIds != null
-                            && isProfile(userId, profileGroupId)) {
-                        Slogf.d(TAG, "adding user %d to list of invisible profiles", userId);
-                        mStartedInvisibleProfileUserIds.add(userId);
-                    }
-                    break;
-                default:
-                    Slogf.wtf(TAG,  "invalid userStartMode passed to assignUserToDisplayOnStart: "
-                            + "%d", userStartMode);
+            // Set current user / profiles state
+            if (userStartMode == USER_START_MODE_FOREGROUND) {
+                mCurrentUserId = userId;
             }
+            if (DBG) {
+                Slogf.d(TAG, "adding user / profile mapping (%d -> %d)", userId, profileGroupId);
+            }
+            mStartedProfileGroupIds.put(userId, profileGroupId);
 
             //  Set user / display state
             switch (mappingResult) {
@@ -335,46 +297,45 @@
         boolean foreground = userStartMode == USER_START_MODE_FOREGROUND;
         if (displayId != DEFAULT_DISPLAY) {
             if (foreground) {
-                Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %s, %d) failed: cannot start "
+                Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %b, %d) failed: cannot start "
                         + "foreground user on secondary display", userId, profileGroupId,
-                        userStartModeToString(userStartMode), displayId);
+                        foreground, displayId);
                 return USER_ASSIGNMENT_RESULT_FAILURE;
             }
             if (!mVisibleBackgroundUsersEnabled) {
-                Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %s, %d) failed: called on "
+                Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %b, %d) failed: called on "
                         + "device that doesn't support multiple users on multiple displays",
-                        userId, profileGroupId, userStartModeToString(userStartMode), displayId);
+                        userId, profileGroupId, foreground, displayId);
                 return USER_ASSIGNMENT_RESULT_FAILURE;
             }
         }
 
         if (isProfile(userId, profileGroupId)) {
             if (displayId != DEFAULT_DISPLAY) {
-                Slogf.w(TAG, "canStartUserLocked(%d, %d, %s, %d) failed: cannot start profile user "
-                        + "on secondary display", userId, profileGroupId,
-                        userStartModeToString(userStartMode), displayId);
+                Slogf.w(TAG, "canStartUserLocked(%d, %d, %b, %d) failed: cannot start profile user "
+                        + "on secondary display", userId, profileGroupId, foreground,
+                        displayId);
                 return USER_ASSIGNMENT_RESULT_FAILURE;
             }
-            switch (userStartMode) {
-                case USER_START_MODE_FOREGROUND:
-                    Slogf.w(TAG, "startUser(%d, %d, %s, %d) failed: cannot start profile user in "
-                            + "foreground", userId, profileGroupId,
-                            userStartModeToString(userStartMode), displayId);
-                    return USER_ASSIGNMENT_RESULT_FAILURE;
-                case USER_START_MODE_BACKGROUND_VISIBLE:
-                    boolean isParentVisibleOnDisplay = isUserVisible(profileGroupId, displayId);
-                    if (!isParentVisibleOnDisplay) {
-                        Slogf.w(TAG, "getUserVisibilityOnStartLocked(%d, %d, %s, %d) failed: cannot"
-                                + " start profile user visible when its parent is not visible in "
-                                + "that display", userId, profileGroupId,
-                                userStartModeToString(userStartMode), displayId);
-                        return USER_ASSIGNMENT_RESULT_FAILURE;
-                    }
-                    return USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE;
-                case USER_START_MODE_BACKGROUND:
-                    return USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
+            if (foreground) {
+                Slogf.w(TAG, "startUser(%d, %d, %b, %d) failed: cannot start profile user in "
+                        + "foreground", userId, profileGroupId, foreground, displayId);
+                return USER_ASSIGNMENT_RESULT_FAILURE;
+            } else {
+                boolean isParentVisibleOnDisplay = isUserVisible(profileGroupId, displayId);
+                if (DBG) {
+                    Slogf.d(TAG, "parent visible on display: %b", isParentVisibleOnDisplay);
+                }
+                return isParentVisibleOnDisplay
+                        ? USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE
+                        : USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
             }
-
+        } else if (mUsersAssignedToDisplayOnStart != null
+                && isUserAssignedToDisplayOnStartLocked(userId, displayId)) {
+            if (DBG) {
+                Slogf.d(TAG, "full user %d is already visible on display %d", userId, displayId);
+            }
+            return USER_ASSIGNMENT_RESULT_SUCCESS_ALREADY_VISIBLE;
         }
 
         return foreground || displayId != DEFAULT_DISPLAY
@@ -392,9 +353,8 @@
             if (mVisibleBackgroundUserOnDefaultDisplayAllowed
                     && userStartMode == USER_START_MODE_BACKGROUND_VISIBLE) {
                 int userStartedOnDefaultDisplay = getUserStartedOnDisplay(DEFAULT_DISPLAY);
-                if (userStartedOnDefaultDisplay != USER_NULL
-                        && userStartedOnDefaultDisplay != profileGroupId) {
-                    Slogf.w(TAG, "canAssignUserToDisplayLocked(): cannot start user %d visible on"
+                if (userStartedOnDefaultDisplay != USER_NULL) {
+                    Slogf.w(TAG, "getUserVisibilityOnStartLocked(): cannot start user %d visible on"
                             + " default display because user %d already did so", userId,
                             userStartedOnDefaultDisplay);
                     return SECONDARY_DISPLAY_MAPPING_FAILED;
@@ -449,7 +409,15 @@
             return SECONDARY_DISPLAY_MAPPING_NOT_NEEDED;
         }
 
-        // Check if display is available
+        if (mUsersAssignedToDisplayOnStart == null) {
+            // Should never have reached this point
+            Slogf.wtf(TAG, "canAssignUserToDisplayLocked(%d, %d, %d, %d) is trying to check "
+                    + "mUsersAssignedToDisplayOnStart when it's not set",
+                    userId, profileGroupId, userStartMode, displayId);
+            return SECONDARY_DISPLAY_MAPPING_FAILED;
+        }
+
+        // Check if display is available and user is not assigned to any display
         for (int i = 0; i < mUsersAssignedToDisplayOnStart.size(); i++) {
             int assignedUserId = mUsersAssignedToDisplayOnStart.keyAt(i);
             int assignedDisplayId = mUsersAssignedToDisplayOnStart.valueAt(i);
@@ -500,7 +468,7 @@
                         userId, displayId);
                 return false;
             }
-            if (isStartedVisibleProfileLocked(userId)) {
+            if (isStartedProfile(userId)) {
                 Slogf.w(TAG, "assignUserToExtraDisplay(%d, %d): failed because user is a profile",
                         userId, displayId);
                 return false;
@@ -588,14 +556,10 @@
     @GuardedBy("mLock")
     private void unassignUserFromAllDisplaysOnStopLocked(@UserIdInt int userId) {
         if (DBG) {
-            Slogf.d(TAG, "Removing %d from mStartedVisibleProfileGroupIds (%s)", userId,
-                    mStartedVisibleProfileGroupIds);
+            Slogf.d(TAG, "Removing %d from mStartedProfileGroupIds (%s)", userId,
+                    mStartedProfileGroupIds);
         }
-        mStartedVisibleProfileGroupIds.delete(userId);
-        if (mStartedInvisibleProfileUserIds != null) {
-            Slogf.d(TAG, "Removing %d from list of invisible profiles", userId);
-            mStartedInvisibleProfileUserIds.remove(Integer.valueOf(userId));
-        }
+        mStartedProfileGroupIds.delete(userId);
 
         if (!mVisibleBackgroundUsersEnabled) {
             // Don't need to update mUsersAssignedToDisplayOnStart because methods (such as
@@ -625,8 +589,7 @@
      * See {@link UserManagerInternal#isUserVisible(int)}.
      */
     public boolean isUserVisible(@UserIdInt int userId) {
-        // For optimization (as most devices don't support visible background users), check for
-        // current foreground user and their profiles first
+        // First check current foreground user and their profiles (on main display)
         if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) {
             if (VERBOSE) {
                 Slogf.v(TAG, "isUserVisible(%d): true to current user or profile", userId);
@@ -635,33 +598,38 @@
         }
 
         if (!mVisibleBackgroundUsersEnabled) {
-            if (VERBOSE) {
-                Slogf.v(TAG, "isUserVisible(%d): false for non-current user (or its profiles) when"
+            if (DBG) {
+                Slogf.d(TAG, "isUserVisible(%d): false for non-current user (or its profiles) when"
                         + " device doesn't support visible background users", userId);
             }
             return false;
         }
 
-
+        boolean visible;
         synchronized (mLock) {
-            int profileGroupId;
-            synchronized (mLock) {
-                profileGroupId = mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID);
-            }
-            if (isProfile(userId, profileGroupId)) {
-                return isUserAssignedToDisplayOnStartLocked(profileGroupId);
-            }
-            return isUserAssignedToDisplayOnStartLocked(userId);
+            visible = mUsersAssignedToDisplayOnStart.indexOfKey(userId) >= 0;
         }
+        if (DBG) {
+            Slogf.d(TAG, "isUserVisible(%d): %b from mapping", userId, visible);
+        }
+        return visible;
     }
 
     @GuardedBy("mLock")
-    private boolean isUserAssignedToDisplayOnStartLocked(@UserIdInt int userId) {
-        boolean visible = mUsersAssignedToDisplayOnStart.indexOfKey(userId) >= 0;
-        if (VERBOSE) {
-            Slogf.v(TAG, "isUserAssignedToDisplayOnStartLocked(%d): %b", userId, visible);
+    private boolean isUserAssignedToDisplayOnStartLocked(@UserIdInt int userId, int displayId) {
+        if (mUsersAssignedToDisplayOnStart == null) {
+            // Shouldn't have been called in this case
+            Slogf.wtf(TAG, "isUserAssignedToDisplayOnStartLocked(%d, %d): called when "
+                    + "mUsersAssignedToDisplayOnStart is null", userId, displayId);
+            return false;
         }
-        return visible;
+        boolean isIt = displayId != INVALID_DISPLAY
+                && mUsersAssignedToDisplayOnStart.get(userId, INVALID_DISPLAY) == displayId;
+        if (VERBOSE) {
+            Slogf.v(TAG, "isUserAssignedToDisplayOnStartLocked(%d, %d): %b", userId, displayId,
+                    isIt);
+        }
+        return isIt;
     }
 
     /**
@@ -672,8 +640,7 @@
             return false;
         }
 
-        // For optimization (as most devices don't support visible background users), check for
-        // current user and profile first. Current user is always visible on:
+        // Current user is always visible on:
         // - Default display
         // - Secondary displays when device doesn't support visible bg users
         //   - Or when explicitly added (which is checked below)
@@ -695,26 +662,14 @@
         }
 
         synchronized (mLock) {
-            int profileGroupId;
-            synchronized (mLock) {
-                profileGroupId = mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID);
+            if (mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY) == displayId) {
+                // User assigned to display on start
+                return true;
             }
-            if (isProfile(userId, profileGroupId)) {
-                return isFullUserVisibleOnBackgroundLocked(profileGroupId, displayId);
-            }
-            return isFullUserVisibleOnBackgroundLocked(userId, displayId);
-        }
-    }
 
-    // NOTE: it doesn't check if the userId is a full user, it's up to the caller to check that
-    @GuardedBy("mLock")
-    private boolean isFullUserVisibleOnBackgroundLocked(@UserIdInt int userId, int displayId) {
-        if (mUsersAssignedToDisplayOnStart.get(userId, Display.INVALID_DISPLAY) == displayId) {
-            // User assigned to display on start
-            return true;
+            // Check for extra display assignment
+            return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId;
         }
-        // Check for extra display assignment
-        return mExtraDisplaysAssignedToUsers.get(displayId, USER_NULL) == userId;
     }
 
     /**
@@ -782,7 +737,7 @@
                     continue;
                 }
                 int userId = mUsersAssignedToDisplayOnStart.keyAt(i);
-                if (!isStartedVisibleProfileLocked(userId)) {
+                if (!isStartedProfile(userId)) {
                     return userId;
                 } else if (DBG) {
                     Slogf.d(TAG, "getUserAssignedToDisplay(%d): skipping user %d because it's "
@@ -815,8 +770,8 @@
         // number of users is too small, the gain is probably not worth the increase on complexity.
         IntArray visibleUsers = new IntArray();
         synchronized (mLock) {
-            for (int i = 0; i < mStartedVisibleProfileGroupIds.size(); i++) {
-                int userId = mStartedVisibleProfileGroupIds.keyAt(i);
+            for (int i = 0; i < mStartedProfileGroupIds.size(); i++) {
+                int userId = mStartedProfileGroupIds.keyAt(i);
                 if (isUserVisible(userId)) {
                     visibleUsers.add(userId);
                 }
@@ -849,7 +804,7 @@
         }
     }
 
-    // TODO(b/266158156): remove this method if not needed anymore
+    // TODO(b/242195409): remove this method if not needed anymore
     /**
      * Nofify all listeners that the system user visibility changed.
      */
@@ -911,9 +866,6 @@
         ipw.println("UserVisibilityMediator");
         ipw.increaseIndent();
 
-        ipw.print("DBG: ");
-        ipw.println(DBG);
-
         synchronized (mLock) {
             ipw.print("Current user id: ");
             ipw.println(mCurrentUserId);
@@ -921,12 +873,8 @@
             ipw.print("Visible users: ");
             ipw.println(getVisibleUsers());
 
-            dumpSparseIntArray(ipw, mStartedVisibleProfileGroupIds,
-                    "started visible user / profile group", "u", "pg");
-            if (mStartedInvisibleProfileUserIds != null) {
-                ipw.print("Profiles started invisible: ");
-                ipw.println(mStartedInvisibleProfileUserIds);
-            }
+            dumpSparseIntArray(ipw, mStartedProfileGroupIds, "started user / profile group",
+                    "u", "pg");
 
             ipw.print("Supports visible background users on displays: ");
             ipw.println(mVisibleBackgroundUsersEnabled);
@@ -1034,25 +982,22 @@
             if (mCurrentUserId == userId) {
                 return true;
             }
-            return mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID)
-                    == mCurrentUserId;
+            return mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID) == mCurrentUserId;
         }
     }
 
-    @GuardedBy("mLock")
-    private boolean isStartedVisibleProfileLocked(@UserIdInt int userId) {
-        int profileGroupId = mStartedVisibleProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID);
+    private boolean isStartedProfile(@UserIdInt int userId) {
+        int profileGroupId;
+        synchronized (mLock) {
+            profileGroupId = mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID);
+        }
         return isProfile(userId, profileGroupId);
     }
 
-    private void validateUserStartMode(@UserStartMode int userStartMode) {
-        switch (userStartMode) {
-            case USER_START_MODE_FOREGROUND:
-            case USER_START_MODE_BACKGROUND:
-            case USER_START_MODE_BACKGROUND_VISIBLE:
-                return;
+    private @UserIdInt int getStartedProfileGroupId(@UserIdInt int userId) {
+        synchronized (mLock) {
+            return mStartedProfileGroupIds.get(userId, NO_PROFILE_GROUP_ID);
         }
-        throw new IllegalArgumentException("Invalid user start mode: " + userStartMode);
     }
 
     private static String secondaryDisplayMappingStatusToString(
diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
index 310c0e8..bdf1cc5 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java
@@ -300,9 +300,9 @@
         if ((mFlags & DEXOPT_BOOT_COMPLETE) != 0) {
             if ((mFlags & DEXOPT_FOR_RESTORE) != 0) {
                 priority = ArtFlags.PRIORITY_INTERACTIVE_FAST;
+            } else if ((mFlags & DEXOPT_IDLE_BACKGROUND_JOB) != 0) {
+                priority = ArtFlags.PRIORITY_BACKGROUND;
             } else {
-                // TODO(b/251903639): Repurpose DEXOPT_IDLE_BACKGROUND_JOB to choose new
-                // dalvik.vm.background-dex2oat-* properties.
                 priority = ArtFlags.PRIORITY_INTERACTIVE;
             }
         } else {
@@ -317,9 +317,6 @@
         //    We don't require it to be set either. It's safe when switching between old and new
         //    code paths since the only effect is that some packages may be unnecessarily compiled
         //    without user profiles.
-        //
-        // -  DEXOPT_IDLE_BACKGROUND_JOB: Its only effect is to allow the debug variant dex2oatd to
-        //    be used, but ART Service never uses that (cf. Artd::GetDex2Oat in artd.cc).
 
         return new DexoptParams.Builder(convertToArtServiceDexoptReason(mCompilationReason), flags)
                 .setCompilerFilter(mCompilerFilter)
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 59256d3..a3be8d3 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -212,7 +212,7 @@
                 }
             }
         }
-        if ((flags & PackageManager.GET_ATTRIBUTIONS) != 0) {
+        if ((flags & PackageManager.GET_ATTRIBUTIONS_LONG) != 0) {
             int size = ArrayUtils.size(pkg.getAttributions());
             if (size > 0) {
                 info.attributions = new Attribution[size];
diff --git a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
index 2a65a01..8641b41 100644
--- a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
+++ b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.app.AlarmManager;
 import android.app.IActivityManager;
 import android.app.IUidObserver;
@@ -34,6 +35,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.LocalServices;
 import com.android.server.PermissionThread;
 
 /**
@@ -50,6 +52,7 @@
 
     private final @NonNull Context mContext;
     private final @NonNull IActivityManager mIActivityManager;
+    private final @NonNull ActivityManagerInternal mActivityManagerInternal;
     private final @NonNull AlarmManager mAlarmManager;
     private final @NonNull PermissionControllerManager mPermissionControllerManager;
 
@@ -80,6 +83,7 @@
     OneTimePermissionUserManager(@NonNull Context context) {
         mContext = context;
         mIActivityManager = ActivityManager.getService();
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mAlarmManager = context.getSystemService(AlarmManager.class);
         mPermissionControllerManager = new PermissionControllerManager(
                 mContext, PermissionThread.getHandler());
@@ -243,12 +247,7 @@
         }
 
         private int getCurrentState() {
-            try {
-                return getStateFromProcState(mIActivityManager.getUidProcessState(mUid, null));
-            } catch (RemoteException e) {
-                Log.e(LOG_TAG, "Couldn't check uid proc state", e);
-            }
-            return STATE_GONE;
+            return getStateFromProcState(mActivityManagerInternal.getUidProcessState(mUid));
         }
 
         private int getStateFromProcState(int procState) {
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 936ef67..a5204d7 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -70,6 +70,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.FeatureInfo;
+import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PermissionGroupInfo;
@@ -3654,7 +3655,7 @@
                 shouldGrantPermission = bp != null && (bp.isRuntime() || bp.isDevelopment())
                         && (!instantApp || bp.isInstant())
                         && (supportsRuntimePermissions || !bp.isRuntimeOnly())
-                        && (permissions == null || permissions.contains(permission));
+                        && (permissions.contains(permission));
             }
             if (shouldGrantPermission) {
                 final int flags = getPermissionFlagsInternal(pkg.getPackageName(), permission,
@@ -4990,7 +4991,15 @@
             addAllowlistedRestrictedPermissionsInternal(pkg,
                     params.getAllowlistedRestrictedPermissions(),
                     FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
-            grantRequestedRuntimePermissionsInternal(pkg, params.getGrantedPermissions(), userId);
+            var grantedPermissions = new ArrayList<String>();
+            var permissionStates = params.getPermissionStates();
+            for (int index = 0; index < permissionStates.size(); index++) {
+                if (permissionStates.valueAt(index)
+                        == PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED) {
+                    grantedPermissions.add(permissionStates.keyAt(index));
+                }
+            }
+            grantRequestedRuntimePermissionsInternal(pkg, grantedPermissions, userId);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index ea85c9d..4dd6966 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -20,8 +20,10 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
+import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PermissionInfo;
 import android.permission.PermissionManagerInternal;
+import android.util.ArrayMap;
 
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageState;
@@ -329,7 +331,7 @@
     /**
      * The permission-related parameters passed in for package installation.
      *
-     * @see android.content.pm.PackageInstaller.SessionParams
+     * @see SessionParams
      */
     //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
     final class PackageInstalledParams {
@@ -339,28 +341,28 @@
         public static final PackageInstalledParams DEFAULT = new Builder().build();
 
         @NonNull
-        private final List<String> mGrantedPermissions;
+        private final ArrayMap<String, Integer> mPermissionStates;
         @NonNull
         private final List<String> mAllowlistedRestrictedPermissions;
         @NonNull
         private final int mAutoRevokePermissionsMode;
 
-        private PackageInstalledParams(@NonNull List<String> grantedPermissions,
+        private PackageInstalledParams(@NonNull ArrayMap<String, Integer> permissionStates,
                 @NonNull List<String> allowlistedRestrictedPermissions,
                 int autoRevokePermissionsMode) {
-            mGrantedPermissions = grantedPermissions;
+            mPermissionStates = permissionStates;
             mAllowlistedRestrictedPermissions = allowlistedRestrictedPermissions;
             mAutoRevokePermissionsMode = autoRevokePermissionsMode;
         }
 
         /**
-         * Get the permissions to be granted.
+         * @return the permissions states requested
          *
-         * @return the permissions to be granted
+         * @see SessionParams#setPermissionState(String, int)
          */
         @NonNull
-        public List<String> getGrantedPermissions() {
-            return mGrantedPermissions;
+        public ArrayMap<String, Integer> getPermissionStates() {
+            return mPermissionStates;
         }
 
         /**
@@ -386,24 +388,23 @@
          * Builder class for {@link PackageInstalledParams}.
          */
         public static final class Builder {
-            @NonNull
-            private List<String> mGrantedPermissions = Collections.emptyList();
+            @Nullable
+            private ArrayMap<String, Integer> mPermissionStates = null;
             @NonNull
             private List<String> mAllowlistedRestrictedPermissions = Collections.emptyList();
             @NonNull
             private int mAutoRevokePermissionsMode = AppOpsManager.MODE_DEFAULT;
 
             /**
-             * Set the permissions to be granted.
+             * Set the permissions states requested by the installer.
              *
-             * @param grantedPermissions the permissions to be granted
-             *
-             * @see android.content.pm.PackageInstaller.SessionParams#setGrantedRuntimePermissions(
-             *      java.lang.String[])
+             * @see SessionParams#setPermissionState(String, int)
              */
-            public void setGrantedPermissions(@NonNull List<String> grantedPermissions) {
-                Objects.requireNonNull(grantedPermissions);
-                mGrantedPermissions = new ArrayList<>(grantedPermissions);
+            public Builder setPermissionStates(
+                    @NonNull ArrayMap<String, Integer> permissionStates) {
+                Objects.requireNonNull(permissionStates);
+                mPermissionStates = permissionStates;
+                return this;
             }
 
             /**
@@ -414,11 +415,11 @@
              *
              * @param allowlistedRestrictedPermissions the restricted permissions to be allowlisted
              *
-             * @see android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)
+             * @see SessionParams#setWhitelistedRestrictedPermissions(Set)
              */
             public void setAllowlistedRestrictedPermissions(
                     @NonNull List<String> allowlistedRestrictedPermissions) {
-                Objects.requireNonNull(mGrantedPermissions);
+                Objects.requireNonNull(allowlistedRestrictedPermissions);
                 mAllowlistedRestrictedPermissions = new ArrayList<>(
                         allowlistedRestrictedPermissions);
             }
@@ -434,8 +435,7 @@
              *
              * @param autoRevokePermissionsMode the mode for auto revoking permissions
              *
-             * @see android.content.pm.PackageInstaller.SessionParams#setAutoRevokePermissionsMode(
-             *      boolean)
+             * @see SessionParams#setAutoRevokePermissionsMode(boolean)
              */
             public void setAutoRevokePermissionsMode(int autoRevokePermissionsMode) {
                 mAutoRevokePermissionsMode = autoRevokePermissionsMode;
@@ -448,7 +448,8 @@
              */
             @NonNull
             public PackageInstalledParams build() {
-                return new PackageInstalledParams(mGrantedPermissions,
+                return new PackageInstalledParams(
+                        mPermissionStates == null ? new ArrayMap<>() : mPermissionStates,
                         mAllowlistedRestrictedPermissions, mAutoRevokePermissionsMode);
             }
         }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5ca3333..7f1679a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -38,6 +38,7 @@
 import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
 import static android.view.KeyEvent.KEYCODE_HOME;
 import static android.view.KeyEvent.KEYCODE_POWER;
+import static android.view.KeyEvent.KEYCODE_STEM_PRIMARY;
 import static android.view.KeyEvent.KEYCODE_UNKNOWN;
 import static android.view.KeyEvent.KEYCODE_VOLUME_DOWN;
 import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
@@ -128,6 +129,7 @@
 import android.media.IAudioService;
 import android.media.session.MediaSessionLegacyHelper;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.DeviceIdleManager;
 import android.os.FactoryTest;
@@ -524,7 +526,7 @@
     int mDoublePressOnStemPrimaryBehavior;
     int mTriplePressOnStemPrimaryBehavior;
     int mLongPressOnStemPrimaryBehavior;
-    boolean mStylusButtonsDisabled = false;
+    boolean mStylusButtonsEnabled = true;
     boolean mHasSoftInput = false;
     boolean mHapticTextHandleEnabled;
     boolean mUseTvRouting;
@@ -783,7 +785,7 @@
                     Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this,
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.STYLUS_BUTTONS_DISABLED), false, this,
+                    Settings.Secure.STYLUS_BUTTONS_ENABLED), false, this,
                     UserHandle.USER_ALL);
             updateSettings();
         }
@@ -2248,6 +2250,21 @@
                             cancelPendingScreenshotChordAction();
                         }
                     });
+            if (mHasFeatureWatch) {
+                mKeyCombinationManager.addRule(
+                        new TwoKeysCombinationRule(KEYCODE_POWER, KEYCODE_STEM_PRIMARY) {
+                            @Override
+                            void execute() {
+                                mPowerKeyHandled = true;
+                                interceptScreenshotChord(SCREENSHOT_KEY_CHORD,
+                                        getScreenshotChordLongPressDelay());
+                            }
+                            @Override
+                            void cancel() {
+                                cancelPendingScreenshotChordAction();
+                            }
+                        });
+            }
         }
 
         mKeyCombinationManager.addRule(
@@ -2603,9 +2620,9 @@
                     mContext.getResources().getInteger(
                             com.android.internal.R.integer.config_keyChordPowerVolumeUp));
 
-            mStylusButtonsDisabled = Settings.Secure.getIntForUser(resolver,
-                    Secure.STYLUS_BUTTONS_DISABLED, 0, UserHandle.USER_CURRENT) == 1;
-            mInputManagerInternal.setStylusButtonMotionEventsEnabled(!mStylusButtonsDisabled);
+            mStylusButtonsEnabled = Settings.Secure.getIntForUser(resolver,
+                    Secure.STYLUS_BUTTONS_ENABLED, 1, UserHandle.USER_CURRENT) == 1;
+            mInputManagerInternal.setStylusButtonMotionEventsEnabled(mStylusButtonsEnabled);
         }
         if (updateRotation) {
             updateRotation(true);
@@ -4317,7 +4334,7 @@
             case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
             case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
             case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL: {
-                if (down && !mStylusButtonsDisabled) {
+                if (down && mStylusButtonsEnabled) {
                     sendSystemKeyToStatusBarAsync(keyCode);
                 }
                 result &= ~ACTION_PASS_TO_USER;
diff --git a/services/core/java/com/android/server/power/LowPowerStandbyController.java b/services/core/java/com/android/server/power/LowPowerStandbyController.java
index ebeb1455..223bd55 100644
--- a/services/core/java/com/android/server/power/LowPowerStandbyController.java
+++ b/services/core/java/com/android/server/power/LowPowerStandbyController.java
@@ -16,36 +16,67 @@
 
 package com.android.server.power;
 
+import static android.os.PowerManager.lowPowerStandbyAllowedReasonsToString;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.PowerManager.LowPowerStandbyAllowedReason;
+import android.os.PowerManager.LowPowerStandbyPolicy;
 import android.os.PowerManagerInternal;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.AtomicFile;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
-import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+import android.util.Xml;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
 import com.android.server.LocalServices;
 import com.android.server.net.NetworkPolicyManagerInternal;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Executor;
 
 /**
  * Controls Low Power Standby state.
@@ -56,11 +87,13 @@
  * <ul>
  *   <li>Low Power Standby is enabled
  *   <li>The device is not interactive, and has been non-interactive for a given timeout
- *   <li>The device is not in a doze maintenance window
+ *   <li>The device is not in a doze maintenance window (devices may be configured to also
+ *   apply restrictions during doze maintenance windows, see {@link #setActiveDuringMaintenance})
  * </ul>
  *
  * <p>When Low Power Standby is active, the following restrictions are applied to applications
- * with procstate less important than {@link android.app.ActivityManager#PROCESS_STATE_BOUND_TOP}:
+ * with procstate less important than {@link android.app.ActivityManager#PROCESS_STATE_BOUND_TOP}
+ * unless they are exempted (see {@link LowPowerStandbyPolicy}):
  * <ul>
  *   <li>Network access is blocked
  *   <li>Wakelocks are disabled
@@ -76,9 +109,19 @@
     private static final int MSG_STANDBY_TIMEOUT = 0;
     private static final int MSG_NOTIFY_ACTIVE_CHANGED = 1;
     private static final int MSG_NOTIFY_ALLOWLIST_CHANGED = 2;
+    private static final int MSG_NOTIFY_POLICY_CHANGED = 3;
+
+    private static final String TAG_ROOT = "low-power-standby-policy";
+    private static final String TAG_IDENTIFIER = "identifier";
+    private static final String TAG_EXEMPT_PACKAGE = "exempt-package";
+    private static final String TAG_ALLOWED_REASONS = "allowed-reasons";
+    private static final String TAG_ALLOWED_FEATURES = "allowed-features";
+    private static final String ATTR_VALUE = "value";
 
     private final Handler mHandler;
     private final SettingsObserver mSettingsObserver;
+    private final DeviceConfigWrapper mDeviceConfig;
+    private final File mPolicyFile;
     private final Object mLock = new Object();
 
     private final Context mContext;
@@ -86,9 +129,12 @@
     private final AlarmManager.OnAlarmListener mOnStandbyTimeoutExpired =
             this::onStandbyTimeoutExpired;
     private final LowPowerStandbyControllerInternal mLocalService = new LocalService();
-    private final SparseBooleanArray mAllowlistUids = new SparseBooleanArray();
+    private final SparseIntArray mUidAllowedReasons = new SparseIntArray();
 
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+    @GuardedBy("mLock")
+    private boolean mEnableCustomPolicy;
+
+    private final BroadcastReceiver mIdleBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             switch (intent.getAction()) {
@@ -105,6 +151,41 @@
         }
     };
 
+    private final BroadcastReceiver mPackageBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Received package intent: action=" + intent.getAction() + ", data="
+                        + intent.getData());
+            }
+            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+            if (replacing) {
+                return;
+            }
+            final Uri intentUri = intent.getData();
+            final String packageName = (intentUri != null) ? intentUri.getSchemeSpecificPart()
+                    : null;
+            synchronized (mLock) {
+                final LowPowerStandbyPolicy policy = getPolicy();
+                if (policy.getExemptPackages().contains(packageName)) {
+                    enqueueNotifyAllowlistChangedLocked();
+                }
+            }
+        }
+    };
+
+    private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Received user intent: action=" + intent.getAction());
+            }
+            synchronized (mLock) {
+                enqueueNotifyAllowlistChangedLocked();
+            }
+        }
+    };
+
     @GuardedBy("mLock")
     private AlarmManager mAlarmManager;
     @GuardedBy("mLock")
@@ -159,6 +240,18 @@
     @GuardedBy("mLock")
     private boolean mForceActive;
 
+    /** Current Low Power Standby policy. */
+    @GuardedBy("mLock")
+    @Nullable
+    private LowPowerStandbyPolicy mPolicy;
+
+    @VisibleForTesting
+    static final LowPowerStandbyPolicy DEFAULT_POLICY = new LowPowerStandbyPolicy(
+            "DEFAULT_POLICY",
+            Collections.emptySet(),
+            PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION,
+            Collections.emptySet());
+
     /** Functional interface for providing time. */
     @VisibleForTesting
     interface Clock {
@@ -166,11 +259,21 @@
         long elapsedRealtime();
     }
 
-    public LowPowerStandbyController(Context context, Looper looper, Clock clock) {
+    public LowPowerStandbyController(Context context, Looper looper) {
+        this(context, looper, SystemClock::elapsedRealtime,
+                new DeviceConfigWrapper(),
+                new File(Environment.getDataSystemDirectory(), "low_power_standby_policy.xml"));
+    }
+
+    @VisibleForTesting
+    LowPowerStandbyController(Context context, Looper looper, Clock clock,
+            DeviceConfigWrapper deviceConfig, File policyFile) {
         mContext = context;
         mHandler = new LowPowerStandbyHandler(looper);
         mClock = clock;
         mSettingsObserver = new SettingsObserver(mHandler);
+        mDeviceConfig = deviceConfig;
+        mPolicyFile = policyFile;
     }
 
     /** Call when system services are ready */
@@ -201,6 +304,16 @@
             mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.LOW_POWER_STANDBY_ACTIVE_DURING_MAINTENANCE),
                     false, mSettingsObserver, UserHandle.USER_ALL);
+
+            mDeviceConfig.registerPropertyUpdateListener(mContext.getMainExecutor(),
+                    properties -> onDeviceConfigFlagsChanged());
+            mEnableCustomPolicy = mDeviceConfig.enableCustomPolicy();
+
+            if (mEnableCustomPolicy) {
+                mPolicy = loadPolicy();
+            } else {
+                mPolicy = DEFAULT_POLICY;
+            }
             initSettingsLocked();
             updateSettingsLocked();
 
@@ -212,6 +325,17 @@
         LocalServices.addService(LowPowerStandbyControllerInternal.class, mLocalService);
     }
 
+    private void onDeviceConfigFlagsChanged() {
+        synchronized (mLock) {
+            boolean enableCustomPolicy = mDeviceConfig.enableCustomPolicy();
+            if (mEnableCustomPolicy != enableCustomPolicy) {
+                enqueueNotifyPolicyChangedLocked();
+                enqueueNotifyAllowlistChangedLocked();
+                mEnableCustomPolicy = enableCustomPolicy;
+            }
+        }
+    }
+
     @GuardedBy("mLock")
     private void initSettingsLocked() {
         final ContentResolver resolver = mContext.getContentResolver();
@@ -242,6 +366,139 @@
         updateActiveLocked();
     }
 
+    @Nullable
+    private LowPowerStandbyPolicy loadPolicy() {
+        final AtomicFile file = getPolicyFile();
+        if (!file.exists()) {
+            return null;
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "Loading policy from " + file.getBaseFile());
+        }
+
+        try (FileInputStream in = file.openRead()) {
+            String identifier = null;
+            Set<String> exemptPackages = new ArraySet<>();
+            int allowedReasons = 0;
+            Set<String> allowedFeatures = new ArraySet<>();
+
+            TypedXmlPullParser parser = Xml.resolvePullParser(in);
+
+            int type;
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+                if (type != XmlPullParser.START_TAG) {
+                    continue;
+                }
+                final int depth = parser.getDepth();
+                // Check the root tag
+                final String tag = parser.getName();
+                if (depth == 1) {
+                    if (!TAG_ROOT.equals(tag)) {
+                        Slog.e(TAG, "Invalid root tag: " + tag);
+                        return null;
+                    }
+                    continue;
+                }
+                // Assume depth == 2
+                switch (tag) {
+                    case TAG_IDENTIFIER:
+                        identifier = parser.getAttributeValue(null, ATTR_VALUE);
+                        break;
+                    case TAG_EXEMPT_PACKAGE:
+                        exemptPackages.add(parser.getAttributeValue(null, ATTR_VALUE));
+                        break;
+                    case TAG_ALLOWED_REASONS:
+                        allowedReasons = parser.getAttributeInt(null, ATTR_VALUE);
+                        break;
+                    case TAG_ALLOWED_FEATURES:
+                        allowedFeatures.add(parser.getAttributeValue(null, ATTR_VALUE));
+                        break;
+                    default:
+                        Slog.e(TAG, "Invalid tag: " + tag);
+                        break;
+                }
+            }
+
+            final LowPowerStandbyPolicy policy = new LowPowerStandbyPolicy(identifier,
+                    exemptPackages, allowedReasons, allowedFeatures);
+            if (DEBUG) {
+                Slog.d(TAG, "Loaded policy: " + policy);
+            }
+            return policy;
+        } catch (FileNotFoundException e) {
+            // Use the default
+            return null;
+        } catch (IOException | NullPointerException | IllegalArgumentException
+                | XmlPullParserException e) {
+            Slog.e(TAG, "Failed to read policy file " + file.getBaseFile(), e);
+            return null;
+        }
+    }
+
+    static void writeTagValue(TypedXmlSerializer out, String tag, String value) throws IOException {
+        if (TextUtils.isEmpty(value)) return;
+
+        out.startTag(null, tag);
+        out.attribute(null, ATTR_VALUE, value);
+        out.endTag(null, tag);
+    }
+
+    static void writeTagValue(TypedXmlSerializer out, String tag, int value) throws IOException {
+        out.startTag(null, tag);
+        out.attributeInt(null, ATTR_VALUE, value);
+        out.endTag(null, tag);
+    }
+
+    private void savePolicy(@Nullable LowPowerStandbyPolicy policy) {
+        final AtomicFile file = getPolicyFile();
+        if (DEBUG) {
+            Slog.d(TAG, "Saving policy to " + file.getBaseFile());
+        }
+        if (policy == null) {
+            file.delete();
+            return;
+        }
+
+        FileOutputStream outs = null;
+        try {
+            file.getBaseFile().mkdirs();
+            outs = file.startWrite();
+
+            // Write to XML
+            TypedXmlSerializer out = Xml.resolveSerializer(outs);
+            out.startDocument(null, true);
+            out.startTag(null, TAG_ROOT);
+
+            // Body.
+            writeTagValue(out, TAG_IDENTIFIER, policy.getIdentifier());
+            for (String exemptPackage : policy.getExemptPackages()) {
+                writeTagValue(out, TAG_EXEMPT_PACKAGE, exemptPackage);
+            }
+            writeTagValue(out, TAG_ALLOWED_REASONS, policy.getAllowedReasons());
+            for (String allowedFeature : policy.getAllowedFeatures()) {
+                writeTagValue(out, TAG_ALLOWED_FEATURES, allowedFeature);
+            }
+
+            // Epilogue.
+            out.endTag(null, TAG_ROOT);
+            out.endDocument();
+
+            // Close.
+            file.finishWrite(outs);
+        } catch (IOException e) {
+            Slog.e(TAG, "Failed to write policy to file " + file.getBaseFile(), e);
+            file.failWrite(outs);
+        }
+    }
+
+    private void enqueueSavePolicy(@Nullable LowPowerStandbyPolicy policy) {
+        mHandler.post(() -> savePolicy(policy));
+    }
+
+    private AtomicFile getPolicyFile() {
+        return new AtomicFile(mPolicyFile);
+    }
+
     @GuardedBy("mLock")
     private void updateActiveLocked() {
         final long now = mClock.elapsedRealtime();
@@ -378,11 +635,25 @@
         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
 
-        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+        mContext.registerReceiver(mIdleBroadcastReceiver, intentFilter);
+
+        IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addDataScheme(IntentFilter.SCHEME_PACKAGE);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        mContext.registerReceiver(mPackageBroadcastReceiver, packageFilter);
+
+        final IntentFilter userFilter = new IntentFilter();
+        userFilter.addAction(Intent.ACTION_USER_ADDED);
+        userFilter.addAction(Intent.ACTION_USER_REMOVED);
+        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
     }
 
     private void unregisterBroadcastReceiver() {
-        mContext.unregisterReceiver(mBroadcastReceiver);
+        mContext.unregisterReceiver(mIdleBroadcastReceiver);
+        mContext.unregisterReceiver(mPackageBroadcastReceiver);
+        mContext.unregisterReceiver(mUserReceiver);
     }
 
     @GuardedBy("mLock")
@@ -396,6 +667,25 @@
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
     }
 
+    @GuardedBy("mLock")
+    private void enqueueNotifyPolicyChangedLocked() {
+        final long now = mClock.elapsedRealtime();
+        final Message msg = mHandler.obtainMessage(MSG_NOTIFY_POLICY_CHANGED, getPolicy());
+        mHandler.sendMessageAtTime(msg, now);
+    }
+
+    private void notifyPolicyChanged(LowPowerStandbyPolicy policy) {
+        if (DEBUG) {
+            Slog.d(TAG, "notifyPolicyChanged, policy=" + policy);
+        }
+
+        final Intent intent = new Intent(
+                PowerManager.ACTION_LOW_POWER_STANDBY_POLICY_CHANGED);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                Manifest.permission.MANAGE_LOW_POWER_STANDBY);
+    }
+
     private void onStandbyTimeoutExpired() {
         if (DEBUG) {
             Slog.d(TAG, "onStandbyTimeoutExpired");
@@ -414,6 +704,9 @@
 
     /** Notify other system components about the updated Low Power Standby active state */
     private void notifyActiveChanged(boolean active) {
+        if (DEBUG) {
+            Slog.d(TAG, "notifyActiveChanged, active=" + active);
+        }
         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
         final NetworkPolicyManagerInternal npmi = LocalServices.getService(
                 NetworkPolicyManagerInternal.class);
@@ -479,6 +772,104 @@
         }
     }
 
+    void setPolicy(@Nullable LowPowerStandbyPolicy policy) {
+        synchronized (mLock) {
+            if (!mSupportedConfig) {
+                Slog.w(TAG, "Low Power Standby policy cannot be changed "
+                        + "because it is not supported on this device");
+                return;
+            }
+
+            if (!mEnableCustomPolicy) {
+                Slog.d(TAG, "Custom policies are not enabled.");
+                return;
+            }
+
+            if (DEBUG) {
+                Slog.d(TAG, "setPolicy: policy=" + policy);
+            }
+            if (Objects.equals(mPolicy, policy)) {
+                return;
+            }
+
+            boolean allowlistChanged = policyChangeAffectsAllowlistLocked(mPolicy, policy);
+            mPolicy = policy;
+            enqueueSavePolicy(mPolicy);
+            if (allowlistChanged) {
+                enqueueNotifyAllowlistChangedLocked();
+            }
+            enqueueNotifyPolicyChangedLocked();
+        }
+    }
+
+    @NonNull
+    LowPowerStandbyPolicy getPolicy() {
+        synchronized (mLock) {
+            if (!mSupportedConfig) {
+                return null;
+            } else if (mEnableCustomPolicy) {
+                return policyOrDefault(mPolicy);
+            } else {
+                return DEFAULT_POLICY;
+            }
+        }
+    }
+
+    @NonNull
+    private LowPowerStandbyPolicy policyOrDefault(@Nullable LowPowerStandbyPolicy policy) {
+        if (policy == null) {
+            return DEFAULT_POLICY;
+        }
+        return policy;
+    }
+
+    boolean isPackageExempt(int uid) {
+        synchronized (mLock) {
+            if (!isEnabled()) {
+                return true;
+            }
+
+            return getExemptPackageAppIdsLocked().contains(UserHandle.getAppId(uid));
+        }
+    }
+
+    boolean isAllowed(@LowPowerStandbyAllowedReason int reason) {
+        synchronized (mLock) {
+            if (!isEnabled()) {
+                return true;
+            }
+
+            return (getPolicy().getAllowedReasons() & reason) != 0;
+        }
+    }
+
+    boolean isAllowed(String feature) {
+        synchronized (mLock) {
+            if (!mSupportedConfig) {
+                return true;
+            }
+
+            return !isEnabled() || getPolicy().getAllowedFeatures().contains(feature);
+        }
+    }
+
+    private boolean policyChangeAffectsAllowlistLocked(
+            @Nullable LowPowerStandbyPolicy oldPolicy, @Nullable LowPowerStandbyPolicy newPolicy) {
+        final LowPowerStandbyPolicy policyA = policyOrDefault(oldPolicy);
+        final LowPowerStandbyPolicy policyB = policyOrDefault(newPolicy);
+        int allowedReasonsInUse = 0;
+        for (int i = 0; i < mUidAllowedReasons.size(); i++) {
+            allowedReasonsInUse |= mUidAllowedReasons.valueAt(i);
+        }
+
+        int policyAllowedReasonsChanged = policyA.getAllowedReasons() ^ policyB.getAllowedReasons();
+
+        boolean exemptPackagesChanged = !policyA.getExemptPackages().equals(
+                policyB.getExemptPackages());
+
+        return (policyAllowedReasonsChanged & allowedReasonsInUse) != 0 || exemptPackagesChanged;
+    }
+
     void dump(PrintWriter pw) {
         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
 
@@ -496,6 +887,8 @@
             ipw.println(mEnabledByDefaultConfig);
             ipw.print("mStandbyTimeoutConfig=");
             ipw.println(mStandbyTimeoutConfig);
+            ipw.print("mEnableCustomPolicy=");
+            ipw.println(mEnableCustomPolicy);
 
             if (mIsActive || mIsEnabled) {
                 ipw.print("mIsInteractive=");
@@ -509,8 +902,35 @@
             }
 
             final int[] allowlistUids = getAllowlistUidsLocked();
-            ipw.print("mAllowlistUids=");
+            ipw.print("Allowed UIDs=");
             ipw.println(Arrays.toString(allowlistUids));
+            ipw.println();
+
+            final LowPowerStandbyPolicy policy = getPolicy();
+            ipw.println("mPolicy:");
+            ipw.increaseIndent();
+            ipw.print("mIdentifier=");
+            ipw.println(policy.getIdentifier());
+            ipw.print("mExemptPackages=");
+            ipw.println(String.join(",", policy.getExemptPackages()));
+            ipw.print("mAllowedReasons=");
+            ipw.println(lowPowerStandbyAllowedReasonsToString(policy.getAllowedReasons()));
+            ipw.print("mAllowedFeatures=");
+            ipw.println(String.join(",", policy.getAllowedFeatures()));
+            ipw.decreaseIndent();
+
+            ipw.println();
+            ipw.println("UID allowed reasons:");
+            ipw.increaseIndent();
+            for (int i = 0; i < mUidAllowedReasons.size(); i++) {
+                if (mUidAllowedReasons.valueAt(i) > 0) {
+                    ipw.print(mUidAllowedReasons.keyAt(i));
+                    ipw.print(": ");
+                    ipw.println(
+                            lowPowerStandbyAllowedReasonsToString(mUidAllowedReasons.valueAt(i)));
+                }
+            }
+            ipw.decreaseIndent();
         }
         ipw.decreaseIndent();
     }
@@ -537,6 +957,17 @@
                 proto.write(LowPowerStandbyControllerDumpProto.ALLOWLIST, appId);
             }
 
+            long policyToken = proto.start(LowPowerStandbyControllerDumpProto.POLICY);
+            final LowPowerStandbyPolicy policy = getPolicy();
+            proto.write(LowPowerStandbyPolicyProto.IDENTIFIER, policy.getIdentifier());
+            for (String exemptPackage : policy.getExemptPackages()) {
+                proto.write(LowPowerStandbyPolicyProto.EXEMPT_PACKAGES, exemptPackage);
+            }
+            proto.write(LowPowerStandbyPolicyProto.ALLOWED_REASONS, policy.getAllowedReasons());
+            for (String feature : policy.getAllowedFeatures()) {
+                proto.write(LowPowerStandbyPolicyProto.ALLOWED_FEATURES, feature);
+            }
+            proto.end(policyToken);
             proto.end(token);
         }
     }
@@ -560,39 +991,133 @@
                     final int[] allowlistUids = (int[]) msg.obj;
                     notifyAllowlistChanged(allowlistUids);
                     break;
-            }
-        }
-    }
-
-    private void addToAllowlistInternal(int uid) {
-        if (DEBUG) {
-            Slog.i(TAG, "Adding to allowlist: " + uid);
-        }
-        synchronized (mLock) {
-            if (mSupportedConfig && !mAllowlistUids.get(uid)) {
-                mAllowlistUids.append(uid, true);
-                enqueueNotifyAllowlistChangedLocked();
-            }
-        }
-    }
-
-    private void removeFromAllowlistInternal(int uid) {
-        if (DEBUG) {
-            Slog.i(TAG, "Removing from allowlist: " + uid);
-        }
-        synchronized (mLock) {
-            if (mSupportedConfig && mAllowlistUids.get(uid)) {
-                mAllowlistUids.delete(uid);
-                enqueueNotifyAllowlistChangedLocked();
+                case MSG_NOTIFY_POLICY_CHANGED:
+                    notifyPolicyChanged((LowPowerStandbyPolicy) msg.obj);
+                    break;
             }
         }
     }
 
     @GuardedBy("mLock")
+    private boolean hasAllowedReasonLocked(int uid,
+            @LowPowerStandbyAllowedReason int allowedReason) {
+        int allowedReasons = mUidAllowedReasons.get(uid);
+        return (allowedReasons & allowedReason) != 0;
+    }
+
+    @GuardedBy("mLock")
+    private boolean addAllowedReasonLocked(int uid,
+            @LowPowerStandbyAllowedReason int allowedReason) {
+        int allowedReasons = mUidAllowedReasons.get(uid);
+        final int newAllowReasons = allowedReasons | allowedReason;
+        mUidAllowedReasons.put(uid, newAllowReasons);
+        return allowedReasons != newAllowReasons;
+    }
+
+    @GuardedBy("mLock")
+    private boolean removeAllowedReasonLocked(int uid,
+            @LowPowerStandbyAllowedReason int allowedReason) {
+        int allowedReasons = mUidAllowedReasons.get(uid);
+        if (allowedReasons == 0) {
+            return false;
+        }
+
+        final int newAllowedReasons = allowedReasons & ~allowedReason;
+        if (newAllowedReasons == 0) {
+            mUidAllowedReasons.removeAt(mUidAllowedReasons.indexOfKey(uid));
+        } else {
+            mUidAllowedReasons.put(uid, newAllowedReasons);
+        }
+        return allowedReasons != newAllowedReasons;
+    }
+
+    private void addToAllowlistInternal(int uid, @LowPowerStandbyAllowedReason int allowedReason) {
+        if (DEBUG) {
+            Slog.i(TAG,
+                    "Adding to allowlist: uid=" + uid + ", allowedReason=" + allowedReason);
+        }
+        synchronized (mLock) {
+            if (allowedReason != 0 && !hasAllowedReasonLocked(uid, allowedReason)) {
+                addAllowedReasonLocked(uid, allowedReason);
+                if ((getPolicy().getAllowedReasons() & allowedReason) != 0) {
+                    enqueueNotifyAllowlistChangedLocked();
+                }
+            }
+        }
+    }
+
+    private void removeFromAllowlistInternal(int uid,
+            @LowPowerStandbyAllowedReason int allowedReason) {
+        if (DEBUG) {
+            Slog.i(TAG, "Removing from allowlist: uid=" + uid + ", allowedReason=" + allowedReason);
+        }
+        synchronized (mLock) {
+            if (allowedReason != 0 && hasAllowedReasonLocked(uid, allowedReason)) {
+                removeAllowedReasonLocked(uid, allowedReason);
+                if ((getPolicy().getAllowedReasons() & allowedReason) != 0) {
+                    enqueueNotifyAllowlistChangedLocked();
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    @NonNull
+    private List<Integer> getExemptPackageAppIdsLocked() {
+        final PackageManager packageManager = mContext.getPackageManager();
+        final LowPowerStandbyPolicy policy = getPolicy();
+        final List<Integer> appIds = new ArrayList<>();
+
+        for (String packageName : policy.getExemptPackages()) {
+            try {
+                int packageUid = packageManager.getPackageUid(packageName,
+                        PackageManager.PackageInfoFlags.of(0));
+                int appId = UserHandle.getAppId(packageUid);
+                appIds.add(appId);
+            } catch (PackageManager.NameNotFoundException e) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Package UID cannot be resolved: packageName=" + packageName);
+                }
+            }
+        }
+
+        return appIds;
+    }
+
+    @GuardedBy("mLock")
     private int[] getAllowlistUidsLocked() {
-        final int[] uids = new int[mAllowlistUids.size()];
-        for (int i = 0; i < mAllowlistUids.size(); i++) {
-            uids[i] = mAllowlistUids.keyAt(i);
+        final UserManager userManager = mContext.getSystemService(UserManager.class);
+        final List<UserHandle> userHandles = userManager.getUserHandles(true);
+        final ArraySet<Integer> uids = new ArraySet<>(mUidAllowedReasons.size());
+        final LowPowerStandbyPolicy policy = getPolicy();
+
+        final int policyAllowedReasons = policy.getAllowedReasons();
+        for (int i = 0; i < mUidAllowedReasons.size(); i++) {
+            Integer uid = mUidAllowedReasons.keyAt(i);
+            if ((mUidAllowedReasons.valueAt(i) & policyAllowedReasons) != 0) {
+                uids.add(uid);
+            }
+        }
+
+        for (int appId : getExemptPackageAppIdsLocked()) {
+            for (int uid : uidsForAppId(appId, userHandles)) {
+                uids.add(uid);
+            }
+        }
+
+        int[] allowlistUids = new int[uids.size()];
+        for (int i = 0; i < uids.size(); i++) {
+            allowlistUids[i] = uids.valueAt(i);
+        }
+        Arrays.sort(allowlistUids);
+        return allowlistUids;
+    }
+
+    private int[] uidsForAppId(int appUid, List<UserHandle> userHandles) {
+        final int appId = UserHandle.getAppId(appUid);
+        final int[] uids = new int[userHandles.size()];
+        for (int i = 0; i < userHandles.size(); i++) {
+            uids[i] = userHandles.get(i).getUid(appId);
         }
         return uids;
     }
@@ -601,11 +1126,21 @@
     private void enqueueNotifyAllowlistChangedLocked() {
         final long now = mClock.elapsedRealtime();
         final int[] allowlistUids = getAllowlistUidsLocked();
+
+        if (DEBUG) {
+            Slog.d(TAG, "enqueueNotifyAllowlistChangedLocked: allowlistUids=" + Arrays.toString(
+                    allowlistUids));
+        }
+
         final Message msg = mHandler.obtainMessage(MSG_NOTIFY_ALLOWLIST_CHANGED, allowlistUids);
         mHandler.sendMessageAtTime(msg, now);
     }
 
     private void notifyAllowlistChanged(int[] allowlistUids) {
+        if (DEBUG) {
+            Slog.d(TAG, "notifyAllowlistChanged: " + Arrays.toString(allowlistUids));
+        }
+
         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
         final NetworkPolicyManagerInternal npmi = LocalServices.getService(
                 NetworkPolicyManagerInternal.class);
@@ -613,15 +1148,42 @@
         npmi.setLowPowerStandbyAllowlist(allowlistUids);
     }
 
+    /**
+     * Class that is used to read device config for low power standby configuration.
+     */
+    @VisibleForTesting
+    public static class DeviceConfigWrapper {
+        public static final String NAMESPACE = "low_power_standby";
+        public static final String FEATURE_FLAG_ENABLE_POLICY = "enable_policy";
+
+        /**
+         * Returns true if custom policies are enabled.
+         * Otherwise, returns false, and the default policy will be used.
+         */
+        public boolean enableCustomPolicy() {
+            return DeviceConfig.getBoolean(NAMESPACE, FEATURE_FLAG_ENABLE_POLICY, false);
+        }
+
+        /**
+         * Registers a DeviceConfig update listener.
+         */
+        public void registerPropertyUpdateListener(
+                @NonNull Executor executor,
+                @NonNull DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
+            DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, executor,
+                    onPropertiesChangedListener);
+        }
+    }
+
     private final class LocalService extends LowPowerStandbyControllerInternal {
         @Override
-        public void addToAllowlist(int uid) {
-            addToAllowlistInternal(uid);
+        public void addToAllowlist(int uid, @LowPowerStandbyAllowedReason int allowedReason) {
+            addToAllowlistInternal(uid, allowedReason);
         }
 
         @Override
-        public void removeFromAllowlist(int uid) {
-            removeFromAllowlistInternal(uid);
+        public void removeFromAllowlist(int uid, @LowPowerStandbyAllowedReason int allowedReason) {
+            removeFromAllowlistInternal(uid, allowedReason);
         }
     }
 
diff --git a/services/core/java/com/android/server/power/LowPowerStandbyControllerInternal.java b/services/core/java/com/android/server/power/LowPowerStandbyControllerInternal.java
index f6953fa..4acbe5d 100644
--- a/services/core/java/com/android/server/power/LowPowerStandbyControllerInternal.java
+++ b/services/core/java/com/android/server/power/LowPowerStandbyControllerInternal.java
@@ -16,6 +16,8 @@
 
 package com.android.server.power;
 
+import android.os.PowerManager.LowPowerStandbyAllowedReason;
+
 /**
  * @hide Only for use within the system server.
  */
@@ -25,13 +27,16 @@
      * exempting it from Low Power Standby restrictions.
      *
      * @param uid UID to add to allowlist.
+     * @param allowedReason reason for this package to be allowed
      */
-    public abstract void addToAllowlist(int uid);
+    public abstract void addToAllowlist(int uid, @LowPowerStandbyAllowedReason int allowedReason);
 
     /**
      * Removes an application from the Low Power Standby allowlist.
      *
      * @param uid UID to remove from allowlist.
+     * @param allowedReason reason for this package to have been allowed
      */
-    public abstract void removeFromAllowlist(int uid);
+    public abstract void removeFromAllowlist(int uid,
+            @LowPowerStandbyAllowedReason int allowedReason);
 }
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index e8cb4e2..ddf70f3 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -94,6 +94,7 @@
 import android.sysprop.InitProperties;
 import android.sysprop.PowerProperties;
 import android.util.ArrayMap;
+import android.util.IntArray;
 import android.util.KeyValueListParser;
 import android.util.LongArray;
 import android.util.PrintWriterPrinter;
@@ -282,6 +283,10 @@
 
     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
 
+    /** Display group IDs representing only DEFAULT_DISPLAY_GROUP. */
+    private static final IntArray DEFAULT_DISPLAY_GROUP_IDS =
+            IntArray.wrap(new int[]{Display.DEFAULT_DISPLAY_GROUP});
+
     private final Context mContext;
     private final ServiceThread mHandlerThread;
     private final Handler mHandler;
@@ -630,7 +635,7 @@
     // Set of app ids that are temporarily allowed to acquire wakelocks due to high-pri message
     int[] mDeviceIdleTempWhitelist = new int[0];
 
-    // Set of app ids that are allowed to acquire wakelocks while low power standby is active
+    // Set of uids that are allowed to acquire wakelocks while low power standby is active
     int[] mLowPowerStandbyAllowlist = new int[0];
 
     private boolean mLowPowerStandbyActive;
@@ -1022,7 +1027,7 @@
         }
 
         LowPowerStandbyController createLowPowerStandbyController(Context context, Looper looper) {
-            return new LowPowerStandbyController(context, looper, SystemClock::elapsedRealtime);
+            return new LowPowerStandbyController(context, looper);
         }
 
         AppOpsManager createAppOpsManager(Context context) {
@@ -1275,6 +1280,9 @@
             mDisplayManagerInternal.initPowerManagement(
                     mDisplayPowerCallbacks, mHandler, sensorManager);
 
+            // Create power groups for display groups other than DEFAULT_DISPLAY_GROUP.
+            addPowerGroupsForNonDefaultDisplayGroupLocked();
+
             try {
                 final ForegroundProfileObserver observer = new ForegroundProfileObserver();
                 ActivityManager.getService().registerUserSwitchObserver(observer, TAG);
@@ -3927,9 +3935,9 @@
         }
     }
 
-    void setLowPowerStandbyAllowlistInternal(int[] appids) {
+    void setLowPowerStandbyAllowlistInternal(int[] uids) {
         synchronized (mLock) {
-            mLowPowerStandbyAllowlist = appids;
+            mLowPowerStandbyAllowlist = uids;
             if (mLowPowerStandbyActive) {
                 updateWakeLockDisabledStatesLocked();
             }
@@ -4087,7 +4095,7 @@
                 }
                 if (mLowPowerStandbyActive) {
                     final UidState state = wakeLock.mUidState;
-                    if (Arrays.binarySearch(mLowPowerStandbyAllowlist, appid) < 0
+                    if (Arrays.binarySearch(mLowPowerStandbyAllowlist, wakeLock.mOwnerUid) < 0
                             && state.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
                             && state.mProcState > ActivityManager.PROCESS_STATE_BOUND_TOP) {
                         disabled = true;
@@ -4278,6 +4286,37 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private void addPowerGroupsForNonDefaultDisplayGroupLocked() {
+        IntArray displayGroupIds = mDisplayManagerInternal.getDisplayGroupIds();
+        if (displayGroupIds == null) {
+            return;
+        }
+
+        for (int i = 0; i < displayGroupIds.size(); i++) {
+            int displayGroupId = displayGroupIds.get(i);
+            if (displayGroupId == Display.DEFAULT_DISPLAY_GROUP) {
+                // Power group for the default display group is already added.
+                continue;
+            }
+            if (mPowerGroups.contains(displayGroupId)) {
+                Slog.e(TAG, "Tried to add already existing group:" + displayGroupId);
+                continue;
+            }
+            PowerGroup powerGroup = new PowerGroup(
+                    displayGroupId,
+                    mPowerGroupWakefulnessChangeListener,
+                    mNotifier,
+                    mDisplayManagerInternal,
+                    WAKEFULNESS_AWAKE,
+                    /* ready= */ false,
+                    /* supportsSandman= */ false,
+                    mClock.uptimeMillis());
+            mPowerGroups.append(displayGroupId, powerGroup);
+        }
+        mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
+    }
+
     /**
      * Low-level function turn the device off immediately, without trying
      * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
@@ -5696,33 +5735,29 @@
         }
 
         @Override // Binder call
+        @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
         public void goToSleep(long eventTime, int reason, int flags) {
-            if (eventTime > mClock.uptimeMillis()) {
-                throw new IllegalArgumentException("event time must not be in the future");
-            }
+            goToSleepInternal(DEFAULT_DISPLAY_GROUP_IDS, eventTime, reason, flags);
+        }
 
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.DEVICE_POWER, null);
+        @Override // Binder call
+        @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+        public void goToSleepWithDisplayId(int displayId, long eventTime, int reason, int flags) {
+            IntArray groupIds;
 
-            final int uid = Binder.getCallingUid();
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                synchronized (mLock) {
-                    PowerGroup defaultPowerGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
-                    if ((flags & PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP) != 0) {
-                        if (defaultPowerGroup.hasWakeLockKeepingScreenOnLocked()) {
-                            return;
-                        }
-                    }
-                    if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
-                        sleepPowerGroupLocked(defaultPowerGroup, eventTime, reason, uid);
-                    } else {
-                        dozePowerGroupLocked(defaultPowerGroup, eventTime, reason, uid);
-                    }
+            if (displayId == Display.INVALID_DISPLAY) {
+                groupIds = mDisplayManagerInternal.getDisplayGroupIds();
+            } else {
+                DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
+                Preconditions.checkArgument(displayInfo != null, "display ID(%d) doesn't exist",
+                        displayId);
+                int groupId = displayInfo.displayGroupId;
+                if (groupId == Display.INVALID_DISPLAY_GROUP) {
+                    throw new IllegalArgumentException("invalid display group ID");
                 }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
+                groupIds = IntArray.wrap(new int[]{groupId});
             }
+            goToSleepInternal(groupIds, eventTime, reason, flags);
         }
 
         @Override // Binder call
@@ -6115,6 +6150,82 @@
             }
         }
 
+        @Override // Binder call
+        @RequiresPermission(anyOf = {
+                android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
+                android.Manifest.permission.DEVICE_POWER
+        })
+        public void setLowPowerStandbyPolicy(@Nullable IPowerManager.LowPowerStandbyPolicy policy) {
+            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
+                    != PackageManager.PERMISSION_GRANTED) {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
+                        "setLowPowerStandbyPolicy");
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                mLowPowerStandbyController.setPolicy(
+                        PowerManager.LowPowerStandbyPolicy.fromParcelable(policy));
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        @RequiresPermission(anyOf = {
+                android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
+                android.Manifest.permission.DEVICE_POWER
+        })
+        public IPowerManager.LowPowerStandbyPolicy getLowPowerStandbyPolicy() {
+            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)
+                    != PackageManager.PERMISSION_GRANTED) {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
+                        "getLowPowerStandbyPolicy");
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return PowerManager.LowPowerStandbyPolicy.toParcelable(
+                        mLowPowerStandbyController.getPolicy());
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public boolean isExemptFromLowPowerStandby() {
+            final int callingUid = Binder.getCallingUid();
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return mLowPowerStandbyController.isPackageExempt(callingUid);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public boolean isReasonAllowedInLowPowerStandby(
+                @PowerManager.LowPowerStandbyAllowedReason int reason) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return mLowPowerStandbyController.isAllowed(reason);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
+        public boolean isFeatureAllowedInLowPowerStandby(String feature) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return mLowPowerStandbyController.isAllowed(feature);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
         /**
          * Gets the reason for the last time the phone had to reboot.
          *
@@ -6518,6 +6629,44 @@
         return false;
     }
 
+    @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+    private void goToSleepInternal(IntArray groupIds, long eventTime, int reason, int flags) {
+        if (eventTime > mClock.uptimeMillis()) {
+            throw new IllegalArgumentException("event time must not be in the future");
+        }
+
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+                /* message= */ null);
+
+        boolean isNoDoze = (flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0;
+        int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                for (int i = 0; i < groupIds.size(); i++) {
+                    int groupId = groupIds.get(i);
+                    PowerGroup powerGroup = mPowerGroups.get(groupId);
+                    if (powerGroup == null) {
+                        throw new IllegalArgumentException("power group(" + groupId
+                                + ") doesn't exist");
+                    }
+                    if ((flags & PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP) != 0) {
+                        if (powerGroup.hasWakeLockKeepingScreenOnLocked()) {
+                            continue;
+                        }
+                    }
+                    if (isNoDoze) {
+                        sleepPowerGroupLocked(powerGroup, eventTime, reason, uid);
+                    } else {
+                        dozePowerGroupLocked(powerGroup, eventTime, reason, uid);
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     @VisibleForTesting
     final class LocalService extends PowerManagerInternal {
         @Override
diff --git a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
index 2fbf3fb..751f535 100644
--- a/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/power/stats/BatteryExternalStatsWorker.java
@@ -79,7 +79,12 @@
     private static final long MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS = 750;
 
     // Delay for clearing out battery stats for UIDs corresponding to a removed user
-    public static final int UID_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS = 10_000;
+    public static final int UID_QUICK_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS = 2_000;
+
+    // Delay for the _final_ clean-up of battery stats after a user removal - just in case
+    // some UIDs took longer than UID_QUICK_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS to
+    // stop running.
+    public static final int UID_FINAL_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS = 10_000;
 
     private final ScheduledExecutorService mExecutorService =
             Executors.newSingleThreadScheduledExecutor(
@@ -336,11 +341,20 @@
     @Override
     public Future<?> scheduleCleanupDueToRemovedUser(int userId) {
         synchronized (BatteryExternalStatsWorker.this) {
+            // Initial quick clean-up after a user removal
+            mExecutorService.schedule(() -> {
+                synchronized (mStats) {
+                    mStats.clearRemovedUserUidsLocked(userId);
+                }
+            }, UID_QUICK_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS, TimeUnit.MILLISECONDS);
+
+            // Final clean-up after a user removal, to take care of UIDs that were running longer
+            // than expected
             return mExecutorService.schedule(() -> {
                 synchronized (mStats) {
                     mStats.clearRemovedUserUidsLocked(userId);
                 }
-            }, UID_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS, TimeUnit.MILLISECONDS);
+            }, UID_FINAL_REMOVAL_AFTER_USER_REMOVAL_DELAY_MILLIS, TimeUnit.MILLISECONDS);
         }
     }
 
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 bc90c89..add4a89 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -12084,11 +12084,16 @@
             final SparseDoubleArray uidEstimatedConsumptionMah;
             final long dataConsumedChargeUC;
             if (consumedChargeUC > 0 && isMobileRadioEnergyConsumerSupportedLocked()) {
-                // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the
-                // numerator for long rounding.
-                final long phoneConsumedChargeUC =
-                        (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2)
-                                / totalRadioDurationMs;
+                final long phoneConsumedChargeUC;
+                if (totalRadioDurationMs == 0) {
+                    phoneConsumedChargeUC = 0;
+                } else {
+                    // Crudely attribute power consumption. Added (totalRadioDurationMs / 2) to the
+                    // numerator for long rounding.
+                    phoneConsumedChargeUC =
+                            (consumedChargeUC * phoneOnDurationMs + totalRadioDurationMs / 2)
+                                    / totalRadioDurationMs;
+                }
                 dataConsumedChargeUC = consumedChargeUC - phoneConsumedChargeUC;
 
                 mGlobalEnergyConsumerStats.updateStandardBucket(
diff --git a/services/core/java/com/android/server/power/stats/MobileRadioPowerCalculator.java b/services/core/java/com/android/server/power/stats/MobileRadioPowerCalculator.java
index 3226260..aba8e5f 100644
--- a/services/core/java/com/android/server/power/stats/MobileRadioPowerCalculator.java
+++ b/services/core/java/com/android/server/power/stats/MobileRadioPowerCalculator.java
@@ -264,8 +264,10 @@
             if (total.remainingPowerMah < 0) total.remainingPowerMah = 0;
         } else {
             // Smear unattributed active time and add it to the remaining power consumption.
-            total.remainingPowerMah +=
-                    (totalActivePowerMah * total.remainingDurationMs) / totalActiveDurationMs;
+            if (totalActiveDurationMs != 0) {
+                total.remainingPowerMah +=
+                        (totalActivePowerMah * total.remainingDurationMs) / totalActiveDurationMs;
+            }
 
             // Calculate the inactive modem power consumption.
             final BatteryStats.ControllerActivityCounter modemActivity =
diff --git a/services/core/java/com/android/server/security/FileIntegrityLocal.java b/services/core/java/com/android/server/security/FileIntegrity.java
similarity index 63%
rename from services/core/java/com/android/server/security/FileIntegrityLocal.java
rename to services/core/java/com/android/server/security/FileIntegrity.java
index 8c7219b..7b87d99 100644
--- a/services/core/java/com/android/server/security/FileIntegrityLocal.java
+++ b/services/core/java/com/android/server/security/FileIntegrity.java
@@ -18,19 +18,22 @@
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.os.ParcelFileDescriptor;
 
 import com.android.internal.security.VerityUtils;
 
+import java.io.File;
 import java.io.IOException;
 
+
 /**
  * In-process API for server side FileIntegrity related infrastructure.
  *
  * @hide
  */
 @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-public final class FileIntegrityLocal {
-    private FileIntegrityLocal() {}
+public final class FileIntegrity {
+    private FileIntegrity() {}
 
     /**
      * Enables fs-verity, if supported by the filesystem.
@@ -38,7 +41,18 @@
      * @hide
      */
     @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    public static void setUpFsVerity(@NonNull String filePath) throws IOException {
-        VerityUtils.setUpFsverity(filePath);
+    public static void setUpFsVerity(@NonNull File file) throws IOException {
+        VerityUtils.setUpFsverity(file.getAbsolutePath());
+    }
+
+    /**
+     * Enables fs-verity, if supported by the filesystem.
+     * @see <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html">
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+    public static void setUpFsVerity(@NonNull ParcelFileDescriptor parcelFileDescriptor)
+            throws IOException {
+        VerityUtils.setUpFsverity(parcelFileDescriptor.getFd());
     }
 }
diff --git a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
index 0e92709..2d3ede0 100644
--- a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
+++ b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
@@ -24,6 +24,7 @@
 import android.security.rkp.IStoreUpgradedKeyCallback;
 import android.security.rkp.service.RegistrationProxy;
 import android.security.rkp.service.RemotelyProvisionedKey;
+import android.security.rkp.service.RkpProxyException;
 import android.util.Log;
 
 import java.util.Set;
@@ -68,13 +69,35 @@
             if (e instanceof OperationCanceledException) {
                 Log.i(TAG, "Operation cancelled for client " + mCallback.hashCode());
                 wrapCallback(mCallback::onCancel);
+            } else if (e instanceof RkpProxyException) {
+                Log.e(TAG, "RKP error fetching key for client " + mCallback.hashCode(), e);
+                RkpProxyException rkpException = (RkpProxyException) e;
+                wrapCallback(() -> mCallback.onError(toGetKeyError(rkpException),
+                        e.getMessage()));
             } else {
                 Log.e(TAG, "Error fetching key for client " + mCallback.hashCode(), e);
-                wrapCallback(() -> mCallback.onError(e.getMessage()));
+                wrapCallback(() -> mCallback.onError(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
+                        e.getMessage()));
             }
         }
     }
 
+    private byte toGetKeyError(RkpProxyException exception) {
+        switch (exception.getError()) {
+            case RkpProxyException.ERROR_UNKNOWN:
+                return IGetKeyCallback.ErrorCode.ERROR_UNKNOWN;
+            case RkpProxyException.ERROR_REQUIRES_SECURITY_PATCH:
+                return IGetKeyCallback.ErrorCode.ERROR_REQUIRES_SECURITY_PATCH;
+            case RkpProxyException.ERROR_PENDING_INTERNET_CONNECTIVITY:
+                return IGetKeyCallback.ErrorCode.ERROR_PENDING_INTERNET_CONNECTIVITY;
+            case RkpProxyException.ERROR_PERMANENT:
+                return IGetKeyCallback.ErrorCode.ERROR_PERMANENT;
+            default:
+                Log.e(TAG, "Unexpected error code in RkpProxyException", exception);
+                return IGetKeyCallback.ErrorCode.ERROR_UNKNOWN;
+        }
+    }
+
     RemoteProvisioningRegistration(RegistrationProxy registration, Executor executor) {
         mRegistration = registration;
         mExecutor = executor;
@@ -97,7 +120,8 @@
         } catch (Exception e) {
             Log.e(TAG, "getKeyAsync threw an exception for client " + callback.hashCode(), e);
             mGetKeyOperations.remove(callback);
-            wrapCallback(() -> callback.onError(e.getMessage()));
+            wrapCallback(() -> callback.onError(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
+                    e.getMessage()));
         }
     }
 
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index b3e915a..601d0e2 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -20,6 +20,8 @@
 import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
+import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_PASSTHROUGH;
+import static android.hardware.graphics.common.Hdr.DOLBY_VISION;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
@@ -38,6 +40,7 @@
 import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
 import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
 import static android.util.MathUtils.constrain;
+import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID;
 
 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
@@ -245,6 +248,7 @@
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 
 /**
@@ -743,6 +747,8 @@
                         return pullSystemServerPinnerStats(atomTag, data);
                     case FrameworkStatsLog.PENDING_INTENTS_PER_PACKAGE:
                         return pullPendingIntentsPerPackage(atomTag, data);
+                    case FrameworkStatsLog.HDR_CAPABILITIES:
+                        return pullHdrCapabilities(atomTag, data);
                     default:
                         throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
                 }
@@ -943,6 +949,7 @@
         registerMediaCapabilitiesStats();
         registerPendingIntentsPerPackagePuller();
         registerPinnerServiceStats();
+        registerHdrCapabilitiesPuller();
     }
 
     private void initAndRegisterNetworkStatsPullers() {
@@ -4720,6 +4727,37 @@
         );
     }
 
+    private int pullHdrCapabilities(int atomTag, List<StatsEvent> pulledData) {
+        DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+        Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+
+        int hdrConversionMode = displayManager.getHdrConversionMode().getConversionMode();
+        int preferredHdrType = displayManager.getHdrConversionMode().getPreferredHdrOutputType();
+        boolean userDisabledHdrConversion = hdrConversionMode == HDR_CONVERSION_PASSTHROUGH;
+        int forceHdrFormat = preferredHdrType == HDR_TYPE_INVALID ? 0 : preferredHdrType;
+        boolean hasDolbyVisionIssue = hasDolbyVisionIssue(display);
+
+        pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
+                new byte[0], userDisabledHdrConversion, forceHdrFormat, hasDolbyVisionIssue));
+
+        return StatsManager.PULL_SUCCESS;
+    }
+
+    private boolean hasDolbyVisionIssue(Display display) {
+        AtomicInteger modesSupportingDolbyVision = new AtomicInteger();
+        Arrays.stream(display.getSupportedModes())
+                .map(Display.Mode::getSupportedHdrTypes)
+                .filter(types -> Arrays.stream(types).anyMatch(hdrType -> hdrType == DOLBY_VISION))
+                .forEach(ignored -> modesSupportingDolbyVision.incrementAndGet());
+
+        if (modesSupportingDolbyVision.get() != 0
+                && modesSupportingDolbyVision.get() < display.getSupportedModes().length) {
+            return true;
+        }
+
+        return false;
+    }
+
     private int pullPendingIntentsPerPackage(int atomTag, List<StatsEvent> pulledData) {
         List<PendingIntentStats> pendingIntentStats =
                 LocalServices.getService(ActivityManagerInternal.class).getPendingIntentStats();
@@ -4740,6 +4778,16 @@
         );
     }
 
+    private void registerHdrCapabilitiesPuller() {
+        int tagId = FrameworkStatsLog.HDR_CAPABILITIES;
+        mStatsManager.setPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                DIRECT_EXECUTOR,
+                mStatsCallbackImpl
+        );
+    }
+
     int pullSystemServerPinnerStats(int atomTag, List<StatsEvent> pulledData) {
         PinnerService pinnerService = LocalServices.getService(PinnerService.class);
         List<PinnedFileStats> pinnedFileStats = pinnerService.dumpDataForStatsd();
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 5521384..ec052ec 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -21,7 +21,6 @@
 import android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.Appearance;
 import android.view.WindowInsetsController.Behavior;
@@ -162,11 +161,10 @@
             LetterboxDetails[] letterboxDetails);
 
     /** @see com.android.internal.statusbar.IStatusBar#showTransient */
-    void showTransient(int displayId, @InternalInsetsType int[] types,
-            boolean isGestureOnSystemBar);
+    void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar);
 
     /** @see com.android.internal.statusbar.IStatusBar#abortTransient */
-    void abortTransient(int displayId, @InternalInsetsType int[] types);
+    void abortTransient(int displayId, @InsetsType int types);
 
     /**
      * @see com.android.internal.statusbar.IStatusBar#showToast(String, IBinder, CharSequence,
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 83f4805..4489ba9 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -79,12 +79,10 @@
 import android.service.quicksettings.TileService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsets;
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowInsetsController.Appearance;
@@ -645,7 +643,7 @@
         }
 
         @Override
-        public void showTransient(int displayId, @InternalInsetsType int[] types,
+        public void showTransient(int displayId, @InsetsType int types,
                 boolean isGestureOnSystemBar) {
             getUiState(displayId).showTransient(types);
             if (mBar != null) {
@@ -656,7 +654,7 @@
         }
 
         @Override
-        public void abortTransient(int displayId, @InternalInsetsType int[] types) {
+        public void abortTransient(int displayId, @InsetsType int types) {
             getUiState(displayId).clearTransient(types);
             if (mBar != null) {
                 try {
@@ -1258,7 +1256,7 @@
     private static class UiState {
         private @Appearance int mAppearance = 0;
         private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0];
-        private final ArraySet<Integer> mTransientBarTypes = new ArraySet<>();
+        private @InsetsType int mTransientBarTypes;
         private boolean mNavbarColorManagedByIme = false;
         private @Behavior int mBehavior;
         private @InsetsType int mRequestedVisibleTypes = WindowInsets.Type.defaultVisible();
@@ -1285,16 +1283,12 @@
             mLetterboxDetails = letterboxDetails;
         }
 
-        private void showTransient(@InternalInsetsType int[] types) {
-            for (int type : types) {
-                mTransientBarTypes.add(type);
-            }
+        private void showTransient(@InsetsType int types) {
+            mTransientBarTypes |= types;
         }
 
-        private void clearTransient(@InternalInsetsType int[] types) {
-            for (int type : types) {
-                mTransientBarTypes.remove(type);
-            }
+        private void clearTransient(@InsetsType int types) {
+            mTransientBarTypes &= ~types;
         }
 
         private int getDisabled1() {
@@ -1410,16 +1404,12 @@
             // TODO(b/118592525): Currently, status bar only works on the default display.
             // Make it aware of multi-display if needed.
             final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
-            final int[] transientBarTypes = new int[state.mTransientBarTypes.size()];
-            for (int i = 0; i < transientBarTypes.length; i++) {
-                transientBarTypes[i] = state.mTransientBarTypes.valueAt(i);
-            }
             return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1),
                     state.mAppearance, state.mAppearanceRegions, state.mImeWindowVis,
                     state.mImeBackDisposition, state.mShowImeSwitcher,
                     gatherDisableActionsLocked(mCurrentUserId, 2), state.mImeToken,
                     state.mNavbarColorManagedByIme, state.mBehavior, state.mRequestedVisibleTypes,
-                    state.mPackageName, transientBarTypes, state.mLetterboxDetails);
+                    state.mPackageName, state.mTransientBarTypes, state.mLetterboxDetails);
         }
     }
 
diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java
index 9faf7a9..4ebd402 100644
--- a/services/core/java/com/android/server/storage/StorageSessionController.java
+++ b/services/core/java/com/android/server/storage/StorageSessionController.java
@@ -19,6 +19,7 @@
 import android.Manifest;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ApplicationExitInfo;
 import android.app.IActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -444,7 +445,7 @@
         IActivityManager am = ActivityManager.getService();
         try {
             am.killApplication(mExternalStorageServicePackageName, mExternalStorageServiceAppId,
-                    userId, "storage_session_controller reset");
+                    userId, "storage_session_controller reset", ApplicationExitInfo.REASON_OTHER);
         } catch (RemoteException e) {
             Slog.i(TAG, "Failed to kill the ExtenalStorageService for user " + userId);
         }
diff --git a/services/core/java/com/android/server/tracing/OWNERS b/services/core/java/com/android/server/tracing/OWNERS
index f5de4eb..079d4c5 100644
--- a/services/core/java/com/android/server/tracing/OWNERS
+++ b/services/core/java/com/android/server/tracing/OWNERS
@@ -1,2 +1,3 @@
-cfijalkovich@google.com
 carmenjackson@google.com
+kevinjeon@google.com
+include platform/external/perfetto:/OWNERS
diff --git a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
index be90530..90b6f95 100644
--- a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
@@ -126,7 +126,7 @@
                     "Turning off vibrator " + getVibratorId());
         }
         controller.off();
-        getVibration().stats().reportVibratorOff();
+        getVibration().stats.reportVibratorOff();
         mPendingVibratorOffDeadline = 0;
     }
 
@@ -136,7 +136,7 @@
                     "Amplitude changed on vibrator " + getVibratorId() + " to " + amplitude);
         }
         controller.setAmplitude(amplitude);
-        getVibration().stats().reportSetAmplitude();
+        getVibration().stats.reportSetAmplitude();
     }
 
     /**
@@ -170,7 +170,7 @@
             // Count the loops that were played.
             int loopSize = effectSize - repeatIndex;
             int loopSegmentsPlayed = nextSegmentIndex - repeatIndex;
-            getVibration().stats().reportRepetition(loopSegmentsPlayed / loopSize);
+            getVibration().stats.reportRepetition(loopSegmentsPlayed / loopSize);
             nextSegmentIndex = repeatIndex + ((nextSegmentIndex - effectSize) % loopSize);
         }
         Step nextStep = conductor.nextVibrateStep(nextStartTime, controller, effect,
diff --git a/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java b/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
index 545ec5b..940bd08 100644
--- a/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
@@ -73,7 +73,7 @@
                     primitives.toArray(new PrimitiveSegment[primitives.size()]);
             long vibratorOnResult = controller.on(primitivesArray, getVibration().id);
             handleVibratorOnResult(vibratorOnResult);
-            getVibration().stats().reportComposePrimitives(vibratorOnResult, primitivesArray);
+            getVibration().stats.reportComposePrimitives(vibratorOnResult, primitivesArray);
 
             // The next start and off times will be calculated from mVibratorOnResult.
             return nextSteps(/* segmentsPlayed= */ primitives.size());
diff --git a/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java b/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
index 8bfa2c3..7100ffd 100644
--- a/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
@@ -72,7 +72,7 @@
             RampSegment[] pwlesArray = pwles.toArray(new RampSegment[pwles.size()]);
             long vibratorOnResult = controller.on(pwlesArray, getVibration().id);
             handleVibratorOnResult(vibratorOnResult);
-            getVibration().stats().reportComposePwle(vibratorOnResult, pwlesArray);
+            getVibration().stats.reportComposePwle(vibratorOnResult, pwlesArray);
 
             // The next start and off times will be calculated from mVibratorOnResult.
             return nextSteps(/* segmentsPlayed= */ pwles.size());
diff --git a/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java b/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java
index bbbca02..c9683d9 100644
--- a/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java
+++ b/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java
@@ -51,7 +51,8 @@
                 Slog.d(VibrationThread.TAG,
                         "FinishSequentialEffectStep for effect #" + startedStep.currentIndex);
             }
-            conductor.vibratorManagerHooks.noteVibratorOff(conductor.getVibration().uid);
+            conductor.vibratorManagerHooks.noteVibratorOff(
+                    conductor.getVibration().callerInfo.uid);
             Step nextStep = startedStep.nextStep();
             return nextStep == null ? VibrationStepConductor.EMPTY_STEP_LIST
                     : Arrays.asList(nextStep);
@@ -68,6 +69,7 @@
 
     @Override
     public void cancelImmediately() {
-        conductor.vibratorManagerHooks.noteVibratorOff(conductor.getVibration().uid);
+        conductor.vibratorManagerHooks.noteVibratorOff(
+                conductor.getVibration().callerInfo.uid);
     }
 }
diff --git a/services/core/java/com/android/server/vibrator/HalVibration.java b/services/core/java/com/android/server/vibrator/HalVibration.java
index 53f04d7..87f189a 100644
--- a/services/core/java/com/android/server/vibrator/HalVibration.java
+++ b/services/core/java/com/android/server/vibrator/HalVibration.java
@@ -16,6 +16,7 @@
 
 package com.android.server.vibrator;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.CombinedVibration;
 import android.os.IBinder;
@@ -35,13 +36,6 @@
  */
 final class HalVibration extends Vibration {
 
-    public final VibrationAttributes attrs;
-    public final long id;
-    public final int uid;
-    public final int displayId;
-    public final String opPkg;
-    public final String reason;
-    public final IBinder token;
     public final SparseArray<VibrationEffect> mFallbacks = new SparseArray<>();
 
     /** The actual effect to be played. */
@@ -58,29 +52,15 @@
     /** Vibration status. */
     private Vibration.Status mStatus;
 
-    /** Vibration runtime stats. */
-    private final VibrationStats mStats = new VibrationStats();
-
     /** A {@link CountDownLatch} to enable waiting for completion. */
     private final CountDownLatch mCompletionLatch = new CountDownLatch(1);
 
-    HalVibration(IBinder token, int id, CombinedVibration effect,
-            VibrationAttributes attrs, int uid, int displayId, String opPkg, String reason) {
-        this.token = token;
+    HalVibration(@NonNull IBinder token, CombinedVibration effect, @NonNull CallerInfo callerInfo) {
+        super(token, callerInfo);
         this.mEffect = effect;
-        this.id = id;
-        this.attrs = attrs;
-        this.uid = uid;
-        this.displayId = displayId;
-        this.opPkg = opPkg;
-        this.reason = reason;
         mStatus = Vibration.Status.RUNNING;
     }
 
-    VibrationStats stats() {
-        return mStats;
-    }
-
     /**
      * Set the {@link Status} of this vibration and reports the current system time as this
      * vibration end time, for debugging purposes.
@@ -94,7 +74,7 @@
             return;
         }
         mStatus = info.status;
-        mStats.reportEnded(info.endedByUid, info.endedByUsage);
+        stats.reportEnded(info.endedBy);
         mCompletionLatch.countDown();
     }
 
@@ -190,8 +170,8 @@
      * Return {@link Vibration.DebugInfo} with read-only debug information about this vibration.
      */
     public Vibration.DebugInfo getDebugInfo() {
-        return new Vibration.DebugInfo(mStatus, mStats, mEffect, mOriginalEffect, /* scale= */ 0,
-                attrs, uid, displayId, opPkg, reason);
+        return new Vibration.DebugInfo(mStatus, stats, mEffect, mOriginalEffect, /* scale= */ 0,
+                callerInfo);
     }
 
     /** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */
@@ -200,7 +180,8 @@
                 ? FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__REPEATED
                 : FrameworkStatsLog.VIBRATION_REPORTED__VIBRATION_TYPE__SINGLE;
         return new VibrationStats.StatsInfo(
-                uid, vibrationType, attrs.getUsage(), mStatus, mStats, completionUptimeMillis);
+                callerInfo.uid, vibrationType, callerInfo.attrs.getUsage(), mStatus,
+                stats, completionUptimeMillis);
     }
 
     /**
@@ -212,8 +193,9 @@
      * pipeline very short vibrations together, regardless of the flag.
      */
     public boolean canPipelineWith(HalVibration vib) {
-        return uid == vib.uid && attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
-                && vib.attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
+        return callerInfo.uid == vib.callerInfo.uid && callerInfo.attrs.isFlagSet(
+                VibrationAttributes.FLAG_PIPELINED_EFFECT)
+                && vib.callerInfo.attrs.isFlagSet(VibrationAttributes.FLAG_PIPELINED_EFFECT)
                 && !isRepeating();
     }
 }
diff --git a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
index 21ba874..4e58b9a 100644
--- a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
+++ b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
@@ -21,7 +21,6 @@
 import android.hardware.input.InputManager;
 import android.os.CombinedVibration;
 import android.os.Handler;
-import android.os.VibrationAttributes;
 import android.os.VibratorManager;
 import android.util.SparseArray;
 import android.view.InputDevice;
@@ -94,11 +93,11 @@
      *
      * @return {@link #isAvailable()}
      */
-    public boolean vibrateIfAvailable(int uid, String opPkg, CombinedVibration effect,
-            String reason, VibrationAttributes attrs) {
+    public boolean vibrateIfAvailable(Vibration.CallerInfo callerInfo, CombinedVibration effect) {
         synchronized (mLock) {
             for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
-                mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, effect, reason, attrs);
+                mInputDeviceVibrators.valueAt(i).vibrate(callerInfo.uid, callerInfo.opPkg, effect,
+                        callerInfo.reason, callerInfo.attrs);
             }
             return mInputDeviceVibrators.size() > 0;
         }
diff --git a/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java b/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java
index d91bafa..8094e7c5 100644
--- a/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java
@@ -64,7 +64,7 @@
             VibrationEffect fallback = getVibration().getFallback(prebaked.getEffectId());
             long vibratorOnResult = controller.on(prebaked, getVibration().id);
             handleVibratorOnResult(vibratorOnResult);
-            getVibration().stats().reportPerformEffect(vibratorOnResult, prebaked);
+            getVibration().stats.reportPerformEffect(vibratorOnResult, prebaked);
 
             if (vibratorOnResult == 0 && prebaked.shouldFallback()
                     && (fallback instanceof VibrationEffect.Composed)) {
diff --git a/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java b/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
index 1672470..cce1ef4 100644
--- a/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
+++ b/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
@@ -161,7 +161,7 @@
         }
         long vibratorOnResult = controller.on(duration, getVibration().id);
         handleVibratorOnResult(vibratorOnResult);
-        getVibration().stats().reportVibratorOn(vibratorOnResult);
+        getVibration().stats.reportVibratorOn(vibratorOnResult);
         return vibratorOnResult;
     }
 
diff --git a/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java b/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
index fd1a3ac..15c60a3 100644
--- a/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
+++ b/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
@@ -93,8 +93,8 @@
             }
 
             mVibratorsOnMaxDuration = startVibrating(effectMapping, nextSteps);
-            conductor.vibratorManagerHooks.noteVibratorOn(conductor.getVibration().uid,
-                    mVibratorsOnMaxDuration);
+            conductor.vibratorManagerHooks.noteVibratorOn(
+                    conductor.getVibration().callerInfo.uid, mVibratorsOnMaxDuration);
         } finally {
             if (mVibratorsOnMaxDuration >= 0) {
                 // It least one vibrator was started then add a finish step to wait for all
@@ -211,7 +211,8 @@
         // Check if sync was prepared and if any step was accepted by a vibrator,
         // otherwise there is nothing to trigger here.
         if (hasPrepared && !hasFailed && maxDuration > 0) {
-            hasTriggered = conductor.vibratorManagerHooks.triggerSyncedVibration(getVibration().id);
+            hasTriggered = conductor.vibratorManagerHooks.triggerSyncedVibration(
+                    getVibration().id);
             hasFailed &= hasTriggered;
         }
 
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index 5667c72..1cc0a4f 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.CombinedVibration;
+import android.os.IBinder;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.os.vibrator.PrebakedSegment;
@@ -31,6 +32,7 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * The base class for all vibrations.
@@ -38,6 +40,13 @@
 class Vibration {
     private static final SimpleDateFormat DEBUG_DATE_FORMAT =
             new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+    // Used to generate globally unique vibration ids.
+    private static final AtomicInteger sNextVibrationId = new AtomicInteger(1); // 0 = no callback
+
+    public final long id;
+    public final CallerInfo callerInfo;
+    public final VibrationStats stats = new VibrationStats();
+    public final IBinder callerToken;
 
     /** Vibration status with reference to values from vibratormanagerservice.proto for logging. */
     enum Status {
@@ -80,24 +89,82 @@
         }
     }
 
+    Vibration(@NonNull IBinder token, @NonNull CallerInfo callerInfo) {
+        Objects.requireNonNull(token);
+        Objects.requireNonNull(callerInfo);
+        this.id = sNextVibrationId.getAndIncrement();
+        this.callerToken = token;
+        this.callerInfo = callerInfo;
+    }
+
+    /**
+     * Holds lightweight immutable info on the process that triggered the vibration. This data
+     * could potentially be kept in memory for a long time for bugreport dumpsys operations.
+     *
+     * Since CallerInfo can be kept in memory for a long time, it shouldn't hold any references to
+     * potentially expensive or resource-linked objects, such as {@link IBinder}.
+     */
+    static final class CallerInfo {
+        public final VibrationAttributes attrs;
+        public final int uid;
+        public final int displayId;
+        public final String opPkg;
+        public final String reason;
+
+        CallerInfo(@NonNull VibrationAttributes attrs, int uid, int displayId,
+                String opPkg, String reason) {
+            Objects.requireNonNull(attrs);
+            this.attrs = attrs;
+            this.uid = uid;
+            this.displayId = displayId;
+            this.opPkg = opPkg;
+            this.reason = reason;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof CallerInfo)) return false;
+            CallerInfo that = (CallerInfo) o;
+            return Objects.equals(attrs, that.attrs)
+                    && uid == that.uid
+                    && displayId == that.displayId
+                    && Objects.equals(opPkg, that.opPkg)
+                    && Objects.equals(reason, that.reason);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(attrs, uid, displayId, opPkg, reason);
+        }
+
+        @Override
+        public String toString() {
+            return "CallerInfo{"
+                    + " attrs=" + attrs
+                    + ", uid=" + uid
+                    + ", displayId=" + displayId
+                    + ", opPkg=" + opPkg
+                    + ", reason=" + reason
+                    + '}';
+        }
+    }
+
     /** Immutable info passed as a signal to end a vibration. */
     static final class EndInfo {
         /** The {@link Status} to be set to the vibration when it ends with this info. */
         @NonNull
         public final Status status;
-        /** The UID that triggered the vibration that ended this, or -1 if undefined. */
-        public final int endedByUid;
-        /** The VibrationAttributes.USAGE_* of the vibration that ended this, or -1 if undefined. */
-        public final int endedByUsage;
+        /** Info about the process that ended the vibration. */
+        public final CallerInfo endedBy;
 
         EndInfo(@NonNull Vibration.Status status) {
-            this(status, /* endedByUid= */ -1, /* endedByUsage= */ -1);
+            this(status, null);
         }
 
-        EndInfo(@NonNull Vibration.Status status, int endedByUid, int endedByUsage) {
+        EndInfo(@NonNull Vibration.Status status, @Nullable CallerInfo endedBy) {
             this.status = status;
-            this.endedByUid = endedByUid;
-            this.endedByUsage = endedByUsage;
+            this.endedBy = endedBy;
         }
 
         @Override
@@ -105,27 +172,31 @@
             if (this == o) return true;
             if (!(o instanceof EndInfo)) return false;
             EndInfo that = (EndInfo) o;
-            return endedByUid == that.endedByUid
-                    && endedByUsage == that.endedByUsage
+            return Objects.equals(endedBy, that.endedBy)
                     && status == that.status;
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(status, endedByUid, endedByUsage);
+            return Objects.hash(status, endedBy);
         }
 
         @Override
         public String toString() {
             return "EndInfo{"
                     + "status=" + status
-                    + ", endedByUid=" + endedByUid
-                    + ", endedByUsage=" + endedByUsage
+                    + ", endedBy=" + endedBy
                     + '}';
         }
     }
 
-    /** Debug information about vibrations. */
+    /**
+     * Holds lightweight debug information about the vibration that could potentially be kept in
+     * memory for a long time for bugreport dumpsys operations.
+     *
+     * Since DebugInfo can be kept in memory for a long time, it shouldn't hold any references to
+     * potentially expensive or resource-linked objects, such as {@link IBinder}.
+     */
     static final class DebugInfo {
         private final long mCreateTime;
         private final long mStartTime;
@@ -134,16 +205,13 @@
         private final CombinedVibration mEffect;
         private final CombinedVibration mOriginalEffect;
         private final float mScale;
-        private final VibrationAttributes mAttrs;
-        private final int mUid;
-        private final int mDisplayId;
-        private final String mOpPkg;
-        private final String mReason;
+        private final CallerInfo mCallerInfo;
         private final Status mStatus;
 
         DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration effect,
-                @Nullable CombinedVibration originalEffect, float scale, VibrationAttributes attrs,
-                int uid, int displayId, String opPkg, String reason) {
+                @Nullable CombinedVibration originalEffect, float scale,
+                @NonNull CallerInfo callerInfo) {
+            Objects.requireNonNull(callerInfo);
             mCreateTime = stats.getCreateTimeDebug();
             mStartTime = stats.getStartTimeDebug();
             mEndTime = stats.getEndTimeDebug();
@@ -151,11 +219,7 @@
             mEffect = effect;
             mOriginalEffect = originalEffect;
             mScale = scale;
-            mAttrs = attrs;
-            mUid = uid;
-            mDisplayId = displayId;
-            mOpPkg = opPkg;
-            mReason = reason;
+            mCallerInfo = callerInfo;
             mStatus = status;
         }
 
@@ -179,16 +243,8 @@
                     .append(mOriginalEffect)
                     .append(", scale: ")
                     .append(String.format("%.2f", mScale))
-                    .append(", attrs: ")
-                    .append(mAttrs)
-                    .append(", uid: ")
-                    .append(mUid)
-                    .append(", displayId: ")
-                    .append(mDisplayId)
-                    .append(", opPkg: ")
-                    .append(mOpPkg)
-                    .append(", reason: ")
-                    .append(mReason)
+                    .append(", callerInfo: ")
+                    .append(mCallerInfo)
                     .toString();
         }
 
@@ -201,9 +257,10 @@
             proto.write(VibrationProto.STATUS, mStatus.ordinal());
 
             final long attrsToken = proto.start(VibrationProto.ATTRIBUTES);
-            proto.write(VibrationAttributesProto.USAGE, mAttrs.getUsage());
-            proto.write(VibrationAttributesProto.AUDIO_USAGE, mAttrs.getAudioUsage());
-            proto.write(VibrationAttributesProto.FLAGS, mAttrs.getFlags());
+            final VibrationAttributes attrs = mCallerInfo.attrs;
+            proto.write(VibrationAttributesProto.USAGE, attrs.getUsage());
+            proto.write(VibrationAttributesProto.AUDIO_USAGE, attrs.getAudioUsage());
+            proto.write(VibrationAttributesProto.FLAGS, attrs.getFlags());
             proto.end(attrsToken);
 
             if (mEffect != null) {
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index d944a3b..8a7d607c 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -27,6 +27,7 @@
 import static android.os.VibrationAttributes.USAGE_TOUCH;
 import static android.os.VibrationAttributes.USAGE_UNKNOWN;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.IUidObserver;
@@ -375,15 +376,15 @@
      * null otherwise.
      */
     @Nullable
-    public Vibration.Status shouldIgnoreVibration(int uid, int displayId,
-            VibrationAttributes attrs) {
-        final int usage = attrs.getUsage();
+    public Vibration.Status shouldIgnoreVibration(@NonNull Vibration.CallerInfo callerInfo) {
+        final int usage = callerInfo.attrs.getUsage();
         synchronized (mLock) {
-            if (!mUidObserver.isUidForeground(uid)
+            if (!mUidObserver.isUidForeground(callerInfo.uid)
                     && !BACKGROUND_PROCESS_USAGE_ALLOWLIST.contains(usage)) {
                 return Vibration.Status.IGNORED_BACKGROUND;
             }
-            if (mVirtualDeviceListener.isAppOrDisplayOnAnyVirtualDevice(uid, displayId)) {
+            if (mVirtualDeviceListener.isAppOrDisplayOnAnyVirtualDevice(callerInfo.uid,
+                    callerInfo.displayId)) {
                 return Vibration.Status.IGNORED_FROM_VIRTUAL_DEVICE;
             }
 
@@ -391,7 +392,8 @@
                 return Vibration.Status.IGNORED_FOR_POWER;
             }
 
-            if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)) {
+            if (!callerInfo.attrs.isFlagSet(
+                    VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)) {
                 if (!mVibrateOn && (VIBRATE_ON_DISABLED_USAGE_ALLOWED != usage)) {
                     return Vibration.Status.IGNORED_FOR_SETTINGS;
                 }
@@ -401,7 +403,7 @@
                 }
             }
 
-            if (!attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
+            if (!callerInfo.attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)) {
                 if (!shouldVibrateForRingerModeLocked(usage)) {
                     return Vibration.Status.IGNORED_FOR_RINGER_MODE;
                 }
@@ -420,8 +422,8 @@
      *
      * @return true if the vibration should be cancelled when the screen goes off, false otherwise.
      */
-    public boolean shouldCancelVibrationOnScreenOff(int uid, String opPkg,
-            @VibrationAttributes.Usage int usage, long vibrationStartUptimeMillis) {
+    public boolean shouldCancelVibrationOnScreenOff(@NonNull Vibration.CallerInfo callerInfo,
+            long vibrationStartUptimeMillis) {
         PowerManagerInternal pm;
         synchronized (mLock) {
             pm = mPowerManagerInternal;
@@ -442,12 +444,13 @@
                 return false;
             }
         }
-        if (!SYSTEM_VIBRATION_SCREEN_OFF_USAGE_ALLOWLIST.contains(usage)) {
+        if (!SYSTEM_VIBRATION_SCREEN_OFF_USAGE_ALLOWLIST.contains(callerInfo.attrs.getUsage())) {
             // Usages not allowed even for system vibrations should always be cancelled.
             return true;
         }
         // Only allow vibrations from System packages to continue vibrating when the screen goes off
-        return uid != Process.SYSTEM_UID && uid != 0 && !mSystemUiPackage.equals(opPkg);
+        return callerInfo.uid != Process.SYSTEM_UID && callerInfo.uid != 0
+                && !mSystemUiPackage.equals(callerInfo.opPkg);
     }
 
     /**
diff --git a/services/core/java/com/android/server/vibrator/VibrationStats.java b/services/core/java/com/android/server/vibrator/VibrationStats.java
index 931be1d..2d00351 100644
--- a/services/core/java/com/android/server/vibrator/VibrationStats.java
+++ b/services/core/java/com/android/server/vibrator/VibrationStats.java
@@ -16,6 +16,8 @@
 
 package com.android.server.vibrator;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.SystemClock;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.PrimitiveSegment;
@@ -159,15 +161,18 @@
      * @return true if the status was accepted. This method will only accept given values if
      * the end timestamp was never set.
      */
-    boolean reportEnded(int endedByUid, int endedByUsage) {
+    boolean reportEnded(@Nullable Vibration.CallerInfo endedBy) {
         if (hasEnded()) {
             // Vibration already ended, keep first ending stats set and ignore this one.
             return false;
         }
-        mEndedByUid = endedByUid;
-        mEndedByUsage = endedByUsage;
+        if (endedBy != null) {
+            mEndedByUid = endedBy.uid;
+            mEndedByUsage = endedBy.attrs.getUsage();
+        }
         mEndUptimeMillis = SystemClock.uptimeMillis();
         mEndTimeDebug = System.currentTimeMillis();
+
         return true;
     }
 
@@ -177,9 +182,9 @@
      * <p>This method will only accept the first value as the one that was interrupted by this
      * vibration, and will ignore all successive calls.
      */
-    void reportInterruptedAnotherVibration(int interruptedUsage) {
+    void reportInterruptedAnotherVibration(@NonNull Vibration.CallerInfo callerInfo) {
         if (mInterruptedUsage < 0) {
-            mInterruptedUsage = interruptedUsage;
+            mInterruptedUsage = callerInfo.attrs.getUsage();
         }
     }
 
diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
index 11cab4b..4202afb 100644
--- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
+++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
@@ -157,7 +157,7 @@
         mNextSteps.offer(new StartSequentialEffectStep(this, sequentialEffect));
         // Vibration will start playing in the Vibrator, following the effect timings and delays.
         // Report current time as the vibration start time, for debugging.
-        mVibration.stats().reportStarted();
+        mVibration.stats.reportStarted();
     }
 
     public HalVibration getVibration() {
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index d2dc43c..cfb4c74 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -161,7 +161,8 @@
             // for this thread.
             // No point doing this in finally, as if there's an exception, this thread will die
             // and be unusable anyway.
-            mVibratorManagerHooks.onVibrationThreadReleased(mExecutingConductor.getVibration().id);
+            mVibratorManagerHooks.onVibrationThreadReleased(
+                    mExecutingConductor.getVibration().id);
             synchronized (mLock) {
                 mLock.notifyAll();
             }
@@ -230,7 +231,8 @@
 
     /** Runs the VibrationThread ensuring that the wake lock is acquired and released. */
     private void runCurrentVibrationWithWakeLock() {
-        WorkSource workSource = new WorkSource(mExecutingConductor.getVibration().uid);
+        WorkSource workSource = new WorkSource(
+                mExecutingConductor.getVibration().callerInfo.uid);
         mWakeLock.setWorkSource(workSource);
         mWakeLock.acquire();
         try {
@@ -251,7 +253,7 @@
      * Called from within runWithWakeLock.
      */
     private void runCurrentVibrationWithWakeLockAndDeathLink() {
-        IBinder vibrationBinderToken = mExecutingConductor.getVibration().token;
+        IBinder vibrationBinderToken = mExecutingConductor.getVibration().callerToken;
         try {
             vibrationBinderToken.linkToDeath(mExecutingConductor, 0);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index c87332d..5756414 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -77,7 +77,6 @@
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -123,9 +122,6 @@
         }
     }
 
-    // Used to generate globally unique vibration ids.
-    private final AtomicInteger mNextVibrationId = new AtomicInteger(1); // 0 = no callback
-
     private final Object mLock = new Object();
     private final Context mContext;
     private final PowerManager.WakeLock mWakeLock;
@@ -367,8 +363,9 @@
                     // missing on individual vibrators.
                     return false;
                 }
-                AlwaysOnVibration alwaysOnVibration = new AlwaysOnVibration(
-                        alwaysOnId, uid, opPkg, attrs, effects);
+                AlwaysOnVibration alwaysOnVibration = new AlwaysOnVibration(alwaysOnId,
+                        new Vibration.CallerInfo(attrs, uid, Display.DEFAULT_DISPLAY, opPkg,
+                                null), effects);
                 mAlwaysOnEffects.put(alwaysOnId, alwaysOnVibration);
                 updateAlwaysOnLocked(alwaysOnVibration);
             }
@@ -408,8 +405,8 @@
             }
             attrs = fixupVibrationAttributes(attrs, effect);
             // Create Vibration.Stats as close to the received request as possible, for tracking.
-            HalVibration vib = new HalVibration(token, mNextVibrationId.getAndIncrement(), effect,
-                    attrs, uid, displayId, opPkg, reason);
+            HalVibration vib = new HalVibration(token, effect,
+                    new Vibration.CallerInfo(attrs, uid, displayId, opPkg, reason));
             fillVibrationFallbacks(vib, effect);
 
             if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
@@ -422,27 +419,23 @@
                 if (DEBUG) {
                     Slog.d(TAG, "Starting vibrate for vibration " + vib.id);
                 }
-                int ignoredByUid = -1;
-                int ignoredByUsage = -1;
-                Vibration.Status status = null;
+                Vibration.CallerInfo ignoredByCallerInfo = null;
+                Vibration.Status status;
 
                 // Check if user settings or DnD is set to ignore this vibration.
-                status = shouldIgnoreVibrationLocked(vib.uid, vib.displayId, vib.opPkg, vib.attrs);
+                status = shouldIgnoreVibrationLocked(vib.callerInfo);
 
                 // Check if something has external control, assume it's more important.
                 if ((status == null) && (mCurrentExternalVibration != null)) {
                     status = Vibration.Status.IGNORED_FOR_EXTERNAL;
-                    ignoredByUid = mCurrentExternalVibration.externalVibration.getUid();
-                    ignoredByUsage = mCurrentExternalVibration.externalVibration
-                            .getVibrationAttributes().getUsage();
+                    ignoredByCallerInfo = mCurrentExternalVibration.callerInfo;
                 }
 
                 // Check if ongoing vibration is more important than this vibration.
                 if (status == null) {
                     status = shouldIgnoreVibrationForOngoingLocked(vib);
                     if (status != null) {
-                        ignoredByUid = mCurrentVibration.getVibration().uid;
-                        ignoredByUsage = mCurrentVibration.getVibration().attrs.getUsage();
+                        ignoredByCallerInfo = mCurrentVibration.getVibration().callerInfo;
                     }
                 }
 
@@ -460,12 +453,11 @@
                                     Slog.d(TAG, "Pipelining vibration " + vib.id);
                                 }
                             } else {
-                                vib.stats().reportInterruptedAnotherVibration(
-                                        mCurrentVibration.getVibration().attrs.getUsage());
+                                vib.stats.reportInterruptedAnotherVibration(
+                                        mCurrentVibration.getVibration().callerInfo);
                                 mCurrentVibration.notifyCancelled(
-                                        new Vibration.EndInfo(
-                                                Vibration.Status.CANCELLED_SUPERSEDED, vib.uid,
-                                                vib.attrs.getUsage()),
+                                        new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED,
+                                                vib.callerInfo),
                                         /* immediate= */ false);
                             }
                         }
@@ -478,7 +470,7 @@
                 // Ignored or failed to start the vibration, end it and report metrics right away.
                 if (status != Vibration.Status.RUNNING) {
                     endVibrationLocked(vib,
-                            new Vibration.EndInfo(status, ignoredByUid, ignoredByUsage),
+                            new Vibration.EndInfo(status, ignoredByCallerInfo),
                             /* shouldWriteStats= */ true);
                 }
                 return vib;
@@ -641,8 +633,7 @@
             }
 
             HalVibration vib = mCurrentVibration.getVibration();
-            Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
-                    vib.uid, vib.displayId, vib.opPkg, vib.attrs);
+            Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib.callerInfo);
 
             if (inputDevicesChanged || (ignoreStatus != null)) {
                 if (DEBUG) {
@@ -671,10 +662,9 @@
             if (vibrator == null) {
                 continue;
             }
-            Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
-                    vib.uid, Display.DEFAULT_DISPLAY, vib.opPkg, vib.attrs);
+            Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vib.callerInfo);
             if (ignoreStatus == null) {
-                effect = mVibrationScaler.scale(effect, vib.attrs.getUsage());
+                effect = mVibrationScaler.scale(effect, vib.callerInfo.attrs.getUsage());
             } else {
                 // Vibration should not run, use null effect to remove registered effect.
                 effect = null;
@@ -687,9 +677,10 @@
     private Vibration.Status startVibrationLocked(HalVibration vib) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked");
         try {
-            vib.updateEffects(effect -> mVibrationScaler.scale(effect, vib.attrs.getUsage()));
+            vib.updateEffects(
+                    effect -> mVibrationScaler.scale(effect, vib.callerInfo.attrs.getUsage()));
             boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
-                    vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs);
+                    vib.callerInfo, vib.getEffect());
             if (inputDevicesAvailable) {
                 return Vibration.Status.FORWARDED_TO_INPUT_DEVICES;
             }
@@ -704,8 +695,7 @@
             // Note that we don't consider pipelining here, because new pipelined ones should
             // replace pending non-executing pipelined ones anyway.
             clearNextVibrationLocked(
-                    new Vibration.EndInfo(Vibration.Status.IGNORED_SUPERSEDED,
-                            vib.uid, vib.attrs.getUsage()));
+                    new Vibration.EndInfo(Vibration.Status.IGNORED_SUPERSEDED, vib.callerInfo));
             mNextVibration = conductor;
             return Vibration.Status.RUNNING;
         } finally {
@@ -718,7 +708,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked");
         try {
             HalVibration vib = conductor.getVibration();
-            int mode = startAppOpModeLocked(vib.uid, vib.opPkg, vib.attrs);
+            int mode = startAppOpModeLocked(vib.callerInfo);
             switch (mode) {
                 case AppOpsManager.MODE_ALLOWED:
                     Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
@@ -731,7 +721,8 @@
                     }
                     return Vibration.Status.RUNNING;
                 case AppOpsManager.MODE_ERRORED:
-                    Slog.w(TAG, "Start AppOpsManager operation errored for uid " + vib.uid);
+                    Slog.w(TAG, "Start AppOpsManager operation errored for uid "
+                            + vib.callerInfo.uid);
                     return Vibration.Status.IGNORED_ERROR_APP_OPS;
                 default:
                     return Vibration.Status.IGNORED_APP_OPS;
@@ -745,7 +736,8 @@
     private void endVibrationLocked(HalVibration vib, Vibration.EndInfo vibrationEndInfo,
             boolean shouldWriteStats) {
         vib.end(vibrationEndInfo);
-        logVibrationStatus(vib.uid, vib.attrs, vibrationEndInfo.status);
+        logVibrationStatus(vib.callerInfo.uid, vib.callerInfo.attrs,
+                vibrationEndInfo.status);
         mVibratorManagerRecords.record(vib);
         if (shouldWriteStats) {
             mFrameworkStatsLogger.writeVibrationReportedAsync(
@@ -817,12 +809,13 @@
         try {
             HalVibration vib = mCurrentVibration.getVibration();
             if (DEBUG) {
-                Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " + vibrationEndInfo);
+                Slog.d(TAG, "Reporting vibration " + vib.id + " finished with "
+                        + vibrationEndInfo);
             }
             // DO NOT write metrics at this point, wait for the VibrationThread to report the
             // vibration was released, after all cleanup. The metrics will be reported then.
             endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false);
-            finishAppOpModeLocked(vib.uid, vib.opPkg);
+            finishAppOpModeLocked(vib.callerInfo);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
         }
@@ -830,7 +823,8 @@
 
     private void onSyncedVibrationComplete(long vibrationId) {
         synchronized (mLock) {
-            if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) {
+            if (mCurrentVibration != null
+                    && mCurrentVibration.getVibration().id == vibrationId) {
                 if (DEBUG) {
                     Slog.d(TAG, "Synced vibration " + vibrationId + " complete, notifying thread");
                 }
@@ -841,7 +835,8 @@
 
     private void onVibrationComplete(int vibratorId, long vibrationId) {
         synchronized (mLock) {
-            if (mCurrentVibration != null && mCurrentVibration.getVibration().id == vibrationId) {
+            if (mCurrentVibration != null
+                    && mCurrentVibration.getVibration().id == vibrationId) {
                 if (DEBUG) {
                     Slog.d(TAG, "Vibration " + vibrationId + " on vibrator " + vibratorId
                             + " complete, notifying thread");
@@ -871,8 +866,8 @@
             return null;
         }
 
-        int currentUsage = currentVibration.attrs.getUsage();
-        int newUsage = vib.attrs.getUsage();
+        int currentUsage = currentVibration.callerInfo.attrs.getUsage();
+        int newUsage = vib.callerInfo.attrs.getUsage();
         if (getVibrationImportance(currentUsage) > getVibrationImportance(newUsage)) {
             // Current vibration has higher importance than this one and should not be cancelled.
             return Vibration.Status.IGNORED_FOR_HIGHER_IMPORTANCE;
@@ -916,15 +911,13 @@
      */
     @GuardedBy("mLock")
     @Nullable
-    private Vibration.Status shouldIgnoreVibrationLocked(int uid, int displayId, String opPkg,
-            VibrationAttributes attrs) {
-        Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(uid,
-                displayId, attrs);
+    private Vibration.Status shouldIgnoreVibrationLocked(Vibration.CallerInfo callerInfo) {
+        Vibration.Status statusFromSettings = mVibrationSettings.shouldIgnoreVibration(callerInfo);
         if (statusFromSettings != null) {
             return statusFromSettings;
         }
 
-        int mode = checkAppOpModeLocked(uid, opPkg, attrs);
+        int mode = checkAppOpModeLocked(callerInfo);
         if (mode != AppOpsManager.MODE_ALLOWED) {
             if (mode == AppOpsManager.MODE_ERRORED) {
                 // We might be getting calls from within system_server, so we don't actually
@@ -948,7 +941,8 @@
      *                    started with the same token can be cancelled with it.
      */
     private boolean shouldCancelVibration(HalVibration vib, int usageFilter, IBinder token) {
-        return (vib.token == token) && shouldCancelVibration(vib.attrs, usageFilter);
+        return (vib.callerToken == token) && shouldCancelVibration(vib.callerInfo.attrs,
+                usageFilter);
     }
 
     /**
@@ -973,24 +967,25 @@
      * {@code attrs}. This will return one of the AppOpsManager.MODE_*.
      */
     @GuardedBy("mLock")
-    private int checkAppOpModeLocked(int uid, String opPkg, VibrationAttributes attrs) {
+    private int checkAppOpModeLocked(Vibration.CallerInfo callerInfo) {
         int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
-                attrs.getAudioUsage(), uid, opPkg);
-        int fixedMode = fixupAppOpModeLocked(mode, attrs);
+                callerInfo.attrs.getAudioUsage(), callerInfo.uid, callerInfo.opPkg);
+        int fixedMode = fixupAppOpModeLocked(mode, callerInfo.attrs);
         if (mode != fixedMode && fixedMode == AppOpsManager.MODE_ALLOWED) {
             // If we're just ignoring the vibration op then this is set by DND and we should ignore
             // if we're asked to bypass. AppOps won't be able to record this operation, so make
             // sure we at least note it in the logs for debugging.
-            Slog.d(TAG, "Bypassing DND for vibrate from uid " + uid);
+            Slog.d(TAG, "Bypassing DND for vibrate from uid " + callerInfo.uid);
         }
         return fixedMode;
     }
 
     /** Start an operation in {@link AppOpsManager}, if allowed. */
     @GuardedBy("mLock")
-    private int startAppOpModeLocked(int uid, String opPkg, VibrationAttributes attrs) {
+    private int startAppOpModeLocked(Vibration.CallerInfo callerInfo) {
         return fixupAppOpModeLocked(
-                mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, uid, opPkg), attrs);
+                mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg),
+                callerInfo.attrs);
     }
 
     /**
@@ -998,8 +993,8 @@
      * operation with same uid was previously started.
      */
     @GuardedBy("mLock")
-    private void finishAppOpModeLocked(int uid, String opPkg) {
-        mAppOps.finishOp(AppOpsManager.OP_VIBRATE, uid, opPkg);
+    private void finishAppOpModeLocked(Vibration.CallerInfo callerInfo) {
+        mAppOps.finishOp(AppOpsManager.OP_VIBRATE, callerInfo.uid, callerInfo.opPkg);
     }
 
     /**
@@ -1186,8 +1181,8 @@
             return false;
         }
         HalVibration vib = conductor.getVibration();
-        return mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                vib.uid, vib.opPkg, vib.attrs.getUsage(), vib.stats().getCreateUptimeMillis());
+        return mVibrationSettings.shouldCancelVibrationOnScreenOff(vib.callerInfo,
+                vib.stats.getCreateUptimeMillis());
     }
 
     @GuardedBy("mLock")
@@ -1385,31 +1380,33 @@
      */
     private static final class AlwaysOnVibration {
         public final int alwaysOnId;
-        public final int uid;
-        public final String opPkg;
-        public final VibrationAttributes attrs;
+        public final Vibration.CallerInfo callerInfo;
         public final SparseArray<PrebakedSegment> effects;
 
-        AlwaysOnVibration(int alwaysOnId, int uid, String opPkg, VibrationAttributes attrs,
+        AlwaysOnVibration(int alwaysOnId, Vibration.CallerInfo callerInfo,
                 SparseArray<PrebakedSegment> effects) {
             this.alwaysOnId = alwaysOnId;
-            this.uid = uid;
-            this.opPkg = opPkg;
-            this.attrs = attrs;
+            this.callerInfo = callerInfo;
             this.effects = effects;
         }
     }
 
     /** Holder for a {@link ExternalVibration}. */
-    private final class ExternalVibrationHolder implements IBinder.DeathRecipient {
+    private final class ExternalVibrationHolder extends Vibration implements
+            IBinder.DeathRecipient {
 
         public final ExternalVibration externalVibration;
-        public final VibrationStats stats = new VibrationStats();
         public int scale;
 
         private Vibration.Status mStatus;
 
         private ExternalVibrationHolder(ExternalVibration externalVibration) {
+            super(externalVibration.getToken(), new Vibration.CallerInfo(
+                    externalVibration.getVibrationAttributes(), externalVibration.getUid(),
+                    // TODO(b/243604888): propagating displayID from IExternalVibration instead of
+                    //  using INVALID_DISPLAY for all external vibrations.
+                    Display.INVALID_DISPLAY,
+                    externalVibration.getPackage(), null));
             this.externalVibration = externalVibration;
             this.scale = IExternalVibratorService.SCALE_NONE;
             mStatus = Vibration.Status.RUNNING;
@@ -1437,14 +1434,15 @@
                 return;
             }
             mStatus = info.status;
-            stats.reportEnded(info.endedByUid, info.endedByUsage);
+            stats.reportEnded(info.endedBy);
 
             if (stats.hasStarted()) {
                 // External vibration doesn't have feedback from total time the vibrator was playing
                 // with non-zero amplitude, so we use the duration between start and end times of
                 // the vibration as the time the vibrator was ON, since the haptic channels are
                 // open for this duration and can receive vibration waveform data.
-                stats.reportVibratorOn(stats.getEndUptimeMillis() - stats.getStartUptimeMillis());
+                stats.reportVibratorOn(
+                        stats.getEndUptimeMillis() - stats.getStartUptimeMillis());
             }
         }
 
@@ -1462,13 +1460,8 @@
         }
 
         public Vibration.DebugInfo getDebugInfo() {
-            return new Vibration.DebugInfo(
-                    mStatus, stats, /* effect= */ null, /* originalEffect= */ null, scale,
-                    externalVibration.getVibrationAttributes(), externalVibration.getUid(),
-                    // TODO(b/243604888): propagating displayID from IExternalVibration instead of
-                    // using INVALID_DISPLAY for all external vibrations.
-                    Display.INVALID_DISPLAY,
-                    externalVibration.getPackage(), /* reason= */ null);
+            return new Vibration.DebugInfo(mStatus, stats, /* effect= */ null,
+                    /* originalEffect= */ null, scale, callerInfo);
         }
 
         public VibrationStats.StatsInfo getStatsInfo(long completionUptimeMillis) {
@@ -1538,7 +1531,7 @@
         }
 
         synchronized void record(HalVibration vib) {
-            int usage = vib.attrs.getUsage();
+            int usage = vib.callerInfo.attrs.getUsage();
             if (!mPreviousVibrations.contains(usage)) {
                 mPreviousVibrations.put(usage, new LinkedList<>());
             }
@@ -1679,8 +1672,7 @@
             synchronized (mLock) {
                 // TODO(b/243604888): propagating displayID from IExternalVibration instead of
                 // using INVALID_DISPLAY for all external vibrations.
-                Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
-                        vib.getUid(), Display.INVALID_DISPLAY, vib.getPackage(), attrs);
+                Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(vibHolder.callerInfo);
                 if (ignoreStatus != null) {
                     vibHolder.scale = IExternalVibratorService.SCALE_MUTE;
                     // Failed to start the vibration, end it and report metrics right away.
@@ -1698,13 +1690,13 @@
                     // vibration that may be playing and ready the vibrator for external control.
                     if (mCurrentVibration != null) {
                         vibHolder.stats.reportInterruptedAnotherVibration(
-                                mCurrentVibration.getVibration().attrs.getUsage());
+                                mCurrentVibration.getVibration().callerInfo);
                         clearNextVibrationLocked(
                                 new Vibration.EndInfo(Vibration.Status.IGNORED_FOR_EXTERNAL,
-                                        vib.getUid(), attrs.getUsage()));
+                                        vibHolder.callerInfo));
                         mCurrentVibration.notifyCancelled(
                                 new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED,
-                                        vib.getUid(), attrs.getUsage()),
+                                        vibHolder.callerInfo),
                                 /* immediate= */ true);
                         waitForCompletion = true;
                     }
@@ -1720,11 +1712,10 @@
                     alreadyUnderExternalControl = true;
                     mCurrentExternalVibration.mute();
                     vibHolder.stats.reportInterruptedAnotherVibration(
-                            mCurrentExternalVibration.externalVibration
-                                    .getVibrationAttributes().getUsage());
+                            mCurrentExternalVibration.callerInfo);
                     endExternalVibrateLocked(
                             new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED,
-                                    vib.getUid(), attrs.getUsage()),
+                                    vibHolder.callerInfo),
                             /* continueExternalControl= */ true);
                 }
                 mCurrentExternalVibration = vibHolder;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperData.java b/services/core/java/com/android/server/wallpaper/WallpaperData.java
index 625e7d9..6763514 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperData.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperData.java
@@ -30,7 +30,7 @@
 import android.content.ComponentName;
 import android.graphics.Rect;
 import android.os.RemoteCallbackList;
-import android.util.ArrayMap;
+import android.util.SparseArray;
 
 import java.io.File;
 
@@ -115,7 +115,7 @@
      * A map to keep track of the dimming set by different applications. The key is the calling
      * UID and the value is the dim amount.
      */
-    ArrayMap<Integer, Float> mUidToDimAmount = new ArrayMap<>();
+    SparseArray<Float> mUidToDimAmount = new SparseArray<>();
 
     /**
      * Whether we need to extract the wallpaper colors again to calculate the dark hints
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
new file mode 100644
index 0000000..7923bb2
--- /dev/null
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.wallpaper;
+
+import static android.app.WallpaperManager.FLAG_LOCK;
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.wallpaper.WallpaperDisplayHelper.DisplayData;
+import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER;
+import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER_CROP;
+import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER_INFO;
+import static com.android.server.wallpaper.WallpaperUtils.getWallpaperDir;
+import static com.android.server.wallpaper.WallpaperUtils.makeWallpaperIdLocked;
+
+import android.annotation.Nullable;
+import android.app.WallpaperColors;
+import android.app.backup.WallpaperBackupHelper;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.os.FileUtils;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.Xml;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.JournaledFile;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper for the wallpaper loading / saving / xml parsing
+ * Only meant to be used lock held by WallpaperManagerService
+ * Only meant to be instantiated once by WallpaperManagerService
+ */
+class WallpaperDataParser {
+
+    private static final String TAG = WallpaperDataParser.class.getSimpleName();
+    private static final boolean DEBUG = false;
+    private final ComponentName mImageWallpaper;
+    private final WallpaperDisplayHelper mWallpaperDisplayHelper;
+    private final WallpaperCropper mWallpaperCropper;
+    private final Context mContext;
+
+    // Temporary feature flag. TODO(b/197814683) remove
+    private final boolean mEnableSeparateLockScreenEngine;
+
+    WallpaperDataParser(Context context, WallpaperDisplayHelper wallpaperDisplayHelper,
+            WallpaperCropper wallpaperCropper, boolean enableSeparateLockScreenEngine) {
+        mContext = context;
+        mWallpaperDisplayHelper = wallpaperDisplayHelper;
+        mWallpaperCropper = wallpaperCropper;
+        mImageWallpaper = ComponentName.unflattenFromString(
+                context.getResources().getString(R.string.image_wallpaper_component));
+        mEnableSeparateLockScreenEngine = enableSeparateLockScreenEngine;
+    }
+
+    private JournaledFile makeJournaledFile(int userId) {
+        final String base = new File(getWallpaperDir(userId), WALLPAPER_INFO).getAbsolutePath();
+        return new JournaledFile(new File(base), new File(base + ".tmp"));
+    }
+
+    static class WallpaperLoadingResult {
+
+        private final WallpaperData mSystemWallpaperData;
+
+        @Nullable
+        private final WallpaperData mLockWallpaperData;
+
+        private final boolean mSuccess;
+
+        private WallpaperLoadingResult(
+                WallpaperData systemWallpaperData,
+                WallpaperData lockWallpaperData,
+                boolean success) {
+            mSystemWallpaperData = systemWallpaperData;
+            mLockWallpaperData = lockWallpaperData;
+            mSuccess = success;
+        }
+
+        public WallpaperData getSystemWallpaperData() {
+            return mSystemWallpaperData;
+        }
+
+        public WallpaperData getLockWallpaperData() {
+            return mLockWallpaperData;
+        }
+
+        public boolean success() {
+            return mSuccess;
+        }
+    }
+
+    /**
+     * Load the system wallpaper (and the lock wallpaper, if it exists) from disk
+     * @param userId the id of the user for which the wallpaper should be loaded
+     * @param keepDimensionHints if false, parse and set the
+     *                      {@link DisplayData} width and height for the specified userId
+     * @param wallpaper the wallpaper object to reuse to do the modifications.
+     *                      If null, a new object will be created.
+     * @param lockWallpaper the lock wallpaper object to reuse to do the modifications.
+     *                      If null, a new object will be created.
+     * @return a {@link WallpaperLoadingResult} object containing the wallpaper data.
+     *                      This object will contain the {@code wallpaper} and
+     *                      {@code lockWallpaper} provided as parameters, if they are not null.
+     */
+    public WallpaperLoadingResult loadSettingsLocked(int userId, boolean keepDimensionHints,
+            WallpaperData wallpaper, WallpaperData lockWallpaper) {
+        JournaledFile journal = makeJournaledFile(userId);
+        FileInputStream stream = null;
+        File file = journal.chooseForRead();
+
+        boolean migrateFromOld = wallpaper == null;
+
+        // don't reuse the wallpaper objects in the new version
+        if (mEnableSeparateLockScreenEngine) {
+            wallpaper = null;
+            lockWallpaper = null;
+        }
+
+        if (wallpaper == null) {
+            // Do this once per boot
+            if (migrateFromOld) migrateFromOld();
+            wallpaper = new WallpaperData(userId, FLAG_SYSTEM);
+            wallpaper.allowBackup = true;
+            if (!wallpaper.cropExists()) {
+                if (wallpaper.sourceExists()) {
+                    mWallpaperCropper.generateCrop(wallpaper);
+                } else {
+                    Slog.i(TAG, "No static wallpaper imagery; defaults will be shown");
+                }
+            }
+        }
+
+        final DisplayData wpdData = mWallpaperDisplayHelper.getDisplayDataOrCreate(DEFAULT_DISPLAY);
+        boolean success = false;
+
+        try {
+            stream = new FileInputStream(file);
+            TypedXmlPullParser parser = Xml.resolvePullParser(stream);
+
+            int type;
+            do {
+                type = parser.next();
+                if (type == XmlPullParser.START_TAG) {
+                    String tag = parser.getName();
+                    if ("wp".equals(tag)
+                            || ("kwp".equals(tag) && mEnableSeparateLockScreenEngine)) {
+
+                        if ("kwp".equals(tag) && lockWallpaper == null) {
+                            lockWallpaper = new WallpaperData(userId, FLAG_LOCK);
+                        }
+                        WallpaperData wallpaperToParse =
+                                "wp".equals(tag) ? wallpaper : lockWallpaper;
+
+                        parseWallpaperAttributes(parser, wallpaperToParse, keepDimensionHints);
+
+                        String comp = parser.getAttributeValue(null, "component");
+                        wallpaperToParse.nextWallpaperComponent = comp != null
+                                ? ComponentName.unflattenFromString(comp)
+                                : null;
+                        if (wallpaperToParse.nextWallpaperComponent == null
+                                || "android".equals(wallpaperToParse.nextWallpaperComponent
+                                .getPackageName())) {
+                            wallpaperToParse.nextWallpaperComponent = mImageWallpaper;
+                        }
+
+                        if (DEBUG) {
+                            Slog.v(TAG, "mWidth:" + wpdData.mWidth);
+                            Slog.v(TAG, "mHeight:" + wpdData.mHeight);
+                            Slog.v(TAG, "cropRect:" + wallpaper.cropHint);
+                            Slog.v(TAG, "primaryColors:" + wallpaper.primaryColors);
+                            Slog.v(TAG, "mName:" + wallpaper.name);
+                            Slog.v(TAG, "mNextWallpaperComponent:"
+                                    + wallpaper.nextWallpaperComponent);
+                        }
+                    } else if ("kwp".equals(tag)) {
+                        // keyguard-specific wallpaper for this user
+
+                        if (lockWallpaper == null) {
+                            lockWallpaper = new WallpaperData(userId, FLAG_LOCK);
+                        }
+                        parseWallpaperAttributes(parser, lockWallpaper, false);
+                    }
+                }
+            } while (type != XmlPullParser.END_DOCUMENT);
+            success = true;
+        } catch (FileNotFoundException e) {
+            Slog.w(TAG, "no current wallpaper -- first boot?");
+        } catch (NullPointerException e) {
+            Slog.w(TAG, "failed parsing " + file + " " + e);
+        } catch (NumberFormatException e) {
+            Slog.w(TAG, "failed parsing " + file + " " + e);
+        } catch (XmlPullParserException e) {
+            Slog.w(TAG, "failed parsing " + file + " " + e);
+        } catch (IOException e) {
+            Slog.w(TAG, "failed parsing " + file + " " + e);
+        } catch (IndexOutOfBoundsException e) {
+            Slog.w(TAG, "failed parsing " + file + " " + e);
+        }
+        IoUtils.closeQuietly(stream);
+
+        if (!success) {
+            wallpaper.cropHint.set(0, 0, 0, 0);
+            wpdData.mPadding.set(0, 0, 0, 0);
+            wallpaper.name = "";
+            lockWallpaper = null;
+        } else {
+            if (wallpaper.wallpaperId <= 0) {
+                wallpaper.wallpaperId = makeWallpaperIdLocked();
+                if (DEBUG) {
+                    Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
+                            + "); now " + wallpaper.wallpaperId);
+                }
+            }
+        }
+
+        mWallpaperDisplayHelper.ensureSaneWallpaperDisplaySize(wpdData, DEFAULT_DISPLAY);
+        ensureSaneWallpaperData(wallpaper);
+        if (lockWallpaper != null) {
+            ensureSaneWallpaperData(lockWallpaper);
+            lockWallpaper.mWhich = FLAG_LOCK;
+            wallpaper.mWhich = FLAG_SYSTEM;
+        } else {
+            wallpaper.mWhich = FLAG_SYSTEM | FLAG_LOCK;
+        }
+
+        return new WallpaperLoadingResult(wallpaper, lockWallpaper, success);
+    }
+
+    private void ensureSaneWallpaperData(WallpaperData wallpaper) {
+        // Only overwrite cropHint if the rectangle is invalid.
+        if (wallpaper.cropHint.width() < 0
+                || wallpaper.cropHint.height() < 0) {
+            wallpaper.cropHint.set(0, 0, 0, 0);
+        }
+    }
+
+
+    private void migrateFromOld() {
+        // Pre-N, what existed is the one we're now using as the display crop
+        File preNWallpaper = new File(getWallpaperDir(0), WALLPAPER_CROP);
+        // In the very-long-ago, imagery lived with the settings app
+        File originalWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
+        File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
+
+        // Migrations from earlier wallpaper image storage schemas
+        if (preNWallpaper.exists()) {
+            if (!newWallpaper.exists()) {
+                // we've got the 'wallpaper' crop file but not the nominal source image,
+                // so do the simple "just take everything" straight copy of legacy data
+                if (DEBUG) {
+                    Slog.i(TAG, "Migrating wallpaper schema");
+                }
+                FileUtils.copyFile(preNWallpaper, newWallpaper);
+            } // else we're in the usual modern case: both source & crop exist
+        } else if (originalWallpaper.exists()) {
+            // VERY old schema; make sure things exist and are in the right place
+            if (DEBUG) {
+                Slog.i(TAG, "Migrating antique wallpaper schema");
+            }
+            File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
+            if (oldInfo.exists()) {
+                File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
+                oldInfo.renameTo(newInfo);
+            }
+
+            FileUtils.copyFile(originalWallpaper, preNWallpaper);
+            originalWallpaper.renameTo(newWallpaper);
+        }
+    }
+
+    @VisibleForTesting
+    void parseWallpaperAttributes(TypedXmlPullParser parser, WallpaperData wallpaper,
+            boolean keepDimensionHints) throws XmlPullParserException {
+        final int id = parser.getAttributeInt(null, "id", -1);
+        if (id != -1) {
+            wallpaper.wallpaperId = id;
+            if (id > WallpaperUtils.getCurrentWallpaperId()) {
+                WallpaperUtils.setCurrentWallpaperId(id);
+            }
+        } else {
+            wallpaper.wallpaperId = makeWallpaperIdLocked();
+        }
+
+        final DisplayData wpData = mWallpaperDisplayHelper.getDisplayDataOrCreate(DEFAULT_DISPLAY);
+
+        if (!keepDimensionHints) {
+            wpData.mWidth = parser.getAttributeInt(null, "width");
+            wpData.mHeight = parser.getAttributeInt(null, "height");
+        }
+        wallpaper.cropHint.left = getAttributeInt(parser, "cropLeft", 0);
+        wallpaper.cropHint.top = getAttributeInt(parser, "cropTop", 0);
+        wallpaper.cropHint.right = getAttributeInt(parser, "cropRight", 0);
+        wallpaper.cropHint.bottom = getAttributeInt(parser, "cropBottom", 0);
+        wpData.mPadding.left = getAttributeInt(parser, "paddingLeft", 0);
+        wpData.mPadding.top = getAttributeInt(parser, "paddingTop", 0);
+        wpData.mPadding.right = getAttributeInt(parser, "paddingRight", 0);
+        wpData.mPadding.bottom = getAttributeInt(parser, "paddingBottom", 0);
+        wallpaper.mWallpaperDimAmount = getAttributeFloat(parser, "dimAmount", 0f);
+        int dimAmountsCount = getAttributeInt(parser, "dimAmountsCount", 0);
+        if (dimAmountsCount > 0) {
+            SparseArray<Float> allDimAmounts = new SparseArray<>(dimAmountsCount);
+            for (int i = 0; i < dimAmountsCount; i++) {
+                int uid = getAttributeInt(parser, "dimUID" + i, 0);
+                float dimValue = getAttributeFloat(parser, "dimValue" + i, 0f);
+                allDimAmounts.put(uid, dimValue);
+            }
+            wallpaper.mUidToDimAmount = allDimAmounts;
+        }
+        int colorsCount = getAttributeInt(parser, "colorsCount", 0);
+        int allColorsCount =  getAttributeInt(parser, "allColorsCount", 0);
+        if (allColorsCount > 0) {
+            Map<Integer, Integer> allColors = new HashMap<>(allColorsCount);
+            for (int i = 0; i < allColorsCount; i++) {
+                int colorInt = getAttributeInt(parser, "allColorsValue" + i, 0);
+                int population = getAttributeInt(parser, "allColorsPopulation" + i, 0);
+                allColors.put(colorInt, population);
+            }
+            int colorHints = getAttributeInt(parser, "colorHints", 0);
+            wallpaper.primaryColors = new WallpaperColors(allColors, colorHints);
+        } else if (colorsCount > 0) {
+            Color primary = null, secondary = null, tertiary = null;
+            for (int i = 0; i < colorsCount; i++) {
+                Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
+                if (i == 0) {
+                    primary = color;
+                } else if (i == 1) {
+                    secondary = color;
+                } else if (i == 2) {
+                    tertiary = color;
+                } else {
+                    break;
+                }
+            }
+            int colorHints = getAttributeInt(parser, "colorHints", 0);
+            wallpaper.primaryColors = new WallpaperColors(primary, secondary, tertiary, colorHints);
+        }
+        wallpaper.name = parser.getAttributeValue(null, "name");
+        wallpaper.allowBackup = parser.getAttributeBoolean(null, "backup", false);
+    }
+
+    private int getAttributeInt(TypedXmlPullParser parser, String name, int defValue) {
+        return parser.getAttributeInt(null, name, defValue);
+    }
+
+    private float getAttributeFloat(TypedXmlPullParser parser, String name, float defValue) {
+        return parser.getAttributeFloat(null, name, defValue);
+    }
+
+    void saveSettingsLocked(int userId, WallpaperData wallpaper, WallpaperData lockWallpaper) {
+        JournaledFile journal = makeJournaledFile(userId);
+        FileOutputStream fstream = null;
+        try {
+            fstream = new FileOutputStream(journal.chooseForWrite(), false);
+            TypedXmlSerializer out = Xml.resolveSerializer(fstream);
+            out.startDocument(null, true);
+
+            if (wallpaper != null) {
+                writeWallpaperAttributes(out, "wp", wallpaper);
+            }
+
+            if (lockWallpaper != null) {
+                writeWallpaperAttributes(out, "kwp", lockWallpaper);
+            }
+
+            out.endDocument();
+
+            fstream.flush();
+            FileUtils.sync(fstream);
+            fstream.close();
+            journal.commit();
+        } catch (IOException e) {
+            IoUtils.closeQuietly(fstream);
+            journal.rollback();
+        }
+    }
+
+    @VisibleForTesting
+    void writeWallpaperAttributes(TypedXmlSerializer out, String tag, WallpaperData wallpaper)
+            throws IllegalArgumentException, IllegalStateException, IOException {
+        if (DEBUG) {
+            Slog.v(TAG, "writeWallpaperAttributes id=" + wallpaper.wallpaperId);
+        }
+        final DisplayData wpdData = mWallpaperDisplayHelper.getDisplayDataOrCreate(DEFAULT_DISPLAY);
+        out.startTag(null, tag);
+        out.attributeInt(null, "id", wallpaper.wallpaperId);
+        out.attributeInt(null, "width", wpdData.mWidth);
+        out.attributeInt(null, "height", wpdData.mHeight);
+
+        out.attributeInt(null, "cropLeft", wallpaper.cropHint.left);
+        out.attributeInt(null, "cropTop", wallpaper.cropHint.top);
+        out.attributeInt(null, "cropRight", wallpaper.cropHint.right);
+        out.attributeInt(null, "cropBottom", wallpaper.cropHint.bottom);
+
+        if (wpdData.mPadding.left != 0) {
+            out.attributeInt(null, "paddingLeft", wpdData.mPadding.left);
+        }
+        if (wpdData.mPadding.top != 0) {
+            out.attributeInt(null, "paddingTop", wpdData.mPadding.top);
+        }
+        if (wpdData.mPadding.right != 0) {
+            out.attributeInt(null, "paddingRight", wpdData.mPadding.right);
+        }
+        if (wpdData.mPadding.bottom != 0) {
+            out.attributeInt(null, "paddingBottom", wpdData.mPadding.bottom);
+        }
+
+        out.attributeFloat(null, "dimAmount", wallpaper.mWallpaperDimAmount);
+        int dimAmountsCount = wallpaper.mUidToDimAmount.size();
+        out.attributeInt(null, "dimAmountsCount", dimAmountsCount);
+        if (dimAmountsCount > 0) {
+            int index = 0;
+            for (int i = 0; i < wallpaper.mUidToDimAmount.size(); i++) {
+                out.attributeInt(null, "dimUID" + index, wallpaper.mUidToDimAmount.keyAt(i));
+                out.attributeFloat(null, "dimValue" + index, wallpaper.mUidToDimAmount.valueAt(i));
+                index++;
+            }
+        }
+
+        if (wallpaper.primaryColors != null) {
+            int colorsCount = wallpaper.primaryColors.getMainColors().size();
+            out.attributeInt(null, "colorsCount", colorsCount);
+            if (colorsCount > 0) {
+                for (int i = 0; i < colorsCount; i++) {
+                    final Color wc = wallpaper.primaryColors.getMainColors().get(i);
+                    out.attributeInt(null, "colorValue" + i, wc.toArgb());
+                }
+            }
+
+            int allColorsCount = wallpaper.primaryColors.getAllColors().size();
+            out.attributeInt(null, "allColorsCount", allColorsCount);
+            if (allColorsCount > 0) {
+                int index = 0;
+                for (Map.Entry<Integer, Integer> entry : wallpaper.primaryColors.getAllColors()
+                        .entrySet()) {
+                    out.attributeInt(null, "allColorsValue" + index, entry.getKey());
+                    out.attributeInt(null, "allColorsPopulation" + index, entry.getValue());
+                    index++;
+                }
+            }
+
+            out.attributeInt(null, "colorHints", wallpaper.primaryColors.getColorHints());
+        }
+
+        out.attribute(null, "name", wallpaper.name);
+        if (wallpaper.wallpaperComponent != null
+                && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) {
+            out.attribute(null, "component",
+                    wallpaper.wallpaperComponent.flattenToShortString());
+        }
+
+        if (wallpaper.allowBackup) {
+            out.attributeBoolean(null, "backup", true);
+        }
+
+        out.endTag(null, tag);
+    }
+
+    // Restore the named resource bitmap to both source + crop files
+    boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
+        if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
+            String resName = wallpaper.name.substring(4);
+
+            String pkg = null;
+            int colon = resName.indexOf(':');
+            if (colon > 0) {
+                pkg = resName.substring(0, colon);
+            }
+
+            String ident = null;
+            int slash = resName.lastIndexOf('/');
+            if (slash > 0) {
+                ident = resName.substring(slash + 1);
+            }
+
+            String type = null;
+            if (colon > 0 && slash > 0 && (slash - colon) > 1) {
+                type = resName.substring(colon + 1, slash);
+            }
+
+            if (pkg != null && ident != null && type != null) {
+                int resId = -1;
+                InputStream res = null;
+                FileOutputStream fos = null;
+                FileOutputStream cos = null;
+                try {
+                    Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
+                    Resources r = c.getResources();
+                    resId = r.getIdentifier(resName, null, null);
+                    if (resId == 0) {
+                        Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
+                                + " ident=" + ident);
+                        return false;
+                    }
+
+                    res = r.openRawResource(resId);
+                    if (wallpaper.wallpaperFile.exists()) {
+                        wallpaper.wallpaperFile.delete();
+                        wallpaper.cropFile.delete();
+                    }
+                    fos = new FileOutputStream(wallpaper.wallpaperFile);
+                    cos = new FileOutputStream(wallpaper.cropFile);
+
+                    byte[] buffer = new byte[32768];
+                    int amt;
+                    while ((amt = res.read(buffer)) > 0) {
+                        fos.write(buffer, 0, amt);
+                        cos.write(buffer, 0, amt);
+                    }
+                    // mWallpaperObserver will notice the close and send the change broadcast
+
+                    Slog.v(TAG, "Restored wallpaper: " + resName);
+                    return true;
+                } catch (PackageManager.NameNotFoundException e) {
+                    Slog.e(TAG, "Package name " + pkg + " not found");
+                } catch (Resources.NotFoundException e) {
+                    Slog.e(TAG, "Resource not found: " + resId);
+                } catch (IOException e) {
+                    Slog.e(TAG, "IOException while restoring wallpaper ", e);
+                } finally {
+                    IoUtils.closeQuietly(res);
+                    if (fos != null) {
+                        FileUtils.sync(fos);
+                    }
+                    if (cos != null) {
+                        FileUtils.sync(cos);
+                    }
+                    IoUtils.closeQuietly(fos);
+                    IoUtils.closeQuietly(cos);
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDisplayHelper.java b/services/core/java/com/android/server/wallpaper/WallpaperDisplayHelper.java
index f02ee66..3f02266 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDisplayHelper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDisplayHelper.java
@@ -30,6 +30,7 @@
 import com.android.server.wm.WindowManagerInternal;
 
 import java.util.function.Consumer;
+
 /**
  * Internal class used to store all the display data relevant to the wallpapers
  */
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 5fd57e3..d7829c8 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -35,7 +35,6 @@
 import static com.android.server.wallpaper.WallpaperUtils.RECORD_FILE;
 import static com.android.server.wallpaper.WallpaperUtils.RECORD_LOCK_FILE;
 import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER;
-import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER_CROP;
 import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER_INFO;
 import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER_LOCK_ORIG;
 import static com.android.server.wallpaper.WallpaperUtils.getWallpaperDir;
@@ -56,7 +55,6 @@
 import android.app.WallpaperManager;
 import android.app.WallpaperManager.SetWallpaperFlags;
 import android.app.admin.DevicePolicyManagerInternal;
-import android.app.backup.WallpaperBackupHelper;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -70,10 +68,8 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
-import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.hardware.display.DisplayManager;
@@ -101,12 +97,10 @@
 import android.service.wallpaper.WallpaperService;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.util.ArrayMap;
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
-import android.util.Xml;
 import android.view.Display;
 
 import com.android.internal.R;
@@ -114,9 +108,6 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.DumpUtils;
-import com.android.internal.util.JournaledFile;
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -125,22 +116,16 @@
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.WindowManagerInternal;
 
-import libcore.io.IoUtils;
-
-import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -152,7 +137,6 @@
     private static final String TAG = "WallpaperManagerService";
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_LIVE = true;
-    private static final boolean DEBUG_CROP = true;
 
     private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
             new RectF(0, 0, 1, 1);
@@ -849,6 +833,9 @@
     private LocalColorRepository mLocalColorRepo = new LocalColorRepository();
 
     @VisibleForTesting
+    final WallpaperDataParser mWallpaperDataParser;
+
+    @VisibleForTesting
     final WallpaperDisplayHelper mWallpaperDisplayHelper;
     final WallpaperCropper mWallpaperCropper;
 
@@ -1618,6 +1605,8 @@
 
         mEnableSeparateLockScreenEngine = mContext.getResources().getBoolean(
                 R.bool.config_independentLockscreenLiveWallpaper);
+        mWallpaperDataParser = new WallpaperDataParser(mContext, mWallpaperDisplayHelper,
+                mWallpaperCropper, mEnableSeparateLockScreenEngine);
         if (DEBUG) {
             Slog.v(TAG, "Separate lock screen engine enabled: " + mEnableSeparateLockScreenEngine);
         }
@@ -1899,7 +1888,6 @@
                     // bound into place
                     wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
                     final WallpaperData fallback = new WallpaperData(wallpaper.userId, FLAG_LOCK);
-                    ensureSaneWallpaperData(fallback);
                     bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply);
                     mWaitingForUnlock = true;
                 }
@@ -2630,12 +2618,10 @@
      *
      * @param uidToDimAmountMap Map of UIDs to dim amounts
      */
-    private float getHighestDimAmountFromMap(ArrayMap<Integer, Float> uidToDimAmountMap) {
+    private float getHighestDimAmountFromMap(SparseArray<Float> uidToDimAmountMap) {
         float maxDimAmount = 0.0f;
-        for (Map.Entry<Integer, Float> entry : uidToDimAmountMap.entrySet()) {
-            if (entry.getValue() > maxDimAmount) {
-                maxDimAmount = entry.getValue();
-            }
+        for (int i = 0; i < uidToDimAmountMap.size(); i++) {
+            maxDimAmount = Math.max(maxDimAmount, uidToDimAmountMap.valueAt(i));
         }
         return maxDimAmount;
     }
@@ -3168,8 +3154,9 @@
                 }
             }
 
-            final ActivityOptions clientOptions = ActivityOptions.makeBasic();
-            clientOptions.setIgnorePendingIntentCreatorForegroundState(true);
+            final ActivityOptions clientOptions = ActivityOptions.makeBasic()
+                    .setPendingIntentCreatorBackgroundActivityStartMode(
+                            ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED);
             PendingIntent clientIntent = PendingIntent.getActivityAsUser(
                     mContext, 0, Intent.createChooser(
                             new Intent(Intent.ACTION_SET_WALLPAPER),
@@ -3432,169 +3419,14 @@
         }
     }
 
-    private JournaledFile makeJournaledFile(int userId) {
-        final String base = new File(getWallpaperDir(userId), WALLPAPER_INFO).getAbsolutePath();
-        return new JournaledFile(new File(base), new File(base + ".tmp"));
-    }
-
     void saveSettingsLocked(int userId) {
         TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG);
         t.traceBegin("WPMS.saveSettingsLocked-" + userId);
-        JournaledFile journal = makeJournaledFile(userId);
-        FileOutputStream fstream = null;
-        try {
-            fstream = new FileOutputStream(journal.chooseForWrite(), false);
-            TypedXmlSerializer out = Xml.resolveSerializer(fstream);
-            out.startDocument(null, true);
-
-            WallpaperData wallpaper;
-
-            wallpaper = mWallpaperMap.get(userId);
-            if (wallpaper != null) {
-                writeWallpaperAttributes(out, "wp", wallpaper);
-            }
-            wallpaper = mLockWallpaperMap.get(userId);
-            if (wallpaper != null) {
-                writeWallpaperAttributes(out, "kwp", wallpaper);
-            }
-
-            out.endDocument();
-
-            fstream.flush();
-            FileUtils.sync(fstream);
-            fstream.close();
-            journal.commit();
-        } catch (IOException e) {
-            IoUtils.closeQuietly(fstream);
-            journal.rollback();
-        }
+        mWallpaperDataParser.saveSettingsLocked(
+                userId, mWallpaperMap.get(userId), mLockWallpaperMap.get(userId));
         t.traceEnd();
     }
 
-
-    @VisibleForTesting
-    void writeWallpaperAttributes(TypedXmlSerializer out, String tag,
-            WallpaperData wallpaper)
-            throws IllegalArgumentException, IllegalStateException, IOException {
-        if (DEBUG) {
-            Slog.v(TAG, "writeWallpaperAttributes id=" + wallpaper.wallpaperId);
-        }
-        final DisplayData wpdData = mWallpaperDisplayHelper.getDisplayDataOrCreate(DEFAULT_DISPLAY);
-        out.startTag(null, tag);
-        out.attributeInt(null, "id", wallpaper.wallpaperId);
-        out.attributeInt(null, "width", wpdData.mWidth);
-        out.attributeInt(null, "height", wpdData.mHeight);
-
-        out.attributeInt(null, "cropLeft", wallpaper.cropHint.left);
-        out.attributeInt(null, "cropTop", wallpaper.cropHint.top);
-        out.attributeInt(null, "cropRight", wallpaper.cropHint.right);
-        out.attributeInt(null, "cropBottom", wallpaper.cropHint.bottom);
-
-        if (wpdData.mPadding.left != 0) {
-            out.attributeInt(null, "paddingLeft", wpdData.mPadding.left);
-        }
-        if (wpdData.mPadding.top != 0) {
-            out.attributeInt(null, "paddingTop", wpdData.mPadding.top);
-        }
-        if (wpdData.mPadding.right != 0) {
-            out.attributeInt(null, "paddingRight", wpdData.mPadding.right);
-        }
-        if (wpdData.mPadding.bottom != 0) {
-            out.attributeInt(null, "paddingBottom", wpdData.mPadding.bottom);
-        }
-
-        out.attributeFloat(null, "dimAmount", wallpaper.mWallpaperDimAmount);
-        int dimAmountsCount = wallpaper.mUidToDimAmount.size();
-        out.attributeInt(null, "dimAmountsCount", dimAmountsCount);
-        if (dimAmountsCount > 0) {
-            int index = 0;
-            for (Map.Entry<Integer, Float> entry : wallpaper.mUidToDimAmount.entrySet()) {
-                out.attributeInt(null, "dimUID" + index, entry.getKey());
-                out.attributeFloat(null, "dimValue" + index, entry.getValue());
-                index++;
-            }
-        }
-
-        if (wallpaper.primaryColors != null) {
-            int colorsCount = wallpaper.primaryColors.getMainColors().size();
-            out.attributeInt(null, "colorsCount", colorsCount);
-            if (colorsCount > 0) {
-                for (int i = 0; i < colorsCount; i++) {
-                    final Color wc = wallpaper.primaryColors.getMainColors().get(i);
-                    out.attributeInt(null, "colorValue" + i, wc.toArgb());
-                }
-            }
-
-            int allColorsCount = wallpaper.primaryColors.getAllColors().size();
-            out.attributeInt(null, "allColorsCount", allColorsCount);
-            if (allColorsCount > 0) {
-                int index = 0;
-                for (Map.Entry<Integer, Integer> entry : wallpaper.primaryColors.getAllColors()
-                        .entrySet()) {
-                    out.attributeInt(null, "allColorsValue" + index, entry.getKey());
-                    out.attributeInt(null, "allColorsPopulation" + index, entry.getValue());
-                    index++;
-                }
-            }
-
-            out.attributeInt(null, "colorHints", wallpaper.primaryColors.getColorHints());
-        }
-
-        out.attribute(null, "name", wallpaper.name);
-        if (wallpaper.wallpaperComponent != null
-                && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) {
-            out.attribute(null, "component",
-                    wallpaper.wallpaperComponent.flattenToShortString());
-        }
-
-        if (wallpaper.allowBackup) {
-            out.attributeBoolean(null, "backup", true);
-        }
-
-        out.endTag(null, tag);
-    }
-
-    private void migrateFromOld() {
-        // Pre-N, what existed is the one we're now using as the display crop
-        File preNWallpaper = new File(getWallpaperDir(0), WALLPAPER_CROP);
-        // In the very-long-ago, imagery lived with the settings app
-        File originalWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
-        File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
-
-        // Migrations from earlier wallpaper image storage schemas
-        if (preNWallpaper.exists()) {
-            if (!newWallpaper.exists()) {
-                // we've got the 'wallpaper' crop file but not the nominal source image,
-                // so do the simple "just take everything" straight copy of legacy data
-                if (DEBUG) {
-                    Slog.i(TAG, "Migrating wallpaper schema");
-                }
-                FileUtils.copyFile(preNWallpaper, newWallpaper);
-            } // else we're in the usual modern case: both source & crop exist
-        } else if (originalWallpaper.exists()) {
-            // VERY old schema; make sure things exist and are in the right place
-            if (DEBUG) {
-                Slog.i(TAG, "Migrating antique wallpaper schema");
-            }
-            File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
-            if (oldInfo.exists()) {
-                File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
-                oldInfo.renameTo(newInfo);
-            }
-
-            FileUtils.copyFile(originalWallpaper, preNWallpaper);
-            originalWallpaper.renameTo(newWallpaper);
-        }
-    }
-
-    private int getAttributeInt(TypedXmlPullParser parser, String name, int defValue) {
-        return parser.getAttributeInt(null, name, defValue);
-    }
-
-    private float getAttributeFloat(TypedXmlPullParser parser, String name, float defValue) {
-        return parser.getAttributeFloat(null, name, defValue);
-    }
-
     /**
      * Determines and returns the current wallpaper for the given user and destination, creating
      * a valid entry if it does not already exist and adding it to the appropriate wallpaper map.
@@ -3629,14 +3461,12 @@
                 if (which == FLAG_LOCK) {
                     wallpaper = new WallpaperData(userId, FLAG_LOCK);
                     mLockWallpaperMap.put(userId, wallpaper);
-                    ensureSaneWallpaperData(wallpaper);
                 } else {
                     // rationality fallback: we're in bad shape, but establishing a known
                     // valid system+lock WallpaperData will keep us from dying.
                     Slog.wtf(TAG, "Didn't find wallpaper in non-lock case!");
                     wallpaper = new WallpaperData(userId, FLAG_SYSTEM);
                     mWallpaperMap.put(userId, wallpaper);
-                    ensureSaneWallpaperData(wallpaper);
                 }
             }
         }
@@ -3644,114 +3474,17 @@
     }
 
     private void loadSettingsLocked(int userId, boolean keepDimensionHints) {
-        JournaledFile journal = makeJournaledFile(userId);
-        FileInputStream stream = null;
-        File file = journal.chooseForRead();
+        initializeFallbackWallpaper();
+        WallpaperData wallpaperData = mWallpaperMap.get(userId);
+        WallpaperData lockWallpaperData = mLockWallpaperMap.get(userId);
+        WallpaperDataParser.WallpaperLoadingResult result = mWallpaperDataParser.loadSettingsLocked(
+                userId, keepDimensionHints, wallpaperData, lockWallpaperData);
 
-        WallpaperData wallpaper = mWallpaperMap.get(userId);
-        if (wallpaper == null) {
-            // Do this once per boot
-            migrateFromOld();
-
-            wallpaper = new WallpaperData(userId, FLAG_SYSTEM);
-            wallpaper.allowBackup = true;
-            mWallpaperMap.put(userId, wallpaper);
-            if (!wallpaper.cropExists()) {
-                if (wallpaper.sourceExists()) {
-                    mWallpaperCropper.generateCrop(wallpaper);
-                } else {
-                    Slog.i(TAG, "No static wallpaper imagery; defaults will be shown");
-                }
-            }
-            initializeFallbackWallpaper();
-        }
-        boolean success = false;
-        final DisplayData wpdData = mWallpaperDisplayHelper.getDisplayDataOrCreate(DEFAULT_DISPLAY);
-        try {
-            stream = new FileInputStream(file);
-            TypedXmlPullParser parser = Xml.resolvePullParser(stream);
-
-            int type;
-            do {
-                type = parser.next();
-                if (type == XmlPullParser.START_TAG) {
-                    String tag = parser.getName();
-                    if ("wp".equals(tag)) {
-                        // Common to system + lock wallpapers
-                        parseWallpaperAttributes(parser, wallpaper, keepDimensionHints);
-
-                        // A system wallpaper might also be a live wallpaper
-                        String comp = parser.getAttributeValue(null, "component");
-                        wallpaper.nextWallpaperComponent = comp != null
-                                ? ComponentName.unflattenFromString(comp)
-                                : null;
-                        if (wallpaper.nextWallpaperComponent == null
-                                || "android".equals(wallpaper.nextWallpaperComponent
-                                        .getPackageName())) {
-                            wallpaper.nextWallpaperComponent = mImageWallpaper;
-                        }
-
-                        if (DEBUG) {
-                            Slog.v(TAG, "mWidth:" + wpdData.mWidth);
-                            Slog.v(TAG, "mHeight:" + wpdData.mHeight);
-                            Slog.v(TAG, "cropRect:" + wallpaper.cropHint);
-                            Slog.v(TAG, "primaryColors:" + wallpaper.primaryColors);
-                            Slog.v(TAG, "mName:" + wallpaper.name);
-                            Slog.v(TAG, "mNextWallpaperComponent:"
-                                    + wallpaper.nextWallpaperComponent);
-                        }
-                    } else if ("kwp".equals(tag)) {
-                        // keyguard-specific wallpaper for this user
-                        WallpaperData lockWallpaper = mLockWallpaperMap.get(userId);
-                        if (lockWallpaper == null) {
-                            lockWallpaper = new WallpaperData(userId, FLAG_LOCK);
-                            mLockWallpaperMap.put(userId, lockWallpaper);
-                        }
-                        parseWallpaperAttributes(parser, lockWallpaper, false);
-                    }
-                }
-            } while (type != XmlPullParser.END_DOCUMENT);
-            success = true;
-        } catch (FileNotFoundException e) {
-            Slog.w(TAG, "no current wallpaper -- first boot?");
-        } catch (NullPointerException e) {
-            Slog.w(TAG, "failed parsing " + file + " " + e);
-        } catch (NumberFormatException e) {
-            Slog.w(TAG, "failed parsing " + file + " " + e);
-        } catch (XmlPullParserException e) {
-            Slog.w(TAG, "failed parsing " + file + " " + e);
-        } catch (IOException e) {
-            Slog.w(TAG, "failed parsing " + file + " " + e);
-        } catch (IndexOutOfBoundsException e) {
-            Slog.w(TAG, "failed parsing " + file + " " + e);
-        }
-        IoUtils.closeQuietly(stream);
-
-        if (!success) {
-            wallpaper.cropHint.set(0, 0, 0, 0);
-            wpdData.mPadding.set(0, 0, 0, 0);
-            wallpaper.name = "";
-
+        mWallpaperMap.put(userId, result.getSystemWallpaperData());
+        if (result.success()) {
+            mLockWallpaperMap.put(userId, result.getLockWallpaperData());
+        } else {
             mLockWallpaperMap.remove(userId);
-        } else {
-            if (wallpaper.wallpaperId <= 0) {
-                wallpaper.wallpaperId = makeWallpaperIdLocked();
-                if (DEBUG) {
-                    Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
-                            + "); now " + wallpaper.wallpaperId);
-                }
-            }
-        }
-
-        mWallpaperDisplayHelper.ensureSaneWallpaperDisplaySize(wpdData, DEFAULT_DISPLAY);
-        ensureSaneWallpaperData(wallpaper);
-        WallpaperData lockWallpaper = mLockWallpaperMap.get(userId);
-        if (lockWallpaper != null) {
-            ensureSaneWallpaperData(lockWallpaper);
-            lockWallpaper.mWhich = FLAG_LOCK;
-            wallpaper.mWhich = FLAG_SYSTEM;
-        } else {
-            wallpaper.mWhich = FLAG_SYSTEM | FLAG_LOCK;
         }
     }
 
@@ -3766,84 +3499,6 @@
         }
     }
 
-    private void ensureSaneWallpaperData(WallpaperData wallpaper) {
-        // Only overwrite cropHint if the rectangle is invalid.
-        if (wallpaper.cropHint.width() < 0
-                || wallpaper.cropHint.height() < 0) {
-            wallpaper.cropHint.set(0, 0, 0, 0);
-        }
-    }
-
-    @VisibleForTesting
-    void parseWallpaperAttributes(TypedXmlPullParser parser, WallpaperData wallpaper,
-            boolean keepDimensionHints) throws XmlPullParserException {
-        final int id = parser.getAttributeInt(null, "id", -1);
-        if (id != -1) {
-            wallpaper.wallpaperId = id;
-            if (id > WallpaperUtils.getCurrentWallpaperId()) {
-                WallpaperUtils.setCurrentWallpaperId(id);
-            }
-        } else {
-            wallpaper.wallpaperId = makeWallpaperIdLocked();
-        }
-
-        final DisplayData wpData = mWallpaperDisplayHelper.getDisplayDataOrCreate(DEFAULT_DISPLAY);
-
-        if (!keepDimensionHints) {
-            wpData.mWidth = parser.getAttributeInt(null, "width");
-            wpData.mHeight = parser.getAttributeInt(null, "height");
-        }
-        wallpaper.cropHint.left = getAttributeInt(parser, "cropLeft", 0);
-        wallpaper.cropHint.top = getAttributeInt(parser, "cropTop", 0);
-        wallpaper.cropHint.right = getAttributeInt(parser, "cropRight", 0);
-        wallpaper.cropHint.bottom = getAttributeInt(parser, "cropBottom", 0);
-        wpData.mPadding.left = getAttributeInt(parser, "paddingLeft", 0);
-        wpData.mPadding.top = getAttributeInt(parser, "paddingTop", 0);
-        wpData.mPadding.right = getAttributeInt(parser, "paddingRight", 0);
-        wpData.mPadding.bottom = getAttributeInt(parser, "paddingBottom", 0);
-        wallpaper.mWallpaperDimAmount = getAttributeFloat(parser, "dimAmount", 0f);
-        int dimAmountsCount = getAttributeInt(parser, "dimAmountsCount", 0);
-        if (dimAmountsCount > 0) {
-            ArrayMap<Integer, Float> allDimAmounts = new ArrayMap<>(dimAmountsCount);
-            for (int i = 0; i < dimAmountsCount; i++) {
-                int uid = getAttributeInt(parser, "dimUID" + i, 0);
-                float dimValue = getAttributeFloat(parser, "dimValue" + i, 0f);
-                allDimAmounts.put(uid, dimValue);
-            }
-            wallpaper.mUidToDimAmount = allDimAmounts;
-        }
-        int colorsCount = getAttributeInt(parser, "colorsCount", 0);
-        int allColorsCount =  getAttributeInt(parser, "allColorsCount", 0);
-        if (allColorsCount > 0) {
-            Map<Integer, Integer> allColors = new HashMap<>(allColorsCount);
-            for (int i = 0; i < allColorsCount; i++) {
-                int colorInt = getAttributeInt(parser, "allColorsValue" + i, 0);
-                int population = getAttributeInt(parser, "allColorsPopulation" + i, 0);
-                allColors.put(colorInt, population);
-            }
-            int colorHints = getAttributeInt(parser, "colorHints", 0);
-            wallpaper.primaryColors = new WallpaperColors(allColors, colorHints);
-        } else if (colorsCount > 0) {
-            Color primary = null, secondary = null, tertiary = null;
-            for (int i = 0; i < colorsCount; i++) {
-                Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
-                if (i == 0) {
-                    primary = color;
-                } else if (i == 1) {
-                    secondary = color;
-                } else if (i == 2) {
-                    tertiary = color;
-                } else {
-                    break;
-                }
-            }
-            int colorHints = getAttributeInt(parser, "colorHints", 0);
-            wallpaper.primaryColors = new WallpaperColors(primary, secondary, tertiary, colorHints);
-        }
-        wallpaper.name = parser.getAttributeValue(null, "name");
-        wallpaper.allowBackup = parser.getAttributeBoolean(null, "backup", false);
-    }
-
     // Called by SystemBackupAgent after files are restored to disk.
     public void settingsRestored() {
         // Verify caller is the system
@@ -3878,7 +3533,7 @@
                     success = true;
                 } else {
                     if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
-                    success = restoreNamedResourceLocked(wallpaper);
+                    success = mWallpaperDataParser.restoreNamedResourceLocked(wallpaper);
                 }
                 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success
                         + " id=" + wallpaper.wallpaperId);
@@ -3901,83 +3556,6 @@
         }
     }
 
-    // Restore the named resource bitmap to both source + crop files
-    private boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
-        if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
-            String resName = wallpaper.name.substring(4);
-
-            String pkg = null;
-            int colon = resName.indexOf(':');
-            if (colon > 0) {
-                pkg = resName.substring(0, colon);
-            }
-
-            String ident = null;
-            int slash = resName.lastIndexOf('/');
-            if (slash > 0) {
-                ident = resName.substring(slash+1);
-            }
-
-            String type = null;
-            if (colon > 0 && slash > 0 && (slash-colon) > 1) {
-                type = resName.substring(colon+1, slash);
-            }
-
-            if (pkg != null && ident != null && type != null) {
-                int resId = -1;
-                InputStream res = null;
-                FileOutputStream fos = null;
-                FileOutputStream cos = null;
-                try {
-                    Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
-                    Resources r = c.getResources();
-                    resId = r.getIdentifier(resName, null, null);
-                    if (resId == 0) {
-                        Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
-                                + " ident=" + ident);
-                        return false;
-                    }
-
-                    res = r.openRawResource(resId);
-                    if (wallpaper.wallpaperFile.exists()) {
-                        wallpaper.wallpaperFile.delete();
-                        wallpaper.cropFile.delete();
-                    }
-                    fos = new FileOutputStream(wallpaper.wallpaperFile);
-                    cos = new FileOutputStream(wallpaper.cropFile);
-
-                    byte[] buffer = new byte[32768];
-                    int amt;
-                    while ((amt=res.read(buffer)) > 0) {
-                        fos.write(buffer, 0, amt);
-                        cos.write(buffer, 0, amt);
-                    }
-                    // mWallpaperObserver will notice the close and send the change broadcast
-
-                    Slog.v(TAG, "Restored wallpaper: " + resName);
-                    return true;
-                } catch (NameNotFoundException e) {
-                    Slog.e(TAG, "Package name " + pkg + " not found");
-                } catch (Resources.NotFoundException e) {
-                    Slog.e(TAG, "Resource not found: " + resId);
-                } catch (IOException e) {
-                    Slog.e(TAG, "IOException while restoring wallpaper ", e);
-                } finally {
-                    IoUtils.closeQuietly(res);
-                    if (fos != null) {
-                        FileUtils.sync(fos);
-                    }
-                    if (cos != null) {
-                        FileUtils.sync(cos);
-                    }
-                    IoUtils.closeQuietly(fos);
-                    IoUtils.closeQuietly(cos);
-                }
-            }
-        }
-        return false;
-    }
-
     @Override // Binder call
     public void onShellCommand(FileDescriptor in, FileDescriptor out,
             FileDescriptor err, String[] args, ShellCallback callback,
@@ -3986,6 +3564,56 @@
                 args, callback, resultReceiver);
     }
 
+    private void dumpWallpaper(WallpaperData wallpaper, PrintWriter pw) {
+        pw.print(" User "); pw.print(wallpaper.userId);
+        pw.print(": id="); pw.print(wallpaper.wallpaperId);
+        pw.print(": mWhich="); pw.print(wallpaper.mWhich);
+        pw.print(": mSystemWasBoth="); pw.println(wallpaper.mSystemWasBoth);
+        pw.println(" Display state:");
+        mWallpaperDisplayHelper.forEachDisplayData(wpSize -> {
+            pw.print("  displayId=");
+            pw.println(wpSize.mDisplayId);
+            pw.print("  mWidth=");
+            pw.print(wpSize.mWidth);
+            pw.print("  mHeight=");
+            pw.println(wpSize.mHeight);
+            pw.print("  mPadding="); pw.println(wpSize.mPadding);
+        });
+        pw.print("  mCropHint="); pw.println(wallpaper.cropHint);
+        pw.print("  mName=");  pw.println(wallpaper.name);
+        pw.print("  mAllowBackup="); pw.println(wallpaper.allowBackup);
+        pw.print("  mWallpaperComponent="); pw.println(wallpaper.wallpaperComponent);
+        pw.print("  mWallpaperDimAmount="); pw.println(wallpaper.mWallpaperDimAmount);
+        pw.print("  isColorExtracted="); pw.println(wallpaper.mIsColorExtractedFromDim);
+        pw.println("  mUidToDimAmount:");
+        for (int j = 0; j < wallpaper.mUidToDimAmount.size(); j++) {
+            pw.print("    UID="); pw.print(wallpaper.mUidToDimAmount.keyAt(j));
+            pw.print(" dimAmount="); pw.println(wallpaper.mUidToDimAmount.valueAt(j));
+        }
+        if (wallpaper.connection != null) {
+            WallpaperConnection conn = wallpaper.connection;
+            pw.print("  Wallpaper connection ");
+            pw.print(conn);
+            pw.println(":");
+            if (conn.mInfo != null) {
+                pw.print("    mInfo.component=");
+                pw.println(conn.mInfo.getComponent());
+            }
+            conn.forEachDisplayConnector(connector -> {
+                pw.print("     mDisplayId=");
+                pw.println(connector.mDisplayId);
+                pw.print("     mToken=");
+                pw.println(connector.mToken);
+                pw.print("     mEngine=");
+                pw.println(connector.mEngine);
+            });
+            pw.print("    mService=");
+            pw.println(conn.mService);
+            pw.print("    mLastDiedTime=");
+            pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
+        }
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
@@ -3996,90 +3624,15 @@
         synchronized (mLock) {
             pw.println("System wallpaper state:");
             for (int i = 0; i < mWallpaperMap.size(); i++) {
-                WallpaperData wallpaper = mWallpaperMap.valueAt(i);
-                pw.print(" User "); pw.print(wallpaper.userId);
-                pw.print(": id="); pw.println(wallpaper.wallpaperId);
-                pw.println(" Display state:");
-                mWallpaperDisplayHelper.forEachDisplayData(wpSize -> {
-                    pw.print("  displayId=");
-                    pw.println(wpSize.mDisplayId);
-                    pw.print("  mWidth=");
-                    pw.print(wpSize.mWidth);
-                    pw.print("  mHeight=");
-                    pw.println(wpSize.mHeight);
-                    pw.print("  mPadding="); pw.println(wpSize.mPadding);
-                });
-                pw.print("  mCropHint="); pw.println(wallpaper.cropHint);
-                pw.print("  mName=");  pw.println(wallpaper.name);
-                pw.print("  mAllowBackup="); pw.println(wallpaper.allowBackup);
-                pw.print("  mWallpaperComponent="); pw.println(wallpaper.wallpaperComponent);
-                pw.print("  mWallpaperDimAmount="); pw.println(wallpaper.mWallpaperDimAmount);
-                pw.print("  isColorExtracted="); pw.println(wallpaper.mIsColorExtractedFromDim);
-                pw.println("  mUidToDimAmount:");
-                for (Map.Entry<Integer, Float> entry : wallpaper.mUidToDimAmount.entrySet()) {
-                    pw.print("    UID="); pw.print(entry.getKey());
-                    pw.print(" dimAmount="); pw.println(entry.getValue());
-                }
-                if (wallpaper.connection != null) {
-                    WallpaperConnection conn = wallpaper.connection;
-                    pw.print("  Wallpaper connection ");
-                    pw.print(conn);
-                    pw.println(":");
-                    if (conn.mInfo != null) {
-                        pw.print("    mInfo.component=");
-                        pw.println(conn.mInfo.getComponent());
-                    }
-                    conn.forEachDisplayConnector(connector -> {
-                        pw.print("     mDisplayId=");
-                        pw.println(connector.mDisplayId);
-                        pw.print("     mToken=");
-                        pw.println(connector.mToken);
-                        pw.print("     mEngine=");
-                        pw.println(connector.mEngine);
-                    });
-                    pw.print("    mService=");
-                    pw.println(conn.mService);
-                    pw.print("    mLastDiedTime=");
-                    pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
-                }
+                dumpWallpaper(mWallpaperMap.valueAt(i), pw);
             }
             pw.println("Lock wallpaper state:");
             for (int i = 0; i < mLockWallpaperMap.size(); i++) {
-                WallpaperData wallpaper = mLockWallpaperMap.valueAt(i);
-                pw.print(" User "); pw.print(wallpaper.userId);
-                pw.print(": id="); pw.println(wallpaper.wallpaperId);
-                pw.print("  mCropHint="); pw.println(wallpaper.cropHint);
-                pw.print("  mName=");  pw.println(wallpaper.name);
-                pw.print("  mAllowBackup="); pw.println(wallpaper.allowBackup);
-                pw.print("  mWallpaperDimAmount="); pw.println(wallpaper.mWallpaperDimAmount);
+                dumpWallpaper(mLockWallpaperMap.valueAt(i), pw);
             }
             pw.println("Fallback wallpaper state:");
-            pw.print(" User "); pw.print(mFallbackWallpaper.userId);
-            pw.print(": id="); pw.println(mFallbackWallpaper.wallpaperId);
-            pw.print("  mCropHint="); pw.println(mFallbackWallpaper.cropHint);
-            pw.print("  mName=");  pw.println(mFallbackWallpaper.name);
-            pw.print("  mAllowBackup="); pw.println(mFallbackWallpaper.allowBackup);
-            if (mFallbackWallpaper.connection != null) {
-                WallpaperConnection conn = mFallbackWallpaper.connection;
-                pw.print("  Fallback Wallpaper connection ");
-                pw.print(conn);
-                pw.println(":");
-                if (conn.mInfo != null) {
-                    pw.print("    mInfo.component=");
-                    pw.println(conn.mInfo.getComponent());
-                }
-                conn.forEachDisplayConnector(connector -> {
-                    pw.print("     mDisplayId=");
-                    pw.println(connector.mDisplayId);
-                    pw.print("     mToken=");
-                    pw.println(connector.mToken);
-                    pw.print("     mEngine=");
-                    pw.println(connector.mEngine);
-                });
-                pw.print("    mService=");
-                pw.println(conn.mService);
-                pw.print("    mLastDiedTime=");
-                pw.println(mFallbackWallpaper.lastDiedTime - SystemClock.uptimeMillis());
+            if (mFallbackWallpaper != null) {
+                dumpWallpaper(mFallbackWallpaper, pw);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 65127e4..a0d8dfb 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -342,6 +342,18 @@
         // Not relevant for the window observer.
     }
 
+    void onWMTransition(int displayId, @WindowManager.TransitionType int type) {
+        if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
+            mAccessibilityTracing.logTrace(TAG + ".onAppWindowTransition",
+                    FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + "; type=" + type);
+        }
+        final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
+        if (displayMagnifier != null) {
+            displayMagnifier.onWMTransition(displayId, type);
+        }
+        // Not relevant for the window observer.
+    }
+
     void onWindowTransition(WindowState windowState, int transition) {
         if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK
                 | FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK)) {
@@ -708,6 +720,28 @@
             }
         }
 
+        void onWMTransition(int displayId, @WindowManager.TransitionType int type) {
+            if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
+                mAccessibilityTracing.logTrace(LOG_TAG + ".onWMTransition",
+                        FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + "; type=" + type);
+            }
+            if (DEBUG_WINDOW_TRANSITIONS) {
+                Slog.i(LOG_TAG, "Window transition: " + WindowManager.transitTypeToString(type)
+                        + " displayId: " + displayId);
+            }
+            final boolean magnifying = mMagnifedViewport.isMagnifying();
+            if (magnifying) {
+                // All opening/closing situations.
+                switch (type) {
+                    case WindowManager.TRANSIT_OPEN:
+                    case WindowManager.TRANSIT_TO_FRONT:
+                    case WindowManager.TRANSIT_CLOSE:
+                    case WindowManager.TRANSIT_TO_BACK:
+                        mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
+                }
+            }
+        }
+
         void onWindowTransition(WindowState windowState, int transition) {
             if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
                 mAccessibilityTracing.logTrace(LOG_TAG + ".onWindowTransition",
@@ -960,7 +994,7 @@
                     // navigation bar insets into nonMagnifiedBounds. It happens when
                     // navigation mode is gestural.
                     if (isUntouchableNavigationBar(windowState, mTempRegion3)) {
-                        final Rect navBarInsets = getNavBarInsets(mDisplayContent);
+                        final Rect navBarInsets = getSystemBarInsetsFrame(windowState);
                         nonMagnifiedBounds.op(navBarInsets, Region.Op.UNION);
                         availableBounds.op(navBarInsets, Region.Op.DIFFERENCE);
                     }
@@ -1425,10 +1459,12 @@
         return touchableRegion.isEmpty();
     }
 
-    static Rect getNavBarInsets(DisplayContent displayContent) {
-        final InsetsSource source = displayContent.getInsetsStateController().getRawInsetsState()
-                .peekSource(ITYPE_NAVIGATION_BAR);
-        return source != null ? source.getFrame() : EMPTY_RECT;
+    static Rect getSystemBarInsetsFrame(WindowState win) {
+        if (win == null) {
+            return EMPTY_RECT;
+        }
+        final InsetsSourceProvider provider = win.getControllableInsetProvider();
+        return provider != null ? provider.getSource().getFrame() : EMPTY_RECT;
     }
 
     /**
@@ -1581,7 +1617,10 @@
                         // region of navigation bar inset because all touch events from this region
                         // would be received by launcher, i.e. this region is a un-touchable one
                         // for the application.
-                        unaccountedSpace.op(getNavBarInsets(dc), unaccountedSpace,
+                        unaccountedSpace.op(
+                                getSystemBarInsetsFrame(
+                                        mService.mWindowMap.get(a11yWindow.getWindowInfo().token)),
+                                unaccountedSpace,
                                 Region.Op.REVERSE_DIFFERENCE);
                     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 4507637..502bfd1 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -781,6 +781,7 @@
                 // the running transition finish.
                 final Transition transition = r != null
                         && r.mTransitionController.inPlayingTransition(r)
+                        && !r.mTransitionController.isCollecting()
                         ? r.mTransitionController.createTransition(TRANSIT_TO_BACK) : null;
                 if (transition != null) {
                     r.mTransitionController.requestStartTransition(transition, null /*startTask */,
@@ -820,6 +821,7 @@
                 // visibility while playing transition, there won't able to commit visibility until
                 // the running transition finish.
                 final Transition transition = r.mTransitionController.inPlayingTransition(r)
+                        && !r.mTransitionController.isCollecting()
                         ? r.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null;
                 if (transition != null) {
                     r.mTransitionController.requestStartTransition(transition, null /*startTask */,
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c289153..81ee9cd 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3919,6 +3919,10 @@
         }
     }
 
+    boolean isFinishing() {
+        return finishing;
+    }
+
     /**
      * This method is to only be called from the client via binder when the activity is destroyed
      * AND finished.
@@ -5111,6 +5115,11 @@
         return mDeferHidingClient;
     }
 
+    boolean canAffectSystemUiFlags() {
+        return task != null && task.canAffectSystemUiFlags() && isVisible()
+                && !inPinnedWindowingMode();
+    }
+
     @Override
     boolean isVisible() {
         // If the activity isn't hidden then it is considered visible and there is no need to check
@@ -8375,7 +8384,13 @@
     }
 
     void recomputeConfiguration() {
-        onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
+        // We check if the current activity is transparent. In that case we need to
+        // recomputeConfiguration of the first opaque activity beneath, to allow a
+        // proper computation of the new bounds.
+        if (!mLetterboxUiController.applyOnOpaqueActivityBelow(
+                ActivityRecord::recomputeConfiguration)) {
+            onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
+        }
     }
 
     boolean isInTransition() {
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index a7883cb..5e066fa 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -605,11 +605,16 @@
         final Task task = r.getTask();
         mService.deferWindowLayout();
         try {
-            r.mTransitionController.requestStartTransition(transition,
-                    task, remoteTransition, null /* displayChange */);
-            r.mTransitionController.collect(task);
-            r.mTransitionController.setTransientLaunch(r,
-                    TaskDisplayArea.getRootTaskAbove(rootTask));
+            final TransitionController controller = r.mTransitionController;
+            if (controller.getTransitionPlayer() != null) {
+                controller.requestStartTransition(transition, task, remoteTransition,
+                        null /* displayChange */);
+                controller.collect(task);
+                controller.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask));
+            } else {
+                // The transition player might be died when executing the queued transition.
+                transition.abort();
+            }
             task.moveToFront("startExistingRecents");
             task.mInResumeTopActivity = true;
             task.resumeTopActivity(null /* prev */, options, true /* deferPause */);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 50eb356..c37a3d7 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1033,10 +1033,33 @@
             return err;
         }
 
-        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
-                requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
-                request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
-                resultRootTask);
+        boolean abort;
+        try {
+            abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
+                    requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
+                    request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
+                    resultRootTask);
+        } catch (SecurityException e) {
+            // Return activity not found for the explicit intent if the caller can't see the target
+            // to prevent the disclosure of package existence.
+            final Intent originalIntent = request.ephemeralIntent;
+            if (originalIntent != null && (originalIntent.getComponent() != null
+                    || originalIntent.getPackage() != null)) {
+                final String targetPackageName = originalIntent.getComponent() != null
+                        ? originalIntent.getComponent().getPackageName()
+                        : originalIntent.getPackage();
+                if (mService.getPackageManagerInternalLocked()
+                        .filterAppAccess(targetPackageName, callingUid, userId)) {
+                    if (resultRecord != null) {
+                        resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
+                                RESULT_CANCELED, null /* data */, null /* dataGrants */);
+                    }
+                    SafeActivityOptions.abort(options);
+                    return ActivityManager.START_CLASS_NOT_FOUND;
+                }
+            }
+            throw e;
+        }
         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                 callingPid, resolvedType, aInfo.applicationInfo);
         abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2f82167..e8a0386 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1027,7 +1027,7 @@
         synchronized (mGlobalLock) {
             mWindowManager = wm;
             mRootWindowContainer = wm.mRoot;
-            mWindowOrganizerController.setWindowManager(wm);
+            mWindowOrganizerController.mTransitionController.setWindowManager(wm);
             mTempConfig.setToDefaults();
             mTempConfig.setLocales(LocaleList.getDefault());
             mConfigurationSeq = mTempConfig.seq = 1;
@@ -4748,16 +4748,27 @@
         updateResumedAppTrace(r);
         mLastResumedActivity = r;
 
-        final boolean changed = r.mDisplayContent.setFocusedApp(r);
-        if (changed) {
-            mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
-                    true /*updateInputWindows*/);
-        }
-        if (prevTask == null || task != prevTask) {
-            if (prevTask != null) {
-                mTaskChangeNotificationController.notifyTaskFocusChanged(prevTask.mTaskId, false);
+        // Don't take focus when transient launching. We don't want the app to know anything
+        // until we've committed to the gesture. The focus will be transferred at the end of
+        // the transition (if the transient launch is committed) or early if explicitly requested
+        // via `setFocused*`.
+        if (!getTransitionController().isTransientCollect(r)) {
+            final Task prevFocusTask = r.mDisplayContent.mFocusedApp != null
+                    ? r.mDisplayContent.mFocusedApp.getTask() : null;
+            final boolean changed = r.mDisplayContent.setFocusedApp(r);
+            if (changed) {
+                mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
+                        true /*updateInputWindows*/);
             }
-            mTaskChangeNotificationController.notifyTaskFocusChanged(task.mTaskId, true);
+            if (task != prevFocusTask) {
+                if (prevFocusTask != null) {
+                    mTaskChangeNotificationController.notifyTaskFocusChanged(
+                            prevFocusTask.mTaskId, false);
+                }
+                mTaskChangeNotificationController.notifyTaskFocusChanged(task.mTaskId, true);
+            }
+        }
+        if (task != prevTask) {
             mTaskSupervisor.mRecentTasks.add(task);
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 0f1f51f..2869133 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1161,6 +1161,11 @@
             return false;
         }
 
+        if ((displayContent.mDisplay.getFlags() & Display.FLAG_REAR) != 0) {
+            Slog.w(TAG, "Launch on display check: activity launch is not allowed on rear display");
+            return false;
+        }
+
         // Check if the caller has enough privileges to embed activities and launch to private
         // displays.
         final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
@@ -2053,7 +2058,7 @@
         // Stop any activities that are scheduled to do so but have been waiting for the transition
         // animation to finish.
         ArrayList<ActivityRecord> readyToStopActivities = null;
-        for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
+        for (int i = 0; i < mStoppingActivities.size(); i++) {
             final ActivityRecord s = mStoppingActivities.get(i);
             final boolean animating = s.isInTransition();
             ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
@@ -2074,6 +2079,7 @@
                 readyToStopActivities.add(s);
 
                 mStoppingActivities.remove(i);
+                i--;
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 7c0d658..bbe7a33 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -81,6 +81,10 @@
                     Slog.e(TAG_WM, "Unknown app appToken:" + applicationHandle.name
                             + ". Dropping notifyNoFocusedWindowAnr request");
                     return;
+                } else if (activity.mAppStopped) {
+                    Slog.d(TAG_WM, "App is in stopped state:" + applicationHandle.name
+                            + ". Dropping notifyNoFocusedWindowAnr request");
+                    return;
                 }
 
                 // App is unresponsive, but we are actively trying to give focus to a window.
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index cc71155..bc5f67b 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -19,7 +19,6 @@
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
 import static android.view.RemoteAnimationTarget.MODE_OPENING;
-import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -28,12 +27,12 @@
 import static com.android.server.wm.BackNavigationProto.ANIMATION_IN_PROGRESS;
 import static com.android.server.wm.BackNavigationProto.LAST_BACK_TYPE;
 import static com.android.server.wm.BackNavigationProto.SHOW_WALLPAPER;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteCallback;
@@ -45,6 +44,7 @@
 import android.view.IWindowFocusObserver;
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
+import android.view.WindowInsets;
 import android.window.BackAnimationAdapter;
 import android.window.BackNavigationInfo;
 import android.window.IBackAnimationFinishedCallback;
@@ -54,8 +54,11 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.LocalServices;
+import com.android.server.wm.utils.InsetUtils;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.function.Consumer;
 
 /**
  * Controller to handle actions related to the back gesture on the server side.
@@ -69,7 +72,7 @@
     private boolean mShowWallpaper;
     private Runnable mPendingAnimation;
 
-    private final AnimationTargets mAnimationTargets = new AnimationTargets();
+    private AnimationHandler mAnimationHandler;
     private final ArrayList<WindowContainer> mTmpOpenApps = new ArrayList<>();
     private final ArrayList<WindowContainer> mTmpCloseApps = new ArrayList<>();
 
@@ -233,7 +236,6 @@
                 return infoBuilder.build();
             }
 
-            mBackAnimationInProgress = true;
             // We don't have an application callback, let's find the destination of the back gesture
             // The search logic should align with ActivityClientController#finishActivity
             prevActivity = currentTask.topRunningActivity(currentActivity.token, INVALID_TASK_ID);
@@ -314,8 +316,17 @@
             }
 
             if (prepareAnimation) {
-                prepareAnimationIfNeeded(currentTask, prevTask, prevActivity,
-                        removedWindowContainer, backType, adapter);
+                mPendingAnimation = mAnimationHandler.scheduleAnimation(backType, adapter,
+                        currentTask, prevTask, currentActivity, prevActivity);
+                prepareAnimation = mPendingAnimation != null;
+                mBackAnimationInProgress = prepareAnimation;
+                if (prepareAnimation) {
+                    mWindowManagerService.mWindowPlacerLocked.requestTraversal();
+                    if (mShowWallpaper) {
+                        currentTask.getDisplayContent().mWallpaperController
+                                .adjustWallpaperWindows();
+                    }
+                }
             }
             infoBuilder.setPrepareRemoteAnimation(prepareAnimation);
         } // Release wm Lock
@@ -333,7 +344,7 @@
     }
 
     boolean isWaitBackTransition() {
-        return mAnimationTargets.mComposed && mAnimationTargets.mWaitTransition;
+        return mAnimationHandler.mComposed && mAnimationHandler.mWaitTransition;
     }
 
     boolean isKeyguardOccluded(WindowState focusWindow) {
@@ -359,18 +370,19 @@
         boolean result = false;
         // Note: TmpOpenApps is empty. Unlike shell transition, the open apps will be removed from
         // mOpeningApps if there is no visibility change.
-        if (mAnimationTargets.containsBackAnimationTargets(mTmpOpenApps, mTmpCloseApps)) {
+        if (mAnimationHandler.containsBackAnimationTargets(mTmpOpenApps, mTmpCloseApps)) {
             // remove close target from close list, open target from open list;
             // but the open target can be in close list.
             for (int i = openApps.size() - 1; i >= 0; --i) {
                 final ActivityRecord ar = openApps.valueAt(i);
-                if (mAnimationTargets.isTarget(ar, true /* open */)) {
+                if (mAnimationHandler.isTarget(ar, true /* open */)) {
                     openApps.removeAt(i);
+                    mAnimationHandler.mOpenTransitionTargetMatch = true;
                 }
             }
             for (int i = closeApps.size() - 1; i >= 0; --i) {
                 final ActivityRecord ar = closeApps.valueAt(i);
-                if (mAnimationTargets.isTarget(ar, false /* open */)) {
+                if (mAnimationHandler.isTarget(ar, false /* open */)) {
                     closeApps.removeAt(i);
                 }
             }
@@ -391,7 +403,7 @@
      *  animations, and shouldn't join next transition.
      */
     boolean containsBackAnimationTargets(Transition transition) {
-        if (!mAnimationTargets.mComposed
+        if (!mAnimationHandler.mComposed
                 || (transition.mType != TRANSIT_CLOSE && transition.mType != TRANSIT_TO_BACK)) {
             return false;
         }
@@ -408,18 +420,22 @@
                 mTmpCloseApps.add(wc);
             }
         }
-        final boolean result = mAnimationTargets.containsBackAnimationTargets(
+        final boolean result = mAnimationHandler.containsBackAnimationTargets(
                 mTmpOpenApps, mTmpCloseApps);
+        if (result) {
+            mAnimationHandler.mOpenTransitionTargetMatch =
+                    mAnimationHandler.containTarget(mTmpOpenApps, true);
+        }
         mTmpOpenApps.clear();
         mTmpCloseApps.clear();
         return result;
     }
 
     boolean isMonitorTransitionTarget(WindowContainer wc) {
-        if (!mAnimationTargets.mComposed || !mAnimationTargets.mWaitTransition) {
+        if (!mAnimationHandler.mComposed || !mAnimationHandler.mWaitTransition) {
             return false;
         }
-        return mAnimationTargets.isTarget(wc, wc.isVisibleRequested() /* open */);
+        return mAnimationHandler.isTarget(wc, wc.isVisibleRequested() /* open */);
     }
 
     /**
@@ -428,60 +444,106 @@
      *                           cleanup together.
      */
     void clearBackAnimations(SurfaceControl.Transaction cleanupTransaction) {
-        mAnimationTargets.clearBackAnimateTarget(cleanupTransaction);
+        mAnimationHandler.clearBackAnimateTarget(cleanupTransaction);
     }
 
     /**
-     * TODO: Animation composer
-     * prepareAnimationIfNeeded will become too complicated in order to support
-     * ActivityRecord/WindowState, using a factory class to create the RemoteAnimationTargets for
-     * different scenario.
+     * Create and handling animations status for an open/close animation targets.
      */
-    private static class AnimationTargets {
-        ActivityRecord mCloseTarget; // Must be activity
-        WindowContainer mOpenTarget; // Can be activity or task if activity was removed
+    private static class AnimationHandler {
+        private final WindowManagerService mWindowManagerService;
+        private BackWindowAnimationAdaptor mCloseAdaptor;
+        private BackWindowAnimationAdaptor mOpenAdaptor;
         private boolean mComposed;
         private boolean mWaitTransition;
         private int mSwitchType = UNKNOWN;
         private SurfaceControl.Transaction mFinishedTransaction;
+        // This will be set before transition happen, to know whether the real opening target
+        // exactly match animating target. When target match, reparent the starting surface to
+        // the opening target like starting window do.
+        private boolean mOpenTransitionTargetMatch;
+        // The starting surface task Id. Used to clear the starting surface if the animation has
+        // request one during animating.
+        private int mRequestedStartingSurfaceTaskId;
+        private SurfaceControl mStartingSurface;
 
+        AnimationHandler(WindowManagerService wms) {
+            mWindowManagerService = wms;
+        }
         private static final int UNKNOWN = 0;
         private static final int TASK_SWITCH = 1;
         private static final int ACTIVITY_SWITCH = 2;
 
-        void reset(@NonNull WindowContainer close, @NonNull WindowContainer open) {
-            clearBackAnimateTarget(null);
-            if (close == null || open == null) {
-                Slog.e(TAG, "reset animation with null target close: "
-                        + close + " open: " + open);
-                return;
-            }
+        private void initiate(WindowContainer close, WindowContainer open)  {
+            WindowContainer closeTarget;
             if (close.asActivityRecord() != null && open.asActivityRecord() != null
                     && (close.asActivityRecord().getTask() == open.asActivityRecord().getTask())) {
                 mSwitchType = ACTIVITY_SWITCH;
-                mCloseTarget = close.asActivityRecord();
+                closeTarget = close.asActivityRecord();
             } else if (close.asTask() != null && open.asTask() != null
                     && close.asTask() != open.asTask()) {
                 mSwitchType = TASK_SWITCH;
-                mCloseTarget = close.asTask().getTopNonFinishingActivity();
+                closeTarget = close.asTask().getTopNonFinishingActivity();
             } else {
                 mSwitchType = UNKNOWN;
                 return;
             }
 
-            mOpenTarget = open;
-            mComposed = false;
-            mWaitTransition = false;
+            mCloseAdaptor = createAdaptor(closeTarget, false /* isOpen */);
+            mOpenAdaptor = createAdaptor(open, true /* isOpen */);
+
+            if (mCloseAdaptor.mAnimationTarget == null || mOpenAdaptor.mAnimationTarget == null) {
+                Slog.w(TAG, "composeNewAnimations fail, skip");
+                clearBackAnimateTarget(null /* cleanupTransaction */);
+            }
         }
 
-        void composeNewAnimations(@NonNull WindowContainer close, @NonNull WindowContainer open) {
-            reset(close, open);
-            if (mSwitchType == UNKNOWN || mComposed || mCloseTarget == mOpenTarget
-                    || mCloseTarget == null || mOpenTarget == null) {
-                return;
+        boolean composeAnimations(@NonNull WindowContainer close, @NonNull WindowContainer open) {
+            clearBackAnimateTarget(null /* cleanupTransaction */);
+            if (close == null || open == null) {
+                Slog.e(TAG, "reset animation with null target close: "
+                        + close + " open: " + open);
+                return false;
+            }
+            initiate(close, open);
+            if (mSwitchType == UNKNOWN) {
+                return false;
             }
             mComposed = true;
             mWaitTransition = false;
+            return true;
+        }
+
+        RemoteAnimationTarget[] getAnimationTargets() {
+            return mComposed ? new RemoteAnimationTarget[] {
+                    mCloseAdaptor.mAnimationTarget, mOpenAdaptor.mAnimationTarget} : null;
+        }
+
+        boolean isSupportWindowlessSurface() {
+            return mWindowManagerService.mAtmService.mTaskOrganizerController
+                    .isSupportWindowlessStartingSurface();
+        }
+
+        void createStartingSurface(TaskSnapshot snapshot) {
+            if (!mComposed) {
+                return;
+            }
+
+            final ActivityRecord topActivity = getTopOpenActivity();
+            if (topActivity == null) {
+                Slog.e(TAG, "createStartingSurface fail, no open activity: " + this);
+                return;
+            }
+            // TODO (b/257857570) draw snapshot by starting surface.
+        }
+
+        private ActivityRecord getTopOpenActivity() {
+            if (mSwitchType == ACTIVITY_SWITCH) {
+                return mOpenAdaptor.mTarget.asActivityRecord();
+            } else if (mSwitchType == TASK_SWITCH) {
+                return mOpenAdaptor.mTarget.asTask().getTopNonFinishingActivity();
+            }
+            return null;
         }
 
         boolean containTarget(ArrayList<WindowContainer> wcs, boolean open) {
@@ -495,13 +557,13 @@
 
         boolean isTarget(WindowContainer wc, boolean open) {
             if (open) {
-                return wc == mOpenTarget || mOpenTarget.hasChild(wc);
+                return wc == mOpenAdaptor.mTarget || mOpenAdaptor.mTarget.hasChild(wc);
             }
             if (mSwitchType == TASK_SWITCH) {
-                return  wc == mCloseTarget
-                        || (wc.asTask() != null && wc.hasChild(mCloseTarget));
+                return  wc == mCloseAdaptor.mTarget
+                        || (wc.asTask() != null && wc.hasChild(mCloseAdaptor.mTarget));
             } else if (mSwitchType == ACTIVITY_SWITCH) {
-                return wc == mCloseTarget;
+                return wc == mCloseAdaptor.mTarget;
             }
             return false;
         }
@@ -519,19 +581,53 @@
                 return;
             }
             final SurfaceControl.Transaction pt = t != null ? t
-                    : mOpenTarget.getPendingTransaction();
+                    : mOpenAdaptor.mTarget.getPendingTransaction();
             if (mFinishedTransaction != null) {
                 pt.merge(mFinishedTransaction);
                 mFinishedTransaction = null;
             }
+            cleanUpWindowlessSurface();
+
+            if (mCloseAdaptor != null) {
+                mCloseAdaptor.mTarget.cancelAnimation();
+                mCloseAdaptor = null;
+            }
+            if (mOpenAdaptor != null) {
+                mOpenAdaptor.mTarget.cancelAnimation();
+                mOpenAdaptor = null;
+            }
+        }
+
+        private void cleanUpWindowlessSurface() {
+            final ActivityRecord ar = getTopOpenActivity();
+            if (ar == null) {
+                Slog.w(TAG, "finishPresentAnimations without top activity: " + this);
+            }
+            final SurfaceControl.Transaction pendingT = ar != null ? ar.getPendingTransaction()
+                    : mOpenAdaptor.mTarget.getPendingTransaction();
+            // ensure open target is visible before cancel animation.
+            mOpenTransitionTargetMatch &= ar != null;
+            if (mOpenTransitionTargetMatch) {
+                pendingT.show(ar.getSurfaceControl());
+            }
+            if (mRequestedStartingSurfaceTaskId != 0) {
+                // If open target match, reparent to open activity
+                if (mStartingSurface != null && mOpenTransitionTargetMatch) {
+                    pendingT.reparent(mStartingSurface, ar.getSurfaceControl());
+                }
+                // remove starting surface.
+                mStartingSurface = null;
+                // TODO (b/257857570) draw snapshot by starting surface.
+                mRequestedStartingSurfaceTaskId = 0;
+            }
         }
 
         void clearBackAnimateTarget(SurfaceControl.Transaction cleanupTransaction) {
             finishPresentAnimations(cleanupTransaction);
-            mCloseTarget = null;
-            mOpenTarget = null;
             mComposed = false;
             mWaitTransition = false;
+            mOpenTransitionTargetMatch = false;
+            mRequestedStartingSurfaceTaskId = 0;
             mSwitchType = UNKNOWN;
             if (mFinishedTransaction != null) {
                 Slog.w(TAG, "Clear back animation, found un-processed finished transaction");
@@ -555,211 +651,284 @@
 
         @Override
         public String toString() {
-            final StringBuilder sb = new StringBuilder(128);
-            sb.append("AnimationTargets{");
-            sb.append(" mOpenTarget= ");
-            sb.append(mOpenTarget);
-            sb.append(" mCloseTarget= ");
-            sb.append(mCloseTarget);
-            sb.append(" mSwitchType= ");
-            sb.append(mSwitchType);
-            sb.append(" mComposed= ");
-            sb.append(mComposed);
-            sb.append(" mWaitTransition= ");
-            sb.append(mWaitTransition);
-            sb.append('}');
-            return sb.toString();
+            return "AnimationTargets{"
+                    + " openTarget= "
+                    + mOpenAdaptor.mTarget
+                    + " closeTarget= "
+                    + mCloseAdaptor.mTarget
+                    + " mSwitchType= "
+                    + mSwitchType
+                    + " mComposed= "
+                    + mComposed
+                    + " mWaitTransition= "
+                    + mWaitTransition
+                    + '}';
         }
-    }
 
-    private void prepareAnimationIfNeeded(Task currentTask,
-            Task prevTask, ActivityRecord prevActivity, WindowContainer<?> removedWindowContainer,
-            int backType, BackAnimationAdapter adapter) {
-        final ArrayList<SurfaceControl> leashes = new ArrayList<>();
-        final SurfaceControl.Transaction startedTransaction = currentTask.getPendingTransaction();
-        final SurfaceControl.Transaction finishedTransaction = new SurfaceControl.Transaction();
-        // Prepare a leash to animate for the departing window
-        final SurfaceControl animLeash = currentTask.makeAnimationLeash()
-                .setName("BackPreview Leash for " + currentTask)
-                .setHidden(false)
-                .build();
-        removedWindowContainer.reparentSurfaceControl(startedTransaction, animLeash);
+        private static BackWindowAnimationAdaptor createAdaptor(
+                WindowContainer target, boolean isOpen) {
+            final BackWindowAnimationAdaptor adaptor =
+                    new BackWindowAnimationAdaptor(target, isOpen);
+            target.startAnimation(target.getPendingTransaction(), adaptor, false /* hidden */,
+                    ANIMATION_TYPE_PREDICT_BACK);
+            return adaptor;
+        }
 
-        final RemoteAnimationTarget topAppTarget = createRemoteAnimationTargetLocked(
-                currentTask, animLeash, MODE_CLOSING);
+        private static class BackWindowAnimationAdaptor implements AnimationAdapter {
+            SurfaceControl mCapturedLeash;
+            private final Rect mBounds = new Rect();
+            private final WindowContainer mTarget;
+            private final boolean mIsOpen;
+            private RemoteAnimationTarget mAnimationTarget;
 
-        // reset leash after animation finished.
-        leashes.add(animLeash);
-        removedWindowContainer.reparentSurfaceControl(finishedTransaction,
-                removedWindowContainer.getParentSurfaceControl());
+            BackWindowAnimationAdaptor(WindowContainer closeTarget, boolean isOpen) {
+                mBounds.set(closeTarget.getBounds());
+                mTarget = closeTarget;
+                mIsOpen = isOpen;
+            }
+            @Override
+            public boolean getShowWallpaper() {
+                return false;
+            }
 
-        // Prepare a leash to animate for the entering window.
-        RemoteAnimationTarget behindAppTarget = null;
-        if (needsScreenshot(backType)) {
-            HardwareBuffer screenshotBuffer = null;
-            Task backTargetTask = prevTask;
-            switch(backType) {
-                case BackNavigationInfo.TYPE_CROSS_TASK:
-                    int prevTaskId = prevTask != null ? prevTask.mTaskId : 0;
-                    int prevUserId = prevTask != null ? prevTask.mUserId : 0;
-                    screenshotBuffer = getTaskSnapshot(prevTaskId, prevUserId);
-                    break;
+            @Override
+            public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
+                    int type, SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
+                mCapturedLeash = animationLeash;
+                createRemoteAnimationTarget(mIsOpen);
+            }
+
+            @Override
+            public void onAnimationCancelled(SurfaceControl animationLeash) {
+                if (mCapturedLeash == animationLeash) {
+                    mCapturedLeash = null;
+                }
+            }
+
+            @Override
+            public long getDurationHint() {
+                return 0;
+            }
+
+            @Override
+            public long getStatusBarTransitionsStartTime() {
+                return 0;
+            }
+
+            @Override
+            public void dump(PrintWriter pw, String prefix) {
+                pw.print(prefix + "BackWindowAnimationAdaptor mCapturedLeash=");
+                pw.print(mCapturedLeash);
+                pw.println();
+            }
+
+            @Override
+            public void dumpDebug(ProtoOutputStream proto) {
+
+            }
+
+            RemoteAnimationTarget createRemoteAnimationTarget(boolean isOpen) {
+                if (mAnimationTarget != null) {
+                    return mAnimationTarget;
+                }
+                Task t = mTarget.asTask();
+                final ActivityRecord r = t != null ? t.getTopNonFinishingActivity()
+                        : mTarget.asActivityRecord();
+                if (t == null && r != null) {
+                    t = r.getTask();
+                }
+                if (t == null || r == null) {
+                    Slog.e(TAG, "createRemoteAnimationTarget fail " + mTarget);
+                    return null;
+                }
+                final WindowState mainWindow = r.findMainWindow();
+                Rect insets;
+                if (mainWindow != null) {
+                    insets = mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets(
+                            mBounds, WindowInsets.Type.systemBars(),
+                            false /* ignoreVisibility */).toRect();
+                    InsetUtils.addInsets(insets, mainWindow.mActivityRecord.getLetterboxInsets());
+                } else {
+                    insets = new Rect();
+                }
+                final int mode = isOpen ? MODE_OPENING : MODE_CLOSING;
+                mAnimationTarget = new RemoteAnimationTarget(t.mTaskId, mode, mCapturedLeash,
+                        !r.fillsParent(), new Rect(),
+                        insets, r.getPrefixOrderIndex(), new Point(mBounds.left, mBounds.top),
+                        mBounds, mBounds, t.getWindowConfiguration(),
+                        true /* isNotInRecents */, null, null, t.getTaskInfo(),
+                        r.checkEnterPictureInPictureAppOpsState());
+                return mAnimationTarget;
+            }
+        }
+
+        Runnable scheduleAnimation(int backType, BackAnimationAdapter adapter,
+                Task currentTask, Task previousTask, ActivityRecord currentActivity,
+                ActivityRecord previousActivity) {
+            switch (backType) {
+                case BackNavigationInfo.TYPE_RETURN_TO_HOME:
+                    return new ScheduleAnimationBuilder(backType, adapter)
+                            .setIsLaunchBehind(true)
+                            .setComposeTarget(currentTask, previousTask)
+                            .build();
                 case BackNavigationInfo.TYPE_CROSS_ACTIVITY:
-                    if (prevActivity != null && prevActivity.mActivityComponent != null) {
-                        screenshotBuffer = getActivitySnapshot(currentTask, prevActivity);
+                    return new ScheduleAnimationBuilder(backType, adapter)
+                            .setComposeTarget(currentActivity, previousActivity)
+                            .setOpeningSnapshot(getActivitySnapshot(previousActivity)).build();
+                case BackNavigationInfo.TYPE_CROSS_TASK:
+                    return new ScheduleAnimationBuilder(backType, adapter)
+                            .setComposeTarget(currentTask, previousTask)
+                            .setOpeningSnapshot(getTaskSnapshot(previousTask)).build();
+            }
+            return null;
+        }
+
+        private class ScheduleAnimationBuilder {
+            final int mType;
+            final BackAnimationAdapter mBackAnimationAdapter;
+            WindowContainer mCloseTarget;
+            WindowContainer mOpenTarget;
+            TaskSnapshot mOpenSnapshot;
+            boolean mIsLaunchBehind;
+
+            ScheduleAnimationBuilder(int type, BackAnimationAdapter backAnimationAdapter) {
+                mType = type;
+                mBackAnimationAdapter = backAnimationAdapter;
+            }
+
+            ScheduleAnimationBuilder setComposeTarget(WindowContainer close, WindowContainer open) {
+                mCloseTarget = close;
+                mOpenTarget = open;
+                return this;
+            }
+
+            ScheduleAnimationBuilder setOpeningSnapshot(TaskSnapshot snapshot) {
+                mOpenSnapshot = snapshot;
+                return this;
+            }
+
+            ScheduleAnimationBuilder setIsLaunchBehind(boolean launchBehind) {
+                mIsLaunchBehind = launchBehind;
+                return this;
+            }
+
+            Runnable build() {
+                if (mOpenTarget == null || mCloseTarget == null) {
+                    return null;
+                }
+                final boolean shouldLaunchBehind = mIsLaunchBehind || !isSupportWindowlessSurface();
+                final ActivityRecord launchBehindActivity = !shouldLaunchBehind ? null
+                        : mOpenTarget.asTask() != null
+                                ? mOpenTarget.asTask().getTopNonFinishingActivity()
+                                : mOpenTarget.asActivityRecord() != null
+                                        ? mOpenTarget.asActivityRecord() : null;
+                if (shouldLaunchBehind && launchBehindActivity == null) {
+                    Slog.e(TAG, "No opening activity");
+                    return null;
+                }
+
+                if (!composeAnimations(mCloseTarget, mOpenTarget)) {
+                    return null;
+                }
+                if (launchBehindActivity != null) {
+                    setLaunchBehind(launchBehindActivity);
+                } else {
+                    createStartingSurface(mOpenSnapshot);
+                }
+
+                final IBackAnimationFinishedCallback callback = makeAnimationFinishedCallback(
+                        launchBehindActivity != null ? triggerBack -> {
+                            if (!triggerBack) {
+                                restoreLaunchBehind(launchBehindActivity);
+                            }
+                        } : null,
+                        mCloseTarget);
+                final RemoteAnimationTarget[] targets = getAnimationTargets();
+
+                return () -> {
+                    try {
+                        mBackAnimationAdapter.getRunner().onAnimationStart(mType,
+                                targets, null, null, callback);
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
                     }
-                    backTargetTask = currentTask;
-                    break;
+                };
             }
 
-            // Find a screenshot of the previous activity if we actually have an animation
-            SurfaceControl animationLeashParent = removedWindowContainer.getAnimationLeashParent();
-            if (screenshotBuffer != null) {
-                final SurfaceControl screenshotSurface = new SurfaceControl.Builder()
-                        .setName("BackPreview Screenshot for " + prevActivity)
-                        .setHidden(false)
-                        .setParent(animationLeashParent)
-                        .setBLASTLayer()
-                        .build();
-                startedTransaction.setBuffer(screenshotSurface, screenshotBuffer);
-
-                // The Animation leash needs to be above the screenshot surface, but the animation
-                // leash needs to be added before to be in the synchronized block.
-                startedTransaction.setLayer(topAppTarget.leash, 1);
-
-                behindAppTarget =
-                        createRemoteAnimationTargetLocked(
-                                backTargetTask, screenshotSurface, MODE_OPENING);
-
-                // reset leash after animation finished.
-                leashes.add(screenshotSurface);
-            }
-        } else if (prevTask != null && prevActivity != null) {
-            // Make previous task show from behind by marking its top activity as visible
-            // and launch-behind to bump its visibility for the duration of the back gesture.
-            setLaunchBehind(prevActivity);
-
-            final SurfaceControl leash = prevActivity.makeAnimationLeash()
-                    .setName("BackPreview Leash for " + prevActivity)
-                    .setHidden(false)
-                    .build();
-            prevActivity.reparentSurfaceControl(startedTransaction, leash);
-            behindAppTarget = createRemoteAnimationTargetLocked(
-                    prevTask, leash, MODE_OPENING);
-
-            // reset leash after animation finished.
-            leashes.add(leash);
-            prevActivity.reparentSurfaceControl(finishedTransaction,
-                    prevActivity.getParentSurfaceControl());
-        }
-
-        if (mShowWallpaper) {
-            currentTask.getDisplayContent().mWallpaperController.adjustWallpaperWindows();
-            // TODO(b/241808055): If the current animation need to show wallpaper and animate the
-            //  wallpaper, start the wallpaper animation to collect wallpaper target and deliver it
-            //  to the back animation controller.
-        }
-
-        final RemoteAnimationTarget[] targets = (behindAppTarget == null)
-                ? new RemoteAnimationTarget[] {topAppTarget}
-                : new RemoteAnimationTarget[] {topAppTarget, behindAppTarget};
-
-        final ActivityRecord finalPrevActivity = prevActivity;
-        final IBackAnimationFinishedCallback callback =
-                new IBackAnimationFinishedCallback.Stub() {
+            private IBackAnimationFinishedCallback makeAnimationFinishedCallback(
+                    Consumer<Boolean> b, WindowContainer closeTarget) {
+                return new IBackAnimationFinishedCallback.Stub() {
                     @Override
                     public void onAnimationFinished(boolean triggerBack) {
-                        for (SurfaceControl sc: leashes) {
-                            finishedTransaction.remove(sc);
-                        }
+                        final SurfaceControl.Transaction finishedTransaction =
+                                new SurfaceControl.Transaction();
                         synchronized (mWindowManagerService.mGlobalLock) {
+                            if (b != null) {
+                                b.accept(triggerBack);
+                            }
                             if (triggerBack) {
                                 final SurfaceControl surfaceControl =
-                                        removedWindowContainer.getSurfaceControl();
+                                        closeTarget.getSurfaceControl();
                                 if (surfaceControl != null && surfaceControl.isValid()) {
-                                    // The animation is finish and start waiting for transition,
-                                    // hide the task surface before it re-parented to avoid flicker.
+                                    // Hide the close target surface when transition start.
                                     finishedTransaction.hide(surfaceControl);
                                 }
-                            } else if (!needsScreenshot(backType)) {
-                                restoreLaunchBehind(finalPrevActivity);
                             }
-                            if (!mAnimationTargets.setFinishTransaction(finishedTransaction)) {
+                            if (!setFinishTransaction(finishedTransaction)) {
                                 finishedTransaction.apply();
                             }
                             if (!triggerBack) {
-                                mAnimationTargets.clearBackAnimateTarget(null);
+                                clearBackAnimateTarget(
+                                        null /* cleanupTransaction */);
                             } else {
-                                mAnimationTargets.mWaitTransition = true;
+                                mWaitTransition = true;
                             }
                         }
                         // TODO Add timeout monitor if transition didn't happen
                     }
                 };
-        if (backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
-            mAnimationTargets.composeNewAnimations(removedWindowContainer, prevActivity);
-        } else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
-                || backType == BackNavigationInfo.TYPE_CROSS_TASK) {
-            mAnimationTargets.composeNewAnimations(removedWindowContainer, prevTask);
-        }
-        scheduleAnimationLocked(backType, targets, adapter, callback);
-    }
-
-    @NonNull
-    private static RemoteAnimationTarget createRemoteAnimationTargetLocked(
-            Task task, SurfaceControl animLeash, int mode) {
-        ActivityRecord topApp = task.getTopRealVisibleActivity();
-        if (topApp == null) {
-            topApp = task.getTopNonFinishingActivity();
-        }
-
-        final WindowState mainWindow = topApp != null
-                ? topApp.findMainWindow()
-                : null;
-        int windowType = INVALID_WINDOW_TYPE;
-        if (mainWindow != null) {
-            windowType = mainWindow.getWindowType();
-        }
-
-        Rect bounds = new Rect(task.getBounds());
-        Rect localBounds = new Rect(bounds);
-        Point tmpPos = new Point();
-        task.getRelativePosition(tmpPos);
-        localBounds.offsetTo(tmpPos.x, tmpPos.y);
-
-        return new RemoteAnimationTarget(
-                task.mTaskId,
-                mode,
-                animLeash,
-                false /* isTransluscent */,
-                new Rect() /* clipRect */,
-                new Rect() /* contentInsets */,
-                task.getPrefixOrderIndex(),
-                tmpPos /* position */,
-                localBounds /* localBounds */,
-                bounds /* screenSpaceBounds */,
-                task.getWindowConfiguration(),
-                true /* isNotInRecent */,
-                null,
-                null,
-                task.getTaskInfo(),
-                false,
-                windowType);
-    }
-
-    @VisibleForTesting
-    void scheduleAnimationLocked(@BackNavigationInfo.BackTargetType int type,
-            RemoteAnimationTarget[] targets, BackAnimationAdapter backAnimationAdapter,
-            IBackAnimationFinishedCallback callback) {
-        mPendingAnimation = () -> {
-            try {
-                backAnimationAdapter.getRunner().onAnimationStart(type,
-                        targets, null, null, callback);
-            } catch (RemoteException e) {
-                e.printStackTrace();
             }
-        };
-        mWindowManagerService.mWindowPlacerLocked.requestTraversal();
+
+            private void setLaunchBehind(ActivityRecord activity) {
+                if (activity == null) {
+                    return;
+                }
+                if (!activity.isVisibleRequested()) {
+                    activity.setVisibility(true);
+                }
+                activity.mLaunchTaskBehind = true;
+
+                // Handle fixed rotation launching app.
+                final DisplayContent dc = activity.mDisplayContent;
+                dc.rotateInDifferentOrientationIfNeeded(activity);
+                if (activity.hasFixedRotationTransform()) {
+                    // Set the record so we can recognize it to continue to update display
+                    // orientation if the previous activity becomes the top later.
+                    dc.setFixedRotationLaunchingApp(activity,
+                            activity.getWindowConfiguration().getRotation());
+                }
+
+                ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+                        "Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity);
+                activity.mTaskSupervisor.mStoppingActivities.remove(activity);
+                activity.getDisplayContent().ensureActivitiesVisible(null /* starting */,
+                        0 /* configChanges */, false /* preserveWindows */, true);
+            }
+            private void restoreLaunchBehind(ActivityRecord activity) {
+                if (activity == null) {
+                    return;
+                }
+
+                activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
+
+                // Restore the launch-behind state.
+                activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
+                activity.mLaunchTaskBehind = false;
+                ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+                        "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
+                        activity);
+            }
+        }
     }
 
     void checkAnimationReady(WallpaperController wallpaperController) {
@@ -796,80 +965,36 @@
         mShowWallpaper = false;
     }
 
-    private HardwareBuffer getActivitySnapshot(@NonNull Task task, ActivityRecord r) {
-        return task.getSnapshotForActivityRecord(r);
-    }
-
-    private HardwareBuffer getTaskSnapshot(int taskId, int userId) {
-        if (mWindowManagerService.mTaskSnapshotController == null) {
+    private static TaskSnapshot getActivitySnapshot(@NonNull ActivityRecord r) {
+        if (!isScreenshotEnabled()) {
             return null;
         }
-        TaskSnapshot snapshot = mWindowManagerService.mTaskSnapshotController.getSnapshot(taskId,
-                userId, true /* restoreFromDisk */, false  /* isLowResolution */);
-        return snapshot != null ? snapshot.getHardwareBuffer() : null;
+        // Check if we have a screenshot of the previous activity, indexed by its
+        // component name.
+        // TODO return TaskSnapshot when feature complete.
+//        final HardwareBuffer hw = r.getTask().getSnapshotForActivityRecord(r);
+        return null;
     }
 
-    private boolean needsScreenshot(int backType) {
+    private static TaskSnapshot getTaskSnapshot(Task task) {
         if (!isScreenshotEnabled()) {
-            return false;
+            return null;
         }
-        switch (backType) {
-            case BackNavigationInfo.TYPE_RETURN_TO_HOME:
-            case BackNavigationInfo.TYPE_DIALOG_CLOSE:
-                return false;
-        }
-        return true;
+        // Don't read from disk!!
+        return  task.mRootWindowContainer.mWindowManager.mTaskSnapshotController.getSnapshot(
+                task.mTaskId, task.mUserId, false /* restoreFromDisk */,
+                false /* isLowResolution */);
     }
 
     void setWindowManager(WindowManagerService wm) {
         mWindowManagerService = wm;
-    }
-
-    private void setLaunchBehind(ActivityRecord activity) {
-        if (activity == null) {
-            return;
-        }
-        if (!activity.isVisibleRequested()) {
-            activity.setVisibility(true);
-        }
-        activity.mLaunchTaskBehind = true;
-
-        // Handle fixed rotation launching app.
-        final DisplayContent dc = activity.mDisplayContent;
-        dc.rotateInDifferentOrientationIfNeeded(activity);
-        if (activity.hasFixedRotationTransform()) {
-            // Set the record so we can recognize it to continue to update display orientation
-            // if the previous activity becomes the top later.
-            dc.setFixedRotationLaunchingApp(activity,
-                    activity.getWindowConfiguration().getRotation());
-        }
-
-        ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
-                "Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity);
-        activity.mTaskSupervisor.mStoppingActivities.remove(activity);
-        activity.getDisplayContent().ensureActivitiesVisible(null /* starting */,
-                0 /* configChanges */, false /* preserveWindows */, true);
-    }
-
-    private void restoreLaunchBehind(ActivityRecord activity) {
-        if (activity == null) {
-            return;
-        }
-
-        activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
-
-        // Restore the launch-behind state.
-        activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
-        activity.mLaunchTaskBehind = false;
-        ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
-                "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
-                activity);
+        mAnimationHandler = new AnimationHandler(wm);
     }
 
     boolean isWallpaperVisible(WindowState w) {
-        return mAnimationTargets.mComposed && mShowWallpaper
+        return mAnimationHandler.mComposed && mShowWallpaper
                 && w.mAttrs.type == TYPE_BASE_APPLICATION && w.mActivityRecord != null
-                && mAnimationTargets.isTarget(w.mActivityRecord, true /* open */);
+                && mAnimationHandler.isTarget(w.mActivityRecord, true /* open */);
     }
 
     // Called from WindowManagerService to write to a protocol buffer output stream.
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index cd79f2e..e1fdeca1 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -32,6 +32,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.BackgroundStartPrivileges;
+import android.app.ComponentOptions;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -166,7 +167,8 @@
         final boolean useCallingUidState =
                 originatingPendingIntent == null
                         || checkedOptions == null
-                        || !checkedOptions.getIgnorePendingIntentCreatorForegroundState();
+                        || checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+                                != ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
         if (useCallingUidState) {
             if (callingUid == Process.ROOT_UID
                     || callingAppId == Process.SYSTEM_UID
diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java
index 7d9a4ec..f5313cb 100644
--- a/services/core/java/com/android/server/wm/DeviceStateController.java
+++ b/services/core/java/com/android/server/wm/DeviceStateController.java
@@ -17,13 +17,13 @@
 package com.android.server.wm;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.devicestate.DeviceStateManager;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
 
 import java.util.ArrayList;
@@ -46,17 +46,26 @@
     private final int[] mFoldedDeviceStates;
     @NonNull
     private final int[] mRearDisplayDeviceStates;
+    private final int mConcurrentDisplayDeviceState;
     @NonNull
     private final int[] mReverseRotationAroundZAxisStates;
+    @GuardedBy("this")
     @NonNull
     private final List<Consumer<DeviceState>> mDeviceStateCallbacks = new ArrayList<>();
 
-    @Nullable
-    private DeviceState mLastDeviceState;
+    private final boolean mMatchBuiltInDisplayOrientationToDefaultDisplay;
+
+    @NonNull
+    private DeviceState mCurrentDeviceState = DeviceState.UNKNOWN;
     private int mCurrentState;
 
     public enum DeviceState {
-        UNKNOWN, OPEN, FOLDED, HALF_FOLDED, REAR,
+        UNKNOWN,
+        OPEN,
+        FOLDED,
+        HALF_FOLDED,
+        REAR,
+        CONCURRENT,
     }
 
     DeviceStateController(@NonNull Context context, @NonNull Handler handler) {
@@ -70,22 +79,23 @@
                 .getIntArray(R.array.config_foldedDeviceStates);
         mRearDisplayDeviceStates = context.getResources()
                 .getIntArray(R.array.config_rearDisplayDeviceStates);
+        mConcurrentDisplayDeviceState = context.getResources()
+                .getInteger(R.integer.config_deviceStateConcurrentRearDisplay);
         mReverseRotationAroundZAxisStates = context.getResources()
                 .getIntArray(R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis);
+        mMatchBuiltInDisplayOrientationToDefaultDisplay = context.getResources()
+                .getBoolean(R.bool
+                        .config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay);
 
         if (mDeviceStateManager != null) {
             mDeviceStateManager.registerCallback(new HandlerExecutor(handler), this);
         }
     }
 
-    void unregisterFromDeviceStateManager() {
-        if (mDeviceStateManager != null) {
-            mDeviceStateManager.unregisterCallback(this);
-        }
-    }
-
     void registerDeviceStateCallback(@NonNull Consumer<DeviceState> callback) {
-        mDeviceStateCallbacks.add(callback);
+        synchronized (this) {
+            mDeviceStateCallbacks.add(callback);
+        }
     }
 
     /**
@@ -95,6 +105,15 @@
         return ArrayUtils.contains(mReverseRotationAroundZAxisStates, mCurrentState);
     }
 
+    /**
+     * @return true if non-default built-in displays should match the default display's rotation.
+     */
+    boolean shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay() {
+        // TODO(b/265991392): This should come from display_settings.xml once it's easier to
+        //  extend with complex configurations.
+        return mMatchBuiltInDisplayOrientationToDefaultDisplay;
+    }
+
     @Override
     public void onStateChanged(int state) {
         mCurrentState = state;
@@ -108,15 +127,19 @@
             deviceState = DeviceState.REAR;
         } else if (ArrayUtils.contains(mOpenDeviceStates, state)) {
             deviceState = DeviceState.OPEN;
+        } else if (state == mConcurrentDisplayDeviceState) {
+            deviceState = DeviceState.CONCURRENT;
         } else {
             deviceState = DeviceState.UNKNOWN;
         }
 
-        if (mLastDeviceState == null || !mLastDeviceState.equals(deviceState)) {
-            mLastDeviceState = deviceState;
+        if (mCurrentDeviceState == null || !mCurrentDeviceState.equals(deviceState)) {
+            mCurrentDeviceState = deviceState;
 
-            for (Consumer<DeviceState> callback : mDeviceStateCallbacks) {
-                callback.accept(mLastDeviceState);
+            synchronized (this) {
+                for (Consumer<DeviceState> callback : mDeviceStateCallbacks) {
+                    callback.accept(mCurrentDeviceState);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index de63191..c2ddb41 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -246,7 +247,22 @@
                 || orientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
             return false;
         }
-        return getIgnoreOrientationRequest();
+        return getIgnoreOrientationRequest()
+                && !shouldRespectOrientationRequestDueToPerAppOverride();
+    }
+
+    private boolean shouldRespectOrientationRequestDueToPerAppOverride() {
+        if (mDisplayContent == null) {
+            return false;
+        }
+        ActivityRecord activity = mDisplayContent.topRunningActivity(
+                /* considerKeyguardState= */ true);
+        return activity != null && activity.getTaskFragment() != null
+                // Checking TaskFragment rather than ActivityRecord to ensure that transition
+                // between fullscreen and PiP would work well. Checking TaskFragment rather than
+                // Task to ensure that Activity Embedding is excluded.
+                && activity.getTaskFragment().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+                && activity.mLetterboxUiController.isOverrideRespectRequestedOrientationEnabled();
     }
 
     boolean getIgnoreOrientationRequest() {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f592f9a..719edee 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -46,9 +46,7 @@
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
 import static android.view.Display.STATE_UNKNOWN;
 import static android.view.Display.isSuspendedState;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
-import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
@@ -57,10 +55,10 @@
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowInsets.Type.systemGestures;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
-import static android.view.WindowManager.LayoutParams;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -120,12 +118,10 @@
 import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
 import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
 import static com.android.server.wm.DisplayContentProto.ID;
-import static com.android.server.wm.DisplayContentProto.IME_INSETS_SOURCE_PROVIDER;
 import static com.android.server.wm.DisplayContentProto.IME_POLICY;
 import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_CONTROL_TARGET;
 import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_INPUT_TARGET;
 import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_TARGET;
-import static com.android.server.wm.DisplayContentProto.INSETS_SOURCE_PROVIDERS;
 import static com.android.server.wm.DisplayContentProto.IS_SLEEPING;
 import static com.android.server.wm.DisplayContentProto.KEEP_CLEAR_AREAS;
 import static com.android.server.wm.DisplayContentProto.MIN_SIZE_OF_RESIZEABLE_TASK_DP;
@@ -176,6 +172,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.ColorSpace;
+import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -223,7 +220,6 @@
 import android.view.InputDevice;
 import android.view.InsetsSource;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.MagnificationSpec;
 import android.view.PrivacyIndicatorBounds;
 import android.view.RemoteAnimationDefinition;
@@ -250,7 +246,6 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
-import com.android.internal.util.function.TriConsumer;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
 import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -293,6 +288,13 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface ForceScalingMode {}
 
+    private static final InsetsState.OnTraverseCallbacks COPY_SOURCE_VISIBILITY =
+            new InsetsState.OnTraverseCallbacks() {
+                public void onIdMatch(InsetsSource source1, InsetsSource source2) {
+                    source1.setVisible(source2.isVisible());
+                }
+            };
+
     final ActivityTaskManagerService mAtmService;
 
     /**
@@ -461,6 +463,8 @@
     private boolean mSystemGestureExclusionWasRestricted = false;
     private final Region mSystemGestureExclusionUnrestricted = new Region();
     private int mSystemGestureExclusionLimit;
+    private final Rect mSystemGestureFrameLeft = new Rect();
+    private final Rect mSystemGestureFrameRight = new Rect();
 
     private Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>();
     private Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>();
@@ -590,7 +594,8 @@
     final FixedRotationTransitionListener mFixedRotationTransitionListener =
             new FixedRotationTransitionListener();
 
-    private final DeviceStateController mDeviceStateController;
+    @VisibleForTesting
+    final DeviceStateController mDeviceStateController;
     private final PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
     final RemoteDisplayChangeController mRemoteDisplayChangeController;
 
@@ -1086,7 +1091,8 @@
      * @param display May not be null.
      * @param root {@link RootWindowContainer}
      */
-    DisplayContent(Display display, RootWindowContainer root) {
+    DisplayContent(Display display, RootWindowContainer root,
+            @NonNull DeviceStateController deviceStateController) {
         super(root.mWindowManager, "DisplayContent", FEATURE_ROOT);
         if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) {
             throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
@@ -1146,11 +1152,11 @@
                     mWmService.mAtmService.getRecentTasks().getInputListener());
         }
 
-        mDeviceStateController = new DeviceStateController(mWmService.mContext, mWmService.mH);
+        mDeviceStateController = deviceStateController;
 
         mDisplayPolicy = new DisplayPolicy(mWmService, this);
         mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address,
-                mDeviceStateController);
+                mDeviceStateController, root.getDisplayRotationCoordinator());
 
         final Consumer<DeviceStateController.DeviceState> deviceStateConsumer =
                 (@NonNull DeviceStateController.DeviceState newFoldState) -> {
@@ -1512,31 +1518,6 @@
         return mDisplayRotation;
     }
 
-    void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
-            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
-        setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
-    }
-
-    /**
-     * Marks a window as providing insets for the rest of the windows in the system.
-     *
-     * @param type The type of inset this window provides.
-     * @param win The window.
-     * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
-     *                      the window should be taken. Only for non-WindowState providers, nav bar
-     *                      and status bar.
-     * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
-     *                               given window types, or {@code null} if the normal frame should
-     *                               be taken.
-     */
-    void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
-            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
-            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
-                    overrideFrameProviders) {
-        mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
-                overrideFrameProviders);
-    }
-
     InsetsStateController getInsetsStateController() {
         return mInsetsStateController;
     }
@@ -1725,7 +1706,7 @@
             }
             // The orientation source may not be the top if it uses SCREEN_ORIENTATION_BEHIND.
             final ActivityRecord topCandidate = !r.isVisibleRequested() ? topRunningActivity() : r;
-            if (handleTopActivityLaunchingInDifferentOrientation(
+            if (topCandidate != null && handleTopActivityLaunchingInDifferentOrientation(
                     topCandidate, r, true /* checkOpening */)) {
                 // Display orientation should be deferred until the top fixed rotation is finished.
                 return false;
@@ -2088,12 +2069,7 @@
                     mFixedRotationLaunchingApp.getFixedRotationTransformInsetsState();
             if (rotatedState != null) {
                 final InsetsState state = mInsetsStateController.getRawInsetsState();
-                for (int i = 0; i < InsetsState.SIZE; i++) {
-                    final InsetsSource source = state.peekSource(i);
-                    if (source != null) {
-                        rotatedState.setSourceVisible(i, source.isVisible());
-                    }
-                }
+                InsetsState.traverse(rotatedState, state, COPY_SOURCE_VISIBILITY);
             }
         }
         forAllWindows(dispatchInsetsChanged, true /* traverseTopToBottom */);
@@ -2163,6 +2139,10 @@
                 w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly);
             }, true /* traverseTopToBottom */);
             mPinnedTaskController.startSeamlessRotationIfNeeded(transaction, oldRotation, rotation);
+            if (!mDisplayRotation.hasSeamlessRotatingWindow()) {
+                // Make sure DisplayRotation#isRotatingSeamlessly() will return false.
+                mDisplayRotation.cancelSeamlessRotation();
+            }
         }
 
         mWmService.mDisplayManagerInternal.performTraversal(transaction);
@@ -3160,22 +3140,6 @@
     }
 
     /**
-     * Returns true if the input point is within an app window.
-     */
-    boolean pointWithinAppWindow(int x, int y) {
-        final int[] targetWindowType = {-1};
-        forAllWindows(w -> {
-            if (w.isOnScreen() && w.isVisible() && w.getFrame().contains(x, y)) {
-                targetWindowType[0] = w.mAttrs.type;
-                return true;
-            }
-            return false;
-        }, true /* traverseTopToBottom */);
-        return FIRST_APPLICATION_WINDOW <= targetWindowType[0]
-                && targetWindowType[0] <= LAST_APPLICATION_WINDOW;
-    }
-
-    /**
      * Find the task whose outside touch area (for resizing) (x, y) falls within.
      * Returns null if the touch doesn't fall into a resizing area.
      */
@@ -3322,7 +3286,7 @@
             mTransitionController.unregisterLegacyListener(mFixedRotationTransitionListener);
             handleAnimatingStoppedAndTransition();
             mWmService.stopFreezingDisplayLocked();
-            mDeviceStateController.unregisterFromDeviceStateManager();
+            mDisplayRotation.removeDefaultDisplayRotationChangedCallback();
             super.removeImmediately();
             if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
             mPointerEventDispatcher.dispose();
@@ -3377,7 +3341,7 @@
 
     int getInputMethodWindowVisibleHeight() {
         final InsetsState state = getInsetsStateController().getRawInsetsState();
-        final InsetsSource imeSource = state.peekSource(ITYPE_IME);
+        final InsetsSource imeSource = state.peekSource(ID_IME);
         if (imeSource == null || !imeSource.isVisible()) {
             return 0;
         }
@@ -3544,14 +3508,7 @@
             mCurrentFocus.dumpDebug(proto, CURRENT_FOCUS, logLevel);
         }
         if (mInsetsStateController != null) {
-            for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
-                final WindowContainerInsetsSourceProvider provider = mInsetsStateController
-                        .peekSourceProvider(type);
-                if (provider != null) {
-                    provider.dumpDebug(proto, type == ITYPE_IME ? IME_INSETS_SOURCE_PROVIDER :
-                            INSETS_SOURCE_PROVIDERS, logLevel);
-                }
-            }
+            mInsetsStateController.dumpDebug(proto, logLevel);
         }
         proto.write(IME_POLICY, getImePolicy());
         for (Rect r : getKeepClearAreas()) {
@@ -3811,6 +3768,17 @@
      */
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,
             int topFocusedDisplayId) {
+        // Don't re-assign focus automatically away from a should-keep-focus app window.
+        // `findFocusedWindow` will always grab the transient-launch app since it is "on top" which
+        // would create a mismatch, so just early-out here.
+        if (mCurrentFocus != null && mTransitionController.shouldKeepFocus(mCurrentFocus)
+                // This is only keeping focus, so don't early-out if the focused-app has been
+                // explicitly changed (eg. via setFocusedTask).
+                && mFocusedApp != null && mCurrentFocus.isDescendantOf(mFocusedApp)
+                && mCurrentFocus.isVisible() && mCurrentFocus.isFocusable()) {
+            ProtoLog.v(WM_DEBUG_FOCUS, "Current transition prevents automatic focus change");
+            return false;
+        }
         WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
         if (mCurrentFocus == newFocus) {
             return false;
@@ -3968,23 +3936,6 @@
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
-    // TODO: This should probably be called any time a visual change is made to the hierarchy like
-    // moving containers or resizing them. Need to investigate the best way to have it automatically
-    // happen so we don't run into issues with programmers forgetting to do it.
-    void layoutAndAssignWindowLayersIfNeeded() {
-        mWmService.mWindowsChanged = true;
-        setLayoutNeeded();
-
-        if (!mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-                false /*updateInputWindows*/)) {
-            assignWindowLayers(false /* setLayoutNeeded */);
-        }
-
-        mInputMonitor.setUpdateInputWindowsNeededLw();
-        mWmService.mWindowPlacerLocked.performSurfacePlacement();
-        mInputMonitor.updateInputWindowsLw(false /*force*/);
-    }
-
     /** Returns true if a leaked surface was destroyed */
     boolean destroyLeakedSurfaces() {
         // Used to indicate that a surface was leaked.
@@ -4038,7 +3989,7 @@
             final int imePid = mInputMethodWindow.mSession.mPid;
             mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
         }
-        mInsetsStateController.getSourceProvider(ITYPE_IME).setWindowContainer(win,
+        mInsetsStateController.getImeSourceProvider().setWindowContainer(win,
                 mDisplayPolicy.getImeSourceFrameProvider(), null);
         computeImeTarget(true /* updateImeTarget */);
         updateImeControlTarget();
@@ -4287,7 +4238,8 @@
         assignWindowLayers(true /* setLayoutNeeded */);
         // 3. The z-order of IME might have been changed. Update the above insets state.
         mInsetsStateController.updateAboveInsetsState(
-                mInsetsStateController.getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
+                mInsetsStateController.getRawInsetsState().isSourceOrDefaultVisible(
+                        ID_IME, ime()));
         // 4. Update the IME control target to apply any inset change and animation.
         // 5. Reparent the IME container surface to either the input target app, or the IME window
         // parent.
@@ -4335,6 +4287,11 @@
             return mImeTarget;
         }
 
+        @VisibleForTesting
+        SurfaceControl getImeScreenshotSurface() {
+            return mImeSurface;
+        }
+
         private SurfaceControl createImeSurface(ScreenCapture.ScreenshotHardwareBuffer b,
                 Transaction t) {
             final HardwareBuffer buffer = b.getHardwareBuffer();
@@ -4444,33 +4401,45 @@
         }
     }
 
-    private void attachAndShowImeScreenshotOnTarget() {
+    private void attachImeScreenshotOnTargetIfNeeded() {
         // No need to attach screenshot if the IME target not exists or screen is off.
         if (!shouldImeAttachedToApp() || !mWmService.mPolicy.isScreenOn()) {
             return;
         }
 
-        final SurfaceControl.Transaction t = getPendingTransaction();
         // Prepare IME screenshot for the target if it allows to attach into.
         if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
-            // Remove the obsoleted IME snapshot first in case the new snapshot happens to
-            // override the current one before the transition finish and the surface never be
-            // removed on the task.
-            removeImeSurfaceImmediately();
-            mImeScreenshot = new ImeScreenshot(
-                    mWmService.mSurfaceControlFactory.apply(null), mImeLayeringTarget);
-            mImeScreenshot.attachAndShow(t);
+            attachImeScreenshotOnTarget(mImeLayeringTarget);
         }
     }
 
+    private void attachImeScreenshotOnTarget(WindowState imeTarget) {
+        final SurfaceControl.Transaction t = getPendingTransaction();
+        // Remove the obsoleted IME snapshot first in case the new snapshot happens to
+        // override the current one before the transition finish and the surface never be
+        // removed on the task.
+        removeImeSurfaceImmediately();
+        mImeScreenshot = new ImeScreenshot(
+                mWmService.mSurfaceControlFactory.apply(null), imeTarget);
+        mImeScreenshot.attachAndShow(t);
+    }
+
     /**
-     * Shows the IME screenshot and attach to the IME target window.
+     * Shows the IME screenshot and attach to the IME layering target window.
      *
      * Used when the IME target window with IME visible is transitioning to the next target.
      * e.g. App transitioning or swiping this the task of the IME target window to recents app.
      */
     void showImeScreenshot() {
-        attachAndShowImeScreenshotOnTarget();
+        attachImeScreenshotOnTargetIfNeeded();
+    }
+
+    /**
+     * Shows the IME screenshot and attach it to the given IME target window.
+     */
+    @VisibleForTesting
+    void showImeScreenshot(WindowState imeTarget) {
+        attachImeScreenshotOnTarget(imeTarget);
     }
 
     /**
@@ -4513,7 +4482,7 @@
             ProtoLog.i(WM_DEBUG_IME, "setInputMethodInputTarget %s", target);
             setImeInputTarget(target);
             mInsetsStateController.updateAboveInsetsState(mInsetsStateController
-                    .getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
+                    .getRawInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
             // Force updating the IME parent when the IME control target has been updated to the
             // remote target but updateImeParent not happen because ImeLayeringTarget and
             // ImeInputTarget are different. Then later updateImeParent would be ignored when there
@@ -4631,24 +4600,9 @@
      */
     @VisibleForTesting
     SurfaceControl computeImeParent() {
-        if (mImeLayeringTarget != null) {
-            // Ensure changing the IME parent when the layering target that may use IME has
-            // became to the input target for preventing IME flickers.
-            // Note that:
-            // 1) For the imeLayeringTarget that may not use IME but requires IME on top
-            // of it (e.g. an overlay window with NOT_FOCUSABLE|ALT_FOCUSABLE_IM flags), we allow
-            // it to re-parent the IME on top the display to keep the legacy behavior.
-            // 2) Even though the starting window won't use IME, the associated activity
-            // behind the starting window may request the input. If so, then we should still hold
-            // the IME parent change until the activity started the input.
-            boolean imeLayeringTargetMayUseIme =
-                    LayoutParams.mayUseInputMethod(mImeLayeringTarget.mAttrs.flags)
-                    || mImeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
-            if (imeLayeringTargetMayUseIme && (mImeInputTarget == null
-                    || mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord())) {
-                // Do not change parent if the window hasn't requested IME.
-                return null;
-            }
+        if (!ImeTargetVisibilityPolicy.isReadyToComputeImeParent(mImeLayeringTarget,
+                mImeInputTarget)) {
+            return null;
         }
         // Attach it to app if the target is part of an app and such app is covering the entire
         // screen. If it's not covering the entire screen the IME might extend beyond the apps
@@ -4933,7 +4887,7 @@
         mInsetsStateController.getImeSourceProvider().checkShowImePostLayout();
 
         mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
-        if (!mWmService.mDisplayFrozen) {
+        if (!inTransition() && !mDisplayRotation.isRotatingSeamlessly()) {
             mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
                     mLastHasContent,
                     mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,
@@ -5708,10 +5662,12 @@
         final Region unhandled = Region.obtain();
         unhandled.set(0, 0, mDisplayFrames.mWidth, mDisplayFrames.mHeight);
 
-        final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES)
-                .getSource().getFrame();
-        final Rect rightEdge = mInsetsStateController.getSourceProvider(ITYPE_RIGHT_GESTURES)
-                .getSource().getFrame();
+        final InsetsState state = mInsetsStateController.getRawInsetsState();
+        final Rect df = state.getDisplayFrame();
+        final Insets gestureInsets = state.calculateInsets(df, systemGestures(),
+                false /* ignoreVisibility */);
+        mSystemGestureFrameLeft.set(df.left, df.top, gestureInsets.left, df.bottom);
+        mSystemGestureFrameRight.set(gestureInsets.right, df.top, df.right, df.bottom);
 
         final Region touchableRegion = Region.obtain();
         final Region local = Region.obtain();
@@ -5755,25 +5711,25 @@
             if (needsGestureExclusionRestrictions(w, false /* ignoreRequest */)) {
 
                 // Processes the region along the left edge.
-                remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
-                        remainingLeftRight[0], w, EXCLUSION_LEFT);
+                remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion,
+                        mSystemGestureFrameLeft, remainingLeftRight[0], w, EXCLUSION_LEFT);
 
                 // Processes the region along the right edge.
-                remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
-                        remainingLeftRight[1], w, EXCLUSION_RIGHT);
+                remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion,
+                        mSystemGestureFrameRight, remainingLeftRight[1], w, EXCLUSION_RIGHT);
 
                 // Adds the middle (unrestricted area)
                 final Region middle = Region.obtain(local);
-                middle.op(leftEdge, Op.DIFFERENCE);
-                middle.op(rightEdge, Op.DIFFERENCE);
+                middle.op(mSystemGestureFrameLeft, Op.DIFFERENCE);
+                middle.op(mSystemGestureFrameRight, Op.DIFFERENCE);
                 outExclusion.op(middle, Op.UNION);
                 middle.recycle();
             } else {
                 boolean loggable = needsGestureExclusionRestrictions(w, true /* ignoreRequest */);
                 if (loggable) {
-                    addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
+                    addToGlobalAndConsumeLimit(local, outExclusion, mSystemGestureFrameLeft,
                             Integer.MAX_VALUE, w, EXCLUSION_LEFT);
-                    addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
+                    addToGlobalAndConsumeLimit(local, outExclusion, mSystemGestureFrameRight,
                             Integer.MAX_VALUE, w, EXCLUSION_RIGHT);
                 }
                 outExclusion.op(local, Op.UNION);
@@ -6861,12 +6817,12 @@
         public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme,
                 @Nullable ImeTracker.Token statsToken) {
             try {
-                ImeTracker.get().onProgress(statsToken,
+                ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SHOW_INSETS);
                 mRemoteInsetsController.showInsets(types, fromIme, statsToken);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to deliver showInsets", e);
-                ImeTracker.get().onFailed(statsToken,
+                ImeTracker.forLogging().onFailed(statsToken,
                         ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SHOW_INSETS);
             }
         }
@@ -6875,12 +6831,12 @@
         public void hideInsets(@InsetsType int types, boolean fromIme,
                 @Nullable ImeTracker.Token statsToken) {
             try {
-                ImeTracker.get().onProgress(statsToken,
+                ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_HIDE_INSETS);
                 mRemoteInsetsController.hideInsets(types, fromIme, statsToken);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed to deliver hideInsets", e);
-                ImeTracker.get().onFailed(statsToken,
+                ImeTracker.forLogging().onFailed(statsToken,
                         ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_HIDE_INSETS);
             }
         }
diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java
index e984456..7f785af 100644
--- a/services/core/java/com/android/server/wm/DisplayFrames.java
+++ b/services/core/java/com/android/server/wm/DisplayFrames.java
@@ -16,10 +16,8 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
-import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
-import static android.view.InsetsState.ITYPE_RIGHT_DISPLAY_CUTOUT;
-import static android.view.InsetsState.ITYPE_TOP_DISPLAY_CUTOUT;
+import static android.view.InsetsSource.createId;
+import static android.view.WindowInsets.Type.displayCutout;
 
 import android.annotation.NonNull;
 import android.graphics.Rect;
@@ -38,6 +36,12 @@
  * @hide
  */
 public class DisplayFrames {
+
+    private static final int ID_DISPLAY_CUTOUT_LEFT = createId(null, 0, displayCutout());
+    private static final int ID_DISPLAY_CUTOUT_TOP = createId(null, 1, displayCutout());
+    private static final int ID_DISPLAY_CUTOUT_RIGHT = createId(null, 2, displayCutout());
+    private static final int ID_DISPLAY_CUTOUT_BOTTOM = createId(null, 3, displayCutout());
+
     public final InsetsState mInsetsState;
 
     /**
@@ -97,28 +101,28 @@
         state.setDisplayShape(displayShape);
         state.getDisplayCutoutSafe(safe);
         if (safe.left > unrestricted.left) {
-            state.getSource(ITYPE_LEFT_DISPLAY_CUTOUT).setFrame(
+            state.getOrCreateSource(ID_DISPLAY_CUTOUT_LEFT, displayCutout()).setFrame(
                     unrestricted.left, unrestricted.top, safe.left, unrestricted.bottom);
         } else {
-            state.removeSource(ITYPE_LEFT_DISPLAY_CUTOUT);
+            state.removeSource(ID_DISPLAY_CUTOUT_LEFT);
         }
         if (safe.top > unrestricted.top) {
-            state.getSource(ITYPE_TOP_DISPLAY_CUTOUT).setFrame(
+            state.getOrCreateSource(ID_DISPLAY_CUTOUT_TOP, displayCutout()).setFrame(
                     unrestricted.left, unrestricted.top, unrestricted.right, safe.top);
         } else {
-            state.removeSource(ITYPE_TOP_DISPLAY_CUTOUT);
+            state.removeSource(ID_DISPLAY_CUTOUT_TOP);
         }
         if (safe.right < unrestricted.right) {
-            state.getSource(ITYPE_RIGHT_DISPLAY_CUTOUT).setFrame(
+            state.getOrCreateSource(ID_DISPLAY_CUTOUT_RIGHT, displayCutout()).setFrame(
                     safe.right, unrestricted.top, unrestricted.right, unrestricted.bottom);
         } else {
-            state.removeSource(ITYPE_RIGHT_DISPLAY_CUTOUT);
+            state.removeSource(ID_DISPLAY_CUTOUT_RIGHT);
         }
         if (safe.bottom < unrestricted.bottom) {
-            state.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame(
+            state.getOrCreateSource(ID_DISPLAY_CUTOUT_BOTTOM, displayCutout()).setFrame(
                     unrestricted.left, safe.bottom, unrestricted.right, unrestricted.bottom);
         } else {
-            state.removeSource(ITYPE_BOTTOM_DISPLAY_CUTOUT);
+            state.removeSource(ID_DISPLAY_CUTOUT_BOTTOM);
         }
         return true;
     }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index d759ff5..3c2832e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -108,7 +108,6 @@
 import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewDebug;
@@ -171,9 +170,8 @@
     /** Use the transit animation in style resource (see {@link #selectAnimation}). */
     static final int ANIMATION_STYLEABLE = 0;
 
-    private static final int[] SHOW_TYPES_FOR_SWIPE = {ITYPE_NAVIGATION_BAR, ITYPE_STATUS_BAR,
-            ITYPE_CLIMATE_BAR, ITYPE_EXTRA_NAVIGATION_BAR};
-    private static final int[] SHOW_TYPES_FOR_PANIC = {ITYPE_NAVIGATION_BAR};
+    private static final int SHOW_TYPES_FOR_SWIPE = Type.statusBars() | Type.navigationBars();
+    private static final int SHOW_TYPES_FOR_PANIC = Type.navigationBars();
 
     private final WindowManagerService mService;
     private final Context mContext;
@@ -251,7 +249,7 @@
 
     private boolean mIsFreeformWindowOverlappingWithNavBar;
 
-    private boolean mLastImmersiveMode;
+    private boolean mIsImmersiveMode;
 
     // The windows we were told about in focusChanged.
     private WindowState mFocusedWindow;
@@ -1077,8 +1075,16 @@
                 } else {
                     overrideProviders = null;
                 }
-                mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
-                        overrideProviders);
+                // TODO (b/234093736): Let InsetsFrameProvider have the following fields:
+                //                     - IBinder owner.
+                //                     - int index.
+                //                     - @InsetsType int type.
+                //                     So we can create the id by using InsetsSource#createId.
+                //                     And we won't need toPublicType anymore.
+                final int id = provider.type;
+                final @InsetsType int type = InsetsState.toPublicType(id);
+                mDisplayContent.getInsetsStateController().getOrCreateSourceProvider(id, type)
+                        .setWindowContainer(win, frameProvider, overrideProviders);
                 mInsetsSourceWindowsExceptIme.add(win);
             }
         }
@@ -1171,10 +1177,17 @@
             mLastFocusedWindow = null;
         }
 
-        final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
-        for (int index = sources.size() - 1; index >= 0; index--) {
-            final @InternalInsetsType int type = sources.keyAt(index);
-            mDisplayContent.setInsetProvider(type, null /* win */, null /* frameProvider */);
+        if (win.hasInsetsSourceProvider()) {
+            final SparseArray<InsetsSourceProvider> providers = win.getInsetsSourceProviders();
+            final InsetsStateController controller = mDisplayContent.getInsetsStateController();
+            for (int index = providers.size() - 1; index >= 0; index--) {
+                final InsetsSourceProvider provider = providers.valueAt(index);
+                provider.setWindowContainer(
+                        null /* windowContainer */,
+                        null /* frameProvider */,
+                        null /* overrideFrameProviders */);
+                controller.removeSourceProvider(provider.getSource().getId());
+            }
         }
         mInsetsSourceWindowsExceptIme.remove(win);
     }
@@ -1243,7 +1256,6 @@
      * some temporal states, but doesn't change the window frames used to show on screen.
      */
     void simulateLayoutDisplay(DisplayFrames displayFrames) {
-        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
         sTmpClientFrames.attachedFrame = null;
         for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
             final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
@@ -1252,11 +1264,10 @@
                     displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
                     UNSPECIFIED_LENGTH, win.getRequestedVisibleTypes(), win.mGlobalScale,
                     sTmpClientFrames);
-            final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
+            final SparseArray<InsetsSourceProvider> providers = win.getInsetsSourceProviders();
             final InsetsState state = displayFrames.mInsetsState;
-            for (int index = sources.size() - 1; index >= 0; index--) {
-                final int type = sources.keyAt(index);
-                state.addSource(controller.getSourceProvider(type).createSimulatedSource(
+            for (int index = providers.size() - 1; index >= 0; index--) {
+                state.addSource(providers.valueAt(index).createSimulatedSource(
                         displayFrames, sTmpClientFrames.frame));
             }
         }
@@ -1359,30 +1370,33 @@
             mIsFreeformWindowOverlappingWithNavBar = true;
         }
 
-        final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
-        final Rect bounds = win.getBounds();
-        for (int index = sources.size() - 1; index >= 0; index--) {
-            final InsetsSource source = sources.valueAt(index);
-            if ((source.getType()
-                    & (Type.systemGestures() | Type.mandatorySystemGestures())) == 0) {
-                continue;
-            }
-            if (mLeftGestureHost != null && mTopGestureHost != null
-                    && mRightGestureHost != null && mBottomGestureHost != null) {
-                continue;
-            }
-            final Insets insets = source.calculateInsets(bounds, false /* ignoreVisibility */);
-            if (mLeftGestureHost == null && insets.left > 0) {
-                mLeftGestureHost = win;
-            }
-            if (mTopGestureHost == null && insets.top > 0) {
-                mTopGestureHost = win;
-            }
-            if (mRightGestureHost == null && insets.right > 0) {
-                mRightGestureHost = win;
-            }
-            if (mBottomGestureHost == null && insets.bottom > 0) {
-                mBottomGestureHost = win;
+        if (win.hasInsetsSourceProvider()) {
+            final SparseArray<InsetsSourceProvider> providers = win.getInsetsSourceProviders();
+            final Rect bounds = win.getBounds();
+            for (int index = providers.size() - 1; index >= 0; index--) {
+                final InsetsSourceProvider provider = providers.valueAt(index);
+                final InsetsSource source = provider.getSource();
+                if ((source.getType()
+                        & (Type.systemGestures() | Type.mandatorySystemGestures())) == 0) {
+                    continue;
+                }
+                if (mLeftGestureHost != null && mTopGestureHost != null
+                        && mRightGestureHost != null && mBottomGestureHost != null) {
+                    continue;
+                }
+                final Insets insets = source.calculateInsets(bounds, false /* ignoreVisibility */);
+                if (mLeftGestureHost == null && insets.left > 0) {
+                    mLeftGestureHost = win;
+                }
+                if (mTopGestureHost == null && insets.top > 0) {
+                    mTopGestureHost = win;
+                }
+                if (mRightGestureHost == null && insets.right > 0) {
+                    mRightGestureHost = win;
+                }
+                if (mBottomGestureHost == null && insets.bottom > 0) {
+                    mBottomGestureHost = win;
+                }
             }
         }
 
@@ -1609,14 +1623,13 @@
     }
 
     /**
-     * @return Whether the top app should hide the statusbar based on the top fullscreen opaque
-     *         window.
+     * @return Whether the top fullscreen app hides the given type of system bar.
      */
-    boolean topAppHidesStatusBar() {
+    boolean topAppHidesSystemBar(@InsetsType int type) {
         if (mTopFullscreenOpaqueWindowState == null || mForceShowSystemBars) {
             return false;
         }
-        return !mTopFullscreenOpaqueWindowState.isRequestedVisible(Type.statusBars());
+        return !mTopFullscreenOpaqueWindowState.isRequestedVisible(type);
     }
 
     /**
@@ -1741,21 +1754,6 @@
     }
 
     /**
-     * Get the Navigation Bar Frame height. This dimension is the height of the navigation bar that
-     * is used for spacing to show additional buttons on the navigation bar (such as the ime
-     * switcher when ime is visible).
-     *
-     * @param rotation specifies rotation to return dimension from
-     * @return navigation bar frame height
-     */
-    private int getNavigationBarFrameHeight(int rotation) {
-        if (mNavigationBar == null) {
-            return 0;
-        }
-        return mNavigationBar.mAttrs.forRotation(rotation).height;
-    }
-
-    /**
      * Return corner radius in pixels that should be used on windows in order to cover the display.
      *
      * The radius is only valid for internal displays, since the corner radius of external displays
@@ -2054,7 +2052,10 @@
                 navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow;
         final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance,
                 navColorWin) | opaqueAppearance;
-        final int behavior = win.mAttrs.insetsFlags.behavior;
+        final WindowState navBarControlWin = topAppHidesSystemBar(Type.navigationBars())
+                ? mTopFullscreenOpaqueWindowState
+                : win;
+        final int behavior = navBarControlWin.mAttrs.insetsFlags.behavior;
         final String focusedApp = win.mAttrs.packageName;
         final boolean isFullscreen = !win.isRequestedVisible(Type.statusBars())
                 || !win.isRequestedVisible(Type.navigationBars());
@@ -2169,7 +2170,7 @@
                 || mDisplayContent.getInsetsPolicy().remoteInsetsControllerControlsSystemBars(win);
         mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
 
-        final boolean topAppHidesStatusBar = topAppHidesStatusBar();
+        final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars());
         if (getStatusBar() != null) {
             final StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
             if (statusBar != null) {
@@ -2186,14 +2187,27 @@
         appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible,
                 freeformRootTaskVisible);
 
+        // Show immersive mode confirmation if needed.
+        final boolean wasImmersiveMode = mIsImmersiveMode;
+        final boolean isImmersiveMode = isImmersiveMode(win);
+        if (wasImmersiveMode != isImmersiveMode) {
+            mIsImmersiveMode = isImmersiveMode;
+            // The immersive confirmation window should be attached to the immersive window root.
+            final RootDisplayArea root = win.getRootDisplayArea();
+            final int rootDisplayAreaId = root == null ? FEATURE_UNDEFINED : root.mFeatureId;
+            mImmersiveModeConfirmation.immersiveModeChangedLw(rootDisplayAreaId, isImmersiveMode,
+                    mService.mPolicy.isUserSetupComplete(),
+                    isNavBarEmpty(disableFlags));
+        }
+
+        // Show transient bars for panic if needed.
         final boolean requestHideNavBar = !win.isRequestedVisible(Type.navigationBars());
         final long now = SystemClock.uptimeMillis();
         final boolean pendingPanic = mPendingPanicGestureUptime != 0
                 && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
         final DisplayPolicy defaultDisplayPolicy =
                 mService.getDefaultDisplayContentLocked().getDisplayPolicy();
-        if (pendingPanic && requestHideNavBar && win != mNotificationShade
-                && getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)
+        if (pendingPanic && requestHideNavBar && isImmersiveMode
                 // TODO (b/111955725): Show keyguard presentation on all external displays
                 && defaultDisplayPolicy.isKeyguardDrawComplete()) {
             // The user performed the panic gesture recently, we're about to hide the bars,
@@ -2205,19 +2219,6 @@
             }
         }
 
-        // update navigation bar
-        boolean oldImmersiveMode = mLastImmersiveMode;
-        boolean newImmersiveMode = isImmersiveMode(win);
-        if (oldImmersiveMode != newImmersiveMode) {
-            mLastImmersiveMode = newImmersiveMode;
-            // The immersive confirmation window should be attached to the immersive window root.
-            final RootDisplayArea root = win.getRootDisplayArea();
-            final int rootDisplayAreaId = root == null ? FEATURE_UNDEFINED : root.mFeatureId;
-            mImmersiveModeConfirmation.immersiveModeChangedLw(rootDisplayAreaId, newImmersiveMode,
-                    mService.mPolicy.isUserSetupComplete(),
-                    isNavBarEmpty(disableFlags));
-        }
-
         return appearance;
     }
 
@@ -2228,23 +2229,40 @@
         return intersectsAnyInsets(win.getFrame(), win.getInsetsState(), type);
     }
 
-    private Rect getBarContentFrameForWindow(WindowState win, @InternalInsetsType int type) {
+    private Rect getBarContentFrameForWindow(WindowState win, @InsetsType int type) {
         final DisplayFrames displayFrames = win.getDisplayFrames(mDisplayContent.mDisplayFrames);
         final InsetsState state = displayFrames.mInsetsState;
-        final Rect tmpRect = new Rect();
-        sTmpDisplayCutoutSafe.set(displayFrames.mDisplayCutoutSafe);
-        if (type == ITYPE_STATUS_BAR) {
-            // The status bar content can extend into regular display cutout insets but not
-            // waterfall insets.
-            sTmpDisplayCutoutSafe.top =
-                    Math.max(state.getDisplayCutout().getWaterfallInsets().top, 0);
+        final Rect df = displayFrames.mUnrestricted;
+        final Rect safe = sTmpDisplayCutoutSafe;
+        final Insets waterfallInsets = state.getDisplayCutout().getWaterfallInsets();
+        final Rect outRect = new Rect();
+        final Rect sourceContent = sTmpRect;
+        safe.set(displayFrames.mDisplayCutoutSafe);
+        for (int i = state.sourceSize() - 1; i >= 0; i--) {
+            final InsetsSource source = state.sourceAt(i);
+            if (source.getType() != type) {
+                continue;
+            }
+            if (type == Type.statusBars()) {
+                safe.set(displayFrames.mDisplayCutoutSafe);
+                final Insets insets = source.calculateInsets(df, true /* ignoreVisibility */);
+                // The status bar content can extend into regular display cutout insets if they are
+                // at the same side, but the content cannot extend into waterfall insets.
+                if (insets.left > 0) {
+                    safe.left = Math.max(df.left + waterfallInsets.left, df.left);
+                } else if (insets.top > 0) {
+                    safe.top = Math.max(df.top + waterfallInsets.top, df.top);
+                } else if (insets.right > 0) {
+                    safe.right = Math.max(df.right - waterfallInsets.right, df.right);
+                } else if (insets.bottom > 0) {
+                    safe.bottom = Math.max(df.bottom - waterfallInsets.bottom, df.bottom);
+                }
+            }
+            sourceContent.set(source.getFrame());
+            sourceContent.intersect(safe);
+            outRect.union(sourceContent);
         }
-        final InsetsSource source = state.peekSource(type);
-        if (source != null) {
-            tmpRect.set(source.getFrame());
-            tmpRect.intersect(sTmpDisplayCutoutSafe);
-        }
-        return tmpRect;
+        return outRect;
     }
 
     /**
@@ -2257,7 +2275,7 @@
      * be drawn over letterboxed activity.
      */
     @VisibleForTesting
-    boolean isFullyTransparentAllowed(WindowState win, @InternalInsetsType int type) {
+    boolean isFullyTransparentAllowed(WindowState win, @InsetsType int type) {
         if (win == null) {
             return true;
         }
@@ -2284,7 +2302,7 @@
         for (int i = mStatusBarBackgroundWindows.size() - 1; i >= 0; i--) {
             final WindowState window = mStatusBarBackgroundWindows.get(i);
             drawBackground &= drawsBarBackground(window);
-            isFullyTransparentAllowed &= isFullyTransparentAllowed(window, ITYPE_STATUS_BAR);
+            isFullyTransparentAllowed &= isFullyTransparentAllowed(window, Type.statusBars());
         }
 
         if (drawBackground) {
@@ -2324,7 +2342,7 @@
             }
         }
 
-        if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, ITYPE_NAVIGATION_BAR)) {
+        if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, Type.navigationBars())) {
             appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
         }
 
@@ -2339,18 +2357,10 @@
         if (win == null) {
             return false;
         }
-        return getNavigationBar() != null
-                && canHideNavigationBar()
-                && getInsetsPolicy().isHidden(ITYPE_NAVIGATION_BAR)
-                && win != getNotificationShade()
-                && !win.isActivityTypeDream();
-    }
-
-    /**
-     * @return whether the navigation bar can be hidden, e.g. the device has a navigation bar
-     */
-    private boolean canHideNavigationBar() {
-        return hasNavigationBar();
+        if (win == getNotificationShade() || win.isActivityTypeDream()) {
+            return false;
+        }
+        return getInsetsPolicy().hasHiddenSources(Type.navigationBars());
     }
 
     private static boolean isNavBarEmpty(int systemUiFlags) {
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 3404279..c081725 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -58,6 +58,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.ArraySet;
+import android.util.RotationUtils;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
@@ -120,6 +121,11 @@
     private FoldController mFoldController;
     @NonNull
     private final DeviceStateController mDeviceStateController;
+    @NonNull
+    private final DisplayRotationCoordinator mDisplayRotationCoordinator;
+    @NonNull
+    @VisibleForTesting
+    final Runnable mDefaultDisplayRotationChangedCallback;
 
     @ScreenOrientation
     private int mCurrentAppOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
@@ -221,17 +227,19 @@
     private boolean mDemoRotationLock;
 
     DisplayRotation(WindowManagerService service, DisplayContent displayContent,
-            DisplayAddress displayAddress, @NonNull DeviceStateController deviceStateController) {
+            DisplayAddress displayAddress, @NonNull DeviceStateController deviceStateController,
+            @NonNull DisplayRotationCoordinator displayRotationCoordinator) {
         this(service, displayContent, displayAddress, displayContent.getDisplayPolicy(),
                 service.mDisplayWindowSettings, service.mContext, service.getWindowManagerLock(),
-                deviceStateController);
+                deviceStateController, displayRotationCoordinator);
     }
 
     @VisibleForTesting
     DisplayRotation(WindowManagerService service, DisplayContent displayContent,
             DisplayAddress displayAddress, DisplayPolicy displayPolicy,
             DisplayWindowSettings displayWindowSettings, Context context, Object lock,
-            @NonNull DeviceStateController deviceStateController) {
+            @NonNull DeviceStateController deviceStateController,
+            @NonNull DisplayRotationCoordinator displayRotationCoordinator) {
         mService = service;
         mDisplayContent = displayContent;
         mDisplayPolicy = displayPolicy;
@@ -252,6 +260,19 @@
         int defaultRotation = readDefaultDisplayRotation(displayAddress);
         mRotation = defaultRotation;
 
+        mDisplayRotationCoordinator = displayRotationCoordinator;
+        if (isDefaultDisplay) {
+            mDisplayRotationCoordinator.setDefaultDisplayDefaultRotation(mRotation);
+        }
+        mDefaultDisplayRotationChangedCallback = this::updateRotationAndSendNewConfigIfChanged;
+
+        if (DisplayRotationCoordinator.isSecondaryInternalDisplay(displayContent)
+                && mDeviceStateController
+                        .shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay()) {
+            mDisplayRotationCoordinator.setDefaultDisplayRotationChangedCallback(
+                    mDefaultDisplayRotationChangedCallback);
+        }
+
         if (isDefaultDisplay) {
             final Handler uiHandler = UiThread.getHandler();
             mOrientationListener =
@@ -494,8 +515,11 @@
             return false;
         }
 
+        @Surface.Rotation
         final int oldRotation = mRotation;
+        @ScreenOrientation
         final int lastOrientation = mLastOrientation;
+        @Surface.Rotation
         int rotation = rotationForOrientation(lastOrientation, oldRotation);
         // Use the saved rotation for tabletop mode, if set.
         if (mFoldController != null && mFoldController.shouldRevertOverriddenRotation()) {
@@ -507,6 +531,14 @@
                     Surface.rotationToString(oldRotation),
                     Surface.rotationToString(prevRotation));
         }
+
+        if (DisplayRotationCoordinator.isSecondaryInternalDisplay(mDisplayContent)
+                && mDeviceStateController
+                        .shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay()) {
+            rotation = RotationUtils.reverseRotationDirectionAroundZAxis(
+                    mDisplayRotationCoordinator.getDefaultDisplayCurrentRotation());
+        }
+
         ProtoLog.v(WM_DEBUG_ORIENTATION,
                 "Computed rotation=%s (%d) for display id=%d based on lastOrientation=%s (%d) and "
                         + "oldRotation=%s (%d)",
@@ -525,6 +557,10 @@
             return false;
         }
 
+        if (isDefaultDisplay) {
+            mDisplayRotationCoordinator.onDefaultDisplayRotationChanged(rotation);
+        }
+
         // Preemptively cancel the running recents animation -- SysUI can't currently handle this
         // case properly since the signals it receives all happen post-change. We do this earlier
         // in the rotation flow, since DisplayContent.updateDisplayOverrideConfigurationLocked seems
@@ -599,7 +635,8 @@
 
         if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
             if (!mDisplayContent.mTransitionController.isCollecting()) {
-                throw new IllegalStateException("Trying to rotate outside a transition");
+                // The remote may be too slow to response before transition timeout.
+                Slog.e(TAG, "Trying to continue rotation outside a transition");
             }
             mDisplayContent.mTransitionController.collect(mDisplayContent);
         }
@@ -1142,17 +1179,12 @@
             return mUserRotation;
         }
 
+        @Surface.Rotation
         int sensorRotation = mOrientationListener != null
                 ? mOrientationListener.getProposedRotation() // may be -1
                 : -1;
         if (mDeviceStateController.shouldReverseRotationDirectionAroundZAxis()) {
-            // Flipping 270 and 90 has the same effect as changing the direction which rotation is
-            // applied.
-            if (sensorRotation == Surface.ROTATION_90) {
-                sensorRotation = Surface.ROTATION_270;
-            } else if (sensorRotation == Surface.ROTATION_270) {
-                sensorRotation = Surface.ROTATION_90;
-            }
+            sensorRotation = RotationUtils.reverseRotationDirectionAroundZAxis(sensorRotation);
         }
         mLastSensorRotation = sensorRotation;
         if (sensorRotation < 0) {
@@ -1167,6 +1199,7 @@
         final boolean deskDockEnablesAccelerometer =
                 mDisplayPolicy.isDeskDockEnablesAccelerometer();
 
+        @Surface.Rotation
         final int preferredRotation;
         if (!isDefaultDisplay) {
             // For secondary displays we ignore things like displays sensors, docking mode and
@@ -1536,6 +1569,12 @@
         return shouldUpdateRotation;
     }
 
+    void removeDefaultDisplayRotationChangedCallback() {
+        if (DisplayRotationCoordinator.isSecondaryInternalDisplay(mDisplayContent)) {
+            mDisplayRotationCoordinator.removeDefaultDisplayRotationChangedCallback();
+        }
+    }
+
     void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + "DisplayRotation");
         pw.println(prefix + "  mCurrentAppOrientation="
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index e04900c..47bdba3 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -250,10 +250,7 @@
         }
         ActivityRecord topActivity = mDisplayContent.topRunningActivity(
                     /* considerKeyguardState= */ true);
-        if (topActivity == null
-                // Checking windowing mode on activity level because we don't want to
-                // show toast in case of activity embedding.
-                || topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+        if (!isTreatmentEnabledForActivity(topActivity)) {
             return;
         }
         showToast(R.string.display_rotation_camera_compat_toast_after_rotation);
@@ -309,21 +306,28 @@
     }
 
     boolean isActivityEligibleForOrientationOverride(@NonNull ActivityRecord activity) {
-        return isTreatmentEnabledForDisplay() && isCameraActiveInFullscreen(activity);
+        return isTreatmentEnabledForDisplay()
+                && isCameraActive(activity, /* mustBeFullscreen */ true);
     }
 
+
     /**
      * Whether camera compat treatment is applicable for the given activity.
      *
      * <p>Conditions that need to be met:
      * <ul>
-     *     <li>{@link #isCameraActiveForPackage} is {@code true} for the activity.
+     *     <li>Camera is active for the package.
      *     <li>The activity is in fullscreen
      *     <li>The activity has fixed orientation but not "locked" or "nosensor" one.
      * </ul>
      */
     boolean isTreatmentEnabledForActivity(@Nullable ActivityRecord activity) {
-        return activity != null && isCameraActiveInFullscreen(activity)
+        return isTreatmentEnabledForActivity(activity, /* mustBeFullscreen */ true);
+    }
+
+    private boolean isTreatmentEnabledForActivity(@Nullable ActivityRecord activity,
+            boolean mustBeFullscreen) {
+        return activity != null && isCameraActive(activity, mustBeFullscreen)
                 && activity.getRequestedConfigurationOrientation() != ORIENTATION_UNDEFINED
                 // "locked" and "nosensor" values are often used by camera apps that can't
                 // handle dynamic changes so we shouldn't force rotate them.
@@ -331,8 +335,10 @@
                 && activity.getOverrideOrientation() != SCREEN_ORIENTATION_LOCKED;
     }
 
-    private boolean isCameraActiveInFullscreen(@NonNull ActivityRecord activity) {
-        return !activity.inMultiWindowMode()
+    private boolean isCameraActive(@NonNull ActivityRecord activity, boolean mustBeFullscreen) {
+        // Checking windowing mode on activity level because we don't want to
+        // apply treatment in case of activity embedding.
+        return (!mustBeFullscreen || !activity.inMultiWindowMode())
                 && mCameraIdPackageBiMap.containsPackageName(activity.packageName)
                 && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
     }
@@ -385,7 +391,8 @@
         }
         // Checking that the whole app is in multi-window mode as we shouldn't show toast
         // for the activity embedding case.
-        if (topActivity.getTask().getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
+        if (topActivity.getTask().getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
+                && isTreatmentEnabledForActivity(topActivity, /* mustBeFullscreen */ false)) {
             showToast(R.string.display_rotation_camera_compat_toast_in_split_screen);
         }
     }
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCoordinator.java b/services/core/java/com/android/server/wm/DisplayRotationCoordinator.java
new file mode 100644
index 0000000..ae3787c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayRotationCoordinator.java
@@ -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.server.wm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.Display;
+import android.view.Surface;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Singleton for coordinating rotation across multiple displays. Used to notify non-default
+ * displays when the default display rotates.
+ *
+ * Note that this class does not need locking because it is always protected by WindowManagerService
+ * mGlobalLock.
+ */
+class DisplayRotationCoordinator {
+
+    private static final String TAG = "DisplayRotationCoordinator";
+
+    @Surface.Rotation
+    private int mDefaultDisplayDefaultRotation;
+
+    @Nullable
+    @VisibleForTesting
+    Runnable mDefaultDisplayRotationChangedCallback;
+
+    @Surface.Rotation
+    private int mDefaultDisplayCurrentRotation;
+
+    /**
+     * Notifies clients when the default display rotation changes.
+     */
+    void onDefaultDisplayRotationChanged(@Surface.Rotation int rotation) {
+        mDefaultDisplayCurrentRotation = rotation;
+
+        if (mDefaultDisplayRotationChangedCallback != null) {
+            mDefaultDisplayRotationChangedCallback.run();
+        }
+    }
+
+    void setDefaultDisplayDefaultRotation(@Surface.Rotation int rotation) {
+        mDefaultDisplayDefaultRotation = rotation;
+    }
+
+    @Surface.Rotation
+    int getDefaultDisplayCurrentRotation() {
+        return mDefaultDisplayCurrentRotation;
+    }
+
+    /**
+     * Register a callback to be notified when the default display's rotation changes. Clients can
+     * query the default display's current rotation via {@link #getDefaultDisplayCurrentRotation()}.
+     */
+    void setDefaultDisplayRotationChangedCallback(@NonNull Runnable callback) {
+        if (mDefaultDisplayRotationChangedCallback != null) {
+            throw new UnsupportedOperationException("Multiple clients unsupported");
+        }
+
+        mDefaultDisplayRotationChangedCallback = callback;
+
+        if (mDefaultDisplayCurrentRotation != mDefaultDisplayDefaultRotation) {
+            callback.run();
+        }
+    }
+
+    /**
+     * Removes the callback that was added via
+     * {@link #setDefaultDisplayRotationChangedCallback(Runnable)}.
+     */
+    void removeDefaultDisplayRotationChangedCallback() {
+        mDefaultDisplayRotationChangedCallback = null;
+    }
+
+    static boolean isSecondaryInternalDisplay(@NonNull DisplayContent displayContent) {
+        if (displayContent.isDefaultDisplay) {
+            return false;
+        } else if (displayContent.mDisplay == null) {
+            return false;
+        }
+        return displayContent.mDisplay.getType() == Display.TYPE_INTERNAL;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 154fb0c..1fb97f9 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -21,6 +21,7 @@
 import android.app.WindowConfiguration;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -138,10 +139,14 @@
                 true /* includeOverlays */);
         if (topActivity != mTopRunningActivity) {
             mTopRunningActivity = topActivity;
-            mDisplayWindowPolicyController.onTopActivityChanged(
-                    topActivity == null ? null : topActivity.info.getComponentName(),
-                    topActivity == null
-                            ? UserHandle.USER_NULL : topActivity.info.applicationInfo.uid);
+            if (topActivity == null) {
+                mDisplayWindowPolicyController.onTopActivityChanged(null, Process.INVALID_UID,
+                        UserHandle.USER_NULL);
+            } else {
+                mDisplayWindowPolicyController.onTopActivityChanged(
+                        topActivity.info.getComponentName(), topActivity.info.applicationInfo.uid,
+                        topActivity.mUserId);
+            }
         }
 
         // Update running uid.
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 85938e3..4be98a3 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
 import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
@@ -57,7 +57,7 @@
     private Runnable mShowImeRunner;
     private boolean mIsImeLayoutDrawn;
     private boolean mImeShowing;
-    private final InsetsSource mLastSource = new InsetsSource(ITYPE_IME, WindowInsets.Type.ime());
+    private final InsetsSource mLastSource = new InsetsSource(ID_IME, WindowInsets.Type.ime());
 
     /** @see #setFrozen(boolean) */
     private boolean mFrozen;
@@ -182,7 +182,8 @@
         boolean targetChanged = isTargetChangedWithinActivity(imeTarget);
         mImeRequester = imeTarget;
         // There was still a stats token, so that request presumably failed.
-        ImeTracker.get().onFailed(mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
+        ImeTracker.forLogging().onFailed(
+                mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
         mImeRequesterStatsToken = statsToken;
         if (targetChanged) {
             // target changed, check if new target can show IME.
@@ -197,12 +198,12 @@
         ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeRequester.getWindow() == null
                 ? mImeRequester : mImeRequester.getWindow().getName());
         mShowImeRunner = () -> {
-            ImeTracker.get().onProgress(mImeRequesterStatsToken,
+            ImeTracker.forLogging().onProgress(mImeRequesterStatsToken,
                     ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
             ProtoLog.d(WM_DEBUG_IME, "Run showImeRunner");
             // Target should still be the same.
             if (isReadyToShowIme()) {
-                ImeTracker.get().onProgress(mImeRequesterStatsToken,
+                ImeTracker.forLogging().onProgress(mImeRequesterStatsToken,
                         ImeTracker.PHASE_WM_SHOW_IME_READY);
                 final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
 
@@ -219,7 +220,7 @@
                                     ? mImeRequester.getWindow().getName() : ""));
                 }
             } else {
-                ImeTracker.get().onFailed(mImeRequesterStatsToken,
+                ImeTracker.forLogging().onFailed(mImeRequesterStatsToken,
                         ImeTracker.PHASE_WM_SHOW_IME_READY);
             }
             // Clear token here so we don't report an error in abortShowImePostLayout().
@@ -258,7 +259,8 @@
         mImeRequester = null;
         mIsImeLayoutDrawn = false;
         mShowImeRunner = null;
-        ImeTracker.get().onCancelled(mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
+        ImeTracker.forLogging().onCancelled(
+                mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
         mImeRequesterStatsToken = null;
     }
 
diff --git a/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java b/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java
new file mode 100644
index 0000000..49218ad
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ImeTargetVisibilityPolicy.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+
+import android.os.IBinder;
+import android.view.WindowManager;
+
+/**
+ * A class for {@link com.android.server.inputmethod.InputMethodManagerService} to
+ * control IME visibility operations in {@link WindowManagerService}.
+ */
+public abstract class ImeTargetVisibilityPolicy {
+
+    /**
+     * Shows the IME screenshot and attach it to the given IME target window.
+     *
+     * @param imeTarget The target window to show the IME screenshot.
+     * @param displayId A unique id to identify the display.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    public abstract boolean showImeScreenShot(IBinder imeTarget, int displayId);
+
+    /**
+     * Updates the IME parent for target window.
+     *
+     * @param imeTarget The target window to update the IME parent.
+     * @param displayId A unique id to identify the display.
+     * @return {@code true} if success, {@code false} otherwise.
+     */
+    public abstract boolean updateImeParent(IBinder imeTarget, int displayId);
+
+    /**
+     * Called when {@link DisplayContent#computeImeParent()} to check if it's valid to keep
+     * computing the ime parent.
+     *
+     * @return {@code true} to keep computing the ime parent, {@code false} to defer this operation
+     */
+    public static boolean isReadyToComputeImeParent(WindowState imeLayeringTarget,
+            InputTarget imeInputTarget) {
+        if (imeLayeringTarget == null) {
+            return false;
+        }
+        // Ensure changing the IME parent when the layering target that may use IME has
+        // became to the input target for preventing IME flickers.
+        // Note that:
+        // 1) For the imeLayeringTarget that may not use IME but requires IME on top
+        // of it (e.g. an overlay window with NOT_FOCUSABLE|ALT_FOCUSABLE_IM flags), we allow
+        // it to re-parent the IME on top the display to keep the legacy behavior.
+        // 2) Even though the starting window won't use IME, the associated activity
+        // behind the starting window may request the input. If so, then we should still hold
+        // the IME parent change until the activity started the input.
+        boolean imeLayeringTargetMayUseIme =
+                WindowManager.LayoutParams.mayUseInputMethod(imeLayeringTarget.mAttrs.flags)
+                        || imeLayeringTarget.mAttrs.type == TYPE_APPLICATION_STARTING;
+
+        // Do not change parent if the window hasn't requested IME.
+        var inputAndLayeringTargetsDisagree = (imeInputTarget == null
+                || imeLayeringTarget.mActivityRecord != imeInputTarget.getActivityRecord());
+        var inputTargetStale = imeLayeringTargetMayUseIme && inputAndLayeringTargetsDisagree;
+
+        return !inputTargetStale;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 3e1105b..8c59548 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -405,8 +405,12 @@
             // Apply recents input consumer when the focusing window is in recents animation.
             final boolean shouldApplyRecentsInputConsumer = (recentsAnimationController != null
                     && recentsAnimationController.shouldApplyInputConsumer(focus.mActivityRecord))
-                    // Shell transitions doesn't use RecentsAnimationController
-                    || getWeak(mActiveRecentsActivity) != null && focus.inTransition();
+                    // Shell transitions doesn't use RecentsAnimationController but we still
+                    // have carryover legacy logic that relies on the consumer.
+                    || (getWeak(mActiveRecentsActivity) != null && focus.inTransition()
+                            // only take focus from the recents activity to avoid intercepting
+                            // events before the gesture officially starts.
+                            && focus.isActivityTypeHomeOrRecents());
             if (shouldApplyRecentsInputConsumer) {
                 if (mInputFocus != recentsAnimationInputConsumer.mWindowHandle.token) {
                     requestFocus(recentsAnimationInputConsumer.mWindowHandle.token,
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 1df534f..25ce569 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -25,9 +25,7 @@
 import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
 import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN;
 import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
@@ -41,8 +39,6 @@
 import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.res.Resources;
-import android.util.ArrayMap;
-import android.util.IntArray;
 import android.util.SparseArray;
 import android.view.InsetsAnimationControlCallbacks;
 import android.view.InsetsAnimationControlImpl;
@@ -52,7 +48,6 @@
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.InternalInsetsAnimationController;
 import android.view.SurfaceControl;
 import android.view.SyncRtSurfaceTransactionApplier;
@@ -81,7 +76,6 @@
     private final InsetsStateController mStateController;
     private final DisplayContent mDisplayContent;
     private final DisplayPolicy mPolicy;
-    private final IntArray mShowingTransientTypes = new IntArray();
 
     /** For resetting visibilities of insets sources. */
     private final InsetsControlTarget mDummyControlTarget = new InsetsControlTarget() {
@@ -95,7 +89,7 @@
                 return;
             }
             for (InsetsSourceControl control : controls) {
-                if (mShowingTransientTypes.indexOf(control.getId()) != -1) {
+                if (isTransient(control.getType())) {
                     // The visibilities of transient bars will be handled with animations.
                     continue;
                 }
@@ -117,13 +111,16 @@
     };
 
     private WindowState mFocusedWin;
-    private BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
-    private BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);
+    private final BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
+    private final BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);
+    private @InsetsType int mShowingTransientTypes;
     private boolean mAnimatingShown;
+
     /**
      * Let remote insets controller control system bars regardless of other settings.
      */
     private boolean mRemoteInsetsControllerControlsSystemBars;
+
     private final boolean mHideNavBarForKeyboard;
     private final float[] mTmpFloat9 = new float[9];
 
@@ -178,37 +175,46 @@
         mNavBar.updateVisibility(navControlTarget, Type.navigationBars());
     }
 
-    boolean isHidden(@InternalInsetsType int type) {
-        final WindowContainerInsetsSourceProvider provider = mStateController
-                .peekSourceProvider(type);
-        return provider != null && provider.hasWindowContainer()
-                && !provider.getSource().isVisible();
+    boolean hasHiddenSources(@InsetsType int types) {
+        final InsetsState state = mStateController.getRawInsetsState();
+        for (int i = state.sourceSize() - 1; i >= 0; i--) {
+            final InsetsSource source = state.sourceAt(i);
+            if ((source.getType() & types) == 0) {
+                continue;
+            }
+            if (!source.getFrame().isEmpty() && !source.isVisible()) {
+                return true;
+            }
+        }
+        return false;
     }
 
-    void showTransient(@InternalInsetsType int[] types, boolean isGestureOnSystemBar) {
-        boolean changed = false;
-        for (int i = types.length - 1; i >= 0; i--) {
-            final @InternalInsetsType int type = types[i];
-            if (!isHidden(type)) {
+    void showTransient(@InsetsType int types, boolean isGestureOnSystemBar) {
+        @InsetsType int showingTransientTypes = mShowingTransientTypes;
+        final InsetsState rawState = mStateController.getRawInsetsState();
+        for (int i = rawState.sourceSize() - 1; i >= 0; i--) {
+            final InsetsSource source = rawState.sourceAt(i);
+            if (source.isVisible()) {
                 continue;
             }
-            if (mShowingTransientTypes.indexOf(type) != -1) {
+            final @InsetsType int type = source.getType();
+            if ((source.getType() & types) == 0) {
                 continue;
             }
-            mShowingTransientTypes.add(type);
-            changed = true;
+            showingTransientTypes |= type;
         }
-        if (changed) {
+        if (mShowingTransientTypes != showingTransientTypes) {
+            mShowingTransientTypes = showingTransientTypes;
             StatusBarManagerInternal statusBarManagerInternal =
                     mPolicy.getStatusBarManagerInternal();
             if (statusBarManagerInternal != null) {
                 statusBarManagerInternal.showTransient(mDisplayContent.getDisplayId(),
-                        mShowingTransientTypes.toArray(), isGestureOnSystemBar);
+                        showingTransientTypes, isGestureOnSystemBar);
             }
             updateBarControlTarget(mFocusedWin);
             dispatchTransientSystemBarsVisibilityChanged(
                     mFocusedWin,
-                    isTransient(ITYPE_STATUS_BAR) || isTransient(ITYPE_NAVIGATION_BAR),
+                    (showingTransientTypes & (Type.statusBars() | Type.navigationBars())) != 0,
                     isGestureOnSystemBar);
 
             // The leashes can be created while updating bar control target. The surface transaction
@@ -224,7 +230,7 @@
     }
 
     void hideTransient() {
-        if (mShowingTransientTypes.size() == 0) {
+        if (mShowingTransientTypes == 0) {
             return;
         }
 
@@ -235,20 +241,25 @@
 
         startAnimation(false /* show */, () -> {
             synchronized (mDisplayContent.mWmService.mGlobalLock) {
-                for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
+                final SparseArray<WindowContainerInsetsSourceProvider> providers =
+                        mStateController.getSourceProviders();
+                for (int i = providers.size() - 1; i >= 0; i--) {
+                    final WindowContainerInsetsSourceProvider provider = providers.valueAt(i);
+                    if (!isTransient(provider.getSource().getType())) {
+                        continue;
+                    }
                     // We are about to clear mShowingTransientTypes, we don't want the transient bar
                     // can cause insets on the client. Restore the client visibility.
-                    final @InternalInsetsType int type = mShowingTransientTypes.get(i);
-                    mStateController.getSourceProvider(type).setClientVisible(false);
+                    provider.setClientVisible(false);
                 }
-                mShowingTransientTypes.clear();
+                mShowingTransientTypes = 0;
                 updateBarControlTarget(mFocusedWin);
             }
         });
     }
 
-    boolean isTransient(@InternalInsetsType int type) {
-        return mShowingTransientTypes.indexOf(type) != -1;
+    boolean isTransient(@InsetsType int type) {
+        return (mShowingTransientTypes & type) != 0;
     }
 
     /**
@@ -280,9 +291,9 @@
                 ? token.getFixedRotationTransformInsetsState()
                 : mStateController.getRawInsetsState();
         outInsetsState.set(srcState, true /* copySources */);
-        for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
-            final InsetsSource source = outInsetsState.peekSource(mShowingTransientTypes.get(i));
-            if (source != null) {
+        for (int i = outInsetsState.sourceSize() - 1; i >= 0; i--) {
+            final InsetsSource source = outInsetsState.sourceAt(i);
+            if (isTransient(source.getType())) {
                 source.setVisible(false);
             }
         }
@@ -315,12 +326,14 @@
         // The caller should not receive the visible insets provided by itself.
         if (attrs.type == TYPE_INPUT_METHOD) {
             state = new InsetsState(state);
-            state.removeSource(ITYPE_IME);
+            state.removeSource(ID_IME);
         } else if (attrs.providedInsets != null) {
             for (InsetsFrameProvider provider : attrs.providedInsets) {
                 // TODO(b/234093736): Let InsetsFrameProvider return the public type and the ID.
                 final int sourceId = provider.type;
-                final @InsetsType int type = InsetsState.toPublicType(sourceId);
+                final @InsetsType int type = sourceId == ID_IME
+                        ? WindowInsets.Type.ime()
+                        : InsetsState.toPublicType(sourceId);
                 if ((type & WindowInsets.Type.systemBars()) == 0) {
                     continue;
                 }
@@ -331,8 +344,8 @@
             }
         }
 
-        final ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
-                .getSourceProviders();
+        final SparseArray<WindowContainerInsetsSourceProvider> providers =
+                mStateController.getSourceProviders();
         final int windowType = attrs.type;
         for (int i = providers.size() - 1; i >= 0; i--) {
             final WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
@@ -340,8 +353,7 @@
                 if (state == originalState) {
                     state = new InsetsState(state);
                 }
-                final InsetsSource override =
-                        new InsetsSource(state.getSource(otherProvider.getSource().getId()));
+                final InsetsSource override = new InsetsSource(otherProvider.getSource());
                 override.setFrame(otherProvider.getOverriddenFrame(windowType));
                 state.addSource(override);
             }
@@ -364,18 +376,17 @@
 
     private InsetsState adjustVisibilityForTransientTypes(InsetsState originalState) {
         InsetsState state = originalState;
-        for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
-            final @InternalInsetsType int type = mShowingTransientTypes.get(i);
-            final InsetsSource originalSource = state.peekSource(type);
-            if (originalSource != null && originalSource.isVisible()) {
+        for (int i = state.sourceSize() - 1; i >= 0; i--) {
+            final InsetsSource source = state.sourceAt(i);
+            if (isTransient(source.getType()) && source.isVisible()) {
                 if (state == originalState) {
                     // The source will be modified, create a non-deep copy to store the new one.
                     state = new InsetsState(originalState);
                 }
                 // Replace the source with a copy in invisible state.
-                final InsetsSource source = new InsetsSource(originalSource);
-                source.setVisible(false);
-                state.addSource(source);
+                final InsetsSource outSource = new InsetsSource(source);
+                outSource.setVisible(false);
+                state.addSource(outSource);
             }
         }
         return state;
@@ -384,23 +395,28 @@
     private InsetsState adjustVisibilityForIme(WindowState w, InsetsState originalState,
             boolean copyState) {
         if (w.mIsImWindow) {
+            InsetsState state = originalState;
             // If navigation bar is not hidden by IME, IME should always receive visible
             // navigation bar insets.
             final boolean navVisible = !mHideNavBarForKeyboard;
-            final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR);
-            if (originalNavSource != null && originalNavSource.isVisible() != navVisible) {
-                final InsetsState state = copyState ? new InsetsState(originalState)
-                        : originalState;
-                final InsetsSource navSource = new InsetsSource(originalNavSource);
+            for (int i = originalState.sourceSize() - 1; i >= 0; i--) {
+                final InsetsSource source = originalState.sourceAt(i);
+                if (source.getType() != Type.navigationBars() || source.isVisible() == navVisible) {
+                    continue;
+                }
+                if (state == originalState && copyState) {
+                    state = new InsetsState(originalState);
+                }
+                final InsetsSource navSource = new InsetsSource(source);
                 navSource.setVisible(navVisible);
                 state.addSource(navSource);
-                return state;
             }
+            return state;
         } else if (w.mActivityRecord != null && w.mActivityRecord.mImeInsetsFrozenUntilStartInput) {
             // During switching tasks with gestural navigation, before the next IME input target
             // starts the input, we should adjust and freeze the last IME visibility of the window
             // in case delivering obsoleted IME insets state during transitioning.
-            final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME);
+            final InsetsSource originalImeSource = originalState.peekSource(ID_IME);
 
             if (originalImeSource != null) {
                 final boolean imeVisibility = w.isRequestedVisible(Type.ime());
@@ -446,23 +462,22 @@
      * @param caller who changed the insets state.
      */
     private void checkAbortTransient(InsetsControlTarget caller) {
-        if (mShowingTransientTypes.size() != 0) {
-            final IntArray abortTypes = new IntArray();
-            final boolean imeRequestedVisible = caller.isRequestedVisible(Type.ime());
-            for (int i = mShowingTransientTypes.size() - 1; i >= 0; i--) {
-                final @InternalInsetsType int type = mShowingTransientTypes.get(i);
-                if ((mStateController.isFakeTarget(type, caller)
-                                && caller.isRequestedVisible(InsetsState.toPublicType(type)))
-                        || (type == ITYPE_NAVIGATION_BAR && imeRequestedVisible)) {
-                    mShowingTransientTypes.remove(i);
-                    abortTypes.add(type);
-                }
-            }
-            StatusBarManagerInternal statusBarManagerInternal =
-                    mPolicy.getStatusBarManagerInternal();
-            if (abortTypes.size() > 0 && statusBarManagerInternal != null) {
-                statusBarManagerInternal.abortTransient(
-                        mDisplayContent.getDisplayId(), abortTypes.toArray());
+        if (mShowingTransientTypes == 0) {
+            return;
+        }
+        final boolean isImeVisible = mStateController.getImeSourceProvider().isClientVisible();
+        final @InsetsType int fakeControllingTypes =
+                mStateController.getFakeControllingTypes(caller);
+        final @InsetsType int abortTypes =
+                (fakeControllingTypes & caller.getRequestedVisibleTypes())
+                | (isImeVisible ? Type.navigationBars() : 0);
+        mShowingTransientTypes &= ~abortTypes;
+        if (abortTypes != 0) {
+            mDisplayContent.setLayoutNeeded();
+            mDisplayContent.mWmService.requestTraversal();
+            final StatusBarManagerInternal statusBarManager = mPolicy.getStatusBarManagerInternal();
+            if (statusBarManager != null) {
+                statusBarManager.abortTransient(mDisplayContent.getDisplayId(), abortTypes);
             }
         }
     }
@@ -472,12 +487,16 @@
      * updateBarControlTarget(mFocusedWin) after this invocation.
      */
     private void abortTransient() {
-        StatusBarManagerInternal statusBarManagerInternal = mPolicy.getStatusBarManagerInternal();
-        if (statusBarManagerInternal != null) {
-            statusBarManagerInternal.abortTransient(
-                    mDisplayContent.getDisplayId(), mShowingTransientTypes.toArray());
+        if (mShowingTransientTypes == 0) {
+            return;
         }
-        mShowingTransientTypes.clear();
+        final StatusBarManagerInternal statusBarManager = mPolicy.getStatusBarManagerInternal();
+        if (statusBarManager != null) {
+            statusBarManager.abortTransient(mDisplayContent.getDisplayId(), mShowingTransientTypes);
+        }
+        mShowingTransientTypes = 0;
+        mDisplayContent.setLayoutNeeded();
+        mDisplayContent.mWmService.requestTraversal();
 
         dispatchTransientSystemBarsVisibilityChanged(
                 mFocusedWin,
@@ -487,7 +506,7 @@
 
     private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin,
             boolean fake) {
-        if (!fake && isShowingTransientTypes(Type.statusBars())) {
+        if (!fake && isTransient(Type.statusBars())) {
             return mDummyControlTarget;
         }
         final WindowState notificationShade = mPolicy.getNotificationShade();
@@ -513,7 +532,8 @@
             // fake control to the client, so that it can re-show the bar during this scenario.
             return mDummyControlTarget;
         }
-        if (!canBeTopFullscreenOpaqueWindow(focusedWin) && mPolicy.topAppHidesStatusBar()
+        if (!canBeTopFullscreenOpaqueWindow(focusedWin)
+                && mPolicy.topAppHidesSystemBar(Type.statusBars())
                 && (notificationShade == null || !notificationShade.canReceiveKeys())) {
             // Non-fullscreen focused window should not break the state that the top-fullscreen-app
             // window hides status bar, unless the notification shade can receive keys.
@@ -540,7 +560,7 @@
             // configured to be hidden by the IME.
             return null;
         }
-        if (!fake && isShowingTransientTypes(Type.navigationBars())) {
+        if (!fake && isTransient(Type.navigationBars())) {
             return mDummyControlTarget;
         }
         if (focusedWin == mPolicy.getNotificationShade()) {
@@ -573,17 +593,15 @@
             // fake control to the client, so that it can re-show the bar during this scenario.
             return mDummyControlTarget;
         }
-        return focusedWin;
-    }
-
-    private boolean isShowingTransientTypes(@InsetsType int types) {
-        final IntArray showingTransientTypes = mShowingTransientTypes;
-        for (int i = showingTransientTypes.size() - 1; i >= 0; i--) {
-            if ((InsetsState.toPublicType(showingTransientTypes.get(i)) & types) != 0) {
-                return true;
-            }
+        final WindowState notificationShade = mPolicy.getNotificationShade();
+        if (!canBeTopFullscreenOpaqueWindow(focusedWin)
+                && mPolicy.topAppHidesSystemBar(Type.navigationBars())
+                && (notificationShade == null || !notificationShade.canReceiveKeys())) {
+            // Non-fullscreen focused window should not break the state that the top-fullscreen-app
+            // window hides navigation bar, unless the notification shade can receive keys.
+            return mPolicy.getTopFullscreenOpaqueWindow();
         }
-        return false;
+        return focusedWin;
     }
 
     /**
@@ -621,21 +639,23 @@
 
     @VisibleForTesting
     void startAnimation(boolean show, Runnable callback) {
-        int typesReady = 0;
-        final SparseArray<InsetsSourceControl> controls = new SparseArray<>();
-        final IntArray showingTransientTypes = mShowingTransientTypes;
-        for (int i = showingTransientTypes.size() - 1; i >= 0; i--) {
-            final int sourceId = showingTransientTypes.get(i);
-            final WindowContainerInsetsSourceProvider provider =
-                    mStateController.getSourceProvider(sourceId);
-            final InsetsSourceControl control = provider.getControl(mDummyControlTarget);
-            if (control == null || control.getLeash() == null) {
-                continue;
+        @InsetsType int typesReady = 0;
+        final SparseArray<InsetsSourceControl> controlsReady = new SparseArray<>();
+        final InsetsSourceControl[] controls =
+                mStateController.getControlsForDispatch(mDummyControlTarget);
+        if (controls == null) {
+            if (callback != null) {
+                DisplayThread.getHandler().post(callback);
             }
-            typesReady |= control.getType();
-            controls.put(sourceId, new InsetsSourceControl(control));
+            return;
         }
-        controlAnimationUnchecked(typesReady, controls, show, callback);
+        for (InsetsSourceControl control : controls) {
+            if (isTransient(control.getType()) && control.getLeash() != null) {
+                typesReady |= control.getType();
+                controlsReady.put(control.getId(), new InsetsSourceControl(control));
+            }
+        }
+        controlAnimationUnchecked(typesReady, controlsReady, show, callback);
     }
 
     private void controlAnimationUnchecked(int typesReady,
@@ -707,7 +727,8 @@
 
         InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
             super(show, false /* hasCallbacks */, types, BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
-                    false /* disable */, 0 /* floatingImeBottomInsets */, null);
+                    false /* disable */, 0 /* floatingImeBottomInsets */,
+                    null /* loggingListener */, null /* jankContext */);
             mFinishCallback = finishCallback;
             mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
         }
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 49eaea2..2b7a451 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_INSETS;
 import static com.android.server.wm.InsetsSourceProviderProto.CAPTURED_LEASH;
@@ -164,7 +164,7 @@
             // TODO: Ideally, we should wait for the animation to finish so previous window can
             // animate-out as new one animates-in.
             mWindowContainer.cancelAnimation();
-            mWindowContainer.getProvidedInsetsSources().remove(mSource.getId());
+            mWindowContainer.getInsetsSourceProviders().remove(mSource.getId());
             mSeamlessRotating = false;
         }
         ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource setWin %s for type %s",
@@ -180,7 +180,7 @@
             mSource.setInsetsRoundedCornerFrame(false);
             mSourceFrame.setEmpty();
         } else {
-            mWindowContainer.getProvidedInsetsSources().put(mSource.getId(), mSource);
+            mWindowContainer.getInsetsSourceProviders().put(mSource.getId(), this);
             if (mControllable) {
                 mWindowContainer.setControllableInsetProvider(this);
                 if (mPendingControlTarget != null) {
@@ -192,13 +192,6 @@
     }
 
     /**
-     * @return Whether there is a window container which backs this source.
-     */
-    boolean hasWindowContainer() {
-        return mWindowContainer != null;
-    }
-
-    /**
      * The source frame can affect the layout of other windows, so this should be called once the
      * window container gets laid out.
      */
@@ -363,9 +356,9 @@
     }
 
     /**
-     * @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget)
+     * @see InsetsStateController#onControlTargetChanged
      */
-    void updateControlForFakeTarget(@Nullable InsetsControlTarget fakeTarget) {
+    void updateFakeControlTarget(@Nullable InsetsControlTarget fakeTarget) {
         if (fakeTarget == mFakeControlTarget) {
             return;
         }
@@ -541,7 +534,7 @@
             return false;
         }
         for (int i = 0; i < providers.length; i++) {
-            if (providers[i].type == ITYPE_IME) {
+            if (providers[i].type == ID_IME) {
                 return true;
             }
         }
@@ -570,6 +563,10 @@
         return mControlTarget;
     }
 
+    InsetsControlTarget getFakeControlTarget() {
+        return mFakeControlTarget;
+    }
+
     boolean isClientVisible() {
         return mClientVisible;
     }
@@ -609,15 +606,15 @@
         }
         if (mControlTarget != null) {
             pw.print(prefix + "mControlTarget=");
-            pw.println(mControlTarget.getWindow());
+            pw.println(mControlTarget);
         }
         if (mPendingControlTarget != null) {
             pw.print(prefix + "mPendingControlTarget=");
-            pw.println(mPendingControlTarget.getWindow());
+            pw.println(mPendingControlTarget);
         }
         if (mFakeControlTarget != null) {
             pw.print(prefix + "mFakeControlTarget=");
-            pw.println(mFakeControlTarget.getWindow());
+            pw.println(mFakeControlTarget);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 455cd48..0e1e63e 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -17,16 +17,15 @@
 package com.android.server.wm;
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.mandatorySystemGestures;
 import static android.view.WindowInsets.Type.systemGestures;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
+import static com.android.server.wm.DisplayContentProto.IME_INSETS_SOURCE_PROVIDER;
+import static com.android.server.wm.DisplayContentProto.INSETS_SOURCE_PROVIDERS;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -34,11 +33,12 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
 import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.WindowInsets;
+import android.view.WindowInsets.Type.InsetsType;
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -46,7 +46,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.function.Consumer;
-import java.util.function.Function;
 
 /**
  * Manages global window inset state in the system represented by {@link InsetsState}.
@@ -57,14 +56,11 @@
     private final InsetsState mState = new InsetsState();
     private final DisplayContent mDisplayContent;
 
-    private final ArrayMap<Integer, WindowContainerInsetsSourceProvider> mProviders =
-            new ArrayMap<>();
-    private final ArrayMap<InsetsControlTarget, ArrayList<Integer>> mControlTargetTypeMap =
-            new ArrayMap<>();
-    private final SparseArray<InsetsControlTarget> mTypeControlTargetMap = new SparseArray<>();
-
-    /** @see #onControlFakeTargetChanged */
-    private final SparseArray<InsetsControlTarget> mTypeFakeControlTargetMap = new SparseArray<>();
+    private final SparseArray<WindowContainerInsetsSourceProvider> mProviders = new SparseArray<>();
+    private final ArrayMap<InsetsControlTarget, ArrayList<InsetsSourceProvider>>
+            mControlTargetProvidersMap = new ArrayMap<>();
+    private final SparseArray<InsetsControlTarget> mIdControlTargetMap = new SparseArray<>();
+    private final SparseArray<InsetsControlTarget> mIdFakeControlTargetMap = new SparseArray<>();
 
     private final ArraySet<InsetsControlTarget> mPendingControlChanged = new ArraySet<>();
 
@@ -89,17 +85,8 @@
         }
     };
 
-    private final Function<Integer, WindowContainerInsetsSourceProvider> mSourceProviderFunc;
-
     InsetsStateController(DisplayContent displayContent) {
         mDisplayContent = displayContent;
-        mSourceProviderFunc = type -> {
-            final InsetsSource source = mState.getSource(type);
-            if (type == ITYPE_IME) {
-                return new ImeInsetsSourceProvider(source, this, mDisplayContent);
-            }
-            return new WindowContainerInsetsSourceProvider(source, this, mDisplayContent);
-        };
     }
 
     InsetsState getRawInsetsState() {
@@ -107,39 +94,55 @@
     }
 
     @Nullable InsetsSourceControl[] getControlsForDispatch(InsetsControlTarget target) {
-        ArrayList<Integer> controlled = mControlTargetTypeMap.get(target);
+        final ArrayList<InsetsSourceProvider> controlled = mControlTargetProvidersMap.get(target);
         if (controlled == null) {
             return null;
         }
         final int size = controlled.size();
         final InsetsSourceControl[] result = new InsetsSourceControl[size];
         for (int i = 0; i < size; i++) {
-            result[i] = mProviders.get(controlled.get(i)).getControl(target);
+            result[i] = controlled.get(i).getControl(target);
         }
         return result;
     }
 
-    ArrayMap<Integer, WindowContainerInsetsSourceProvider> getSourceProviders() {
+    SparseArray<WindowContainerInsetsSourceProvider> getSourceProviders() {
         return mProviders;
     }
 
     /**
-     * @return The provider of a specific type.
+     * @return The provider of a specific source ID.
      */
-    WindowContainerInsetsSourceProvider getSourceProvider(@InternalInsetsType int type) {
-        return mProviders.computeIfAbsent(type, mSourceProviderFunc);
+    WindowContainerInsetsSourceProvider getOrCreateSourceProvider(int id, @InsetsType int type) {
+        WindowContainerInsetsSourceProvider provider = mProviders.get(id);
+        if (provider != null) {
+            return provider;
+        }
+        final InsetsSource source = mState.getOrCreateSource(id, type);
+        provider = id == ID_IME
+                ? new ImeInsetsSourceProvider(source, this, mDisplayContent)
+                : new WindowContainerInsetsSourceProvider(source, this, mDisplayContent);
+        mProviders.put(id, provider);
+        return provider;
     }
 
     ImeInsetsSourceProvider getImeSourceProvider() {
-        return (ImeInsetsSourceProvider) getSourceProvider(ITYPE_IME);
+        return (ImeInsetsSourceProvider) getOrCreateSourceProvider(ID_IME, ime());
+    }
+
+    void removeSourceProvider(int id) {
+        if (id != ID_IME) {
+            mState.removeSource(id);
+            mProviders.remove(id);
+        }
     }
 
     /**
-     * @return The provider of a specific type or null if we don't have it.
+     * @return The provider of a source ID or null if we don't have it.
      */
     @Nullable
-    WindowContainerInsetsSourceProvider peekSourceProvider(@InternalInsetsType int type) {
-        return mProviders.get(type);
+    WindowContainerInsetsSourceProvider peekSourceProvider(int id) {
+        return mProviders.get(id);
     }
 
     /**
@@ -207,8 +210,16 @@
         }
     }
 
-    boolean isFakeTarget(@InternalInsetsType int type, InsetsControlTarget target) {
-        return mTypeFakeControlTargetMap.get(type) == target;
+    @InsetsType int getFakeControllingTypes(InsetsControlTarget target) {
+        @InsetsType int types = 0;
+        for (int i = mProviders.size() - 1; i >= 0; i--) {
+            final InsetsSourceProvider provider = mProviders.valueAt(i);
+            final InsetsControlTarget fakeControlTarget = provider.getFakeControlTarget();
+            if (target == fakeControlTarget) {
+                types |= provider.getSource().getType();
+            }
+        }
+        return types;
     }
 
     void onImeControlTargetChanged(@Nullable InsetsControlTarget imeTarget) {
@@ -216,7 +227,7 @@
         // Make sure that we always have a control target for the IME, even if the IME target is
         // null. Otherwise there is no leash that will hide it and IME becomes "randomly" visible.
         InsetsControlTarget target = imeTarget != null ? imeTarget : mEmptyImeControlTarget;
-        onControlChanged(ITYPE_IME, target);
+        onControlTargetChanged(getImeSourceProvider(), target, false /* fake */);
         ProtoLog.d(WM_DEBUG_IME, "onImeControlTargetChanged %s",
                 target != null ? target.getWindow() : "null");
         notifyPendingInsetsControlChanged();
@@ -234,101 +245,88 @@
             @Nullable InsetsControlTarget fakeStatusControlling,
             @Nullable InsetsControlTarget navControlling,
             @Nullable InsetsControlTarget fakeNavControlling) {
-        onControlChanged(ITYPE_STATUS_BAR, statusControlling);
-        onControlChanged(ITYPE_NAVIGATION_BAR, navControlling);
-        onControlChanged(ITYPE_CLIMATE_BAR, statusControlling);
-        onControlChanged(ITYPE_EXTRA_NAVIGATION_BAR, navControlling);
-        onControlFakeTargetChanged(ITYPE_STATUS_BAR, fakeStatusControlling);
-        onControlFakeTargetChanged(ITYPE_NAVIGATION_BAR, fakeNavControlling);
-        onControlFakeTargetChanged(ITYPE_CLIMATE_BAR, fakeStatusControlling);
-        onControlFakeTargetChanged(ITYPE_EXTRA_NAVIGATION_BAR, fakeNavControlling);
+        for (int i = mProviders.size() - 1; i >= 0; i--) {
+            final InsetsSourceProvider provider = mProviders.valueAt(i);
+            final @InsetsType int type = provider.getSource().getType();
+            if (type == WindowInsets.Type.statusBars()) {
+                onControlTargetChanged(provider, statusControlling, false /* fake */);
+                onControlTargetChanged(provider, fakeStatusControlling, true /* fake */);
+            } else if (type == WindowInsets.Type.navigationBars()) {
+                onControlTargetChanged(provider, navControlling, false /* fake */);
+                onControlTargetChanged(provider, fakeNavControlling, true /* fake */);
+            }
+        }
         notifyPendingInsetsControlChanged();
     }
 
     void notifyControlRevoked(@NonNull InsetsControlTarget previousControlTarget,
             InsetsSourceProvider provider) {
-        removeFromControlMaps(previousControlTarget, provider.getSource().getId(),
-                false /* fake */);
+        removeFromControlMaps(previousControlTarget, provider, false /* fake */);
     }
 
-    private void onControlChanged(@InternalInsetsType int type,
-            @Nullable InsetsControlTarget target) {
-        final InsetsControlTarget previous = mTypeControlTargetMap.get(type);
-        if (target == previous) {
-            return;
-        }
-        final WindowContainerInsetsSourceProvider provider = mProviders.get(type);
-        if (provider == null) {
+    private void onControlTargetChanged(InsetsSourceProvider provider,
+            @Nullable InsetsControlTarget target, boolean fake) {
+        final InsetsControlTarget lastTarget = fake
+                ? mIdFakeControlTargetMap.get(provider.getSource().getId())
+                : mIdControlTargetMap.get(provider.getSource().getId());
+        if (target == lastTarget) {
             return;
         }
         if (!provider.isControllable()) {
             return;
         }
-        provider.updateControlForTarget(target, false /* force */);
-        target = provider.getControlTarget();
-        if (previous != null) {
-            removeFromControlMaps(previous, type, false /* fake */);
-            mPendingControlChanged.add(previous);
+        if (fake) {
+            // The fake target updated here will be used to pretend to the app that it's still under
+            // control of the bars while it's not really, but we still need to find out the apps
+            // intentions around showing/hiding. For example, when the transient bars are showing,
+            // and the fake target requests to show system bars, the transient state will be
+            // aborted.
+            provider.updateFakeControlTarget(target);
+        } else {
+            provider.updateControlForTarget(target, false /* force */);
+
+            // Get control target again in case the provider didn't accept the one we passed to it.
+            target = provider.getControlTarget();
+            if (target == lastTarget) {
+                return;
+            }
+        }
+        if (lastTarget != null) {
+            removeFromControlMaps(lastTarget, provider, fake);
+            mPendingControlChanged.add(lastTarget);
         }
         if (target != null) {
-            addToControlMaps(target, type, false /* fake */);
+            addToControlMaps(target, provider, fake);
             mPendingControlChanged.add(target);
         }
     }
 
-    /**
-     * The fake target saved here will be used to pretend to the app that it's still under control
-     * of the bars while it's not really, but we still need to find out the apps intentions around
-     * showing/hiding. For example, when the transient bars are showing, and the fake target
-     * requests to show system bars, the transient state will be aborted.
-     */
-    void onControlFakeTargetChanged(@InternalInsetsType int type,
-            @Nullable InsetsControlTarget fakeTarget) {
-        final InsetsControlTarget previous = mTypeFakeControlTargetMap.get(type);
-        if (fakeTarget == previous) {
-            return;
-        }
-        final WindowContainerInsetsSourceProvider provider = mProviders.get(type);
-        if (provider == null) {
-            return;
-        }
-        provider.updateControlForFakeTarget(fakeTarget);
-        if (previous != null) {
-            removeFromControlMaps(previous, type, true /* fake */);
-            mPendingControlChanged.add(previous);
-        }
-        if (fakeTarget != null) {
-            addToControlMaps(fakeTarget, type, true /* fake */);
-            mPendingControlChanged.add(fakeTarget);
-        }
-    }
-
     private void removeFromControlMaps(@NonNull InsetsControlTarget target,
-            @InternalInsetsType int type, boolean fake) {
-        final ArrayList<Integer> array = mControlTargetTypeMap.get(target);
+            InsetsSourceProvider provider, boolean fake) {
+        final ArrayList<InsetsSourceProvider> array = mControlTargetProvidersMap.get(target);
         if (array == null) {
             return;
         }
-        array.remove((Integer) type);
+        array.remove(provider);
         if (array.isEmpty()) {
-            mControlTargetTypeMap.remove(target);
+            mControlTargetProvidersMap.remove(target);
         }
         if (fake) {
-            mTypeFakeControlTargetMap.remove(type);
+            mIdFakeControlTargetMap.remove(provider.getSource().getId());
         } else {
-            mTypeControlTargetMap.remove(type);
+            mIdControlTargetMap.remove(provider.getSource().getId());
         }
     }
 
     private void addToControlMaps(@NonNull InsetsControlTarget target,
-            @InternalInsetsType int type, boolean fake) {
-        final ArrayList<Integer> array = mControlTargetTypeMap.computeIfAbsent(target,
-                key -> new ArrayList<>());
-        array.add(type);
+            InsetsSourceProvider provider, boolean fake) {
+        final ArrayList<InsetsSourceProvider> array = mControlTargetProvidersMap.computeIfAbsent(
+                target, key -> new ArrayList<>());
+        array.add(provider);
         if (fake) {
-            mTypeFakeControlTargetMap.put(type, target);
+            mIdFakeControlTargetMap.put(provider.getSource().getId(), target);
         } else {
-            mTypeControlTargetMap.put(type, target);
+            mIdControlTargetMap.put(provider.getSource().getId(), target);
         }
     }
 
@@ -350,7 +348,7 @@
             for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
                 final InsetsControlTarget controlTarget = mPendingControlChanged.valueAt(i);
                 controlTarget.notifyInsetsControlChanged();
-                if (mControlTargetTypeMap.containsKey(controlTarget)) {
+                if (mControlTargetProvidersMap.containsKey(controlTarget)) {
                     // We only collect targets who get controls, not lose controls.
                     newControlTargets.add(controlTarget);
                 }
@@ -376,14 +374,40 @@
         prefix = prefix + "  ";
         mState.dump(prefix, pw);
         pw.println(prefix + "Control map:");
-        for (int i = mTypeControlTargetMap.size() - 1; i >= 0; i--) {
+        for (int i = mControlTargetProvidersMap.size() - 1; i >= 0; i--) {
+            final InsetsControlTarget controlTarget = mControlTargetProvidersMap.keyAt(i);
             pw.print(prefix + "  ");
-            pw.println(InsetsState.typeToString(mTypeControlTargetMap.keyAt(i)) + " -> "
-                    + mTypeControlTargetMap.valueAt(i));
+            pw.print(controlTarget);
+            pw.println(":");
+            final ArrayList<InsetsSourceProvider> providers = mControlTargetProvidersMap.valueAt(i);
+            for (int j = providers.size() - 1; j >= 0; j--) {
+                final InsetsSourceProvider provider = providers.get(j);
+                if (provider != null) {
+                    pw.print(prefix + "    ");
+                    if (controlTarget == provider.getFakeControlTarget()) {
+                        pw.print("(fake) ");
+                    }
+                    pw.println(provider.getControl(controlTarget));
+                }
+            }
+        }
+        if (mControlTargetProvidersMap.isEmpty()) {
+            pw.print(prefix + "  none");
         }
         pw.println(prefix + "InsetsSourceProviders:");
         for (int i = mProviders.size() - 1; i >= 0; i--) {
             mProviders.valueAt(i).dump(pw, prefix + "  ");
         }
     }
+
+    void dumpDebug(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
+        for (int i = mProviders.size() - 1; i >= 0; i--) {
+            final InsetsSourceProvider provider = mProviders.valueAt(i);
+            provider.dumpDebug(proto,
+                    provider.getSource().getType() == ime()
+                            ? IME_INSETS_SOURCE_PROVIDER
+                            : INSETS_SOURCE_PROVIDERS,
+                    logLevel);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 7066a33..5136670 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -20,6 +20,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ALLOW_IGNORE_ORIENTATION_REQUEST;
 import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_CAMERA_COMPAT_TREATMENT;
+import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_COMPAT_FAKE_FOCUS;
 import static com.android.server.wm.LetterboxConfigurationDeviceConfig.KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY;
 
 import android.annotation.IntDef;
@@ -42,10 +43,6 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxConfiguration" : TAG_ATM;
 
-    @VisibleForTesting
-    static final String DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS =
-            "enable_compat_fake_focus";
-
     /**
      * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
      * set-fixed-orientation-letterbox-aspect-ratio or via {@link
@@ -115,12 +112,6 @@
     /** Letterboxed app window is aligned to the right side. */
     static final int LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM = 2;
 
-    @VisibleForTesting
-    static final String PROPERTY_COMPAT_FAKE_FOCUS_OPT_IN = "com.android.COMPAT_FAKE_FOCUS_OPT_IN";
-    @VisibleForTesting
-    static final String PROPERTY_COMPAT_FAKE_FOCUS_OPT_OUT =
-            "com.android.COMPAT_FAKE_FOCUS_OPT_OUT";
-
     final Context mContext;
 
     // Responsible for the persistence of letterbox[Horizontal|Vertical]PositionMultiplier
@@ -317,6 +308,9 @@
         mDeviceConfig.updateFlagActiveStatus(
                 /* isActive */ true,
                 /* key */ KEY_ALLOW_IGNORE_ORIENTATION_REQUEST);
+        mDeviceConfig.updateFlagActiveStatus(
+                /* isActive */ mIsCompatFakeFocusEnabled,
+                /* key */ KEY_ENABLE_COMPAT_FAKE_FOCUS);
 
         mLetterboxConfigurationPersister = letterboxConfigurationPersister;
         mLetterboxConfigurationPersister.start();
@@ -1066,9 +1060,7 @@
 
     /** Whether fake sending focus is enabled for unfocused apps in splitscreen */
     boolean isCompatFakeFocusEnabled() {
-        return mIsCompatFakeFocusEnabled
-                && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                        DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, true);
+        return mIsCompatFakeFocusEnabled && mDeviceConfig.getFlag(KEY_ENABLE_COMPAT_FAKE_FOCUS);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
index d004fa6..b364872 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfigurationDeviceConfig.java
@@ -45,6 +45,9 @@
             "allow_ignore_orientation_request";
     private static final boolean DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST = true;
 
+    static final String KEY_ENABLE_COMPAT_FAKE_FOCUS = "enable_compat_fake_focus";
+    private static final boolean DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS = true;
+
     @VisibleForTesting
     static final Map<String, Boolean> sKeyToDefaultValueMap = Map.of(
             KEY_ENABLE_CAMERA_COMPAT_TREATMENT,
@@ -52,7 +55,9 @@
             KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY,
             DEFAULT_VALUE_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY,
             KEY_ALLOW_IGNORE_ORIENTATION_REQUEST,
-            DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST
+            DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST,
+            KEY_ENABLE_COMPAT_FAKE_FOCUS,
+            DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS
     );
 
     // Whether camera compatibility treatment is enabled.
@@ -72,6 +77,11 @@
     private boolean mIsAllowIgnoreOrientationRequest =
             DEFAULT_VALUE_ALLOW_IGNORE_ORIENTATION_REQUEST;
 
+    // Whether sending compat fake focus for split screen resumed activities is enabled. This is
+    // needed because some game engines wait to get focus before drawing the content of the app
+    // which isn't guaranteed by default in multi-window modes.
+    private boolean mIsCompatFakeFocusAllowed = DEFAULT_VALUE_ENABLE_COMPAT_FAKE_FOCUS;
+
     // Set of active device configs that need to be updated in
     // DeviceConfig.OnPropertiesChangedListener#onPropertiesChanged.
     private final ArraySet<String> mActiveDeviceConfigsSet = new ArraySet<>();
@@ -117,6 +127,8 @@
                 return mIsDisplayRotationImmersiveAppCompatPolicyEnabled;
             case KEY_ALLOW_IGNORE_ORIENTATION_REQUEST:
                 return mIsAllowIgnoreOrientationRequest;
+            case KEY_ENABLE_COMPAT_FAKE_FOCUS:
+                return mIsCompatFakeFocusAllowed;
             default:
                 throw new AssertionError("Unexpected flag name: " + key);
         }
@@ -140,6 +152,10 @@
                 mIsAllowIgnoreOrientationRequest =
                         getDeviceConfig(key, defaultValue);
                 break;
+            case KEY_ENABLE_COMPAT_FAKE_FOCUS:
+                mIsCompatFakeFocusAllowed =
+                        getDeviceConfig(key, defaultValue);
+                break;
             default:
                 throw new AssertionError("Unexpected flag name: " + key);
         }
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 8d6de58..d2e8ad1 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -25,6 +25,7 @@
 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_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;
 import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
 import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
@@ -80,6 +81,7 @@
 import static java.lang.Boolean.FALSE;
 import static java.lang.Boolean.TRUE;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager.TaskDescription;
 import android.content.pm.ActivityInfo.ScreenOrientation;
@@ -103,7 +105,10 @@
 import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
 
 import java.io.PrintWriter;
+import java.util.Optional;
 import java.util.function.BooleanSupplier;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */
 // TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in
@@ -113,6 +118,9 @@
 // TODO(b/263021211): Consider renaming to more generic CompatUIController.
 final class LetterboxUiController {
 
+    private static final Predicate<ActivityRecord> FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE =
+            activityRecord -> activityRecord.fillsParent() && !activityRecord.isFinishing();
+
     private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
 
     private static final float UNDEFINED_ASPECT_RATIO = 0f;
@@ -143,6 +151,8 @@
     private final boolean mIsOverrideOrientationOnlyForCameraEnabled;
     // Corresponds to OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION
     private final boolean mIsOverrideUseDisplayLandscapeNaturalOrientationEnabled;
+    // Corresponds to OVERRIDE_RESPECT_REQUESTED_ORIENTATION
+    private final boolean mIsOverrideRespectRequestedOrientationEnabled;
 
     // Corresponds to OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION
     private final boolean mIsOverrideCameraCompatDisableForceRotationEnabled;
@@ -272,6 +282,8 @@
                 isCompatChangeEnabled(OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA);
         mIsOverrideUseDisplayLandscapeNaturalOrientationEnabled =
                 isCompatChangeEnabled(OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION);
+        mIsOverrideRespectRequestedOrientationEnabled =
+                isCompatChangeEnabled(OVERRIDE_RESPECT_REQUESTED_ORIENTATION);
 
         mIsOverrideCameraCompatDisableForceRotationEnabled =
                 isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION);
@@ -418,6 +430,10 @@
         mIsRefreshAfterRotationRequested = isRequested;
     }
 
+    boolean isOverrideRespectRequestedOrientationEnabled() {
+        return mIsOverrideRespectRequestedOrientationEnabled;
+    }
+
     /**
      * Whether should fix display orientation to landscape natural orientation when a task is
      * fullscreen and the display is ignoring orientation requests.
@@ -1381,7 +1397,8 @@
             return;
         }
         final ActivityRecord firstOpaqueActivityBeneath = mActivityRecord.getTask().getActivity(
-                ActivityRecord::fillsParent, mActivityRecord, false /* includeBoundary */,
+                FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE /* callback */,
+                mActivityRecord /* boundary */, false /* includeBoundary */,
                 true /* traverseTopToBottom */);
         if (firstOpaqueActivityBeneath == null) {
             // We skip letterboxing if the translucent activity doesn't have any opaque
@@ -1457,6 +1474,32 @@
         return mInheritedCompatDisplayInsets;
     }
 
+    /**
+     * In case of translucent activities, it consumes the {@link ActivityRecord} of the first opaque
+     * activity beneath using the given consumer and returns {@code true}.
+     */
+    boolean applyOnOpaqueActivityBelow(@NonNull Consumer<ActivityRecord> consumer) {
+        return findOpaqueNotFinishingActivityBelow()
+                .map(activityRecord -> {
+                    consumer.accept(activityRecord);
+                    return true;
+                }).orElse(false);
+    }
+
+    /**
+     * @return The first not finishing opaque activity beneath the current translucent activity
+     * if it exists and the strategy is enabled.
+     */
+    private Optional<ActivityRecord> findOpaqueNotFinishingActivityBelow() {
+        if (!hasInheritedLetterboxBehavior() || mActivityRecord.getTask() == null) {
+            return Optional.empty();
+        }
+        return Optional.ofNullable(mActivityRecord.getTask().getActivity(
+                FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE /* callback */,
+                mActivityRecord /* boundary */, false /* includeBoundary */,
+                true /* traverseTopToBottom */));
+    }
+
     private void inheritConfiguration(ActivityRecord firstOpaque) {
         // To avoid wrong behaviour, we're not forcing a specific aspet ratio to activities
         // which are not already providing one (e.g. permission dialogs) and presumably also
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 4be1c83..14b845c 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -33,6 +33,8 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.os.Process.SYSTEM_UID;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
@@ -215,10 +217,16 @@
             int y = (int) ev.getY();
             mService.mH.post(PooledLambda.obtainRunnable((nonArg) -> {
                 synchronized (mService.mGlobalLock) {
-                    // Unfreeze the task list once we touch down in a task
                     final RootWindowContainer rac = mService.mRootWindowContainer;
                     final DisplayContent dc = rac.getDisplayContent(displayId).mDisplayContent;
-                    if (dc.pointWithinAppWindow(x, y)) {
+                    final WindowState win = dc.getTouchableWinAtPointLocked((float) x, (float) y);
+                    if (win == null) {
+                        return;
+                    }
+                    // Unfreeze the task list once we touch down in a task
+                    final boolean isAppWindowTouch = FIRST_APPLICATION_WINDOW <= win.mAttrs.type
+                            && win.mAttrs.type <= LAST_APPLICATION_WINDOW;
+                    if (isAppWindowTouch) {
                         final Task stack = mService.getTopDisplayFocusedRootTask();
                         final Task topTask = stack != null ? stack.getTopMostTask() : null;
                         resetFreezeTaskListReordering(topTask);
diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
index de42c55..99831d3 100644
--- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java
+++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
@@ -19,9 +19,6 @@
 import static android.hardware.display.DisplayManager.SWITCHING_TYPE_NONE;
 import static android.hardware.display.DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY;
 
-import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
-
 import android.hardware.display.DisplayManager;
 import android.view.Display;
 import android.view.Display.Mode;
@@ -59,6 +56,8 @@
         }
     }
 
+    private final DisplayInfo mDisplayInfo;
+    private final Mode mDefaultMode;
     private final Mode mLowRefreshRateMode;
     private final PackageRefreshRate mNonHighRefreshRatePackages = new PackageRefreshRate();
     private final HighRefreshRateDenylist mHighRefreshRateDenylist;
@@ -89,7 +88,9 @@
 
     RefreshRatePolicy(WindowManagerService wmService, DisplayInfo displayInfo,
             HighRefreshRateDenylist denylist) {
-        mLowRefreshRateMode = findLowRefreshRateMode(displayInfo);
+        mDisplayInfo = displayInfo;
+        mDefaultMode = displayInfo.getDefaultMode();
+        mLowRefreshRateMode = findLowRefreshRateMode(displayInfo, mDefaultMode);
         mHighRefreshRateDenylist = denylist;
         mWmService = wmService;
     }
@@ -98,10 +99,9 @@
      * Finds the mode id with the lowest refresh rate which is >= 60hz and same resolution as the
      * default mode.
      */
-    private Mode findLowRefreshRateMode(DisplayInfo displayInfo) {
-        Mode mode = displayInfo.getDefaultMode();
+    private Mode findLowRefreshRateMode(DisplayInfo displayInfo, Mode defaultMode) {
         float[] refreshRates = displayInfo.getDefaultRefreshRates();
-        float bestRefreshRate = mode.getRefreshRate();
+        float bestRefreshRate = defaultMode.getRefreshRate();
         mMinSupportedRefreshRate = bestRefreshRate;
         mMaxSupportedRefreshRate = bestRefreshRate;
         for (int i = refreshRates.length - 1; i >= 0; i--) {
@@ -127,13 +127,39 @@
     }
 
     int getPreferredModeId(WindowState w) {
-        // If app is animating, it's not able to control refresh rate because we want the animation
-        // to run in default refresh rate.
-        if (w.isAnimating(TRANSITION | PARENTS)) {
+        final int preferredDisplayModeId = w.mAttrs.preferredDisplayModeId;
+        if (preferredDisplayModeId <= 0) {
+            // Unspecified, use default mode.
             return 0;
         }
 
-        return w.mAttrs.preferredDisplayModeId;
+        // If app is animating, it's not able to control refresh rate because we want the animation
+        // to run in default refresh rate. But if the display size of default mode is different
+        // from the using preferred mode, then still keep the preferred mode to avoid disturbing
+        // the animation.
+        if (w.isAnimationRunningSelfOrParent()) {
+            Display.Mode preferredMode = null;
+            for (Display.Mode mode : mDisplayInfo.supportedModes) {
+                if (preferredDisplayModeId == mode.getModeId()) {
+                    preferredMode = mode;
+                    break;
+                }
+            }
+            if (preferredMode != null) {
+                final int pW = preferredMode.getPhysicalWidth();
+                final int pH = preferredMode.getPhysicalHeight();
+                if ((pW != mDefaultMode.getPhysicalWidth()
+                        || pH != mDefaultMode.getPhysicalHeight())
+                        && pW == mDisplayInfo.getNaturalWidth()
+                        && pH == mDisplayInfo.getNaturalHeight()) {
+                    // Prefer not to change display size when animating.
+                    return preferredDisplayModeId;
+                }
+            }
+            return 0;
+        }
+
+        return preferredDisplayModeId;
     }
 
     /**
@@ -225,7 +251,7 @@
 
         // If app is animating, it's not able to control refresh rate because we want the animation
         // to run in default refresh rate.
-        if (w.isAnimating(TRANSITION | PARENTS)) {
+        if (w.isAnimationRunningSelfOrParent()) {
             return w.mFrameRateVote.reset();
         }
 
@@ -234,14 +260,10 @@
         if (refreshRateSwitchingType != SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY) {
             final int preferredModeId = w.mAttrs.preferredDisplayModeId;
             if (preferredModeId > 0) {
-                DisplayInfo info = w.getDisplayInfo();
-                if (info != null) {
-                    for (Display.Mode mode : info.supportedModes) {
-                        if (preferredModeId == mode.getModeId()) {
-                            return w.mFrameRateVote.update(mode.getRefreshRate(),
-                                    Surface.FRAME_RATE_COMPATIBILITY_EXACT);
-
-                        }
+                for (Display.Mode mode : mDisplayInfo.supportedModes) {
+                    if (preferredModeId == mode.getModeId()) {
+                        return w.mFrameRateVote.update(mode.getRefreshRate(),
+                                Surface.FRAME_RATE_COMPATIBILITY_EXACT);
                     }
                 }
             }
@@ -268,7 +290,7 @@
     float getPreferredMinRefreshRate(WindowState w) {
         // If app is animating, it's not able to control refresh rate because we want the animation
         // to run in default refresh rate.
-        if (w.isAnimating(TRANSITION | PARENTS)) {
+        if (w.isAnimationRunningSelfOrParent()) {
             return 0;
         }
 
@@ -291,7 +313,7 @@
     float getPreferredMaxRefreshRate(WindowState w) {
         // If app is animating, it's not able to control refresh rate because we want the animation
         // to run in default refresh rate.
-        if (w.isAnimating(TRANSITION | PARENTS)) {
+        if (w.isAnimationRunningSelfOrParent()) {
             return 0;
         }
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index e8aa2c8..8c0b5b9 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -136,6 +136,7 @@
 import android.view.DisplayInfo;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
+import android.window.TaskFragmentAnimationParams;
 import android.window.WindowContainerToken;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -234,6 +235,10 @@
     WindowManagerService mWindowManager;
     DisplayManager mDisplayManager;
     private DisplayManagerInternal mDisplayManagerInternal;
+    @NonNull
+    private final DeviceStateController mDeviceStateController;
+    @NonNull
+    private final DisplayRotationCoordinator mDisplayRotationCoordinator;
 
     /** Reference to default display so we can quickly look it up. */
     private DisplayContent mDefaultDisplay;
@@ -380,9 +385,9 @@
             }
 
             ProtoLog.d(WM_DEBUG_TASKS, "Comparing existing cls=%s /aff=%s to new cls=%s /aff=%s",
-                    r.getTask().rootAffinity, mIntent.getComponent().flattenToShortString(),
-                    mInfo.taskAffinity, (task.realActivity != null
-                            ? task.realActivity.flattenToShortString() : ""));
+                    (task.realActivity != null ? task.realActivity.flattenToShortString() : ""),
+                    task.rootAffinity, mIntent.getComponent().flattenToShortString(),
+                    mTaskAffinity);
             // TODO Refactor to remove duplications. Check if logic can be simplified.
             if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
                     && Objects.equals(documentData, taskDocumentData)) {
@@ -440,6 +445,8 @@
         mTaskSupervisor = mService.mTaskSupervisor;
         mTaskSupervisor.mRootWindowContainer = this;
         mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG);
+        mDeviceStateController = new DeviceStateController(service.mContext, service.mH);
+        mDisplayRotationCoordinator = new DisplayRotationCoordinator();
     }
 
     /**
@@ -1279,7 +1286,8 @@
         final Display[] displays = mDisplayManager.getDisplays();
         for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
             final Display display = displays[displayNdx];
-            final DisplayContent displayContent = new DisplayContent(display, this);
+            final DisplayContent displayContent =
+                    new DisplayContent(display, this, mDeviceStateController);
             addChild(displayContent, POSITION_BOTTOM);
             if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
                 mDefaultDisplay = displayContent;
@@ -1297,6 +1305,11 @@
         return mDefaultDisplay;
     }
 
+    @NonNull
+    DisplayRotationCoordinator getDisplayRotationCoordinator() {
+        return mDisplayRotationCoordinator;
+    }
+
     /**
      * Get the default display area on the device dedicated to app windows. This one should be used
      * only as a fallback location for activity launches when no target display area is specified,
@@ -1358,7 +1371,7 @@
             return null;
         }
         // The display hasn't been added to ActivityManager yet, create a new record now.
-        displayContent = new DisplayContent(display, this);
+        displayContent = new DisplayContent(display, this, mDeviceStateController);
         addChild(displayContent, POSITION_BOTTOM);
         return displayContent;
     }
@@ -2082,6 +2095,8 @@
                     return;
                 }
                 tf.resetAdjacentTaskFragment();
+                tf.setCompanionTaskFragment(null /* companionTaskFragment */);
+                tf.setAnimationParams(TaskFragmentAnimationParams.DEFAULT);
                 if (tf.getTopNonFinishingActivity() != null) {
                     // When the Task is entering picture-in-picture, we should clear all override
                     // from the client organizer, so the PIP activity can get the correct config
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 98ca9ae..5860776 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -146,8 +146,8 @@
                 .setLaunchRootTask(options.getLaunchRootTask())
                 .setPendingIntentBackgroundActivityStartMode(
                         options.getPendingIntentBackgroundActivityStartMode())
-                .setIgnorePendingIntentCreatorForegroundState(
-                        options.getIgnorePendingIntentCreatorForegroundState());
+                .setPendingIntentCreatorBackgroundActivityStartMode(
+                        options.getPendingIntentCreatorBackgroundActivityStartMode());
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index ca86db9..408ea6e 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -565,6 +565,11 @@
     public static final int ANIMATION_TYPE_STARTING_REVEAL = 1 << 7;
 
     /**
+     * Animation when a back gesture animation is applied to a window container.
+     * @hide
+     */
+    public static final int ANIMATION_TYPE_PREDICT_BACK = 1 << 8;
+    /**
      * Bitmask to include all animation types. This is NOT an {@link AnimationType}
      * @hide
      */
@@ -583,7 +588,8 @@
             ANIMATION_TYPE_WINDOW_ANIMATION,
             ANIMATION_TYPE_INSETS_CONTROL,
             ANIMATION_TYPE_TOKEN_TRANSFORM,
-            ANIMATION_TYPE_STARTING_REVEAL
+            ANIMATION_TYPE_STARTING_REVEAL,
+            ANIMATION_TYPE_PREDICT_BACK
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface AnimationType {}
@@ -602,6 +608,7 @@
             case ANIMATION_TYPE_INSETS_CONTROL: return "insets_animation";
             case ANIMATION_TYPE_TOKEN_TRANSFORM: return "token_transform";
             case ANIMATION_TYPE_STARTING_REVEAL: return "starting_reveal";
+            case ANIMATION_TYPE_PREDICT_BACK: return "predict_back";
             default: return "unknown type:" + type;
         }
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index ee11f68..986c8f4 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -149,7 +149,6 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
-import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -171,6 +170,7 @@
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.DisplayInfo;
+import android.view.InsetsSource;
 import android.view.InsetsState;
 import android.view.RemoteAnimationAdapter;
 import android.view.Surface;
@@ -2833,14 +2833,13 @@
     void adjustAnimationBoundsForTransition(Rect animationBounds) {
         TaskTransitionSpec spec = mWmService.mTaskTransitionSpec;
         if (spec != null) {
-            for (@InsetsState.InternalInsetsType int insetType : spec.animationBoundInsets) {
-                WindowContainerInsetsSourceProvider insetProvider = getDisplayContent()
-                        .getInsetsStateController()
-                        .getSourceProvider(insetType);
-
-                Insets insets = insetProvider.getSource().calculateVisibleInsets(
-                        animationBounds);
-                animationBounds.inset(insets);
+            final InsetsState state =
+                    getDisplayContent().getInsetsStateController().getRawInsetsState();
+            for (int id : spec.animationBoundInsets) {
+                final InsetsSource source = state.peekSource(id);
+                if (source != null) {
+                    animationBounds.inset(source.calculateVisibleInsets(animationBounds));
+                }
             }
         }
     }
@@ -5874,9 +5873,6 @@
         }
 
         positionChildAt(POSITION_TOP, child, true /* includingParents */);
-
-        final DisplayContent displayContent = getDisplayContent();
-        displayContent.layoutAndAssignWindowLayersIfNeeded();
     }
 
     void positionChildAtBottom(Task child) {
@@ -5897,7 +5893,6 @@
         }
 
         positionChildAt(POSITION_BOTTOM, child, includingParents);
-        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
     }
 
     @Override
@@ -5911,12 +5906,6 @@
             // Non-root task position changed.
             mRootWindowContainer.invalidateTaskLayers();
         }
-
-        final boolean isTop = getTopChild() == child;
-        if (isTop) {
-            final DisplayContent displayContent = getDisplayContent();
-            displayContent.layoutAndAssignWindowLayersIfNeeded();
-        }
     }
 
     void reparent(TaskDisplayArea newParent, boolean onTop) {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 0457408..a0608db 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -405,8 +405,6 @@
 
         child.updateTaskMovement(moveToTop, targetPosition);
 
-        mDisplayContent.layoutAndAssignWindowLayersIfNeeded();
-
         // The insert position may be adjusted to non-top when there is always-on-top root task.
         // Since the original position is preferred to be top, the root task should have higher
         // priority when we are looking for top focusable root task. The condition {@code
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index eb06b91..294e90b 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2813,7 +2813,7 @@
     void removeImmediately() {
         mIsRemovalRequested = false;
         resetAdjacentTaskFragment();
-        cleanUp();
+        cleanUpEmbeddedTaskFragment();
         final boolean shouldExecuteAppTransition =
                 mClearedTaskFragmentForPip && isTaskVisibleRequested();
         super.removeImmediately();
@@ -2830,10 +2830,20 @@
     }
 
     /** Called on remove to cleanup. */
-    private void cleanUp() {
-        if (mIsEmbedded) {
-            mAtmService.mWindowOrganizerController.cleanUpEmbeddedTaskFragment(this);
+    private void cleanUpEmbeddedTaskFragment() {
+        if (!mIsEmbedded) {
+            return;
         }
+        mAtmService.mWindowOrganizerController.cleanUpEmbeddedTaskFragment(this);
+        final Task task = getTask();
+        if (task == null) {
+            return;
+        }
+        task.forAllLeafTaskFragments(taskFragment -> {
+            if (taskFragment.getCompanionTaskFragment() == this) {
+                taskFragment.setCompanionTaskFragment(null /* companionTaskFragment */);
+            }
+        }, false /* traverseTopToBottom */);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 8570db2..3a30e4b 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -722,6 +722,14 @@
         return true;
     }
 
+    boolean isSupportWindowlessStartingSurface() {
+        // Enable after ag/20426257
+        final ITaskOrganizer lastOrganizer = mTaskOrganizers.peekLast();
+        if (lastOrganizer == null) {
+            return false;
+        }
+        return false;
+    }
     /**
      * Notify the shell ({@link com.android.wm.shell.ShellTaskOrganizer} that the client has
      * removed the splash screen view.
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index d2f30ce..d23b954 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -41,6 +41,7 @@
 import static android.view.WindowManager.TransitionFlags;
 import static android.view.WindowManager.TransitionType;
 import static android.view.WindowManager.transitTypeToString;
+import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR;
 import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
 import static android.window.TransitionInfo.FLAG_FILLS_TASK;
 import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
@@ -92,6 +93,7 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -216,6 +218,12 @@
 
     final TransitionController.Logger mLogger = new TransitionController.Logger();
 
+    /**
+     * {@code false} if this transition runs purely in WMCore (meaning Shell is completely unaware
+     * of it). Currently, this happens before the display is ready since nothing can be seen yet.
+     */
+    boolean mIsPlayerEnabled = true;
+
     Transition(@TransitionType int type, @TransitionFlags int flags,
             TransitionController controller, BLASTSyncEngine syncEngine) {
         mType = type;
@@ -225,7 +233,7 @@
         mToken = new Token(this);
 
         mLogger.mCreateWallTimeMs = System.currentTimeMillis();
-        mLogger.mCreateTimeNs = SystemClock.uptimeNanos();
+        mLogger.mCreateTimeNs = SystemClock.elapsedRealtimeNanos();
         controller.mTransitionTracer.logState(this);
     }
 
@@ -277,6 +285,17 @@
         return false;
     }
 
+    /** @return whether `wc` is a descendent of a transient-hide window. */
+    boolean isInTransientHide(@NonNull WindowContainer wc) {
+        if (mTransientLaunches == null) return false;
+        for (int i = 0; i < mTransientLaunches.size(); ++i) {
+            if (wc.isDescendantOf(mTransientLaunches.valueAt(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     boolean isTransientLaunch(@NonNull ActivityRecord activity) {
         return mTransientLaunches != null && mTransientLaunches.containsKey(activity);
     }
@@ -374,6 +393,14 @@
         return mState == STATE_STARTED;
     }
 
+    boolean isPlaying() {
+        return mState == STATE_PLAYING;
+    }
+
+    boolean isFinished() {
+        return mState == STATE_FINISHED;
+    }
+
     @VisibleForTesting
     void startCollecting(long timeoutMs) {
         startCollecting(timeoutMs, TransitionController.SYNC_METHOD);
@@ -388,7 +415,7 @@
         mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG, method);
 
         mLogger.mSyncId = mSyncId;
-        mLogger.mCollectTimeNs = SystemClock.uptimeNanos();
+        mLogger.mCollectTimeNs = SystemClock.elapsedRealtimeNanos();
         mController.mTransitionTracer.logState(this);
     }
 
@@ -401,14 +428,17 @@
         if (mState < STATE_COLLECTING) {
             throw new IllegalStateException("Can't start Transition which isn't collecting.");
         } else if (mState >= STATE_STARTED) {
-            Slog.w(TAG, "Transition already started: " + mSyncId);
+            Slog.w(TAG, "Transition already started id=" + mSyncId + " state=" + mState);
+            // The transition may be aborted (STATE_ABORT) or timed out (STATE_PLAYING by
+            // SyncGroup#finishNow), so do not revert the state to STATE_STARTED.
+            return;
         }
         mState = STATE_STARTED;
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
                 mSyncId);
         applyReady();
 
-        mLogger.mStartTimeNs = SystemClock.uptimeNanos();
+        mLogger.mStartTimeNs = SystemClock.elapsedRealtimeNanos();
         mController.mTransitionTracer.logState(this);
 
         mController.updateAnimatingState(mTmpTransaction);
@@ -618,7 +648,7 @@
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                 "Set transition ready=%b %d", ready, mSyncId);
         mSyncEngine.setReady(mSyncId, ready);
-        if (ready) mLogger.mReadyTimeNs = SystemClock.uptimeNanos();
+        if (ready) mLogger.mReadyTimeNs = SystemClock.elapsedRealtimeNanos();
     }
 
     /**
@@ -766,11 +796,11 @@
      * be called directly; use {@link TransitionController#finishTransition} instead.
      */
     void finishTransition() {
-        if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+        if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER) && mIsPlayerEnabled) {
             Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, TRACE_NAME_PLAY_TRANSITION,
                     System.identityHashCode(this));
         }
-        mLogger.mFinishTimeNs = SystemClock.uptimeNanos();
+        mLogger.mFinishTimeNs = SystemClock.elapsedRealtimeNanos();
         mController.mLoggerHandler.post(mLogger::logOnFinish);
         // Close the transactions now. They were originally copied to Shell in case we needed to
         // apply them due to a remote failure. Since we don't need to apply them anymore, free them
@@ -825,6 +855,11 @@
                         && ar.isVisible()) {
                     // Transient launch was committed, so report enteringAnimation
                     ar.mEnteringAnimation = true;
+                    // Since transient launches don't automatically take focus, make sure we
+                    // synchronize focus since we committed to the launch.
+                    if (ar.isTopRunningActivity()) {
+                        ar.moveFocusableActivityToTop("transitionFinished");
+                    }
                 }
                 continue;
             }
@@ -1096,13 +1131,15 @@
             controller.setupStartTransaction(transaction);
         }
         buildFinishTransaction(mFinishTransaction, info.getRootLeash());
-        if (mController.getTransitionPlayer() != null) {
+        if (mController.getTransitionPlayer() != null && mIsPlayerEnabled) {
             mController.dispatchLegacyAppTransitionStarting(info, mStatusBarTransitionDelay);
             try {
                 ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                         "Calling onTransitionReady: %s", info);
-                mLogger.mSendTimeNs = SystemClock.uptimeNanos();
+                mLogger.mSendTimeNs = SystemClock.elapsedRealtimeNanos();
                 mLogger.mInfo = info;
+                mController.mTransitionTracer.logSentTransition(
+                        this, mTargets, mLogger.mCreateTimeNs, mLogger.mSendTimeNs, info);
                 mController.getTransitionPlayer().onTransitionReady(
                         mToken, info, transaction, mFinishTransaction);
                 if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
@@ -1112,11 +1149,21 @@
             } catch (RemoteException e) {
                 // If there's an exception when trying to send the mergedTransaction to the
                 // client, we should finish and apply it here so the transactions aren't lost.
-                cleanUpOnFailure();
+                postCleanupOnFailure();
+            }
+            final AccessibilityController accessibilityController =
+                    dc.mWmService.mAccessibilityController;
+            if (accessibilityController.hasCallbacks()) {
+                accessibilityController.onWMTransition(dc.getDisplayId(), mType);
             }
         } else {
-            // No player registered, so just finish/apply immediately
-            cleanUpOnFailure();
+            // No player registered or it's not enabled, so just finish/apply immediately
+            if (!mIsPlayerEnabled) {
+                mLogger.mSendTimeNs = SystemClock.uptimeNanos();
+                ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Apply and finish immediately"
+                        + " because player is disabled for transition #%d .", mSyncId);
+            }
+            postCleanupOnFailure();
         }
         mController.mLoggerHandler.post(mLogger::logOnSend);
         mOverrideOptions = null;
@@ -1127,6 +1174,14 @@
         info.releaseAnimSurfaces();
     }
 
+    private void postCleanupOnFailure() {
+        mController.mAtm.mH.post(() -> {
+            synchronized (mController.mAtm.mGlobalLock) {
+                cleanUpOnFailure();
+            }
+        });
+    }
+
     /**
      * If the remote failed for any reason, use this to do any appropriate clean-up. Do not call
      * this directly, it's designed to by called by {@link TransitionController} only.
@@ -1170,6 +1225,7 @@
         }
     }
 
+    // TODO(b/188595497): Remove after migrating to shell.
     /** @see RecentsAnimationController#attachNavigationBarToApp */
     private void handleLegacyRecentsStartBehavior(DisplayContent dc, TransitionInfo info) {
         if ((mFlags & TRANSIT_FLAG_IS_RECENTS) == 0) {
@@ -1250,8 +1306,9 @@
             // Place the nav bar on top of anything else in the top activity.
             t.setLayer(navSurfaceControl, Integer.MAX_VALUE);
         }
-        if (mController.mStatusBar != null) {
-            mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, false);
+        final StatusBarManagerInternal bar = dc.getDisplayPolicy().getStatusBarManagerInternal();
+        if (bar != null) {
+            bar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, false);
         }
     }
 
@@ -1265,12 +1322,12 @@
             mRecentsDisplayId = DEFAULT_DISPLAY;
         }
 
-        if (mController.mStatusBar != null) {
-            mController.mStatusBar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, true);
-        }
-
         final DisplayContent dc =
                 mController.mAtm.mRootWindowContainer.getDisplayContent(mRecentsDisplayId);
+        final StatusBarManagerInternal bar = dc.getDisplayPolicy().getStatusBarManagerInternal();
+        if (bar != null) {
+            bar.setNavigationBarLumaSamplingEnabled(mRecentsDisplayId, true);
+        }
         final WindowState navWindow = dc.getDisplayPolicy().getNavigationBar();
         if (navWindow == null) return;
         navWindow.setSurfaceTranslationY(0);
@@ -1794,7 +1851,7 @@
                         ? activityRecord.getOrganizedTaskFragment()
                         : taskFragment.getOrganizedTaskFragment();
                 if (organizedTf != null && organizedTf.getAnimationParams()
-                        .getAnimationBackgroundColor() != 0) {
+                        .getAnimationBackgroundColor() != DEFAULT_ANIMATION_BACKGROUND_COLOR) {
                     // This window is embedded and has an animation background color set on the
                     // TaskFragment. Pass this color with this window, so the handler can use it as
                     // the animation background color if needed,
@@ -1806,10 +1863,11 @@
                     final Task parentTask = activityRecord != null
                             ? activityRecord.getTask()
                             : taskFragment.getTask();
-                    backgroundColor = ColorUtils.setAlphaComponent(
-                            parentTask.getTaskDescription().getBackgroundColor(), 255);
+                    backgroundColor = parentTask.getTaskDescription().getBackgroundColor();
                 }
-                change.setBackgroundColor(backgroundColor);
+                // Set to opaque for animation background to prevent it from exposing the blank
+                // background or content below.
+                change.setBackgroundColor(ColorUtils.setAlphaComponent(backgroundColor, 255));
             }
 
             change.setRotation(info.mRotation, endRotation);
@@ -1954,17 +2012,15 @@
         return mainWin.getAttrs().rotationAnimation;
     }
 
-    /** Applies the new configuration and returns {@code true} if there is a display change. */
-    boolean applyDisplayChangeIfNeeded() {
-        boolean changed = false;
+    /** Applies the new configuration for the changed displays. */
+    void applyDisplayChangeIfNeeded() {
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
             final WindowContainer<?> wc = mParticipants.valueAt(i);
             final DisplayContent dc = wc.asDisplayContent();
             if (dc == null || !mChanges.get(dc).hasChanged()) continue;
             dc.sendNewConfiguration();
-            changed = true;
+            setReady(dc, true);
         }
-        return changed;
     }
 
     boolean getLegacyIsReady() {
@@ -2046,7 +2102,7 @@
 
         @VisibleForTesting
         ChangeInfo(@NonNull WindowContainer container, boolean visible, boolean existChange) {
-            mContainer = container;
+            this(container);
             mVisible = visible;
             mExistenceChanged = existChange;
             mShowWallpaper = false;
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 5e116ba..ed7e9ed 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -55,8 +55,6 @@
 import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.FgThread;
-import com.android.server.LocalServices;
-import com.android.server.statusbar.StatusBarManagerInternal;
 
 import java.util.ArrayList;
 import java.util.function.LongConsumer;
@@ -88,12 +86,12 @@
 
     private ITransitionPlayer mTransitionPlayer;
     final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
-    final TransitionTracer mTransitionTracer;
 
     private WindowProcessController mTransitionPlayerProc;
     final ActivityTaskManagerService mAtm;
-    final TaskSnapshotController mTaskSnapshotController;
     final RemotePlayer mRemotePlayer;
+    TaskSnapshotController mTaskSnapshotController;
+    TransitionTracer mTransitionTracer;
 
     private final ArrayList<WindowManagerInternal.AppTransitionListener> mLegacyListeners =
             new ArrayList<>();
@@ -111,9 +109,6 @@
     /** The transition currently being constructed (collecting participants). */
     private Transition mCollectingTransition = null;
 
-    // TODO(b/188595497): remove when not needed.
-    final StatusBarManagerInternal mStatusBar;
-
     /**
      * `true` when building surface layer order for the finish transaction. We want to prevent
      * wm from touching z-order of surfaces during transitions, but we still need to be able to
@@ -126,14 +121,16 @@
 
     final Handler mLoggerHandler = FgThread.getHandler();
 
-    TransitionController(ActivityTaskManagerService atm,
-            TaskSnapshotController taskSnapshotController,
-            TransitionTracer transitionTracer) {
+    /**
+     * {@code true} While this waits for the display to become enabled (during boot). While waiting
+     * for the display, all core-initiated transitions will be "local".
+     * Note: This defaults to false so that it doesn't interfere with unit tests.
+     */
+    boolean mIsWaitingForDisplayEnabled = false;
+
+    TransitionController(ActivityTaskManagerService atm) {
         mAtm = atm;
         mRemotePlayer = new RemotePlayer(atm);
-        mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
-        mTaskSnapshotController = taskSnapshotController;
-        mTransitionTracer = transitionTracer;
         mTransitionPlayerDeath = () -> {
             synchronized (mAtm.mGlobalLock) {
                 detachPlayer();
@@ -141,6 +138,13 @@
         };
     }
 
+    void setWindowManager(WindowManagerService wms) {
+        mTaskSnapshotController = wms.mTaskSnapshotController;
+        mTransitionTracer = wms.mTransitionTracer;
+        mIsWaitingForDisplayEnabled = !wms.mDisplayEnabled;
+        registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
+    }
+
     private void detachPlayer() {
         if (mTransitionPlayer == null) return;
         // Clean-up/finish any playing transitions.
@@ -353,11 +357,37 @@
     }
 
     /**
+     * During transient-launch, the "behind" app should retain focus during the transition unless
+     * something takes focus from it explicitly (eg. by calling ATMS.setFocusedTask or by another
+     * transition interrupting this one.
+     *
+     * The rules around this are basically: if there is exactly one active transition and `wc` is
+     * the "behind" of a transient launch, then it can retain focus.
+     */
+    boolean shouldKeepFocus(@NonNull WindowContainer wc) {
+        if (mCollectingTransition != null) {
+            if (!mPlayingTransitions.isEmpty()) return false;
+            return mCollectingTransition.isInTransientHide(wc);
+        } else if (mPlayingTransitions.size() == 1) {
+            return mPlayingTransitions.get(0).isInTransientHide(wc);
+        }
+        return false;
+    }
+
+    /**
+     * @return {@code true} if {@param ar} is part of a transient-launch activity in the
+     * collecting transition.
+     */
+    boolean isTransientCollect(@NonNull ActivityRecord ar) {
+        return mCollectingTransition != null && mCollectingTransition.isTransientLaunch(ar);
+    }
+
+    /**
      * @return {@code true} if {@param ar} is part of a transient-launch activity in an active
      * transition.
      */
     boolean isTransientLaunch(@NonNull ActivityRecord ar) {
-        if (mCollectingTransition != null && mCollectingTransition.isTransientLaunch(ar)) {
+        if (isTransientCollect(ar)) {
             return true;
         }
         for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
@@ -460,6 +490,15 @@
     Transition requestStartTransition(@NonNull Transition transition, @Nullable Task startTask,
             @Nullable RemoteTransition remoteTransition,
             @Nullable TransitionRequestInfo.DisplayChange displayChange) {
+        if (mIsWaitingForDisplayEnabled) {
+            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Disabling player for transition"
+                    + " #%d because display isn't enabled yet", transition.getSyncId());
+            transition.mIsPlayerEnabled = false;
+            transition.mLogger.mRequestTimeNs = SystemClock.uptimeNanos();
+            mAtm.mH.post(() -> mAtm.mWindowOrganizerController.startTransition(
+                    transition.getToken(), null));
+            return transition;
+        }
         try {
             ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                     "Requesting StartTransition: %s", transition);
@@ -470,7 +509,7 @@
             }
             final TransitionRequestInfo request = new TransitionRequestInfo(
                     transition.mType, info, remoteTransition, displayChange);
-            transition.mLogger.mRequestTimeNs = SystemClock.uptimeNanos();
+            transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos();
             transition.mLogger.mRequest = request;
             mTransitionPlayer.requestStartTransition(transition.getToken(), request);
             transition.setRemoteTransition(remoteTransition);
diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java
index 022c19b..7b1975d 100644
--- a/services/core/java/com/android/server/wm/TransitionTracer.java
+++ b/services/core/java/com/android/server/wm/TransitionTracer.java
@@ -21,19 +21,14 @@
 import static com.android.server.wm.shell.ChangeInfo.CHANGE_FLAGS;
 import static com.android.server.wm.shell.ChangeInfo.HAS_CHANGED;
 import static com.android.server.wm.shell.ChangeInfo.TRANSIT_MODE;
+import static com.android.server.wm.shell.ChangeInfo.WINDOWING_MODE;
 import static com.android.server.wm.shell.ChangeInfo.WINDOW_IDENTIFIER;
-import static com.android.server.wm.shell.Transition.CHANGE;
-import static com.android.server.wm.shell.Transition.FINISH_TRANSACTION_ID;
-import static com.android.server.wm.shell.Transition.FLAGS;
-import static com.android.server.wm.shell.Transition.ID;
-import static com.android.server.wm.shell.Transition.START_TRANSACTION_ID;
-import static com.android.server.wm.shell.Transition.STATE;
-import static com.android.server.wm.shell.Transition.TIMESTAMP;
-import static com.android.server.wm.shell.Transition.TRANSITION_TYPE;
+import static com.android.server.wm.shell.TransitionInfoChange.LAYER_ID;
+import static com.android.server.wm.shell.TransitionInfoChange.MODE;
+import static com.android.server.wm.shell.TransitionState.CHANGE;
 import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER;
 import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_H;
 import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_L;
-import static com.android.server.wm.shell.TransitionTraceProto.TRANSITION;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -41,14 +36,15 @@
 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;
-import com.android.server.wm.shell.TransitionTraceProto;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
 /**
  * Helper class to collect and dump transition traces.
@@ -57,10 +53,8 @@
 
     private static final String LOG_TAG = "TransitionTracer";
 
-    /**
-     * Maximum buffer size, currently defined as 5 MB
-     */
-    private static final int BUFFER_CAPACITY = 5120 * 1024; // 5 MB
+    private static final int ALWAYS_ON_TRACING_CAPACITY = 15 * 1024; // 15 KB
+    private static final int ACTIVE_TRACING_BUFFER_CAPACITY = 5000 * 1024; // 5 MB
     static final String WINSCOPE_EXT = ".winscope";
     private static final String TRACE_FILE = "/data/misc/wmtrace/transition_trace" + WINSCOPE_EXT;
     private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
@@ -68,28 +62,129 @@
     private final TransitionTraceBuffer mTraceBuffer = new TransitionTraceBuffer();
 
     private final Object mEnabledLock = new Object();
-    private volatile boolean mEnabled = false;
+    private volatile boolean mActiveTracingEnabled = false;
 
-    private long mTraceStartTimestamp;
+    /**
+     * Records key information about a transition that has been sent to Shell to be played.
+     * @param transition The transition that has been sent to Shell.
+     * @param targets Information about the target windows of the transition.
+     * @param createTimeNs System elapsed time (nanoseconds since boot including sleep time) at
+ *                     which the transition to be recorded was created.
+     * @param sendTimeNs System elapsed time (nanoseconds since boot including sleep time) at which
+     * @param info
+     */
+    public void logSentTransition(Transition transition, ArrayList<ChangeInfo> targets,
+            long createTimeNs, long sendTimeNs, TransitionInfo info) {
+        mTraceBuffer.pushSentTransition(transition, targets, createTimeNs, sendTimeNs);
+        logTransitionInfo(transition, info);
+    }
+
+    /**
+     * Records the current state of a transition in the transition trace (if it is running).
+     * @param transition the transition that we want to record the state of.
+     */
+    public void logState(com.android.server.wm.Transition transition) {
+        if (!mActiveTracingEnabled) {
+            return;
+        }
+        mTraceBuffer.pushTransitionState(transition);
+    }
+
+    /**
+     * Records the transition info that is being sent over to Shell.
+     * @param transition The transition the info is associated with.
+     * @param info The transition info we want to log.
+     */
+    private void logTransitionInfo(Transition transition, TransitionInfo info) {
+        if (!mActiveTracingEnabled) {
+            return;
+        }
+        mTraceBuffer.pushTransitionInfo(transition, info);
+    }
 
     private class TransitionTraceBuffer {
-        private final TraceBuffer mBuffer = new TraceBuffer(BUFFER_CAPACITY);
+        private final TraceBuffer mBuffer = new TraceBuffer(ALWAYS_ON_TRACING_CAPACITY);
+        private final TraceBuffer mStateBuffer = new TraceBuffer(ACTIVE_TRACING_BUFFER_CAPACITY);
+        private final TraceBuffer mTransitionInfoBuffer =
+                new TraceBuffer(ACTIVE_TRACING_BUFFER_CAPACITY);
+
+        public void pushSentTransition(
+                Transition transition,
+                ArrayList<ChangeInfo> targets,
+                long createTimeNs,
+                long sendTimeNs
+        ) {
+            Trace.beginSection("TransitionTraceBuffer#pushSentTransition");
+            final ProtoOutputStream outputStream = new ProtoOutputStream();
+            final long transitionToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionTraceProto.SENT_TRANSITIONS);
+
+            if (mActiveTracingEnabled) {
+                outputStream.write(com.android.server.wm.shell.Transition.ID,
+                        transition.getSyncId());
+            }
+
+            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());
+
+            outputStream.write(com.android.server.wm.shell.Transition.CREATE_TIME_NS, createTimeNs);
+            outputStream.write(com.android.server.wm.shell.Transition.SEND_TIME_NS, sendTimeNs);
+
+            for (int i = 0; i < targets.size(); ++i) {
+                final long changeToken = outputStream
+                        .start(com.android.server.wm.shell.Transition.TARGETS);
+
+                final Transition.ChangeInfo target = targets.get(i);
+
+                final int mode = target.getTransitMode(target.mContainer);
+                final int layerId;
+                if (target.mContainer.mSurfaceControl.isValid()) {
+                    layerId = target.mContainer.mSurfaceControl.getLayerId();
+                } else {
+                    layerId = -1;
+                }
+
+                outputStream.write(com.android.server.wm.shell.Target.MODE, mode);
+                outputStream.write(com.android.server.wm.shell.Target.LAYER_ID, layerId);
+
+                if (mActiveTracingEnabled) {
+                    // What we use in the WM trace
+                    final int windowId = System.identityHashCode(target.mContainer);
+                    outputStream.write(com.android.server.wm.shell.Target.WINDOW_ID, windowId);
+                }
+
+                outputStream.end(changeToken);
+            }
+
+            outputStream.end(transitionToken);
+            mBuffer.add(outputStream);
+
+            Trace.endSection();
+        }
 
         private void pushTransitionState(Transition transition) {
+            Trace.beginSection("TransitionTraceBuffer#pushTransitionState");
             final ProtoOutputStream outputStream = new ProtoOutputStream();
-            final long transitionEntryToken = outputStream.start(TRANSITION);
+            final long stateToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITION_STATES);
 
-            outputStream.write(ID, transition.getSyncId());
-            outputStream.write(TIMESTAMP, SystemClock.elapsedRealtimeNanos());
-            outputStream.write(TRANSITION_TYPE, transition.mType);
-            outputStream.write(STATE, transition.getState());
-            outputStream.write(FLAGS, transition.getFlags());
-            if (transition.getStartTransaction() != null) {
-                outputStream.write(START_TRANSACTION_ID, transition.getStartTransaction().getId());
-            }
-            if (transition.getFinishTransaction() != null) {
-                outputStream.write(FINISH_TRANSACTION_ID,
-                        transition.getFinishTransaction().getId());
+            outputStream.write(com.android.server.wm.shell.TransitionState.TIME_NS,
+                    SystemClock.elapsedRealtimeNanos());
+            outputStream.write(com.android.server.wm.shell.TransitionState.TRANSITION_ID,
+                    transition.getSyncId());
+            outputStream.write(com.android.server.wm.shell.TransitionState.TRANSITION_TYPE,
+                    transition.mType);
+            outputStream.write(com.android.server.wm.shell.TransitionState.STATE,
+                    transition.getState());
+            outputStream.write(com.android.server.wm.shell.TransitionState.FLAGS,
+                    transition.getFlags());
+
+            for (int i = 0; i < transition.mChanges.size(); ++i) {
+                final WindowContainer window = transition.mChanges.keyAt(i);
+                final ChangeInfo changeInfo = transition.mChanges.valueAt(i);
+                writeChange(outputStream, window, changeInfo);
             }
 
             for (int i = 0; i < transition.mChanges.size(); ++i) {
@@ -98,29 +193,71 @@
                 writeChange(outputStream, window, changeInfo);
             }
 
-            outputStream.end(transitionEntryToken);
+            for (int i = 0; i < transition.mParticipants.size(); ++i) {
+                final WindowContainer window = transition.mParticipants.valueAt(i);
+                window.writeIdentifierToProto(outputStream,
+                        com.android.server.wm.shell.TransitionState.PARTICIPANTS);
+            }
 
-            mBuffer.add(outputStream);
+            outputStream.end(stateToken);
+
+            mStateBuffer.add(outputStream);
+            Trace.endSection();
+        }
+
+        private void pushTransitionInfo(Transition transition, TransitionInfo info) {
+            Trace.beginSection("TransitionTraceBuffer#pushTransitionInfo");
+            final ProtoOutputStream outputStream = new ProtoOutputStream();
+            final long transitionInfoToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITION_INFO);
+
+            outputStream.write(com.android.server.wm.shell.TransitionInfo.TRANSITION_ID,
+                    transition.getSyncId());
+            for (int i = 0; i < info.getChanges().size(); ++i) {
+                TransitionInfo.Change change = info.getChanges().get(i);
+                writeTransitionInfoChange(outputStream, change);
+            }
+
+            outputStream.end(transitionInfoToken);
+            mTransitionInfoBuffer.add(outputStream);
+            Trace.endSection();
         }
 
         private void writeChange(ProtoOutputStream outputStream, WindowContainer window,
                 ChangeInfo changeInfo) {
-            Trace.beginSection("TransitionProto#addChange");
+            Trace.beginSection("TransitionTraceBuffer#writeChange");
             final long changeEntryToken = outputStream.start(CHANGE);
 
             final int transitMode = changeInfo.getTransitMode(window);
             final boolean hasChanged = changeInfo.hasChanged();
             final int changeFlags = changeInfo.getChangeFlags(window);
+            final int windowingMode = changeInfo.mWindowingMode;
 
             outputStream.write(TRANSIT_MODE, transitMode);
             outputStream.write(HAS_CHANGED, hasChanged);
             outputStream.write(CHANGE_FLAGS, changeFlags);
+            outputStream.write(WINDOWING_MODE, windowingMode);
             window.writeIdentifierToProto(outputStream, WINDOW_IDENTIFIER);
 
             outputStream.end(changeEntryToken);
             Trace.endSection();
         }
 
+        private void writeTransitionInfoChange(
+                ProtoOutputStream outputStream,
+                TransitionInfo.Change change
+        ) {
+            Trace.beginSection("TransitionTraceBuffer#writeTransitionInfoChange");
+            final long changeEntryToken = outputStream
+                    .start(com.android.server.wm.shell.TransitionInfo.CHANGE);
+
+            outputStream.write(LAYER_ID, change.getLeash().getLayerId());
+            outputStream.write(MODE, change.getMode());
+
+            outputStream.end(changeEntryToken);
+            Trace.endSection();
+        }
+
         public void writeToFile(File file, ProtoOutputStream proto) throws IOException {
             mBuffer.writeTraceToFile(file, proto);
         }
@@ -131,19 +268,6 @@
     }
 
     /**
-     * Records the current state of a transition in the transition trace (if it is running).
-     * @param transition the transition that we want to record the state of.
-     */
-    public void logState(com.android.server.wm.Transition transition) {
-        if (!mEnabled) {
-            return;
-        }
-
-        Log.d(LOG_TAG, "Logging state of transition " + transition);
-        mTraceBuffer.pushTransitionState(transition);
-    }
-
-    /**
      * Starts collecting transitions for the trace.
      * If called while a trace is already running, this will reset the trace.
      */
@@ -155,8 +279,8 @@
         Trace.beginSection("TransitionTracer#startTrace");
         LogAndPrintln.i(pw, "Starting shell transition trace.");
         synchronized (mEnabledLock) {
-            mTraceStartTimestamp = SystemClock.elapsedRealtime();
-            mEnabled = true;
+            mActiveTracingEnabled = true;
+            mTraceBuffer.mBuffer.setCapacity(ACTIVE_TRACING_BUFFER_CAPACITY);
             mTraceBuffer.reset();
         }
         Trace.endSection();
@@ -183,20 +307,15 @@
         Trace.beginSection("TransitionTracer#stopTrace");
         LogAndPrintln.i(pw, "Stopping shell transition trace.");
         synchronized (mEnabledLock) {
-            if (!mEnabled) {
-                LogAndPrintln.e(pw,
-                        "Error: Tracing can't be stopped because it hasn't been started.");
-                return;
-            }
-
-            mEnabled = false;
+            mActiveTracingEnabled = false;
             writeTraceToFileLocked(pw, outputFile);
+            mTraceBuffer.mBuffer.setCapacity(ALWAYS_ON_TRACING_CAPACITY);
         }
         Trace.endSection();
     }
 
-    boolean isEnabled() {
-        return mEnabled;
+    boolean isActiveTracingEnabled() {
+        return mActiveTracingEnabled;
     }
 
     private void writeTraceToFileLocked(@Nullable PrintWriter pw, File file) {
@@ -204,7 +323,6 @@
         try {
             ProtoOutputStream proto = new ProtoOutputStream();
             proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
-            proto.write(TransitionTraceProto.TIMESTAMP, mTraceStartTimestamp);
             int pid = android.os.Process.myPid();
             LogAndPrintln.i(pw, "Writing file to " + file.getAbsolutePath()
                     + " from process " + pid);
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 6b2bf59..8708f73 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -41,6 +41,8 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM;
 
+    private boolean mShowWhenLocked = false;
+
     WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit,
             DisplayContent dc, boolean ownerCanManageAppTokens) {
         this(service, token, explicit, dc, ownerCanManageAppTokens, null /* options */);
@@ -65,6 +67,29 @@
         mDisplayContent.mWallpaperController.removeWallpaperToken(this);
     }
 
+    /**
+     * Controls whether this wallpaper shows underneath the keyguard or is hidden and only
+     * revealed once keyguard is dismissed.
+     */
+    void setShowWhenLocked(boolean showWhenLocked) {
+        if (showWhenLocked == mShowWhenLocked) {
+            return;
+        }
+        mShowWhenLocked = showWhenLocked;
+
+        // Move the window token to the front (private) or back (showWhenLocked). This is possible
+        // because the DisplayArea underneath TaskDisplayArea only contains TYPE_WALLPAPER windows.
+        final int position = showWhenLocked ? POSITION_BOTTOM : POSITION_TOP;
+
+        // Note: Moving all the way to the front or back breaks ordering based on addition times.
+        // We should never have more than one non-animating token of each type.
+        getParent().positionChildAt(position, this /* child */, false  /*includingParents */);
+    }
+
+    boolean canShowWhenLocked() {
+        return mShowWhenLocked;
+    }
+
     void sendWindowWallpaperCommand(
             String action, int x, int y, int z, Bundle extras, boolean sync) {
         for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index b06bdb1..bb706ec 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -33,6 +33,7 @@
 import static android.view.SurfaceControl.Transaction;
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
@@ -170,9 +171,9 @@
     protected InsetsSourceProvider mControllableInsetProvider;
 
     /**
-     * The insets sources provided by this windowContainer.
+     * The {@link InsetsSourceProvider}s provided by this window container.
      */
-    protected SparseArray<InsetsSource> mProvidedInsetsSources = null;
+    protected SparseArray<InsetsSourceProvider> mInsetsSourceProviders = null;
 
     // List of children for this window container. List is in z-order as the children appear on
     // screen with the top-most window container at the tail of the list.
@@ -366,7 +367,7 @@
      * {@link WindowState#mMergedLocalInsetsSources} by visiting the entire hierarchy.
      *
      * {@link WindowState#mAboveInsetsState} is updated by visiting all the windows in z-order
-     * top-to-bottom manner and considering the {@link WindowContainer#mProvidedInsetsSources}
+     * top-to-bottom manner and considering the {@link WindowContainer#mInsetsSourceProviders}
      * provided by the {@link WindowState}s at the top.
      * {@link WindowState#updateAboveInsetsState(InsetsState, SparseArray, ArraySet)} visits the
      * IME container in the correct order to make sure the IME insets are passed correctly to the
@@ -566,7 +567,6 @@
             onDisplayChanged(dc);
             prevDc.setLayoutNeeded();
         }
-        getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
 
         // Send onParentChanged notification here is we disabled sending it in setParent for
         // reparenting case.
@@ -1035,11 +1035,21 @@
         }
     }
 
-    public SparseArray<InsetsSource> getProvidedInsetsSources() {
-        if (mProvidedInsetsSources == null) {
-            mProvidedInsetsSources = new SparseArray<>();
+    /**
+     * Returns {@code true} if this node provides insets.
+     */
+    public boolean hasInsetsSourceProvider() {
+        return mInsetsSourceProviders != null;
+    }
+
+    /**
+     * Returns {@link InsetsSourceProvider}s provided by this node.
+     */
+    public SparseArray<InsetsSourceProvider> getInsetsSourceProviders() {
+        if (mInsetsSourceProviders == null) {
+            mInsetsSourceProviders = new SparseArray<>();
         }
-        return mProvidedInsetsSources;
+        return mInsetsSourceProviders;
     }
 
     public DisplayContent getDisplayContent() {
@@ -3208,7 +3218,7 @@
                             ? activityRecord.getOrganizedTaskFragment()
                             : taskFragment.getOrganizedTaskFragment();
                     if (organizedTf != null && organizedTf.getAnimationParams()
-                            .getAnimationBackgroundColor() != 0) {
+                            .getAnimationBackgroundColor() != DEFAULT_ANIMATION_BACKGROUND_COLOR) {
                         // This window is embedded and has an animation background color set on the
                         // TaskFragment. Pass this color with this window, so the handler can use it
                         // as the animation background color if needed,
@@ -3221,11 +3231,14 @@
                         final Task parentTask = activityRecord != null
                                 ? activityRecord.getTask()
                                 : taskFragment.getTask();
-                        backgroundColorForTransition = ColorUtils.setAlphaComponent(
-                                parentTask.getTaskDescription().getBackgroundColor(), 255);
+                        backgroundColorForTransition = parentTask.getTaskDescription()
+                                .getBackgroundColor();
                     }
                 }
-                animationRunnerBuilder.setTaskBackgroundColor(backgroundColorForTransition);
+                // Set to opaque for animation background to prevent it from exposing the blank
+                // background or content below.
+                animationRunnerBuilder.setTaskBackgroundColor(ColorUtils.setAlphaComponent(
+                        backgroundColorForTransition, 255));
             }
 
             animationRunnerBuilder.build()
@@ -4102,13 +4115,13 @@
             }
         }
 
-        private void hideInsetSourceViewOverflows(Set<Integer> insetTypes) {
-            final ArrayList<SurfaceControl> surfaceControls =
-                    new ArrayList<>(insetTypes.size());
-
-            for (int insetType : insetTypes) {
-                WindowContainerInsetsSourceProvider insetProvider = getDisplayContent()
-                        .getInsetsStateController().getSourceProvider(insetType);
+        private void hideInsetSourceViewOverflows(Set<Integer> sourceIds) {
+            final InsetsStateController controller = getDisplayContent().getInsetsStateController();
+            for (int id : sourceIds) {
+                final InsetsSourceProvider insetProvider = controller.peekSourceProvider(id);
+                if (insetProvider == null) {
+                    return;
+                }
 
                 // Will apply it immediately to current leash and to all future inset animations
                 // until we disable it.
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 1282acb..2f3a70e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -657,6 +657,17 @@
     public abstract int getWindowOwnerUserId(IBinder windowToken);
 
     /**
+     * Control visilibility of a {@link WallpaperWindowToken} {@code} binder on the lock screen.
+     *
+     * <p>This will also affect its Z-ordering as {@code showWhenLocked} wallpaper tokens are
+     * arranged underneath non-{@code showWhenLocked} wallpaper tokens.
+     *
+     * @param windowToken wallpaper token previously added via {@link #addWindowToken}
+     * @param showWhenLocked whether {@param token} can continue to be shown on the lock screen.
+     */
+    public abstract void setWallpaperShowWhenLocked(IBinder windowToken, boolean showWhenLocked);
+
+    /**
      * Returns {@code true} if a Window owned by {@code uid} has focus.
      */
     public abstract boolean isUidFocused(int uid);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b46a720..a63f9a3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -310,6 +310,7 @@
 import com.android.internal.policy.IKeyguardLockedStateListener;
 import com.android.internal.policy.IShortcutService;
 import com.android.internal.policy.KeyInterceptionInfo;
+import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.ProtoLogImpl;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.DumpUtils;
@@ -636,7 +637,8 @@
     String mLastANRState;
 
     // The root of the device window hierarchy.
-    RootWindowContainer mRoot;
+    @NonNull
+    final RootWindowContainer mRoot;
 
     // Whether the system should use BLAST for ViewRootImpl
     final boolean mUseBLAST;
@@ -1337,6 +1339,8 @@
         mConstants.start(new HandlerExecutor(mH));
 
         LocalServices.addService(WindowManagerInternal.class, new LocalService());
+        LocalServices.addService(
+                ImeTargetVisibilityPolicy.class, new ImeTargetVisibilityPolicyImpl());
         mEmbeddedWindowController = new EmbeddedWindowController(mAtmService);
 
         mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(
@@ -3776,6 +3780,12 @@
 
         // Make sure the last requested orientation has been applied.
         updateRotationUnchecked(false, false);
+
+        synchronized (mGlobalLock) {
+            mAtmService.getTransitionController().mIsWaitingForDisplayEnabled = false;
+            ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Notified TransitionController "
+                    + "that the display is ready.");
+        }
     }
 
     private boolean checkBootAnimationCompleteLocked() {
@@ -3835,8 +3845,9 @@
      *
      * If {@code com.android.internal.R.bool.config_perDisplayFocusEnabled} is set to true, then
      * only the display represented by the {@code displayId} parameter will be requested to switch
-     * the touch mode state. Otherwise all all displays will be requested to switch their touch mode
-     * state (disregarding {@code displayId} parameter).
+     * the touch mode state. Otherwise all displays that do not maintain their own focus and touch
+     * mode will be requested to switch their touch mode state (disregarding {@code displayId}
+     * parameter).
      *
      * To be able to change touch mode state, the caller must either own the focused window, or must
      * have the {@link android.Manifest.permission#MODIFY_TOUCH_MODE_STATE} permission. Instrumented
@@ -3848,27 +3859,9 @@
      */
     @Override // Binder call
     public void setInTouchMode(boolean inTouch, int displayId) {
-        boolean perDisplayFocusEnabled = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_perDisplayFocusEnabled);
-        setInTouchMode(inTouch, displayId, perDisplayFocusEnabled);
-    }
-
-    /**
-     * Sets the touch mode state on all displays (disregarding the value of
-     * {@code com.android.internal.R.bool.config_perDisplayFocusEnabled}).
-     *
-     * @param inTouch the touch mode to set
-     */
-    @Override // Binder call
-    public void setInTouchModeOnAllDisplays(boolean inTouch) {
-        setInTouchMode(inTouch, /* any display id */ DEFAULT_DISPLAY,
-                /* perDisplayFocusEnabled= */ false);
-    }
-
-    private void setInTouchMode(boolean inTouch, int displayId, boolean perDisplayFocusEnabled) {
         synchronized (mGlobalLock) {
             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
-            if (perDisplayFocusEnabled && (displayContent == null
+            if (mPerDisplayFocusEnabled && (displayContent == null
                     || displayContent.isInTouchMode() == inTouch)) {
                 return;
             }
@@ -3879,15 +3872,12 @@
             }
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
-            final boolean hasPermission =
-                    mAtmService.instrumentationSourceHasPermission(pid, MODIFY_TOUCH_MODE_STATE)
-                            || checkCallingPermission(MODIFY_TOUCH_MODE_STATE, "setInTouchMode()",
-                            /* printlog= */ false);
+            final boolean hasPermission = hasTouchModePermission(pid);
             final long token = Binder.clearCallingIdentity();
             try {
-                // If perDisplayFocusEnabled is set or the display maintains its own touch mode,
+                // If mPerDisplayFocusEnabled is set or the display maintains its own touch mode,
                 // then just update the display pointed by displayId
-                if (perDisplayFocusEnabled || displayHasOwnTouchMode) {
+                if (mPerDisplayFocusEnabled || displayHasOwnTouchMode) {
                     if (mInputManager.setInTouchMode(inTouch, pid, uid, hasPermission, displayId)) {
                         displayContent.setInTouchMode(inTouch);
                     }
@@ -3911,6 +3901,41 @@
     }
 
     /**
+     * Sets the touch mode state forcibly on all displays (disregarding both the value of
+     * {@code com.android.internal.R.bool.config_perDisplayFocusEnabled} and whether the display
+     * maintains its own focus and touch mode).
+     *
+     * @param inTouch the touch mode to set
+     */
+    @Override // Binder call
+    public void setInTouchModeOnAllDisplays(boolean inTouch) {
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
+        final boolean hasPermission = hasTouchModePermission(pid);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                for (int i = 0; i < mRoot.mChildren.size(); ++i) {
+                    DisplayContent dc = mRoot.mChildren.get(i);
+                    if (dc.isInTouchMode() != inTouch
+                            && mInputManager.setInTouchMode(inTouch, pid, uid, hasPermission,
+                            dc.mDisplayId)) {
+                        dc.setInTouchMode(inTouch);
+                    }
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private boolean hasTouchModePermission(int pid) {
+        return mAtmService.instrumentationSourceHasPermission(pid, MODIFY_TOUCH_MODE_STATE)
+                || checkCallingPermission(MODIFY_TOUCH_MODE_STATE, "setInTouchMode()",
+                /* printlog= */ false);
+    }
+
+    /**
      * Returns the touch mode state for the display id passed as argument.
      */
     @Override  // Binder call
@@ -6003,7 +6028,7 @@
 
     @Override
     public boolean isTransitionTraceEnabled() {
-        return mTransitionTracer.isEnabled();
+        return mTransitionTracer.isActiveTracingEnabled();
     }
 
     @Override
@@ -8021,6 +8046,19 @@
         }
 
         @Override
+        public void setWallpaperShowWhenLocked(IBinder binder, boolean showWhenLocked) {
+            synchronized (mGlobalLock) {
+                final WindowToken token = mRoot.getWindowToken(binder);
+                if (token == null || token.asWallpaperToken() == null) {
+                    ProtoLog.w(WM_ERROR,
+                            "setWallpaperShowWhenLocked: non-existent wallpaper token: %s", binder);
+                    return;
+                }
+                token.asWallpaperToken().setShowWhenLocked(showWhenLocked);
+            }
+        }
+
+        @Override
         public boolean isUidFocused(int uid) {
             synchronized (mGlobalLock) {
                 for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
@@ -8118,14 +8156,14 @@
                     dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout();
                 }
                 if (dc != null && dc.getImeTarget(IME_TARGET_CONTROL) != null) {
-                    ImeTracker.get().onProgress(statsToken,
+                    ImeTracker.forLogging().onProgress(statsToken,
                             ImeTracker.PHASE_WM_HAS_IME_INSETS_CONTROL_TARGET);
                     ProtoLog.d(WM_DEBUG_IME, "hideIme Control target: %s ",
                             dc.getImeTarget(IME_TARGET_CONTROL));
                     dc.getImeTarget(IME_TARGET_CONTROL).hideInsets(WindowInsets.Type.ime(),
                             true /* fromIme */, statsToken);
                 } else {
-                    ImeTracker.get().onFailed(statsToken,
+                    ImeTracker.forLogging().onFailed(statsToken,
                             ImeTracker.PHASE_WM_HAS_IME_INSETS_CONTROL_TARGET);
                 }
                 if (dc != null) {
@@ -8380,6 +8418,47 @@
         }
     }
 
+    private final class ImeTargetVisibilityPolicyImpl extends ImeTargetVisibilityPolicy {
+
+        // TODO(b/258048231): Track IME visibility change in bugreport when invocations.
+        @Override
+        public boolean showImeScreenShot(@NonNull IBinder imeTarget, int displayId) {
+            synchronized (mGlobalLock) {
+                final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
+                if (imeTargetWindow == null) {
+                    return false;
+                }
+                final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                if (dc == null) {
+                    Slog.w(TAG, "Invalid displayId:" + displayId + ", fail to show ime screenshot");
+                    return false;
+                }
+
+                dc.showImeScreenshot(imeTargetWindow);
+                return true;
+            }
+        }
+
+        // TODO(b/258048231): Track IME visibility change in bugreport when invocations.
+        @Override
+        public boolean updateImeParent(@NonNull IBinder imeTarget, int displayId) {
+            synchronized (mGlobalLock) {
+                final WindowState imeTargetWindow = mWindowMap.get(imeTarget);
+                if (imeTargetWindow == null) {
+                    return false;
+                }
+                final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                if (dc == null) {
+                    Slog.w(TAG, "Invalid displayId:" + displayId + ", fail to update ime parent");
+                    return false;
+                }
+
+                dc.updateImeParent();
+                return true;
+            }
+        }
+    }
+
     void registerAppFreezeListener(AppFreezeListener listener) {
         if (!mAppFreezeListeners.contains(listener)) {
             mAppFreezeListeners.add(listener);
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index e931175..cfb3c6c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -34,6 +34,7 @@
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ShellCommand;
 import android.os.UserHandle;
@@ -46,6 +47,7 @@
 
 import com.android.internal.os.ByteTransferPipe;
 import com.android.internal.protolog.ProtoLogImpl;
+import com.android.server.IoThread;
 import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
 import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition;
 import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilityPosition;
@@ -587,8 +589,22 @@
                         ByteTransferPipe pipe = null;
                         try {
                             pipe = new ByteTransferPipe();
-                            w.mClient.executeCommand(ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null,
-                                    pipe.getWriteFd());
+                            final ParcelFileDescriptor pfd = pipe.getWriteFd();
+                            if (w.isClientLocal()) {
+                                // Make it asynchronous to avoid writer from being blocked
+                                // by waiting for the buffer to be consumed in the same process.
+                                IoThread.getExecutor().execute(() -> {
+                                    try {
+                                        w.mClient.executeCommand(
+                                                ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd);
+                                    } catch (RemoteException e) {
+                                        // Ignore for local call.
+                                    }
+                                });
+                            } else {
+                                w.mClient.executeCommand(
+                                        ViewDebug.REMOTE_COMMAND_DUMP_ENCODED, null, pfd);
+                            }
                             requestList.add(Pair.create(w.getName(), pipe));
                         } catch (IOException | RemoteException e) {
                             // Skip this window
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index abdc708..f9592cc 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -29,6 +29,7 @@
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
+import static android.window.TaskFragmentOperation.OP_TYPE_SET_RELATIVE_BOUNDS;
 import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_UNKNOWN;
 import static android.window.WindowContainerTransaction.Change.CHANGE_RELATIVE_BOUNDS;
@@ -52,7 +53,6 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_SHORTCUT;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
-import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED;
 import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission;
 import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK;
@@ -95,6 +95,7 @@
 import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentCreationParams;
 import android.window.TaskFragmentOperation;
+import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -146,7 +147,8 @@
     final DisplayAreaOrganizerController mDisplayAreaOrganizerController;
     final TaskFragmentOrganizerController mTaskFragmentOrganizerController;
 
-    TransitionController mTransitionController;
+    final TransitionController mTransitionController;
+
     /**
      * A Map which manages the relationship between
      * {@link TaskFragmentCreationParams#getFragmentToken()} and {@link TaskFragment}
@@ -163,12 +165,7 @@
         mTaskOrganizerController = new TaskOrganizerController(mService);
         mDisplayAreaOrganizerController = new DisplayAreaOrganizerController(mService);
         mTaskFragmentOrganizerController = new TaskFragmentOrganizerController(atm, this);
-    }
-
-    void setWindowManager(WindowManagerService wms) {
-        mTransitionController = new TransitionController(mService, wms.mTaskSnapshotController,
-                wms.mTransitionTracer);
-        mTransitionController.registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
+        mTransitionController = new TransitionController(atm);
     }
 
     TransitionController getTransitionController() {
@@ -431,6 +428,7 @@
                 applyTransaction(wct, -1 /* syncId */, transition, caller);
                 mTransitionController.requestStartTransition(transition, null /* startTask */,
                         null /* remoteTransition */, null /* displayChange */);
+                transition.setAllReady();
                 return;
             }
 
@@ -469,6 +467,7 @@
                             mTransitionController.requestStartTransition(nextTransition,
                                     null /* startTask */, null /* remoteTransition */,
                                     null /* displayChange */);
+                            nextTransition.setAllReady();
                         } else {
                             nextTransition.abort();
                         }
@@ -497,8 +496,8 @@
         mService.deferWindowLayout();
         mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
         try {
-            if (transition != null && transition.applyDisplayChangeIfNeeded()) {
-                effects |= TRANSACT_EFFECTS_LIFECYCLE;
+            if (transition != null) {
+                transition.applyDisplayChangeIfNeeded();
             }
             final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
             final int hopSize = hops.size();
@@ -619,8 +618,8 @@
                 }
             }
 
-            if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
-                mService.addWindowLayoutReasons(LAYOUT_REASON_CONFIG_CHANGED);
+            if (effects != 0) {
+                mService.mWindowManager.mWindowPlacerLocked.requestTraversal();
             }
         } finally {
             mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
@@ -787,8 +786,8 @@
         taskFragment.deferOrganizedTaskFragmentSurfaceUpdate();
         final Rect relBounds = c.getRelativeBounds();
         if (relBounds != null) {
-            // Make sure the TaskFragment bounds satisfied the min dimensions requirement.
-            adjustTaskFragmentBoundsForMinDimensionsIfNeeded(taskFragment, relBounds,
+            // Make sure the requested bounds satisfied the min dimensions requirement.
+            adjustTaskFragmentRelativeBoundsForMinDimensionsIfNeeded(taskFragment, relBounds,
                     errorCallbackToken);
 
             // For embedded TaskFragment, the organizer set the bounds in parent coordinate to
@@ -800,13 +799,6 @@
                     parentBounds);
             c.getConfiguration().windowConfiguration.setBounds(absBounds);
             taskFragment.setRelativeEmbeddedBounds(relBounds);
-        } else if ((c.getWindowSetMask() & WINDOW_CONFIG_BOUNDS) != 0) {
-            // TODO(b/265271880): remove after we drop support to setBounds for TaskFragment in next
-            // release.
-            adjustTaskFragmentBoundsForMinDimensionsIfNeeded(taskFragment, c.getConfiguration()
-                    .windowConfiguration.getBounds(), errorCallbackToken);
-            // Reset the relative embedded bounds if WCT#setBounds is used instead for CTS compat.
-            taskFragment.setRelativeEmbeddedBounds(new Rect());
         }
         final int effects = applyChanges(taskFragment, c);
         if (taskFragment.shouldStartChangeTransition(mTmpBounds0, mTmpBounds1)) {
@@ -817,25 +809,27 @@
     }
 
     /**
-     * Adjusts the override absolute bounds on {@link TaskFragment} to make sure it satisfies the
+     * Adjusts the requested relative bounds on {@link TaskFragment} to make sure it satisfies the
      * activity min dimensions.
      */
-    private void adjustTaskFragmentBoundsForMinDimensionsIfNeeded(
-            @NonNull TaskFragment taskFragment, @NonNull Rect inOutBounds,
+    private void adjustTaskFragmentRelativeBoundsForMinDimensionsIfNeeded(
+            @NonNull TaskFragment taskFragment, @NonNull Rect inOutRelativeBounds,
             @Nullable IBinder errorCallbackToken) {
-        if (inOutBounds.isEmpty()) {
+        if (inOutRelativeBounds.isEmpty()) {
             return;
         }
         final Point minDimensions = taskFragment.calculateMinDimension();
-        if (inOutBounds.width() < minDimensions.x || inOutBounds.height() < minDimensions.y) {
-            // Reset to match parent bounds.
-            inOutBounds.setEmpty();
+        if (inOutRelativeBounds.width() < minDimensions.x
+                || inOutRelativeBounds.height() < minDimensions.y) {
             // Notify organizer about the request failure.
-            final Throwable exception = new SecurityException("The task fragment's bounds:"
-                    + taskFragment.getBounds() + " does not satisfy minimum dimensions:"
+            final Throwable exception = new SecurityException("The requested relative bounds:"
+                    + inOutRelativeBounds + " does not satisfy minimum dimensions:"
                     + minDimensions);
             sendTaskFragmentOperationFailure(taskFragment.getTaskFragmentOrganizer(),
-                    errorCallbackToken, taskFragment, OP_TYPE_UNKNOWN, exception);
+                    errorCallbackToken, taskFragment, OP_TYPE_SET_RELATIVE_BOUNDS, exception);
+
+            // Reset to match parent bounds.
+            inOutRelativeBounds.setEmpty();
         }
     }
 
@@ -1729,9 +1723,7 @@
                 t.getChanges().entrySet().iterator();
         while (entries.hasNext()) {
             final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next();
-            // Only allow to apply changes to TaskFragment that is created by this organizer.
             final WindowContainer wc = WindowContainer.fromBinder(entry.getKey());
-            enforceTaskFragmentOrganized(func, wc, organizer);
             enforceTaskFragmentConfigChangeAllowed(func, wc, entry.getValue(), organizer);
         }
 
@@ -1767,27 +1759,6 @@
     }
 
     /**
-     * Makes sure that the given {@link WindowContainer} is a {@link TaskFragment} organized by the
-     * given {@link ITaskFragmentOrganizer}.
-     */
-    private void enforceTaskFragmentOrganized(@NonNull String func, @Nullable WindowContainer wc,
-            @NonNull ITaskFragmentOrganizer organizer) {
-        if (wc == null) {
-            Slog.e(TAG, "Attempt to operate on window that no longer exists");
-            return;
-        }
-
-        final TaskFragment tf = wc.asTaskFragment();
-        if (tf == null || !tf.hasTaskFragmentOrganizer(organizer)) {
-            String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid() + " trying to modify window container not"
-                    + " belonging to the TaskFragmentOrganizer=" + organizer;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-    }
-
-    /**
      * Makes sure that the {@link TaskFragment} of the given fragment token is created and organized
      * by the given {@link ITaskFragmentOrganizer}.
      */
@@ -1808,81 +1779,49 @@
     }
 
     /**
-     * Makes sure that SurfaceControl transactions and the ability to set bounds outside of the
-     * parent bounds are not allowed for embedding without full trust between the host and the
-     * target.
+     * For config change on {@link TaskFragment}, we only support the following operations:
+     * {@link WindowContainerTransaction#setRelativeBounds(WindowContainerToken, Rect)},
+     * {@link WindowContainerTransaction#setWindowingMode(WindowContainerToken, int)}.
      */
-    private void enforceTaskFragmentConfigChangeAllowed(String func, @Nullable WindowContainer wc,
-            WindowContainerTransaction.Change change, ITaskFragmentOrganizer organizer) {
+    private void enforceTaskFragmentConfigChangeAllowed(@NonNull String func,
+            @Nullable WindowContainer wc, @NonNull WindowContainerTransaction.Change change,
+            @NonNull ITaskFragmentOrganizer organizer) {
         if (wc == null) {
             Slog.e(TAG, "Attempt to operate on task fragment that no longer exists");
             return;
         }
-        if (change == null) {
+        final TaskFragment tf = wc.asTaskFragment();
+        if (tf == null || !tf.hasTaskFragmentOrganizer(organizer)) {
+            // Only allow to apply changes to TaskFragment that is organized by this organizer.
+            String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid() + " trying to modify window container"
+                    + " not belonging to the TaskFragmentOrganizer=" + organizer;
+            Slog.w(TAG, msg);
+            throw new SecurityException(msg);
+        }
+
+        final int changeMask = change.getChangeMask();
+        final int configSetMask = change.getConfigSetMask();
+        final int windowSetMask = change.getWindowSetMask();
+        if (changeMask == 0 && configSetMask == 0 && windowSetMask == 0
+                && change.getWindowingMode() >= 0) {
+            // The change contains only setWindowingMode, which is allowed.
             return;
         }
-        final int changeMask = change.getChangeMask();
-        if (changeMask != 0 && changeMask != CHANGE_RELATIVE_BOUNDS) {
+        if (changeMask != CHANGE_RELATIVE_BOUNDS
+                || configSetMask != ActivityInfo.CONFIG_WINDOW_CONFIGURATION
+                || windowSetMask != WindowConfiguration.WINDOW_CONFIG_BOUNDS) {
             // None of the change should be requested from a TaskFragment organizer except
-            // setRelativeBounds.
+            // setRelativeBounds and setWindowingMode.
             // For setRelativeBounds, we don't need to check whether it is outside of the Task
             // bounds, because it is possible that the Task is also resizing, for which we don't
             // want to throw an exception. The bounds will be adjusted in
             // TaskFragment#translateRelativeBoundsToAbsoluteBounds.
             String msg = "Permission Denial: " + func + " from pid="
                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
-                    + " trying to apply changes of " + changeMask + " to TaskFragment"
-                    + " TaskFragmentOrganizer=" + organizer;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-        // Check if TaskFragment is embedded in fully trusted mode.
-        if (wc.asTaskFragment().isAllowedToBeEmbeddedInTrustedMode()) {
-            // Fully trusted, no need to check further
-            return;
-        }
-        final WindowContainer wcParent = wc.getParent();
-        if (wcParent == null) {
-            Slog.e(TAG, "Attempt to apply config change on task fragment that has no parent");
-            return;
-        }
-        // TODO(b/265271880): we can remove those and only support WCT#setRelativeBounds.
-        final Configuration requestedConfig = change.getConfiguration();
-        final Configuration parentConfig = wcParent.getConfiguration();
-        if (parentConfig.screenWidthDp < requestedConfig.screenWidthDp
-                || parentConfig.screenHeightDp < requestedConfig.screenHeightDp
-                || parentConfig.smallestScreenWidthDp < requestedConfig.smallestScreenWidthDp) {
-            String msg = "Permission Denial: " + func + " from pid="
-                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
-                    + " trying to apply screen width/height greater than parent's for non-trusted"
-                    + " host, TaskFragmentOrganizer=" + organizer;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-        if (change.getWindowSetMask() == 0) {
-            // No bounds change.
-            return;
-        }
-        final WindowConfiguration requestedWindowConfig = requestedConfig.windowConfiguration;
-        final WindowConfiguration parentWindowConfig = parentConfig.windowConfiguration;
-        if (!requestedWindowConfig.getBounds().isEmpty()
-                && !parentWindowConfig.getBounds().contains(requestedWindowConfig.getBounds())) {
-            String msg = "Permission Denial: " + func + " from pid="
-                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
-                    + " trying to apply bounds outside of parent for non-trusted host,"
-                    + " TaskFragmentOrganizer=" + organizer;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-        if (requestedWindowConfig.getAppBounds() != null
-                && !requestedWindowConfig.getAppBounds().isEmpty()
-                && parentWindowConfig.getAppBounds() != null
-                && !parentWindowConfig.getAppBounds().contains(
-                        requestedWindowConfig.getAppBounds())) {
-            String msg = "Permission Denial: " + func + " from pid="
-                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
-                    + " trying to apply app bounds outside of parent for non-trusted host,"
-                    + " TaskFragmentOrganizer=" + organizer;
+                    + " trying to apply changes of changeMask=" + changeMask
+                    + " configSetMask=" + configSetMask + " windowSetMask=" + windowSetMask
+                    + " to TaskFragment=" + tf + " TaskFragmentOrganizer=" + organizer;
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 31f30af..69e84c7 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -225,7 +225,6 @@
 import android.view.InputWindowHandle;
 import android.view.InsetsSource;
 import android.view.InsetsState;
-import android.view.InsetsState.InternalInsetsType;
 import android.view.Surface;
 import android.view.Surface.Rotation;
 import android.view.SurfaceControl;
@@ -1393,15 +1392,18 @@
     }
 
     void updateSourceFrame(Rect winFrame) {
+        if (!hasInsetsSourceProvider()) {
+            // This window doesn't provide any insets.
+            return;
+        }
         if (mGivenInsetsPending) {
             // The given insets are pending, and they are not reliable for now. The source frame
             // should be updated after the new given insets are sent to window manager.
             return;
         }
-        final SparseArray<InsetsSource> providedSources = getProvidedInsetsSources();
-        final InsetsStateController controller = getDisplayContent().getInsetsStateController();
-        for (int i = providedSources.size() - 1; i >= 0; i--) {
-            controller.getSourceProvider(providedSources.keyAt(i)).updateSourceFrame(winFrame);
+        final SparseArray<InsetsSourceProvider> providers = getInsetsSourceProviders();
+        for (int i = providers.size() - 1; i >= 0; i--) {
+            providers.valueAt(i).updateSourceFrame(winFrame);
         }
     }
 
@@ -1531,6 +1533,10 @@
                 winAnimator.mDrawState = DRAW_PENDING;
                 if (mActivityRecord != null) {
                     mActivityRecord.clearAllDrawn();
+                    if (mAttrs.type == TYPE_APPLICATION_STARTING
+                            && mActivityRecord.mStartingData != null) {
+                        mActivityRecord.mStartingData.mIsDisplayed = false;
+                    }
                 }
             }
             if (!mWmService.mResizingWindows.contains(this)) {
@@ -1696,14 +1702,12 @@
      * Returns the insets state for the window and applies the requested visibility.
      */
     InsetsState getInsetsStateWithVisibilityOverride() {
-        final InsetsState state = new InsetsState(getInsetsState());
-        for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) {
-            final boolean requestedVisible = isRequestedVisible(InsetsState.toPublicType(type));
-            InsetsSource source = state.peekSource(type);
-            if (source != null && source.isVisible() != requestedVisible) {
-                source = new InsetsSource(source);
+        final InsetsState state = new InsetsState(getInsetsState(), true /* copySources */);
+        for (int i = state.sourceSize() - 1; i >= 0; i--) {
+            final InsetsSource source = state.sourceAt(i);
+            final boolean requestedVisible = isRequestedVisible(source.getType());
+            if (source.isVisible() != requestedVisible) {
                 source.setVisible(requestedVisible);
-                state.addSource(source);
             }
         }
         return state;
@@ -1878,12 +1882,12 @@
     }
 
     boolean providesNonDecorInsets() {
-        if (mProvidedInsetsSources == null) {
+        if (mInsetsSourceProviders == null) {
             return false;
         }
-        for (int i = mProvidedInsetsSources.size() - 1; i >= 0; i--) {
-            final int type = mProvidedInsetsSources.keyAt(i);
-            if ((InsetsState.toPublicType(type) & WindowInsets.Type.navigationBars()) != 0) {
+        for (int i = mInsetsSourceProviders.size() - 1; i >= 0; i--) {
+            final InsetsSource source = mInsetsSourceProviders.valueAt(i).getSource();
+            if (source.getType() == WindowInsets.Type.navigationBars()) {
                 return true;
             }
         }
@@ -2063,12 +2067,10 @@
             final boolean exiting = mAnimatingExit || mDestroying;
             return shown && !exiting;
         } else {
-            final Task task = getTask();
-            final boolean canFromTask = task != null && task.canAffectSystemUiFlags();
-            return canFromTask && mActivityRecord.isVisible()
-            // Do not let snapshot window control the bar
+            return mActivityRecord.canAffectSystemUiFlags()
+                    // Do not let snapshot window control the bar
                     && (mAttrs.type != TYPE_APPLICATION_STARTING
-                    || !(mStartingData instanceof SnapshotStartingData));
+                            || !(mStartingData instanceof SnapshotStartingData));
         }
     }
 
@@ -2080,7 +2082,7 @@
         final ActivityRecord atoken = mActivityRecord;
         return isDrawn() && isVisibleByPolicy()
                 && ((!isParentWindowHidden() && (atoken == null || atoken.isVisibleRequested()))
-                        || isAnimating(TRANSITION | PARENTS));
+                        || isAnimationRunningSelfOrParent());
     }
 
     /**
@@ -2323,7 +2325,7 @@
 
     boolean isObscuringDisplay() {
         Task task = getTask();
-        if (task != null && task.getRootTask() != null && !task.getRootTask().fillsParent()) {
+        if (task != null && !task.fillsParent()) {
             return false;
         }
         return isOpaqueDrawn() && fillsDisplay();
@@ -2588,7 +2590,7 @@
                     }
                 }
                 final boolean isAnimating = allowExitAnimation
-                        && (mAnimatingExit || isExitAnimationRunningSelfOrParent());
+                        && (mAnimatingExit || isAnimationRunningSelfOrParent());
                 final boolean lastWindowIsStartingWindow = startingWindow && mActivityRecord != null
                         && mActivityRecord.isLastWindow(this);
                 // We delay the removal of a window if it has a showing surface that can be used to run
@@ -3159,15 +3161,25 @@
                 + (mActivityRecord == null || mActivityRecord.windowsAreFocusable(fromUserTouch))
                 + " canReceiveTouchInput=" + canReceiveTouchInput()
                 + " displayIsOnTop=" + getDisplayContent().isOnTop()
-                + " displayIsTrusted=" + getDisplayContent().isTrusted();
+                + " displayIsTrusted=" + getDisplayContent().isTrusted()
+                + " transitShouldKeepFocus=" + (mActivityRecord != null
+                        && mTransitionController.shouldKeepFocus(mActivityRecord));
     }
 
     public boolean canReceiveKeys(boolean fromUserTouch) {
+        if (mActivityRecord != null && mTransitionController.shouldKeepFocus(mActivityRecord)) {
+            // During transient launch, the transient-hide windows are not visibleRequested
+            // or on-top but are kept focusable and thus can receive keys.
+            return true;
+        }
         final boolean canReceiveKeys = isVisibleRequestedOrAdding()
                 && (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
                 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
                 && (mActivityRecord == null || mActivityRecord.windowsAreFocusable(fromUserTouch))
-                && canReceiveTouchInput();
+                // can it receive touches
+                && (mActivityRecord == null || mActivityRecord.getTask() == null
+                        || !mActivityRecord.getTask().getRootTask().shouldIgnoreInput());
+
         if (!canReceiveKeys) {
             return false;
         }
@@ -3193,6 +3205,11 @@
         if (mActivityRecord == null  || mActivityRecord.getTask() == null) {
             return true;
         }
+        // During transient launch, the transient-hide windows are not visibleRequested
+        // or on-top but are kept focusable and thus can receive touch input.
+        if (mTransitionController.shouldKeepFocus(mActivityRecord)) {
+            return true;
+        }
 
         return !mActivityRecord.getTask().getRootTask().shouldIgnoreInput()
                 && mActivityRecord.isVisibleRequested();
@@ -3997,12 +4014,12 @@
     public void showInsets(@InsetsType int types, boolean fromIme,
             @Nullable ImeTracker.Token statsToken) {
         try {
-            ImeTracker.get().onProgress(statsToken,
+            ImeTracker.forLogging().onProgress(statsToken,
                     ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_SHOW_INSETS);
             mClient.showInsets(types, fromIme, statsToken);
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed to deliver showInsets", e);
-            ImeTracker.get().onFailed(statsToken,
+            ImeTracker.forLogging().onFailed(statsToken,
                     ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_SHOW_INSETS);
         }
     }
@@ -4011,12 +4028,12 @@
     public void hideInsets(@InsetsType int types, boolean fromIme,
             @Nullable ImeTracker.Token statsToken) {
         try {
-            ImeTracker.get().onProgress(statsToken,
+            ImeTracker.forLogging().onProgress(statsToken,
                     ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_HIDE_INSETS);
             mClient.hideInsets(types, fromIme, statsToken);
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed to deliver hideInsets", e);
-            ImeTracker.get().onFailed(statsToken,
+            ImeTracker.forLogging().onFailed(statsToken,
                     ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_HIDE_INSETS);
         }
     }
@@ -4824,10 +4841,10 @@
                 insetsChangedWindows.add(w);
             }
 
-            final SparseArray<InsetsSource> providedSources = w.mProvidedInsetsSources;
-            if (providedSources != null) {
-                for (int i = providedSources.size() - 1; i >= 0; i--) {
-                    aboveInsetsState.addSource(providedSources.valueAt(i));
+            final SparseArray<InsetsSourceProvider> providers = w.mInsetsSourceProviders;
+            if (providers != null) {
+                for (int i = providers.size() - 1; i >= 0; i--) {
+                    aboveInsetsState.addSource(providers.valueAt(i).getSource());
                 }
             }
         }, true /* traverseTopToBottom */);
@@ -4970,7 +4987,7 @@
         return false;
     }
 
-    boolean isExitAnimationRunningSelfOrParent() {
+    boolean isAnimationRunningSelfOrParent() {
         return inTransitionSelfOrParent()
                 || isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION);
     }
@@ -4986,7 +5003,7 @@
             return true;
         }
         // Exit animation is running.
-        if (isExitAnimationRunningSelfOrParent()) {
+        if (isAnimationRunningSelfOrParent()) {
             ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "shouldWaitAnimatingExit: isAnimating: %s",
                     this);
             return false;
@@ -5646,14 +5663,6 @@
                     && imeTarget.compareTo(this) <= 0;
             return inTokenWithAndAboveImeTarget;
         }
-
-        // The condition is for the system dialog not belonging to any Activity.
-        // (^FLAG_NOT_FOCUSABLE & FLAG_ALT_FOCUSABLE_IM) means the dialog is still focusable but
-        // should be placed above the IME window.
-        if ((mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM))
-                == FLAG_ALT_FOCUSABLE_IM && isTrustedOverlay() && canAddInternalSystemWindow()) {
-            return true;
-        }
         return false;
     }
 
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index e661688..e2bdcdd 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -62,9 +62,9 @@
         "com_android_server_tv_TvInputHal.cpp",
         "com_android_server_vr_VrManagerService.cpp",
         "com_android_server_UsbAlsaJackDetector.cpp",
+        "com_android_server_UsbAlsaMidiDevice.cpp",
         "com_android_server_UsbDeviceManager.cpp",
         "com_android_server_UsbDescriptorParser.cpp",
-        "com_android_server_UsbMidiDevice.cpp",
         "com_android_server_UsbHostManager.cpp",
         "com_android_server_vibrator_VibratorController.cpp",
         "com_android_server_vibrator_VibratorManagerService.cpp",
diff --git a/services/core/jni/com_android_server_UsbMidiDevice.cpp b/services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp
similarity index 83%
rename from services/core/jni/com_android_server_UsbMidiDevice.cpp
rename to services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp
index c8e7698..93938b1 100644
--- a/services/core/jni/com_android_server_UsbMidiDevice.cpp
+++ b/services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp
@@ -14,27 +14,25 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "UsbMidiDeviceJNI"
+#define LOG_TAG "UsbAlsaMidiDeviceJNI"
 #define LOG_NDEBUG 0
-#include "utils/Log.h"
-
-#include "jni.h"
-#include <nativehelper/JNIPlatformHelp.h>
-#include <nativehelper/ScopedLocalRef.h>
-#include "android_runtime/AndroidRuntime.h"
-#include "android_runtime/Log.h"
-
 #include <asm/byteorder.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <nativehelper/JNIPlatformHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
 #include <sound/asound.h>
 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
-namespace android
-{
+#include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
+#include "jni.h"
+#include "utils/Log.h"
+
+namespace android {
 
 static jclass sFileDescriptorClass;
 static jfieldID sPipeFDField;
@@ -46,10 +44,10 @@
 // 1. Input O_RDONLY file descriptor
 // 2. Special input file descriptor to block the input thread
 // 3. Output O_WRONLY file descriptor
-static jobjectArray android_server_UsbMidiDevice_open(JNIEnv *env, jobject thiz, jint card,
-                                                      jint device, jint numInputs,
-                                                      jint numOutputs) {
-    char    path[100];
+static jobjectArray android_server_UsbAlsaMidiDevice_open(JNIEnv *env, jobject thiz, jint card,
+                                                          jint device, jint numInputs,
+                                                          jint numOutputs) {
+    char path[100];
     int fd;
 
     snprintf(path, sizeof(path), "/dev/snd/midiC%dD%d", card, device);
@@ -126,9 +124,7 @@
     return NULL;
 }
 
-static void
-android_server_UsbMidiDevice_close(JNIEnv *env, jobject thiz, jobjectArray fds)
-{
+static void android_server_UsbAlsaMidiDevice_close(JNIEnv *env, jobject thiz, jobjectArray fds) {
     // write to mPipeFD to unblock input thread
     jint pipeFD = env->GetIntField(thiz, sPipeFDField);
     write(pipeFD, &pipeFD, sizeof(pipeFD));
@@ -144,12 +140,12 @@
 
 static JNINativeMethod method_table[] = {
         {"nativeOpen", "(IIII)[Ljava/io/FileDescriptor;",
-         (void *)android_server_UsbMidiDevice_open},
-        {"nativeClose", "([Ljava/io/FileDescriptor;)V", (void *)android_server_UsbMidiDevice_close},
+         (void *)android_server_UsbAlsaMidiDevice_open},
+        {"nativeClose", "([Ljava/io/FileDescriptor;)V",
+         (void *)android_server_UsbAlsaMidiDevice_close},
 };
 
-int register_android_server_UsbMidiDevice(JNIEnv *env)
-{
+int register_android_server_UsbAlsaMidiDevice(JNIEnv *env) {
     jclass clazz = env->FindClass("java/io/FileDescriptor");
     if (clazz == NULL) {
         ALOGE("Can't find java/io/FileDescriptor");
@@ -157,19 +153,19 @@
     }
     sFileDescriptorClass = (jclass)env->NewGlobalRef(clazz);
 
-    clazz = env->FindClass("com/android/server/usb/UsbMidiDevice");
+    clazz = env->FindClass("com/android/server/usb/UsbAlsaMidiDevice");
     if (clazz == NULL) {
-        ALOGE("Can't find com/android/server/usb/UsbMidiDevice");
+        ALOGE("Can't find com/android/server/usb/UsbAlsaMidiDevice");
         return -1;
     }
     sPipeFDField = env->GetFieldID(clazz, "mPipeFD", "I");
     if (sPipeFDField == NULL) {
-        ALOGE("Can't find UsbMidiDevice.mPipeFD");
+        ALOGE("Can't find UsbAlsaMidiDevice.mPipeFD");
         return -1;
     }
 
-    return jniRegisterNativeMethods(env, "com/android/server/usb/UsbMidiDevice",
-            method_table, NELEM(method_table));
+    return jniRegisterNativeMethods(env, "com/android/server/usb/UsbAlsaMidiDevice", method_table,
+                                    NELEM(method_table));
 }
 
-};
+}; // namespace android
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index 4cb7a8f..dd757bc 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -29,8 +29,17 @@
 #include <utils/Log.h>
 
 #include <map>
+#include <set>
 #include <string>
 
+/**
+ * Log debug messages about native virtual input devices.
+ * Enable this via "adb shell setprop log.tag.InputController DEBUG"
+ */
+static bool isDebug() {
+    return __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG, ANDROID_LOG_INFO);
+}
+
 namespace android {
 
 enum class DeviceType {
@@ -194,6 +203,15 @@
         {AKEYCODE_NUMPAD_COMMA, KEY_KPCOMMA},
 };
 
+/*
+ * Map from the uinput touchscreen fd to the pointers present in the previous touch events that
+ * hasn't been lifted.
+ * We only allow pointer id to go up to MAX_POINTERS because the maximum slots of virtual
+ * touchscreen is set up with MAX_POINTERS. Note that in other cases Android allows pointer id to go
+ * up to MAX_POINTERS_ID.
+ */
+static std::map<int32_t, std::bitset<MAX_POINTERS>> unreleasedTouches;
+
 /** Creates a new uinput device and assigns a file descriptor. */
 static int openUinput(const char* readableName, jint vendorId, jint productId, const char* phys,
                       DeviceType deviceType, jint screenHeight, jint screenWidth) {
@@ -366,6 +384,12 @@
 
 static bool nativeCloseUinput(JNIEnv* env, jobject thiz, jint fd) {
     ioctl(fd, UI_DEV_DESTROY);
+    if (auto touchesOnFd = unreleasedTouches.find(fd); touchesOnFd != unreleasedTouches.end()) {
+        const size_t remainingPointers = touchesOnFd->second.size();
+        unreleasedTouches.erase(touchesOnFd);
+        ALOGW_IF(remainingPointers > 0, "Closing touchscreen %d, erased %zu unreleased pointers.",
+                 fd, remainingPointers);
+    }
     return close(fd);
 }
 
@@ -425,6 +449,69 @@
     return true;
 }
 
+static bool handleTouchUp(int fd, int pointerId) {
+    if (!writeInputEvent(fd, EV_ABS, ABS_MT_TRACKING_ID, static_cast<int32_t>(-1))) {
+        return false;
+    }
+    auto touchesOnFd = unreleasedTouches.find(fd);
+    if (touchesOnFd == unreleasedTouches.end()) {
+        ALOGE("PointerId %d action UP received with no prior events on touchscreen %d.", pointerId,
+              fd);
+        return false;
+    }
+    ALOGD_IF(isDebug(), "Unreleased touches found for touchscreen %d in the map", fd);
+
+    // When a pointer is no longer in touch, remove the pointer id from the corresponding
+    // entry in the unreleased touches map.
+    if (pointerId < 0 || pointerId >= MAX_POINTERS) {
+        ALOGE("Virtual touch event has invalid pointer id %d; value must be between 0 and %zu",
+              pointerId, MAX_POINTERS - 1);
+        return false;
+    }
+    if (!touchesOnFd->second.test(pointerId)) {
+        ALOGE("PointerId %d action UP received with no prior action DOWN on touchscreen %d.",
+              pointerId, fd);
+        return false;
+    }
+    touchesOnFd->second.reset(pointerId);
+    ALOGD_IF(isDebug(), "Pointer %d erased from the touchscreen %d", pointerId, fd);
+
+    // Only sends the BTN UP event when there's no pointers on the touchscreen.
+    if (touchesOnFd->second.none()) {
+        unreleasedTouches.erase(touchesOnFd);
+        if (!writeInputEvent(fd, EV_KEY, BTN_TOUCH, static_cast<int32_t>(UinputAction::RELEASE))) {
+            return false;
+        }
+        ALOGD_IF(isDebug(), "No pointers on touchscreen %d, BTN UP event sent.", fd);
+    }
+    return true;
+}
+
+static bool handleTouchDown(int fd, int pointerId) {
+    // When a new pointer is down on the touchscreen, add the pointer id in the corresponding
+    // entry in the unreleased touches map.
+    auto touchesOnFd = unreleasedTouches.find(fd);
+    if (touchesOnFd == unreleasedTouches.end()) {
+        // Only sends the BTN Down event when the first pointer on the touchscreen is down.
+        if (!writeInputEvent(fd, EV_KEY, BTN_TOUCH, static_cast<int32_t>(UinputAction::PRESS))) {
+            return false;
+        }
+        touchesOnFd = unreleasedTouches.insert({fd, {}}).first;
+        ALOGD_IF(isDebug(), "New touchscreen with fd %d added in the unreleased touches map.", fd);
+    }
+    if (touchesOnFd->second.test(pointerId)) {
+        ALOGE("Repetitive action DOWN event received on a pointer %d that is already down.",
+              pointerId);
+        return false;
+    }
+    touchesOnFd->second.set(pointerId);
+    ALOGD_IF(isDebug(), "Added pointer %d under touchscreen %d in the map", pointerId, fd);
+    if (!writeInputEvent(fd, EV_ABS, ABS_MT_TRACKING_ID, static_cast<int32_t>(pointerId))) {
+        return false;
+    }
+    return true;
+}
+
 static bool nativeWriteTouchEvent(JNIEnv* env, jobject thiz, jint fd, jint pointerId, jint toolType,
                                   jint action, jfloat locationX, jfloat locationY, jfloat pressure,
                                   jfloat majorAxisSize) {
@@ -446,15 +533,10 @@
         return false;
     }
     UinputAction uinputAction = actionIterator->second;
-    if (uinputAction == UinputAction::PRESS || uinputAction == UinputAction::RELEASE) {
-        if (!writeInputEvent(fd, EV_KEY, BTN_TOUCH, static_cast<int32_t>(uinputAction))) {
-            return false;
-        }
-        if (!writeInputEvent(fd, EV_ABS, ABS_MT_TRACKING_ID,
-                             static_cast<int32_t>(uinputAction == UinputAction::PRESS ? pointerId
-                                                                                      : -1))) {
-            return false;
-        }
+    if (uinputAction == UinputAction::PRESS && !handleTouchDown(fd, pointerId)) {
+        return false;
+    } else if (uinputAction == UinputAction::RELEASE && !handleTouchUp(fd, pointerId)) {
+        return false;
     }
     if (!writeInputEvent(fd, EV_ABS, ABS_MT_POSITION_X, locationX)) {
         return false;
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index f4d1d1e..b4e2fb6 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -137,6 +137,7 @@
     jmethodID notifyDropWindow;
     jmethodID getParentSurfaceForPointers;
     jmethodID isPerDisplayTouchModeEnabled;
+    jmethodID isStylusPointerIconEnabled;
 } gServiceClassInfo;
 
 static struct {
@@ -363,6 +364,7 @@
             std::map<PointerIconStyle, SpriteIcon>* outResources,
             std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, int32_t displayId);
     virtual PointerIconStyle getDefaultPointerIconId();
+    virtual PointerIconStyle getDefaultStylusIconId();
     virtual PointerIconStyle getCustomPointerIconId();
     virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos);
 
@@ -659,6 +661,12 @@
         outConfig->pointerGestureTapSlop = hoverTapSlop;
     }
 
+    jboolean stylusPointerIconEnabled =
+            env->CallBooleanMethod(mServiceObj, gServiceClassInfo.isStylusPointerIconEnabled);
+    if (!checkAndClearExceptionFromCallback(env, "isStylusPointerIconEnabled")) {
+        outConfig->stylusPointerIconEnabled = stylusPointerIconEnabled;
+    }
+
     { // acquire lock
         AutoMutex _l(mLock);
 
@@ -1605,6 +1613,11 @@
     return PointerIconStyle::TYPE_ARROW;
 }
 
+PointerIconStyle NativeInputManager::getDefaultStylusIconId() {
+    // TODO: add resource for default stylus icon and change this
+    return PointerIconStyle::TYPE_CROSSHAIR;
+}
+
 PointerIconStyle NativeInputManager::getCustomPointerIconId() {
     return PointerIconStyle::TYPE_CUSTOM;
 }
@@ -2787,6 +2800,9 @@
     GET_METHOD_ID(gServiceClassInfo.isPerDisplayTouchModeEnabled, clazz,
                   "isPerDisplayTouchModeEnabled", "()Z");
 
+    GET_METHOD_ID(gServiceClassInfo.isStylusPointerIconEnabled, clazz, "isStylusPointerIconEnabled",
+                  "()Z");
+
     // InputDevice
 
     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 00f851f..290ad8d 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -35,8 +35,8 @@
 int register_android_server_SerialService(JNIEnv* env);
 int register_android_server_SystemServer(JNIEnv* env);
 int register_android_server_UsbAlsaJackDetector(JNIEnv* env);
+int register_android_server_UsbAlsaMidiDevice(JNIEnv* env);
 int register_android_server_UsbDeviceManager(JNIEnv* env);
-int register_android_server_UsbMidiDevice(JNIEnv* env);
 int register_android_server_UsbHostManager(JNIEnv* env);
 int register_android_server_vr_VrManagerService(JNIEnv* env);
 int register_android_server_vibrator_VibratorController(JavaVM* vm, JNIEnv* env);
@@ -90,8 +90,8 @@
     register_android_server_InputManager(env);
     register_android_server_LightsService(env);
     register_android_server_UsbDeviceManager(env);
-    register_android_server_UsbMidiDevice(env);
     register_android_server_UsbAlsaJackDetector(env);
+    register_android_server_UsbAlsaMidiDevice(env);
     register_android_server_UsbHostManager(env);
     register_android_server_vr_VrManagerService(env);
     register_android_server_vibrator_VibratorController(vm, env);
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index ab1badb..ef5aa60 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -477,6 +477,10 @@
                     minOccurs="0" maxOccurs="1">
             <xs:annotation name="final"/>
         </xs:element>
+        <xs:element name="refreshRateZoneProfiles" type="refreshRateZoneProfiles"
+                    minOccurs="0" maxOccurs="1">
+            <xs:annotation name="final"/>
+        </xs:element>
         <xs:element name="lowerBlockingZoneConfigs" type="blockingZoneConfig"
                     minOccurs="0" maxOccurs="1">
             <xs:annotation name="final"/>
@@ -487,6 +491,22 @@
         </xs:element>
     </xs:complexType>
 
+    <xs:complexType name="refreshRateZoneProfiles">
+        <xs:sequence>
+            <xs:element name="refreshRateZoneProfile" type="refreshRateZone"
+                        minOccurs="0" maxOccurs="unbounded">
+                <xs:annotation name="final"/>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="refreshRateZone">
+        <xs:attribute name="id" use="required" type="xs:string" />
+        <xs:element name="refreshRateRange" type="refreshRateRange">
+            <xs:annotation name="final"/>
+        </xs:element>
+    </xs:complexType>
+
     <xs:complexType name="blockingZoneConfig">
         <xs:element name="defaultRefreshRate" type="xs:nonNegativeInteger"
                     minOccurs="1" maxOccurs="1">
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 3e1db4c..ed9f959 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -194,10 +194,12 @@
     method public final java.math.BigInteger getDefaultRefreshRate();
     method public final com.android.server.display.config.BlockingZoneConfig getHigherBlockingZoneConfigs();
     method public final com.android.server.display.config.BlockingZoneConfig getLowerBlockingZoneConfigs();
+    method public final com.android.server.display.config.RefreshRateZoneProfiles getRefreshRateZoneProfiles();
     method public final void setDefaultPeakRefreshRate(java.math.BigInteger);
     method public final void setDefaultRefreshRate(java.math.BigInteger);
     method public final void setHigherBlockingZoneConfigs(com.android.server.display.config.BlockingZoneConfig);
     method public final void setLowerBlockingZoneConfigs(com.android.server.display.config.BlockingZoneConfig);
+    method public final void setRefreshRateZoneProfiles(com.android.server.display.config.RefreshRateZoneProfiles);
   }
 
   public class RefreshRateRange {
@@ -208,6 +210,19 @@
     method public final void setMinimum(java.math.BigInteger);
   }
 
+  public class RefreshRateZone {
+    ctor public RefreshRateZone();
+    method public String getId();
+    method public final com.android.server.display.config.RefreshRateRange getRefreshRateRange();
+    method public void setId(String);
+    method public final void setRefreshRateRange(com.android.server.display.config.RefreshRateRange);
+  }
+
+  public class RefreshRateZoneProfiles {
+    ctor public RefreshRateZoneProfiles();
+    method public final java.util.List<com.android.server.display.config.RefreshRateZone> getRefreshRateZoneProfile();
+  }
+
   public class SdrHdrRatioMap {
     ctor public SdrHdrRatioMap();
     method @NonNull public final java.util.List<com.android.server.display.config.SdrHdrRatioPoint> getPoint();
diff --git a/services/core/xsd/display-layout-config/display-layout-config.xsd b/services/core/xsd/display-layout-config/display-layout-config.xsd
index 78c9a54..d4556d7 100644
--- a/services/core/xsd/display-layout-config/display-layout-config.xsd
+++ b/services/core/xsd/display-layout-config/display-layout-config.xsd
@@ -55,5 +55,13 @@
         </xs:sequence>
         <xs:attribute name="enabled" type="xs:boolean" use="optional" />
         <xs:attribute name="defaultDisplay" type="xs:boolean" use="optional" />
+        <xs:attribute name="refreshRateZoneId" type="xs:string" use="optional" />
+        <xs:attribute name="displayGroup" use="optional" default="">
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:pattern value="|[_a-zA-Z0-9]+(\.[_a-zA-Z0-9]+)*" />
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:attribute>
     </xs:complexType>
 </xs:schema>
diff --git a/services/core/xsd/display-layout-config/schema/current.txt b/services/core/xsd/display-layout-config/schema/current.txt
index 6a28d8a..52133ab 100644
--- a/services/core/xsd/display-layout-config/schema/current.txt
+++ b/services/core/xsd/display-layout-config/schema/current.txt
@@ -5,14 +5,18 @@
     ctor public Display();
     method public java.math.BigInteger getAddress();
     method public String getBrightnessThrottlingMapId();
+    method public String getDisplayGroup();
     method public String getPosition();
+    method public String getRefreshRateZoneId();
     method public boolean isDefaultDisplay();
     method public boolean isEnabled();
     method public void setAddress(java.math.BigInteger);
     method public void setBrightnessThrottlingMapId(String);
     method public void setDefaultDisplay(boolean);
+    method public void setDisplayGroup(String);
     method public void setEnabled(boolean);
     method public void setPosition(String);
+    method public void setRefreshRateZoneId(String);
   }
 
   public class Layout {
diff --git a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
index be60946..447c67f 100644
--- a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
@@ -23,6 +23,7 @@
 import android.credentials.IClearCredentialStateCallback;
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.RequestInfo;
+import android.os.CancellationSignal;
 import android.os.RemoteException;
 import android.service.credentials.CallingAppInfo;
 import android.service.credentials.CredentialProviderInfo;
@@ -41,9 +42,9 @@
 
     public ClearRequestSession(Context context, int userId, int callingUid,
             IClearCredentialStateCallback callback, ClearCredentialStateRequest request,
-            CallingAppInfo callingAppInfo) {
+            CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal) {
         super(context, userId, callingUid, request, callback, RequestInfo.TYPE_UNDEFINED,
-                callingAppInfo);
+                callingAppInfo, cancellationSignal);
     }
 
     /**
@@ -111,6 +112,12 @@
 
     private void respondToClientWithResponseAndFinish() {
         Log.i(TAG, "respondToClientWithResponseAndFinish");
+        if (isSessionCancelled()) {
+            // TODO: Differentiate btw cancelled and false
+            logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ true);
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         try {
             mClientCallback.onSuccess();
             logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ true);
@@ -118,18 +125,24 @@
             Log.i(TAG, "Issue while propagating the response to the client");
             logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ false);
         }
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
     private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
         Log.i(TAG, "respondToClientWithErrorAndFinish");
+        if (isSessionCancelled()) {
+            // TODO: Differentiate btw cancelled and false
+            logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ true);
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         try {
             mClientCallback.onError(errorType, errorMsg);
         } catch (RemoteException e) {
             e.printStackTrace();
         }
         logApiCalled(RequestType.CLEAR_CREDENTIALS, /* isSuccessful */ false);
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
     private void processResponses() {
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 351afb9..c8518c5 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -27,6 +27,7 @@
 import android.credentials.ICreateCredentialCallback;
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.RequestInfo;
+import android.os.CancellationSignal;
 import android.os.RemoteException;
 import android.service.credentials.CallingAppInfo;
 import android.service.credentials.CredentialProviderInfo;
@@ -47,9 +48,10 @@
     CreateRequestSession(@NonNull Context context, int userId, int callingUid,
             CreateCredentialRequest request,
             ICreateCredentialCallback callback,
-            CallingAppInfo callingAppInfo) {
+            CallingAppInfo callingAppInfo,
+            CancellationSignal cancellationSignal) {
         super(context, userId, callingUid, request, callback, RequestInfo.TYPE_CREATE,
-                callingAppInfo);
+                callingAppInfo, cancellationSignal);
     }
 
     /**
@@ -95,7 +97,7 @@
         if (response != null) {
             respondToClientWithResponseAndFinish(response);
         } else {
-            respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
+            respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
                     "Invalid response");
         }
     }
@@ -117,8 +119,20 @@
         }
     }
 
+    @Override
+    public void onUiSelectorInvocationFailure() {
+        respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
+                "No create options available.");
+    }
+
     private void respondToClientWithResponseAndFinish(CreateCredentialResponse response) {
         Log.i(TAG, "respondToClientWithResponseAndFinish");
+        if (isSessionCancelled()) {
+            // TODO: Differentiate btw cancelled and false
+            logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ true);
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         try {
             mClientCallback.onResponse(response);
             logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ true);
@@ -126,18 +140,24 @@
             Log.i(TAG, "Issue while responding to client: " + e.getMessage());
             logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ false);
         }
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
     private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
         Log.i(TAG, "respondToClientWithErrorAndFinish");
+        if (isSessionCancelled()) {
+            // TODO: Differentiate btw cancelled and false
+            logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ true);
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         try {
             mClientCallback.onError(errorType, errorMsg);
         } catch (RemoteException e) {
             Log.i(TAG, "Issue while responding to client: " + e.getMessage());
         }
         logApiCalled(RequestType.CREATE_CREDENTIALS, /* isSuccessful */ false);
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
     @Override
@@ -152,8 +172,8 @@
                 Log.i(TAG, "in onProviderStatusChanged - isUiInvocationNeeded");
                 getProviderDataAndInitiateUi();
             } else {
-                respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREDENTIAL,
-                        "No credentials available");
+                respondToClientWithErrorAndFinish(CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
+                        "No create options available.");
             }
         }
     }
diff --git a/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java b/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java
index fbdcc44..3d504ef 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialDescriptionRegistry.java
@@ -19,35 +19,72 @@
 import android.credentials.CredentialDescription;
 import android.credentials.RegisterCredentialDescriptionRequest;
 import android.credentials.UnregisterCredentialDescriptionRequest;
+import android.service.credentials.CredentialEntry;
 import android.util.SparseArray;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
 
 /** Contains information on what CredentialProvider has what provisioned Credential. */
-public class CredentialDescriptionRegistry {
+public final class CredentialDescriptionRegistry {
 
     private static final int MAX_ALLOWED_CREDENTIAL_DESCRIPTIONS = 128;
     private static final int MAX_ALLOWED_ENTRIES_PER_PROVIDER = 16;
-    private static SparseArray<CredentialDescriptionRegistry> sCredentialDescriptionSessionPerUser;
+    @GuardedBy("sLock")
+    private static final SparseArray<CredentialDescriptionRegistry>
+            sCredentialDescriptionSessionPerUser;
+    private static final ReentrantLock sLock;
 
     static {
         sCredentialDescriptionSessionPerUser = new SparseArray<>();
+        sLock = new ReentrantLock();
     }
 
-    // TODO(b/265992655): add a way to update CredentialRegistry when a user is removed.
-    /** Get and/or create a {@link  CredentialDescription} for the given user id. */
-    public static CredentialDescriptionRegistry forUser(int userId) {
-        CredentialDescriptionRegistry session =
-                sCredentialDescriptionSessionPerUser.get(userId, null);
+    /** Represents the results of a given query into the registry. */
+    public static final class FilterResult {
+        final String mPackageName;
+        final List<CredentialEntry> mCredentialEntries;
 
-        if (session == null) {
-            session = new CredentialDescriptionRegistry();
-            sCredentialDescriptionSessionPerUser.put(userId, session);
+        private FilterResult(String packageName,
+                List<CredentialEntry> credentialEntries) {
+            mPackageName = packageName;
+            mCredentialEntries = credentialEntries;
         }
-        return session;
+    }
+
+    /** Get and/or create a {@link  CredentialDescription} for the given user id. */
+    @GuardedBy("sLock")
+    public static CredentialDescriptionRegistry forUser(int userId) {
+        sLock.lock();
+        try {
+            CredentialDescriptionRegistry session =
+                    sCredentialDescriptionSessionPerUser.get(userId, null);
+
+            if (session == null) {
+                session = new CredentialDescriptionRegistry();
+                sCredentialDescriptionSessionPerUser.put(userId, session);
+            }
+            return session;
+        } finally {
+            sLock.unlock();
+        }
+    }
+
+    /** Clears an existing session for a given user identifier. */
+    @GuardedBy("sLock")
+    public static void clearUserSession(int userId) {
+        sLock.lock();
+        try {
+            sCredentialDescriptionSessionPerUser.remove(userId);
+        } finally {
+            sLock.unlock();
+        }
     }
 
     private Map<String, Set<CredentialDescription>> mCredentialDescriptions;
@@ -74,7 +111,7 @@
             int size = mCredentialDescriptions.get(callingPackageName).size();
             mCredentialDescriptions.get(callingPackageName)
                     .addAll(descriptions);
-            mTotalDescriptionCount += size - mCredentialDescriptions.get(callingPackageName).size();
+            mTotalDescriptionCount += mCredentialDescriptions.get(callingPackageName).size() - size;
         }
 
     }
@@ -93,21 +130,33 @@
         }
     }
 
+    /** Returns package names and entries of a CredentialProviders that can satisfy a given
+     * {@link CredentialDescription}. */
+    public Set<FilterResult> getFilteredResultForProvider(String packageName,
+            List<String> flatRequestStrings) {
+        Set<FilterResult> result = new HashSet<>();
+        Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
+        for (CredentialDescription containedDescription: currentSet) {
+            if (flatRequestStrings.contains(containedDescription.getFlattenedRequestString())) {
+                result.add(new FilterResult(packageName, containedDescription
+                        .getCredentialEntries()));
+            }
+        }
+        return result;
+    }
+
     /** Returns package names of CredentialProviders that can satisfy a given
      * {@link CredentialDescription}. */
-    public Set<String> filterCredentials(String flatRequestString) {
-
+    public Set<String> getMatchingProviders(Set<String> flatRequestString) {
         Set<String> result = new HashSet<>();
-
-        for (String componentName: mCredentialDescriptions.keySet()) {
-            Set<CredentialDescription> currentSet = mCredentialDescriptions.get(componentName);
-            for (CredentialDescription containedDescription: currentSet) {
-                if (flatRequestString.equals(containedDescription.getFlattenedRequestString())) {
-                    result.add(componentName);
+        for (String packageName: mCredentialDescriptions.keySet()) {
+            Set<CredentialDescription> currentSet = mCredentialDescriptions.get(packageName);
+            for (CredentialDescription containedDescription : currentSet) {
+                if (flatRequestString.contains(containedDescription.getFlattenedRequestString())) {
+                    result.add(packageName);
                 }
             }
         }
-
         return result;
     }
 
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index d9a6d54..34101fe 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -16,9 +16,12 @@
 
 package com.android.server.credentials;
 
+import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;
 import static android.content.Context.CREDENTIAL_SERVICE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.content.ComponentName;
@@ -29,8 +32,8 @@
 import android.credentials.CreateCredentialException;
 import android.credentials.CreateCredentialRequest;
 import android.credentials.CredentialDescription;
+import android.credentials.CredentialOption;
 import android.credentials.GetCredentialException;
-import android.credentials.GetCredentialOption;
 import android.credentials.GetCredentialRequest;
 import android.credentials.IClearCredentialStateCallback;
 import android.credentials.ICreateCredentialCallback;
@@ -61,13 +64,11 @@
 import com.android.server.infra.SecureSettingsServiceNameResolver;
 
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * Entry point service for credential management.
@@ -83,17 +84,17 @@
     private static final String TAG = "CredManSysService";
     private static final String DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API =
             "enable_credential_description_api";
+    private static final String PERMISSION_DENIED_ERROR = "permission_denied";
+    private static final String PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR =
+            "Caller is missing WRITE_SECURE_SETTINGS permission";
 
     private final Context mContext;
 
-    /**
-     * Cache of system service list per user id.
-     */
+    /** Cache of system service list per user id. */
     @GuardedBy("mLock")
     private final SparseArray<List<CredentialManagerServiceImpl>> mSystemServicesCacheList =
             new SparseArray<>();
 
-
     public CredentialManagerService(@NonNull Context context) {
         super(
                 context,
@@ -111,9 +112,11 @@
         List<CredentialManagerServiceImpl> services = new ArrayList<>();
         List<CredentialProviderInfo> credentialProviderInfos =
                 CredentialProviderInfo.getAvailableSystemServices(mContext, resolvedUserId);
-        credentialProviderInfos.forEach(info -> {
-            services.add(new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info));
-        });
+        credentialProviderInfos.forEach(
+                info -> {
+                    services.add(
+                            new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info));
+                });
         return services;
     }
 
@@ -176,10 +179,9 @@
         CredentialManagerServiceImpl serviceToBeRemoved = null;
         for (CredentialManagerServiceImpl service : services) {
             if (service != null) {
-                CredentialProviderInfo credentialProviderInfo =
-                        service.getCredentialProviderInfo();
-                ComponentName componentName = credentialProviderInfo.getServiceInfo()
-                        .getComponentName();
+                CredentialProviderInfo credentialProviderInfo = service.getCredentialProviderInfo();
+                ComponentName componentName =
+                        credentialProviderInfo.getServiceInfo().getComponentName();
                 if (packageName.equals(componentName.getPackageName())) {
                     serviceToBeRemoved = service;
                     removeServiceFromMultiModeSettings(componentName.flattenToString(), userId);
@@ -195,8 +197,6 @@
         // TODO("Iterate over system services and remove if needed")
     }
 
-
-
     @GuardedBy("mLock")
     private List<CredentialManagerServiceImpl> getOrConstructSystemServiceListLock(
             int resolvedUserId) {
@@ -208,6 +208,16 @@
         return services;
     }
 
+    private boolean hasWriteSecureSettingsPermission() {
+        final String permission = android.Manifest.permission.WRITE_SECURE_SETTINGS;
+        final boolean result =
+                mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
+        if (!result) {
+            Slog.e(TAG, "Caller does not have WRITE_SECURE_SETTINGS permission.");
+        }
+        return result;
+    }
+
     private void runForUser(@NonNull final Consumer<CredentialManagerServiceImpl> c) {
         final int userId = UserHandle.getCallingUserId();
         final long origId = Binder.clearCallingIdentity();
@@ -225,8 +235,7 @@
     }
 
     @GuardedBy("mLock")
-    private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked(
-            int userId) {
+    private List<CredentialManagerServiceImpl> getAllCredentialProviderServicesLocked(int userId) {
         List<CredentialManagerServiceImpl> concatenatedServices = new ArrayList<>();
         List<CredentialManagerServiceImpl> userConfigurableServices =
                 getServiceListForUserLocked(userId);
@@ -236,52 +245,55 @@
         concatenatedServices.addAll(getOrConstructSystemServiceListLock(userId));
         return concatenatedServices;
     }
+
     public static boolean isCredentialDescriptionApiEnabled() {
-        return DeviceConfig.getBoolean(
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            return DeviceConfig.getBoolean(
                 DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_DESC_API, false);
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
     }
 
     @SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
     // to be guarded by 'service.mLock', which is the same as mLock.
     private List<ProviderSession> initiateProviderSessionsWithActiveContainers(
-            RequestSession session,
-            List<String> requestOptions, Set<ComponentName> activeCredentialContainers) {
+            GetRequestSession session,
+            List<String> requestOptions,
+            Set<String> activeCredentialContainers) {
         List<ProviderSession> providerSessions = new ArrayList<>();
         // Invoke all services of a user to initiate a provider session
-        runForUser((service) -> {
-            if (activeCredentialContainers.contains(service.getComponentName())) {
-                ProviderSession providerSession = service
-                        .initiateProviderSessionForRequestLocked(session, requestOptions);
-                if (providerSession != null) {
-                    providerSessions.add(providerSession);
-                }
-            }
-        });
+        for (String packageName : activeCredentialContainers) {
+            providerSessions.add(
+                    ProviderRegistryGetSession.createNewSession(
+                            mContext,
+                            UserHandle.getCallingUserId(),
+                            session,
+                            packageName,
+                            requestOptions));
+        }
         return providerSessions;
     }
 
     @NonNull
-    private Set<String> getMatchingProviders(GetCredentialRequest request) {
+    private Set<String> getFilteredResultFromRegistry(List<CredentialOption> options) {
         // Session for active/provisioned credential descriptions;
-        CredentialDescriptionRegistry registry = CredentialDescriptionRegistry
-                .forUser(UserHandle.getCallingUserId());
+        CredentialDescriptionRegistry registry =
+                CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId());
 
         // All requested credential descriptions based on the given request.
         Set<String> requestedCredentialDescriptions =
-                request.getGetCredentialOptions().stream().map(
-                        getCredentialOption -> getCredentialOption
-                                        .getCredentialRetrievalData()
-                                        .getString(GetCredentialOption
-                                                .FLATTENED_REQUEST))
+                options.stream()
+                        .map(
+                                getCredentialOption ->
+                                        getCredentialOption
+                                                .getCredentialRetrievalData()
+                                                .getString(CredentialOption.FLATTENED_REQUEST))
                         .collect(Collectors.toSet());
 
         // All requested credential descriptions based on the given request.
-        return requestedCredentialDescriptions.stream()
-                .map(registry::filterCredentials)
-                .flatMap(
-                        (Function<Set<String>, Stream<String>>)
-                                Collection::stream)
-                .collect(Collectors.toSet());
+        return registry.getMatchingProviders(requestedCredentialDescriptions);
     }
 
     @SuppressWarnings("GuardedBy") // ErrorProne requires initiateProviderSessionForRequestLocked
@@ -304,18 +316,33 @@
         return providerSessions;
     }
 
-    private CallingAppInfo constructCallingAppInfo(String packageName, int userId) {
+    @Override
+    @GuardedBy("CredentialDescriptionRegistry.sLock")
+    public void onUserStopped(@NonNull TargetUser user) {
+        super.onUserStopped(user);
+        CredentialDescriptionRegistry.clearUserSession(user.getUserIdentifier());
+    }
+
+    private CallingAppInfo constructCallingAppInfo(
+            String realPackageName,
+            int userId,
+            @Nullable String origin) {
         final PackageInfo packageInfo;
+        String actualPackageName = origin == null ? realPackageName : origin;
         try {
-            packageInfo = getContext().getPackageManager().getPackageInfoAsUser(
-                    packageName,
-                    PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES),
-                    userId);
+            packageInfo =
+                getContext()
+                    .getPackageManager()
+                    .getPackageInfoAsUser(
+                        actualPackageName,
+                        PackageManager.PackageInfoFlags.of(
+                            PackageManager.GET_SIGNING_CERTIFICATES),
+                        userId);
         } catch (PackageManager.NameNotFoundException e) {
             Log.i(TAG, "Issue while retrieving signatureInfo : " + e.getMessage());
-            return new CallingAppInfo(packageName, null);
+            return new CallingAppInfo(actualPackageName, null);
         }
-        return new CallingAppInfo(packageName, packageInfo.signingInfo);
+        return new CallingAppInfo(actualPackageName, packageInfo.signingInfo);
     }
 
     final class CredentialManagerServiceStub extends ICredentialManager.Stub {
@@ -325,11 +352,12 @@
                 IGetCredentialCallback callback,
                 final String callingPackage) {
             Log.i(TAG, "starting executeGetCredential with callingPackage: " + callingPackage);
-            // TODO : Implement cancellation
             ICancellationSignal cancelTransport = CancellationSignal.createTransport();
 
-            int userId = UserHandle.getCallingUserId();
-            int callingUid = Binder.getCallingUid();
+            final int userId = UserHandle.getCallingUserId();
+            final int callingUid = Binder.getCallingUid();
+            enforceCallingPackage(callingPackage, callingUid);
+
             // New request session, scoped for this request only.
             final GetRequestSession session =
                     new GetRequestSession(
@@ -338,32 +366,127 @@
                             callingUid,
                             callback,
                             request,
-                            constructCallingAppInfo(callingPackage, userId));
+                            constructCallingAppInfo(callingPackage, userId, null),
+                            CancellationSignal.fromTransport(cancelTransport));
 
-            // Initiate all provider sessions
-            List<ProviderSession> providerSessions =
+            processGetCredential(request, callback, session);
+            return cancelTransport;
+        }
+
+        public ICancellationSignal executeGetCredentialWithOrigin(
+                GetCredentialRequest request,
+                IGetCredentialCallback callback,
+                final String callingPackage,
+                final String origin) {
+            Log.i(TAG, "starting executeGetCredential with callingPackage: " + callingPackage);
+            ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+
+            // Check privileged permissions
+            mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
+
+            final int userId = UserHandle.getCallingUserId();
+            final int callingUid = Binder.getCallingUid();
+            enforceCallingPackage(callingPackage, callingUid);
+
+            // New request session, scoped for this request only.
+            final GetRequestSession session =
+                    new GetRequestSession(
+                        getContext(),
+                        userId,
+                        callingUid,
+                        callback,
+                        request,
+                        constructCallingAppInfo(callingPackage, userId, origin),
+                        CancellationSignal.fromTransport(cancelTransport));
+
+            processGetCredential(request, callback, session);
+            return cancelTransport;
+        }
+
+        private void processGetCredential(
+                GetCredentialRequest request,
+                IGetCredentialCallback callback,
+                GetRequestSession session) {
+            List<ProviderSession> providerSessions;
+
+            // TODO(b/268143699): temporarily disable the flag due to bug.
+            if (false) {
+                List<CredentialOption> optionsThatRequireActiveCredentials =
+                        request.getCredentialOptions().stream()
+                        .filter(
+                            getCredentialOption ->
+                                !TextUtils.isEmpty(
+                                    getCredentialOption
+                                        .getCredentialRetrievalData()
+                                        .getString(
+                                            CredentialOption
+                                                .FLATTENED_REQUEST,
+                                            null)))
+                        .toList();
+
+                List<CredentialOption> optionsThatDoNotRequireActiveCredentials =
+                        request.getCredentialOptions().stream()
+                        .filter(
+                            getCredentialOption ->
+                                TextUtils.isEmpty(
+                                    getCredentialOption
+                                        .getCredentialRetrievalData()
+                                        .getString(
+                                            CredentialOption
+                                                .FLATTENED_REQUEST,
+                                            null)))
+                        .toList();
+
+                List<ProviderSession> sessionsWithoutRemoteService =
+                        initiateProviderSessionsWithActiveContainers(
+                        session,
+                        optionsThatRequireActiveCredentials.stream()
+                            .map(
+                                getCredentialOption ->
+                                    getCredentialOption
+                                        .getCredentialRetrievalData()
+                                        .getString(
+                                            CredentialOption
+                                                .FLATTENED_REQUEST))
+                            .collect(Collectors.toList()),
+                        getFilteredResultFromRegistry(optionsThatRequireActiveCredentials));
+
+                List<ProviderSession> sessionsWithRemoteService =
                         initiateProviderSessions(
-                                session,
-                                request.getGetCredentialOptions().stream()
-                                        .map(GetCredentialOption::getType)
-                                        .collect(Collectors.toList()));
+                        session,
+                        optionsThatDoNotRequireActiveCredentials.stream()
+                            .map(CredentialOption::getType)
+                            .collect(Collectors.toList()));
+
+                Set<ProviderSession> all = new LinkedHashSet<>();
+                all.addAll(sessionsWithRemoteService);
+                all.addAll(sessionsWithoutRemoteService);
+
+                providerSessions = new ArrayList<>(all);
+            } else {
+                // Initiate all provider sessions
+                providerSessions =
+                    initiateProviderSessions(
+                        session,
+                        request.getCredentialOptions().stream()
+                            .map(CredentialOption::getType)
+                            .collect(Collectors.toList()));
+            }
 
             if (providerSessions.isEmpty()) {
                 try {
-                    callback.onError(GetCredentialException.TYPE_NO_CREDENTIAL,
+                    callback.onError(
+                            GetCredentialException.TYPE_NO_CREDENTIAL,
                             "No credentials available on this device.");
                 } catch (RemoteException e) {
                     Log.i(
                             TAG,
                             "Issue invoking onError on IGetCredentialCallback "
-                                    + "callback: "
-                                    + e.getMessage());
+                                + "callback: "
+                                + e.getMessage());
                 }
             }
-
-            // Iterate over all provider sessions and invoke the request
             providerSessions.forEach(ProviderSession::invokeSession);
-            return cancelTransport;
         }
 
         @Override
@@ -371,13 +494,14 @@
                 CreateCredentialRequest request,
                 ICreateCredentialCallback callback,
                 String callingPackage) {
-            Log.i(TAG, "starting executeCreateCredential with callingPackage: " + callingPackage);
-
+            Log.i(TAG, "starting executeCreateCredential with callingPackage: "
+                    + callingPackage);
             ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+            final int userId = UserHandle.getCallingUserId();
+            final int callingUid = Binder.getCallingUid();
+            enforceCallingPackage(callingPackage, callingUid);
 
             // New request session, scoped for this request only.
-            int userId = UserHandle.getCallingUserId();
-            int callingUid = Binder.getCallingUid();
             final CreateRequestSession session =
                     new CreateRequestSession(
                             getContext(),
@@ -385,29 +509,67 @@
                             callingUid,
                             request,
                             callback,
-                            constructCallingAppInfo(callingPackage, userId));
+                            constructCallingAppInfo(callingPackage, userId, null),
+                            CancellationSignal.fromTransport(cancelTransport));
 
+            processCreateCredential(request, callback, session);
+            return cancelTransport;
+        }
+
+        public ICancellationSignal executeCreateCredentialWithOrigin(
+                CreateCredentialRequest request,
+                ICreateCredentialCallback callback,
+                String callingPackage,
+                String origin) {
+            Log.i(TAG, "starting executeCreateCredential with callingPackage: " + callingPackage);
+            ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+
+            // Check privileged permissions
+            mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
+
+            final int userId = UserHandle.getCallingUserId();
+            final int callingUid = Binder.getCallingUid();
+            enforceCallingPackage(callingPackage, callingUid);
+
+            // New request session, scoped for this request only.
+            final CreateRequestSession session =
+                    new CreateRequestSession(
+                        getContext(),
+                        userId,
+                        callingUid,
+                        request,
+                        callback,
+                        constructCallingAppInfo(callingPackage, userId, origin),
+                        CancellationSignal.fromTransport(cancelTransport));
+
+            processCreateCredential(request, callback, session);
+            return cancelTransport;
+        }
+
+        private void processCreateCredential(
+                CreateCredentialRequest request,
+                ICreateCredentialCallback callback,
+                CreateRequestSession session) {
             // Initiate all provider sessions
             List<ProviderSession> providerSessions =
                     initiateProviderSessions(session, List.of(request.getType()));
 
             if (providerSessions.isEmpty()) {
                 try {
-                    callback.onError(CreateCredentialException.TYPE_NO_CREDENTIAL,
-                            "No credentials available on this device.");
+                    callback.onError(
+                            CreateCredentialException.TYPE_NO_CREATE_OPTIONS,
+                            "No create options available.");
                 } catch (RemoteException e) {
                     Log.i(
                             TAG,
                             "Issue invoking onError on ICreateCredentialCallback "
-                                    + "callback: "
-                                    + e.getMessage());
+                                + "callback: "
+                                + e.getMessage());
                 }
             }
 
             // Iterate over all provider sessions and invoke the request
-            providerSessions.forEach(
-                    ProviderSession::invokeSession);
-            return cancelTransport;
+            providerSessions.forEach(ProviderSession::invokeSession);
         }
 
         @SuppressWarnings("GuardedBy") // ErrorProne requires listEnabledProviders
@@ -417,6 +579,16 @@
             Log.i(TAG, "listEnabledProviders");
             ICancellationSignal cancelTransport = CancellationSignal.createTransport();
 
+            if (!hasWriteSecureSettingsPermission()) {
+                try {
+                    callback.onError(
+                            PERMISSION_DENIED_ERROR, PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Issue with invoking response: " + e.getMessage());
+                }
+                return cancelTransport;
+            }
+
             List<String> enabledProviders = new ArrayList<>();
             runForUser(
                     (service) -> {
@@ -439,6 +611,16 @@
                 List<String> providers, int userId, ISetEnabledProvidersCallback callback) {
             Log.i(TAG, "setEnabledProviders");
 
+            if (!hasWriteSecureSettingsPermission()) {
+                try {
+                    callback.onError(
+                            PERMISSION_DENIED_ERROR, PERMISSION_DENIED_WRITE_SECURE_SETTINGS_ERROR);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Issue with invoking response: " + e.getMessage());
+                }
+                return;
+            }
+
             userId =
                     ActivityManager.handleIncomingUser(
                             Binder.getCallingPid(),
@@ -479,17 +661,52 @@
         }
 
         @Override
+        public boolean isEnabledCredentialProviderService(
+                ComponentName componentName, String callingPackage) {
+            Log.i(TAG, "isEnabledCredentialProviderService");
+
+            // TODO(253157366): Check additional set of services.
+            final int userId = UserHandle.getCallingUserId();
+            final int callingUid = Binder.getCallingUid();
+            enforceCallingPackage(callingPackage, callingUid);
+            synchronized (mLock) {
+                final List<CredentialManagerServiceImpl> services =
+                        getServiceListForUserLocked(userId);
+                for (CredentialManagerServiceImpl s : services) {
+                    final ComponentName serviceComponentName = s.getServiceComponentName();
+
+                    if (serviceComponentName.equals(componentName)) {
+                        if (!s.getServicePackageName().equals(callingPackage)) {
+                            // The component name and the package name do not match.
+                            Log.w(
+                                    TAG,
+                                    "isEnabledCredentialProviderService: Component name does not"
+                                            + " match package name.");
+                            return false;
+                        }
+
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        @Override
         public ICancellationSignal clearCredentialState(
                 ClearCredentialStateRequest request,
                 IClearCredentialStateCallback callback,
                 String callingPackage) {
             Log.i(TAG, "starting clearCredentialState with callingPackage: " + callingPackage);
+            final int userId = UserHandle.getCallingUserId();
+            int callingUid = Binder.getCallingUid();
+            enforceCallingPackage(callingPackage, callingUid);
+
             // TODO : Implement cancellation
             ICancellationSignal cancelTransport = CancellationSignal.createTransport();
 
             // New request session, scoped for this request only.
-            int userId = UserHandle.getCallingUserId();
-            int callingUid = Binder.getCallingUid();
             final ClearRequestSession session =
                     new ClearRequestSession(
                             getContext(),
@@ -497,7 +714,8 @@
                             callingUid,
                             callback,
                             request,
-                            constructCallingAppInfo(callingPackage, userId));
+                            constructCallingAppInfo(callingPackage, userId, null),
+                            CancellationSignal.fromTransport(cancelTransport));
 
             // Initiate all provider sessions
             // TODO: Determine if provider needs to have clear capability in their manifest
@@ -506,8 +724,7 @@
             if (providerSessions.isEmpty()) {
                 try {
                     // TODO("Replace with properly defined error type")
-                    callback.onError("UNKNOWN", "No crdentials available on this "
-                            + "device");
+                    callback.onError("UNKNOWN", "No crdentials available on this " + "device");
                 } catch (RemoteException e) {
                     Log.i(
                             TAG,
@@ -518,47 +735,59 @@
             }
 
             // Iterate over all provider sessions and invoke the request
-            providerSessions.forEach(
-                    ProviderSession::invokeSession);
+            providerSessions.forEach(ProviderSession::invokeSession);
             return cancelTransport;
         }
 
         @Override
         public void registerCredentialDescription(
                 RegisterCredentialDescriptionRequest request, String callingPackage)
-                throws IllegalArgumentException , NonCredentialProviderCallerException {
+                throws IllegalArgumentException, NonCredentialProviderCallerException {
             Log.i(TAG, "registerCredentialDescription");
 
-            List<CredentialProviderInfo> services =
-                    CredentialProviderInfo.getAvailableServices(mContext,
-                            UserHandle.getCallingUserId());
+            enforceCallingPackage(callingPackage, Binder.getCallingUid());
 
-            List<String> providers = services.stream()
-                    .map(credentialProviderInfo
-                            -> credentialProviderInfo.getServiceInfo().packageName).toList();
+            List<CredentialProviderInfo> services =
+                    CredentialProviderInfo.getAvailableServices(
+                            mContext, UserHandle.getCallingUserId());
+
+            List<String> providers =
+                    services.stream()
+                            .map(
+                                    credentialProviderInfo ->
+                                            credentialProviderInfo.getServiceInfo().packageName)
+                            .toList();
 
             if (!providers.contains(callingPackage)) {
                 throw new NonCredentialProviderCallerException(callingPackage);
             }
 
-            List<CredentialProviderInfo> matchingService = services.stream().filter(
-                    credentialProviderInfo ->
-                            credentialProviderInfo.getServiceInfo()
-                                    .packageName.equals(callingPackage)).toList();
+            List<CredentialProviderInfo> matchingService =
+                    services.stream()
+                            .filter(
+                                    credentialProviderInfo ->
+                                            credentialProviderInfo
+                                                    .getServiceInfo()
+                                                    .packageName
+                                                    .equals(callingPackage))
+                            .toList();
 
             CredentialProviderInfo credentialProviderInfo = matchingService.get(0);
 
-            Set<String> supportedTypes = request.getCredentialDescriptions()
-                    .stream().map(CredentialDescription::getType).filter(
-                            credentialProviderInfo::hasCapability).collect(Collectors.toSet());
+            Set<String> supportedTypes =
+                    request.getCredentialDescriptions().stream()
+                            .map(CredentialDescription::getType)
+                            .filter(credentialProviderInfo::hasCapability)
+                            .collect(Collectors.toSet());
 
             if (supportedTypes.size() != request.getCredentialDescriptions().size()) {
-                throw new IllegalArgumentException("CredentialProvider does not support one or more"
-                        + "of the registered types. Check your XML entry.");
+                throw new IllegalArgumentException(
+                        "CredentialProvider does not support one or more"
+                                + "of the registered types. Check your XML entry.");
             }
 
-            CredentialDescriptionRegistry session = CredentialDescriptionRegistry
-                    .forUser(UserHandle.getCallingUserId());
+            CredentialDescriptionRegistry session =
+                    CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId());
 
             session.executeRegisterRequest(request, callingPackage);
         }
@@ -568,24 +797,43 @@
                 UnregisterCredentialDescriptionRequest request, String callingPackage)
                 throws IllegalArgumentException {
             Log.i(TAG, "registerCredentialDescription");
-            ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+
+            enforceCallingPackage(callingPackage, Binder.getCallingUid());
 
             List<CredentialProviderInfo> services =
-                    CredentialProviderInfo.getAvailableServices(mContext,
-                            UserHandle.getCallingUserId());
+                    CredentialProviderInfo.getAvailableServices(
+                            mContext, UserHandle.getCallingUserId());
 
-            List<String> providers = services.stream()
-                    .map(credentialProviderInfo
-                            -> credentialProviderInfo.getServiceInfo().packageName).toList();
+            List<String> providers =
+                    services.stream()
+                            .map(
+                                    credentialProviderInfo ->
+                                            credentialProviderInfo.getServiceInfo().packageName)
+                            .toList();
 
             if (!providers.contains(callingPackage)) {
                 throw new NonCredentialProviderCallerException(callingPackage);
             }
 
-            CredentialDescriptionRegistry session = CredentialDescriptionRegistry
-                    .forUser(UserHandle.getCallingUserId());
+            CredentialDescriptionRegistry session =
+                    CredentialDescriptionRegistry.forUser(UserHandle.getCallingUserId());
 
             session.executeUnregisterRequest(request, callingPackage);
         }
     }
+
+    private void enforceCallingPackage(String callingPackage, int callingUid) {
+        int packageUid;
+        PackageManager pm = mContext.createContextAsUser(
+                UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
+        try {
+            packageUid = pm.getPackageUid(callingPackage,
+                    PackageManager.PackageInfoFlags.of(0));
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new SecurityException(callingPackage + " not found");
+        }
+        if (packageUid != callingUid) {
+            throw new SecurityException(callingPackage + " does not belong to uid " + callingUid);
+        }
+    }
 }
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index 797601a..a6f6a830 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -56,19 +56,29 @@
     };
 
     private void handleUiResult(int resultCode, Bundle resultData) {
-        if (resultCode == UserSelectionDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION) {
-            UserSelectionDialogResult selection = UserSelectionDialogResult
-                    .fromResultData(resultData);
-            if (selection != null) {
-                mCallbacks.onUiSelection(selection);
-            } else {
-                Slog.i(TAG, "No selection found in UI result");
-            }
-        } else if (resultCode == UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED) {
-            mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
-        } else if (resultCode
-                == UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS) {
-            mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
+        switch (resultCode) {
+            case UserSelectionDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION:
+                UserSelectionDialogResult selection = UserSelectionDialogResult
+                        .fromResultData(resultData);
+                if (selection != null) {
+                    mCallbacks.onUiSelection(selection);
+                } else {
+                    Slog.i(TAG, "No selection found in UI result");
+                }
+                break;
+            case UserSelectionDialogResult.RESULT_CODE_DIALOG_USER_CANCELED:
+                mCallbacks.onUiCancellation(/* isUserCancellation= */ true);
+                break;
+            case UserSelectionDialogResult.RESULT_CODE_CANCELED_AND_LAUNCHED_SETTINGS:
+                mCallbacks.onUiCancellation(/* isUserCancellation= */ false);
+                break;
+            case UserSelectionDialogResult.RESULT_CODE_DATA_PARSING_FAILURE:
+                mCallbacks.onUiSelectorInvocationFailure();
+                break;
+            default:
+                Slog.i(TAG, "Unknown error code returned from the UI");
+                mCallbacks.onUiSelectorInvocationFailure();
+                break;
         }
     }
 
@@ -80,6 +90,9 @@
         void onUiSelection(UserSelectionDialogResult selection);
         /** Called when the UI is canceled without a successful provider result. */
         void onUiCancellation(boolean isUserCancellation);
+
+        /** Called when the selector UI fails to come up (mostly due to parsing issue today). */
+        void onUiSelectorInvocationFailure();
     }
     public CredentialManagerUi(Context context, int userId,
             CredentialManagerUiCallback callbacks) {
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index e3a27ec..3324999 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -25,6 +25,7 @@
 import android.credentials.IGetCredentialCallback;
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.RequestInfo;
+import android.os.CancellationSignal;
 import android.os.RemoteException;
 import android.service.credentials.CallingAppInfo;
 import android.service.credentials.CredentialProviderInfo;
@@ -43,8 +44,9 @@
 
     public GetRequestSession(Context context, int userId, int callingUid,
             IGetCredentialCallback callback, GetCredentialRequest request,
-            CallingAppInfo callingAppInfo) {
-        super(context, userId, callingUid, request, callback, RequestInfo.TYPE_GET, callingAppInfo);
+            CallingAppInfo callingAppInfo, CancellationSignal cancellationSignal) {
+        super(context, userId, callingUid, request, callback, RequestInfo.TYPE_GET,
+                callingAppInfo, cancellationSignal);
     }
 
     /**
@@ -102,6 +104,12 @@
     }
 
     private void respondToClientWithResponseAndFinish(GetCredentialResponse response) {
+        if (isSessionCancelled()) {
+            // TODO: Differentiate btw cancelled and false
+            logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         try {
             mClientCallback.onResponse(response);
             logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ true);
@@ -109,18 +117,22 @@
             Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage());
             logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
         }
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
     private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
+        if (isSessionCancelled()) {
+            logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         try {
             mClientCallback.onError(errorType, errorMsg);
         } catch (RemoteException e) {
             Log.i(TAG, "Issue while responding to client with error : " + e.getMessage());
-
         }
         logApiCalled(RequestType.GET_CREDENTIALS, /* isSuccessful */ false);
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
     @Override
@@ -135,6 +147,12 @@
     }
 
     @Override
+    public void onUiSelectorInvocationFailure() {
+        respondToClientWithErrorAndFinish(GetCredentialException.TYPE_NO_CREDENTIAL,
+                    "No credentials to show on the selector.");
+    }
+
+    @Override
     public void onProviderStatusChanged(ProviderSession.Status status,
             ComponentName componentName) {
         Log.i(TAG, "in onStatusChanged with status: " + status);
diff --git a/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java b/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
index c2b346f..efb394d 100644
--- a/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
+++ b/services/credentials/java/com/android/server/credentials/PendingIntentResultHandler.java
@@ -23,8 +23,8 @@
 import android.credentials.GetCredentialException;
 import android.credentials.GetCredentialResponse;
 import android.credentials.ui.ProviderPendingIntentResponse;
+import android.service.credentials.BeginGetCredentialResponse;
 import android.service.credentials.CredentialProviderService;
-import android.service.credentials.CredentialsResponseContent;
 
 /**
  * Helper class for setting up pending intent, and extracting objects from it.
@@ -45,14 +45,14 @@
         return pendingIntentResponse.getResultCode() == Activity.RESULT_CANCELED;
     }
 
-    /** Extracts the {@link CredentialsResponseContent} object added to the result data. */
-    public static CredentialsResponseContent extractResponseContent(Intent resultData) {
+    /** Extracts the {@link BeginGetCredentialResponse} object added to the result data. */
+    public static BeginGetCredentialResponse extractResponseContent(Intent resultData) {
         if (resultData == null) {
             return null;
         }
         return resultData.getParcelableExtra(
-                CredentialProviderService.EXTRA_CREDENTIALS_RESPONSE_CONTENT,
-                CredentialsResponseContent.class);
+                CredentialProviderService.EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE,
+                BeginGetCredentialResponse.class);
     }
 
     /** Extracts the {@link CreateCredentialResponse} object added to the result data. */
diff --git a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
index b112649..b20f0cd 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
@@ -118,8 +118,8 @@
 
     @Override
     protected void invokeSession() {
-        this.mRemoteCredentialService.onClearCredentialState(
-                this.getProviderRequest(),
-                /*callback=*/this);
+        if (mRemoteCredentialService != null) {
+            mRemoteCredentialService.onClearCredentialState(mProviderRequest, this);
+        }
     }
 }
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index cc5a8ab..b4c4233 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -26,6 +26,7 @@
 import android.credentials.ui.CreateCredentialProviderData;
 import android.credentials.ui.Entry;
 import android.credentials.ui.ProviderPendingIntentResponse;
+import android.os.Bundle;
 import android.service.credentials.BeginCreateCredentialRequest;
 import android.service.credentials.BeginCreateCredentialResponse;
 import android.service.credentials.CallingAppInfo;
@@ -34,6 +35,7 @@
 import android.service.credentials.CredentialProviderInfo;
 import android.service.credentials.CredentialProviderService;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 
 import java.util.ArrayList;
@@ -51,6 +53,8 @@
 
     // Key to be used as an entry key for a save entry
     private 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";
 
     @NonNull
     private final Map<String, CreateEntry> mUiSaveEntries = new HashMap<>();
@@ -59,6 +63,8 @@
 
     private CreateCredentialException mProviderException;
 
+    @Nullable protected Pair<String, CreateEntry> mUiRemoteEntry;
+
     /** Creates a new provider session to be used by the request session. */
     @Nullable public static ProviderCreateSession createNewSession(
             Context context,
@@ -71,18 +77,40 @@
                         createRequestSession.mClientRequest,
                         createRequestSession.mClientAppInfo);
         if (providerCreateRequest != null) {
-            BeginCreateCredentialRequest providerBeginCreateRequest =
-                    new BeginCreateCredentialRequest(
-                            providerCreateRequest.getCallingAppInfo(),
-                            providerCreateRequest.getType(),
-                            createRequestSession.mClientRequest.getCandidateQueryData());
-            return new ProviderCreateSession(context, providerInfo, createRequestSession, userId,
-                    remoteCredentialService, providerBeginCreateRequest, providerCreateRequest);
+            return new ProviderCreateSession(
+                    context,
+                    providerInfo,
+                    createRequestSession,
+                    userId,
+                    remoteCredentialService,
+                    constructQueryPhaseRequest(createRequestSession.mClientRequest.getType(),
+                            createRequestSession.mClientRequest.getCandidateQueryData(),
+                            createRequestSession.mClientAppInfo,
+                            createRequestSession
+                                    .mClientRequest.alwaysSendAppInfoToProvider()),
+                    providerCreateRequest
+            );
         }
         Log.i(TAG, "Unable to create provider session");
         return null;
     }
 
+    private static BeginCreateCredentialRequest constructQueryPhaseRequest(
+            String type, Bundle candidateQueryData, CallingAppInfo callingAppInfo,
+            boolean propagateToProvider) {
+        if (propagateToProvider) {
+            return new BeginCreateCredentialRequest(
+                    type,
+                    candidateQueryData,
+                    callingAppInfo
+            );
+        }
+        return new BeginCreateCredentialRequest(
+                type,
+                candidateQueryData
+        );
+    }
+
     @Nullable
     private static CreateCredentialRequest createProviderRequest(List<String> providerCapabilities,
             android.credentials.CreateCredentialRequest clientRequest,
@@ -146,7 +174,16 @@
     private void onUpdateResponse(BeginCreateCredentialResponse response) {
         Log.i(TAG, "updateResponse with save entries");
         mProviderResponse = response;
-        updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
+        if (isEmptyResponse(response)) {
+            updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
+        } else {
+            updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
+        }
+    }
+
+    private boolean isEmptyResponse(BeginCreateCredentialResponse response) {
+        return (response.getCreateEntries() == null || response.getCreateEntries().isEmpty())
+                && response.getRemoteCreateEntry() == null;
     }
 
     @Override
@@ -166,12 +203,22 @@
             Log.i(TAG, "In prepareUiData save entries not null");
             return prepareUiProviderData(
                     prepareUiSaveEntries(response.getCreateEntries()),
-                    null,
-                    /*isDefaultProvider=*/false);
+                    prepareUiRemoteEntry(response.getRemoteCreateEntry()));
         }
         return null;
     }
 
+    private Entry prepareUiRemoteEntry(CreateEntry remoteCreateEntry) {
+        if (remoteCreateEntry == null) {
+            return null;
+        }
+        String entryId = generateUniqueId();
+        Entry remoteEntry = new Entry(REMOTE_ENTRY_KEY, entryId, remoteCreateEntry.getSlice(),
+                setUpFillInIntent());
+        mUiRemoteEntry = new Pair<>(entryId, remoteCreateEntry);
+        return remoteEntry;
+    }
+
     @Override
     public void onUiEntrySelected(String entryType, String entryKey,
             ProviderPendingIntentResponse providerPendingIntentResponse) {
@@ -199,9 +246,9 @@
 
     @Override
     protected void invokeSession() {
-        this.mRemoteCredentialService.onCreateCredential(
-                this.getProviderRequest(),
-                /*callback=*/this);
+        if (mRemoteCredentialService != null) {
+            mRemoteCredentialService.onCreateCredential(mProviderRequest, this);
+        }
     }
 
     private List<Entry> prepareUiSaveEntries(@NonNull List<CreateEntry> saveEntries) {
@@ -210,7 +257,7 @@
 
         // Populate the save entries
         for (CreateEntry createEntry : saveEntries) {
-            String entryId = generateEntryId();
+            String entryId = generateUniqueId();
             mUiSaveEntries.put(entryId, createEntry);
             Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId);
             uiSaveEntries.add(new Entry(SAVE_ENTRY_KEY, entryId, createEntry.getSlice(),
@@ -227,10 +274,11 @@
     }
 
     private CreateCredentialProviderData prepareUiProviderData(List<Entry> saveEntries,
-            Entry remoteEntry, boolean isDefaultProvider) {
+            Entry remoteEntry) {
         return new CreateCredentialProviderData.Builder(
                 mComponentName.flattenToString())
                 .setSaveEntries(saveEntries)
+                .setRemoteEntry(remoteEntry)
                 .build();
     }
 
@@ -261,7 +309,7 @@
             ProviderPendingIntentResponse pendingIntentResponse) {
         if (pendingIntentResponse == null) {
             Log.i(TAG, "pendingIntentResponse is null");
-            return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREDENTIAL);
+            return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREATE_OPTIONS);
         }
         if (PendingIntentResultHandler.isValidResponse(pendingIntentResponse)) {
             CreateCredentialException exception = PendingIntentResultHandler
@@ -273,7 +321,7 @@
         } else if (PendingIntentResultHandler.isCancelledResponse(pendingIntentResponse)) {
             return new CreateCredentialException(CreateCredentialException.TYPE_USER_CANCELED);
         } else {
-            return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREDENTIAL);
+            return new CreateCredentialException(CreateCredentialException.TYPE_NO_CREATE_OPTIONS);
         }
         return null;
     }
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index b4058ed..c2a57a8 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -21,9 +21,10 @@
 import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.Intent;
+import android.credentials.CredentialOption;
 import android.credentials.GetCredentialException;
-import android.credentials.GetCredentialOption;
 import android.credentials.GetCredentialResponse;
+import android.credentials.ui.AuthenticationEntry;
 import android.credentials.ui.Entry;
 import android.credentials.ui.GetCredentialProviderData;
 import android.credentials.ui.ProviderPendingIntentResponse;
@@ -35,7 +36,6 @@
 import android.service.credentials.CredentialEntry;
 import android.service.credentials.CredentialProviderInfo;
 import android.service.credentials.CredentialProviderService;
-import android.service.credentials.CredentialsResponseContent;
 import android.service.credentials.GetCredentialRequest;
 import android.util.Log;
 import android.util.Pair;
@@ -46,7 +46,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
-import java.util.stream.Collectors;
 
 /**
  * Central provider session that listens for provider callbacks, and maintains provider state.
@@ -59,21 +58,25 @@
         implements
         RemoteCredentialService.ProviderCallbacks<BeginGetCredentialResponse> {
     private static final String TAG = "ProviderGetSession";
-
-    // Key to be used as an entry key for a credential entry
-    private static final String CREDENTIAL_ENTRY_KEY = "credential_key";
-
     // Key to be used as the entry key for an action entry
     private static final String ACTION_ENTRY_KEY = "action_key";
     // Key to be used as the entry key for the authentication entry
     private static final String AUTHENTICATION_ACTION_ENTRY_KEY = "authentication_action_key";
+    // Key to be used as an entry key for a remote entry
+    private static final String REMOTE_ENTRY_KEY = "remote_entry_key";
+    // Key to be used as an entry key for a credential entry
+    private static final String CREDENTIAL_ENTRY_KEY = "credential_key";
 
     @NonNull
+    private final Map<String, CredentialOption> mBeginGetOptionToCredentialOptionMap;
+    @NonNull
     private final Map<String, CredentialEntry> mUiCredentialEntries = new HashMap<>();
     @NonNull
     private final Map<String, Action> mUiActionsEntries = new HashMap<>();
     @Nullable
-    private Pair<String, Action> mUiAuthenticationAction = null;
+    private final Map<String, Action> mUiAuthenticationEntries = new HashMap<>();
+
+    @Nullable protected Pair<String, CredentialEntry> mUiRemoteEntry;
 
     /** The complete request to be used in the second round. */
     private final android.credentials.GetCredentialRequest mCompleteRequest;
@@ -92,37 +95,54 @@
                 filterOptions(providerInfo.getCapabilities(),
                         getRequestSession.mClientRequest);
         if (filteredRequest != null) {
-            BeginGetCredentialRequest beginGetCredentialRequest = constructQueryPhaseRequest(
-                    filteredRequest, getRequestSession.mClientAppInfo);
-            return new ProviderGetSession(context, providerInfo, getRequestSession, userId,
-                    remoteCredentialService, beginGetCredentialRequest, filteredRequest);
+            Map<String, CredentialOption> beginGetOptionToCredentialOptionMap =
+                    new HashMap<>();
+            return new ProviderGetSession(
+                    context,
+                    providerInfo,
+                    getRequestSession,
+                    userId,
+                    remoteCredentialService,
+                    constructQueryPhaseRequest(
+                            filteredRequest, getRequestSession.mClientAppInfo,
+                            getRequestSession.mClientRequest.alwaysSendAppInfoToProvider(),
+                            beginGetOptionToCredentialOptionMap),
+                    filteredRequest,
+                    getRequestSession.mClientAppInfo,
+                    beginGetOptionToCredentialOptionMap
+            );
         }
         Log.i(TAG, "Unable to create provider session");
         return null;
     }
-
     private static BeginGetCredentialRequest constructQueryPhaseRequest(
             android.credentials.GetCredentialRequest filteredRequest,
-            CallingAppInfo callingAppInfo
+            CallingAppInfo callingAppInfo,
+            boolean propagateToProvider,
+            Map<String, CredentialOption> beginGetOptionToCredentialOptionMap
     ) {
-        return new BeginGetCredentialRequest.Builder(callingAppInfo)
-                .setBeginGetCredentialOptions(
-                        filteredRequest.getGetCredentialOptions().stream().map(
-                                option -> {
-                                    return new BeginGetCredentialOption(
-                                            option.getType(),
-                                            option.getCandidateQueryData());
-                                }).collect(Collectors.toList()))
-                .build();
+        BeginGetCredentialRequest.Builder builder = new BeginGetCredentialRequest.Builder();
+        filteredRequest.getCredentialOptions().forEach(option -> {
+            String id = generateUniqueId();
+            builder.addBeginGetCredentialOption(
+                    new BeginGetCredentialOption(
+                            id, option.getType(), option.getCandidateQueryData())
+            );
+            beginGetOptionToCredentialOptionMap.put(id, option);
+        });
+        if (propagateToProvider) {
+            builder.setCallingAppInfo(callingAppInfo);
+        }
+        return builder.build();
     }
 
     @Nullable
-    private static android.credentials.GetCredentialRequest filterOptions(
+    protected static android.credentials.GetCredentialRequest filterOptions(
             List<String> providerCapabilities,
             android.credentials.GetCredentialRequest clientRequest
     ) {
-        List<GetCredentialOption> filteredOptions = new ArrayList<>();
-        for (GetCredentialOption option : clientRequest.getGetCredentialOptions()) {
+        List<CredentialOption> filteredOptions = new ArrayList<>();
+        for (CredentialOption option : clientRequest.getCredentialOptions()) {
             if (providerCapabilities.contains(option.getType())) {
                 Log.i(TAG, "In createProviderRequest - capability found : "
                         + option.getType());
@@ -135,7 +155,7 @@
         if (!filteredOptions.isEmpty()) {
             return new android.credentials.GetCredentialRequest
                     .Builder(clientRequest.getData())
-                    .setGetCredentialOptions(
+                    .setCredentialOptions(
                             filteredOptions).build();
         }
         Log.i(TAG, "In createProviderRequest - returning null");
@@ -147,17 +167,14 @@
             ProviderInternalCallback<GetCredentialResponse> callbacks,
             int userId, RemoteCredentialService remoteCredentialService,
             BeginGetCredentialRequest beginGetRequest,
-            android.credentials.GetCredentialRequest completeGetRequest) {
+            android.credentials.GetCredentialRequest completeGetRequest,
+            CallingAppInfo callingAppInfo,
+            Map<String, CredentialOption> beginGetOptionToCredentialOptionMap) {
         super(context, info, beginGetRequest, callbacks, userId, remoteCredentialService);
         mCompleteRequest = completeGetRequest;
-        mCallingAppInfo = beginGetRequest.getCallingAppInfo();
+        mCallingAppInfo = callingAppInfo;
         setStatus(Status.PENDING);
-    }
-
-    /** Returns the credential entry maintained in state by this provider session. */
-    @Nullable
-    public CredentialEntry getCredentialEntry(@NonNull String entryId) {
-        return mUiCredentialEntries.get(entryId);
+        mBeginGetOptionToCredentialOptionMap = new HashMap<>(beginGetOptionToCredentialOptionMap);
     }
 
     /** Called when the provider response has been updated by an external source. */
@@ -210,12 +227,13 @@
                 onActionEntrySelected(providerPendingIntentResponse);
                 break;
             case AUTHENTICATION_ACTION_ENTRY_KEY:
-                if (mUiAuthenticationAction.first.equals(entryKey)) {
-                    onAuthenticationEntrySelected(providerPendingIntentResponse);
-                } else {
-                    Log.i(TAG, "Unexpected authentication entry key");
+                Action authenticationEntry = mUiAuthenticationEntries.get(entryKey);
+                if (authenticationEntry == null) {
+                    Log.i(TAG, "Unexpected authenticationEntry key");
                     invokeCallbackOnInternalInvalidState();
+                    return;
                 }
+                onAuthenticationEntrySelected(providerPendingIntentResponse);
                 break;
             case REMOTE_ENTRY_KEY:
                 if (mUiRemoteEntry.first.equals(entryKey)) {
@@ -232,9 +250,9 @@
 
     @Override
     protected void invokeSession() {
-        this.mRemoteCredentialService.onBeginGetCredential(
-                        this.getProviderRequest(),
-                        /*callback=*/this);
+        if (mRemoteCredentialService != null) {
+            mRemoteCredentialService.onBeginGetCredential(mProviderRequest, this);
+        }
     }
 
     @Override // Call from request session to data to be shown on the UI
@@ -249,43 +267,39 @@
             Log.i(TAG, "In prepareUiData response null");
             throw new IllegalStateException("Response must be in completion mode");
         }
-        if (mProviderResponse.getAuthenticationAction() != null) {
-            Log.i(TAG, "In prepareUiData - top level authentication mode");
-            return prepareUiProviderData(null, null,
-                    prepareUiAuthenticationAction(mProviderResponse.getAuthenticationAction()),
-                    /*remoteEntry=*/null);
-        }
-        if (mProviderResponse.getCredentialsResponseContent() != null) {
-            Log.i(TAG, "In prepareUiData credentialsResponseContent not null");
-            return prepareUiProviderData(prepareUiActionEntries(
-                            mProviderResponse.getCredentialsResponseContent().getActions()),
-                    prepareUiCredentialEntries(mProviderResponse.getCredentialsResponseContent()
-                            .getCredentialEntries()),
-                    /*authenticationAction=*/null,
-                    prepareUiRemoteEntry(mProviderResponse
-                            .getCredentialsResponseContent().getRemoteCredentialEntry()));
-        }
-        return null;
+        return prepareUiProviderData(prepareUiActionEntries(
+                        mProviderResponse.getActions()),
+                prepareUiCredentialEntries(mProviderResponse.getCredentialEntries()),
+                prepareUiAuthenticationEntries(mProviderResponse.getAuthenticationActions()),
+                prepareUiRemoteEntry(mProviderResponse.getRemoteCredentialEntry()));
     }
 
     private Entry prepareUiRemoteEntry(CredentialEntry remoteCredentialEntry) {
         if (remoteCredentialEntry == null) {
             return null;
         }
-        String entryId = generateEntryId();
-        Entry remoteEntry = new Entry(REMOTE_ENTRY_KEY, entryId, remoteCredentialEntry.getSlice());
+        String entryId = generateUniqueId();
+        Entry remoteEntry = new Entry(REMOTE_ENTRY_KEY, entryId, remoteCredentialEntry.getSlice(),
+                setUpFillInIntent(remoteCredentialEntry.getType()));
         mUiRemoteEntry = new Pair<>(entryId, remoteCredentialEntry);
         return remoteEntry;
     }
 
-    private Entry prepareUiAuthenticationAction(@NonNull Action authenticationAction) {
-        String entryId = generateEntryId();
-        Entry authEntry = new Entry(
-                AUTHENTICATION_ACTION_ENTRY_KEY, entryId,
-                authenticationAction.getSlice(),
-                setUpFillInIntentForAuthentication());
-        mUiAuthenticationAction = new Pair<>(entryId, authenticationAction);
-        return authEntry;
+    private List<AuthenticationEntry> prepareUiAuthenticationEntries(
+            @NonNull List<Action> authenticationEntries) {
+        List<AuthenticationEntry> authenticationUiEntries = new ArrayList<>();
+
+        // TODO: properly construct entries when they should have the unlocked status.
+        for (Action authenticationAction : authenticationEntries) {
+            String entryId = generateUniqueId();
+            mUiAuthenticationEntries.put(entryId, authenticationAction);
+            authenticationUiEntries.add(new AuthenticationEntry(
+                    AUTHENTICATION_ACTION_ENTRY_KEY, entryId,
+                    authenticationAction.getSlice(),
+                    AuthenticationEntry.STATUS_LOCKED,
+                    setUpFillInIntentForAuthentication()));
+        }
+        return authenticationUiEntries;
     }
 
     private List<Entry> prepareUiCredentialEntries(@NonNull
@@ -295,28 +309,29 @@
 
         // Populate the credential entries
         for (CredentialEntry credentialEntry : credentialEntries) {
-            String entryId = generateEntryId();
+            String entryId = generateUniqueId();
             mUiCredentialEntries.put(entryId, credentialEntry);
             Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId);
             credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId,
                     credentialEntry.getSlice(),
-                    /*fillInIntent=*/setUpFillInIntent(credentialEntry.getType())));
+                    /*fillInIntent=*/setUpFillInIntent(credentialEntry
+                    .getBeginGetCredentialOption().getId())));
         }
         return credentialUiEntries;
     }
 
-    private Intent setUpFillInIntent(String type) {
-        Intent intent = new Intent();
-        for (GetCredentialOption option : mCompleteRequest.getGetCredentialOptions()) {
-            if (option.getType().equals(type)) {
-                intent.putExtra(
-                        CredentialProviderService
-                                .EXTRA_GET_CREDENTIAL_REQUEST,
-                        new GetCredentialRequest(mCallingAppInfo, option));
-                return intent;
-            }
+    private Intent setUpFillInIntent(@NonNull String id) {
+        // TODO: Determine if we should skip this entry if entry id is not set, or is set
+        // but does not resolve to a valid option. For now, not skipping it because
+        // it may be possible that the provider adds their own extras and expects to receive
+        // those and complete the flow.
+        if (mBeginGetOptionToCredentialOptionMap.get(id) == null) {
+            Log.i(TAG, "Id from Credential Entry does not resolve to a valid option");
+            return new Intent();
         }
-        return intent;
+        return new Intent().putExtra(CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
+                new GetCredentialRequest(
+                        mCallingAppInfo, mBeginGetOptionToCredentialOptionMap.get(id)));
     }
 
     private Intent setUpFillInIntentForAuthentication() {
@@ -340,12 +355,12 @@
     }
 
     private GetCredentialProviderData prepareUiProviderData(List<Entry> actionEntries,
-            List<Entry> credentialEntries, Entry authenticationActionEntry,
+            List<Entry> credentialEntries, List<AuthenticationEntry> authenticationActionEntries,
             Entry remoteEntry) {
         return new GetCredentialProviderData.Builder(
                 mComponentName.flattenToString()).setActionChips(actionEntries)
                 .setCredentialEntries(credentialEntries)
-                .setAuthenticationEntry(authenticationActionEntry)
+                .setAuthenticationEntries(authenticationActionEntries)
                 .setRemoteEntry(remoteEntry)
                 .build();
     }
@@ -379,60 +394,8 @@
         invokeCallbackOnInternalInvalidState();
     }
 
-    private void onAuthenticationEntrySelected(
-            @Nullable ProviderPendingIntentResponse providerPendingIntentResponse) {
-        //TODO: Other provider intent statuses
-        if (providerPendingIntentResponse == null) {
-            Log.i(TAG, "providerPendingIntentResponse is null");
-            onUpdateEmptyResponse();
-        }
-
-        GetCredentialException exception = maybeGetPendingIntentException(
-                providerPendingIntentResponse);
-        if (exception != null) {
-            invokeCallbackWithError(exception.getType(),
-                    exception.getMessage());
-            return;
-        }
-
-        // Check if pending intent has the content
-        CredentialsResponseContent content = PendingIntentResultHandler
-                .extractResponseContent(providerPendingIntentResponse
-                        .getResultData());
-        if (content != null) {
-            onUpdateResponse(BeginGetCredentialResponse.createWithResponseContent(content));
-            return;
-        }
-
-        Log.i(TAG, "No error or respond found in pending intent response");
-        onUpdateEmptyResponse();
-    }
-
-    private void onActionEntrySelected(ProviderPendingIntentResponse
-            providerPendingIntentResponse) {
-        //TODO: Implement if any result expected after an action
-    }
-
-
-    /** Updates the response being maintained in state by this provider session. */
-    private void onUpdateResponse(BeginGetCredentialResponse response) {
-        mProviderResponse = response;
-        if (response.getAuthenticationAction() != null) {
-            Log.i(TAG , "updateResponse with authentication entry");
-            updateStatusAndInvokeCallback(Status.REQUIRES_AUTHENTICATION);
-        } else if (response.getCredentialsResponseContent() != null) {
-            Log.i(TAG , "updateResponse with credentialEntries");
-            // TODO validate response
-            updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
-        }
-    }
-
-    private void onUpdateEmptyResponse() {
-        updateStatusAndInvokeCallback(Status.NO_CREDENTIALS);
-    }
-
     @Nullable
-    private GetCredentialException maybeGetPendingIntentException(
+    protected GetCredentialException maybeGetPendingIntentException(
             ProviderPendingIntentResponse pendingIntentResponse) {
         if (pendingIntentResponse == null) {
             Log.i(TAG, "pendingIntentResponse is null");
@@ -453,6 +416,67 @@
         return null;
     }
 
+    private void onAuthenticationEntrySelected(
+            @Nullable ProviderPendingIntentResponse providerPendingIntentResponse) {
+        //TODO: Other provider intent statuses
+        if (providerPendingIntentResponse == null) {
+            Log.i(TAG, "providerPendingIntentResponse is null");
+            onUpdateEmptyResponse();
+            return;
+        }
+
+        GetCredentialException exception = maybeGetPendingIntentException(
+                providerPendingIntentResponse);
+        if (exception != null) {
+            invokeCallbackWithError(exception.getType(),
+                    exception.getMessage());
+            return;
+        }
+
+        // Check if pending intent has the content
+        BeginGetCredentialResponse content = PendingIntentResultHandler
+                .extractResponseContent(providerPendingIntentResponse
+                        .getResultData());
+        if (content != null) {
+            onUpdateResponse(content);
+            return;
+        }
+
+        Log.i(TAG, "No error or respond found in pending intent response");
+        onUpdateEmptyResponse();
+    }
+
+    private void onActionEntrySelected(ProviderPendingIntentResponse
+            providerPendingIntentResponse) {
+        //TODO: Implement if any result expected after an action
+    }
+
+
+    /** Updates the response being maintained in state by this provider session. */
+    private void onUpdateResponse(BeginGetCredentialResponse response) {
+        mProviderResponse = response;
+        if (isEmptyResponse(response)) {
+            updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
+        } else {
+            updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
+        }
+    }
+
+    private boolean isEmptyResponse(BeginGetCredentialResponse response) {
+        if ((response.getCredentialEntries() == null || response.getCredentialEntries().isEmpty())
+                && (response.getAuthenticationActions() == null || response
+                .getAuthenticationActions().isEmpty())
+                && (response.getActions() == null || response.getActions().isEmpty())
+                && response.getRemoteCredentialEntry() == null) {
+            return true;
+        }
+        return false;
+    }
+
+    private void onUpdateEmptyResponse() {
+        updateStatusAndInvokeCallback(Status.NO_CREDENTIALS);
+    }
+
     /**
      * When an invalid state occurs, e.g. entry mismatch or no response from provider,
      * we send back a TYPE_UNKNOWN error as to the developer.
diff --git a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
new file mode 100644
index 0000000..dd9fcb6
--- /dev/null
+++ b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.Intent;
+import android.credentials.CredentialOption;
+import android.credentials.GetCredentialException;
+import android.credentials.GetCredentialRequest;
+import android.credentials.GetCredentialResponse;
+import android.credentials.ui.Entry;
+import android.credentials.ui.GetCredentialProviderData;
+import android.credentials.ui.ProviderData;
+import android.credentials.ui.ProviderPendingIntentResponse;
+import android.service.credentials.CallingAppInfo;
+import android.service.credentials.CredentialEntry;
+import android.service.credentials.CredentialProviderService;
+import android.telecom.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Central provider session that utilizes {@link CredentialDescriptionRegistry} and therefor is able
+ * to bypass having to use a {@link RemoteCredentialService}.
+ *
+ * @hide
+ */
+public class ProviderRegistryGetSession extends ProviderSession<GetCredentialRequest,
+        Set<CredentialDescriptionRegistry.FilterResult>> {
+
+    private static final String TAG = "ProviderRegistryGetSession";
+    private static final String CREDENTIAL_ENTRY_KEY = "credential_key";
+
+    /** Creates a new provider session to be used by the request session. */
+    @Nullable
+    public static ProviderRegistryGetSession createNewSession(
+            @NonNull Context context,
+            @UserIdInt int userId,
+            @NonNull GetRequestSession getRequestSession,
+            @NonNull String credentialProviderPackageName,
+            @NonNull List<String> requestOptions) {
+        return new ProviderRegistryGetSession(
+                context,
+                userId,
+                getRequestSession,
+                getRequestSession.mClientRequest,
+                getRequestSession.mClientAppInfo,
+                credentialProviderPackageName,
+                requestOptions);
+    }
+
+    @NonNull
+    private final Map<String, CredentialEntry> mUiCredentialEntries = new HashMap<>();
+    @NonNull
+    private final CredentialDescriptionRegistry mCredentialDescriptionRegistry;
+    @NonNull
+    private final CallingAppInfo mCallingAppInfo;
+    @NonNull
+    private final String mCredentialProviderPackageName;
+    @NonNull
+    private final GetRequestSession mGetRequestSession;
+    @NonNull
+    private final List<String> mRequestOptions;
+    private List<CredentialEntry> mCredentialEntries;
+
+    protected ProviderRegistryGetSession(@NonNull Context context,
+            @NonNull int userId,
+            @NonNull GetRequestSession session,
+            @NonNull GetCredentialRequest request,
+            @NonNull CallingAppInfo callingAppInfo,
+            @NonNull String servicePackageName,
+            @NonNull List<String> requestOptions) {
+        super(context, null, request, session, userId, null);
+        mGetRequestSession = session;
+        mCredentialDescriptionRegistry = CredentialDescriptionRegistry.forUser(userId);
+        mCallingAppInfo = callingAppInfo;
+        mCredentialProviderPackageName = servicePackageName;
+        mRequestOptions = requestOptions;
+    }
+
+    private List<Entry> prepareUiCredentialEntries(
+            @NonNull List<CredentialEntry> credentialEntries) {
+        Log.i(TAG, "in prepareUiProviderDataWithCredentials");
+        List<Entry> credentialUiEntries = new ArrayList<>();
+
+        // Populate the credential entries
+        for (CredentialEntry credentialEntry : credentialEntries) {
+            String entryId = generateUniqueId();
+            mUiCredentialEntries.put(entryId, credentialEntry);
+            Log.i(TAG, "in prepareUiProviderData creating ui entry with id " + entryId);
+            credentialUiEntries.add(new Entry(CREDENTIAL_ENTRY_KEY, entryId,
+                    credentialEntry.getSlice(),
+                    setUpFillInIntent(credentialEntry.getType())));
+        }
+        return credentialUiEntries;
+    }
+
+    private Intent setUpFillInIntent(String type) {
+        Intent intent = new Intent();
+        for (CredentialOption option : mProviderRequest.getCredentialOptions()) {
+            if (option.getType().equals(type)) {
+                intent.putExtra(
+                        CredentialProviderService
+                                .EXTRA_GET_CREDENTIAL_REQUEST,
+                        new android.service.credentials.GetCredentialRequest(
+                                mCallingAppInfo, option));
+                return intent;
+            }
+        }
+        return intent;
+    }
+
+    @Override
+    protected ProviderData prepareUiData() {
+        Log.i(TAG, "In prepareUiData");
+        if (!ProviderSession.isUiInvokingStatus(getStatus())) {
+            Log.i(TAG, "In prepareUiData - provider does not want to show UI: "
+                    + mComponentName.flattenToString());
+            return null;
+        }
+        if (mProviderResponse == null) {
+            Log.i(TAG, "In prepareUiData response null");
+            throw new IllegalStateException("Response must be in completion mode");
+        }
+        return new GetCredentialProviderData.Builder(
+                mComponentName.flattenToString()).setActionChips(null)
+                .setCredentialEntries(prepareUiCredentialEntries(
+                        mProviderResponse.stream().flatMap((Function<CredentialDescriptionRegistry
+                                        .FilterResult,
+                                        Stream<CredentialEntry>>) filterResult ->
+                                        filterResult.mCredentialEntries.stream())
+                                .collect(Collectors.toList())))
+                .build();
+    }
+
+    @Override // Selection call from the request provider
+    protected void onUiEntrySelected(String entryType, String entryKey,
+            ProviderPendingIntentResponse providerPendingIntentResponse) {
+        switch (entryType) {
+            case CREDENTIAL_ENTRY_KEY:
+                CredentialEntry credentialEntry = mUiCredentialEntries.get(entryKey);
+                if (credentialEntry == null) {
+                    Log.i(TAG, "Unexpected credential entry key");
+                    return;
+                }
+                onCredentialEntrySelected(credentialEntry, providerPendingIntentResponse);
+                break;
+            default:
+                Log.i(TAG, "Unsupported entry type selected");
+        }
+    }
+
+    private void onCredentialEntrySelected(CredentialEntry credentialEntry,
+            ProviderPendingIntentResponse providerPendingIntentResponse) {
+        if (!mCredentialEntries.contains(credentialEntry)) {
+            invokeCallbackWithError("",
+                    "");
+        }
+
+        if (providerPendingIntentResponse != null) {
+            // Check if pending intent has an error
+            GetCredentialException exception = maybeGetPendingIntentException(
+                    providerPendingIntentResponse);
+            if (exception != null) {
+                invokeCallbackWithError(exception.getType(),
+                        exception.getMessage());
+                return;
+            }
+
+            // Check if pending intent has a credential
+            GetCredentialResponse getCredentialResponse = PendingIntentResultHandler
+                    .extractGetCredentialResponse(
+                            providerPendingIntentResponse.getResultData());
+            if (getCredentialResponse != null) {
+                if (mCallbacks != null) {
+                    mCallbacks.onFinalResponseReceived(mComponentName,
+                            getCredentialResponse);
+                }
+                return;
+            }
+
+            Log.i(TAG, "Pending intent response contains no credential, or error");
+        }
+        Log.i(TAG, "CredentialEntry does not have a credential or a pending intent result");
+    }
+
+    @Override
+    public void onProviderResponseSuccess(
+            @Nullable Set<CredentialDescriptionRegistry.FilterResult> response) {
+        // No need to do anything since this class does not rely on a remote service.
+    }
+
+    @Override
+    public void onProviderResponseFailure(int internalErrorCode, @Nullable Exception e) {
+        // No need to do anything since this class does not rely on a remote service.
+    }
+
+    @Override
+    public void onProviderServiceDied(RemoteCredentialService service) {
+        // No need to do anything since this class does not rely on a remote service.
+    }
+
+    @Override
+    protected void invokeSession() {
+        mProviderResponse = mCredentialDescriptionRegistry
+                .getFilteredResultForProvider(mCredentialProviderPackageName,
+                        mRequestOptions);
+        mCredentialEntries = mProviderResponse.stream().flatMap(
+                        (Function<CredentialDescriptionRegistry.FilterResult,
+                                Stream<CredentialEntry>>) filterResult
+                        -> filterResult.mCredentialEntries.stream())
+                .collect(Collectors.toList());
+        setStatus(Status.CREDENTIALS_RECEIVED);
+    }
+
+    @Nullable
+    protected GetCredentialException maybeGetPendingIntentException(
+            ProviderPendingIntentResponse pendingIntentResponse) {
+        if (pendingIntentResponse == null) {
+            android.util.Log.i(TAG, "pendingIntentResponse is null");
+            return null;
+        }
+        if (PendingIntentResultHandler.isValidResponse(pendingIntentResponse)) {
+            GetCredentialException exception = PendingIntentResultHandler
+                    .extractGetCredentialException(pendingIntentResponse.getResultData());
+            if (exception != null) {
+                android.util.Log.i(TAG, "Pending intent contains provider exception");
+                return exception;
+            }
+        } else if (PendingIntentResultHandler.isCancelledResponse(pendingIntentResponse)) {
+            return new GetCredentialException(GetCredentialException.TYPE_USER_CANCELED);
+        } else {
+            return new GetCredentialException(GetCredentialException.TYPE_NO_CREDENTIAL);
+        }
+        return null;
+    }
+}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java
index 8e0d6f8..1aec934 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java
@@ -23,9 +23,10 @@
 import android.credentials.Credential;
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.ProviderPendingIntentResponse;
-import android.service.credentials.CredentialEntry;
+import android.os.ICancellationSignal;
+import android.os.RemoteException;
 import android.service.credentials.CredentialProviderInfo;
-import android.util.Pair;
+import android.util.Log;
 
 import java.util.UUID;
 
@@ -38,21 +39,20 @@
         implements RemoteCredentialService.ProviderCallbacks<R> {
 
     private static final String TAG = "ProviderSession";
-    // Key to be used as an entry key for a remote entry
-    protected static final String REMOTE_ENTRY_KEY = "remote_entry_key";
 
     @NonNull protected final Context mContext;
     @NonNull protected final ComponentName mComponentName;
-    @NonNull protected final CredentialProviderInfo mProviderInfo;
-    @NonNull protected final RemoteCredentialService mRemoteCredentialService;
+    @Nullable protected final CredentialProviderInfo mProviderInfo;
+    @Nullable protected final RemoteCredentialService mRemoteCredentialService;
     @NonNull protected final int mUserId;
     @NonNull protected Status mStatus = Status.NOT_STARTED;
-    @NonNull protected final ProviderInternalCallback mCallbacks;
+    @Nullable protected final ProviderInternalCallback mCallbacks;
     @Nullable protected Credential mFinalCredentialResponse;
+    @Nullable protected ICancellationSignal mProviderCancellationSignal;
     @NonNull protected final T mProviderRequest;
     @Nullable protected R mProviderResponse;
     @NonNull protected Boolean mProviderResponseSet = false;
-    @Nullable protected Pair<String, CredentialEntry> mUiRemoteEntry;
+
 
 
     /**
@@ -109,9 +109,9 @@
 
     protected ProviderSession(@NonNull Context context, @NonNull CredentialProviderInfo info,
             @NonNull T providerRequest,
-            @NonNull ProviderInternalCallback callbacks,
+            @Nullable ProviderInternalCallback callbacks,
             @NonNull int userId,
-            @NonNull RemoteCredentialService remoteCredentialService) {
+            @Nullable RemoteCredentialService remoteCredentialService) {
         mContext = context;
         mProviderInfo = info;
         mProviderRequest = providerRequest;
@@ -133,7 +133,7 @@
         PENDING_INTENT_INVOKED,
         CREDENTIAL_RECEIVED_FROM_SELECTION,
         SAVE_ENTRIES_RECEIVED, CANCELED,
-        NO_CREDENTIALS, COMPLETE
+        NO_CREDENTIALS, EMPTY_RESPONSE, COMPLETE
     }
 
     /** Converts exception to a provider session status. */
@@ -143,7 +143,7 @@
         return Status.CANCELED;
     }
 
-    protected String generateEntryId() {
+    protected static String generateUniqueId() {
         return UUID.randomUUID().toString();
     }
 
@@ -151,6 +151,18 @@
         return  mFinalCredentialResponse;
     }
 
+    /** Propagates cancellation signal to the remote provider service. */
+    public void cancelProviderRemoteSession() {
+        try {
+            if (mProviderCancellationSignal != null) {
+                mProviderCancellationSignal.cancel();
+            }
+            setStatus(Status.CANCELED);
+        } catch (RemoteException e) {
+            Log.i(TAG, "Issue while cancelling provider session: " + e.getMessage());
+        }
+    }
+
     protected void setStatus(@NonNull Status status) {
         mStatus = status;
     }
@@ -165,7 +177,7 @@
         return mComponentName;
     }
 
-    @NonNull
+    @Nullable
     protected RemoteCredentialService getRemoteCredentialService() {
         return mRemoteCredentialService;
     }
diff --git a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
index 8cad6ac..2dea8bd 100644
--- a/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
+++ b/services/credentials/java/com/android/server/credentials/RemoteCredentialService.java
@@ -110,7 +110,7 @@
      * @param callback the callback to be used to send back the provider response to the
      *                 {@link ProviderGetSession} class that maintains provider state
      */
-    public void onBeginGetCredential(@NonNull BeginGetCredentialRequest request,
+    public ICancellationSignal onBeginGetCredential(@NonNull BeginGetCredentialRequest request,
             ProviderCallbacks<BeginGetCredentialResponse> callback) {
         Log.i(TAG, "In onGetCredentials in RemoteCredentialService");
         AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
@@ -149,6 +149,8 @@
         futureRef.set(connectThenExecute);
         connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
                 handleExecutionResponse(result, error, cancellationSink, callback)));
+
+        return cancellationSink.get();
     }
 
     /** Main entry point to be called for executing a beginCreateCredential call on the remote
@@ -157,7 +159,7 @@
      * @param callback the callback to be used to send back the provider response to the
      *                 {@link ProviderCreateSession} class that maintains provider state
      */
-    public void onCreateCredential(@NonNull BeginCreateCredentialRequest request,
+    public ICancellationSignal onCreateCredential(@NonNull BeginCreateCredentialRequest request,
             ProviderCallbacks<BeginCreateCredentialResponse> callback) {
         Log.i(TAG, "In onCreateCredential in RemoteCredentialService");
         AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
@@ -196,6 +198,8 @@
         futureRef.set(connectThenExecute);
         connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
                 handleExecutionResponse(result, error, cancellationSink, callback)));
+
+        return cancellationSink.get();
     }
 
     /** Main entry point to be called for executing a clearCredentialState call on the remote
@@ -204,7 +208,7 @@
      * @param callback the callback to be used to send back the provider response to the
      *                 {@link ProviderClearSession} class that maintains provider state
      */
-    public void onClearCredentialState(@NonNull ClearCredentialStateRequest request,
+    public ICancellationSignal onClearCredentialState(@NonNull ClearCredentialStateRequest request,
             ProviderCallbacks<Void> callback) {
         Log.i(TAG, "In onClearCredentialState in RemoteCredentialService");
         AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
@@ -243,6 +247,8 @@
         futureRef.set(connectThenExecute);
         connectThenExecute.whenComplete((result, error) -> Handler.getMain().post(() ->
                 handleExecutionResponse(result, error, cancellationSink, callback)));
+
+        return cancellationSink.get();
     }
 
     private <T> void handleExecutionResponse(T result,
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index f92ffe2..fdd0e81 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -29,6 +29,7 @@
 import android.credentials.ui.ProviderData;
 import android.credentials.ui.UserSelectionDialogResult;
 import android.os.Binder;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -83,13 +84,16 @@
     private final int mCallingUid;
     @NonNull
     protected final CallingAppInfo mClientAppInfo;
+    @NonNull
+    protected final CancellationSignal mCancellationSignal;
 
     protected final Map<String, ProviderSession> mProviders = new HashMap<>();
 
     protected RequestSession(@NonNull Context context,
             @UserIdInt int userId, int callingUid, @NonNull T clientRequest, U clientCallback,
             @NonNull String requestType,
-            CallingAppInfo callingAppInfo) {
+            CallingAppInfo callingAppInfo,
+            CancellationSignal cancellationSignal) {
         mContext = context;
         mUserId = userId;
         mCallingUid = callingUid;
@@ -97,6 +101,7 @@
         mClientCallback = clientCallback;
         mRequestType = requestType;
         mClientAppInfo = callingAppInfo;
+        mCancellationSignal = cancellationSignal;
         mHandler = new Handler(Looper.getMainLooper(), null, true);
         mRequestId = new Binder();
         mCredentialManagerUi = new CredentialManagerUi(mContext,
@@ -112,6 +117,10 @@
 
     @Override // from CredentialManagerUiCallbacks
     public void onUiSelection(UserSelectionDialogResult selection) {
+        if (isSessionCancelled()) {
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         String providerId = selection.getProviderId();
         Log.i(TAG, "onUiSelection, providerId: " + providerId);
         ProviderSession providerSession = mProviders.get(providerId);
@@ -127,18 +136,24 @@
     @Override // from CredentialManagerUiCallbacks
     public void onUiCancellation(boolean isUserCancellation) {
         Log.i(TAG, "Ui canceled. Canceled by user: " + isUserCancellation);
+        if (isSessionCancelled()) {
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
         // User canceled the activity
-        finishSession();
+        finishSession(/*propagateCancellation=*/false);
     }
 
-    protected void finishSession() {
+    @Override
+    public void onUiSelectorInvocationFailure() {
+        Log.i(TAG, "onUiSelectorInvocationFailure");
+    }
+
+    protected void finishSession(boolean propagateCancellation) {
         Log.i(TAG, "finishing session");
-        clearProviderSessions();
-    }
-
-    protected void clearProviderSessions() {
-        Log.i(TAG, "Clearing sessions");
-        //TODO: Implement
+        if (propagateCancellation) {
+            mProviders.values().forEach(ProviderSession::cancelProviderRemoteSession);
+        }
         mProviders.clear();
     }
 
@@ -178,6 +193,10 @@
                 isSuccessful ? METRICS_API_STATUS_SUCCESS : METRICS_API_STATUS_FAILURE);
     }
 
+    protected boolean isSessionCancelled() {
+        return mCancellationSignal.isCanceled();
+    }
+
     /**
      * Returns true if at least one provider is ready for UI invocation, and no
      * provider is pending a response.
@@ -197,6 +216,11 @@
         Log.i(TAG, "In getProviderDataAndInitiateUi");
         Log.i(TAG, "In getProviderDataAndInitiateUi providers size: " + mProviders.size());
 
+        if (isSessionCancelled()) {
+            finishSession(/*propagateCancellation=*/true);
+            return;
+        }
+
         ArrayList<ProviderData> providerDataList = new ArrayList<>();
         for (ProviderSession session : mProviders.values()) {
             Log.i(TAG, "preparing data for : " + session.getComponentName());
@@ -208,7 +232,11 @@
         }
         if (!providerDataList.isEmpty()) {
             Log.i(TAG, "provider list not empty about to initiate ui");
-            launchUiWithProviderData(providerDataList);
+            if (isSessionCancelled()) {
+                Log.i(TAG, "In getProviderDataAndInitiateUi but session has been cancelled");
+            } else {
+                launchUiWithProviderData(providerDataList);
+            }
         }
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java
index 9cb7533..474df98 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BooleanPolicySerializer.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.BooleanPolicyValue;
+import android.app.admin.PolicyKey;
 import android.util.Log;
 
 import com.android.modules.utils.TypedXmlPullParser;
@@ -31,7 +33,8 @@
 final class BooleanPolicySerializer extends PolicySerializer<Boolean> {
 
     @Override
-    void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Boolean value)
+    void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer, String attributeName,
+            @NonNull Boolean value)
             throws IOException {
         Objects.requireNonNull(value);
         serializer.attributeBoolean(/* namespace= */ null, attributeName, value);
@@ -39,9 +42,10 @@
 
     @Nullable
     @Override
-    Boolean readFromXml(TypedXmlPullParser parser, String attributeName) {
+    BooleanPolicyValue readFromXml(TypedXmlPullParser parser, String attributeName) {
         try {
-            return parser.getAttributeBoolean(/* namespace= */ null, attributeName);
+            return new BooleanPolicyValue(
+                    parser.getAttributeBoolean(/* namespace= */ null, attributeName));
         } catch (XmlPullParserException e) {
             Log.e(DevicePolicyEngine.TAG, "Error parsing Boolean policy value", e);
             return null;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
new file mode 100644
index 0000000..c79aac7
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.BundlePolicyValue;
+import android.app.admin.PackagePolicyKey;
+import android.app.admin.PolicyKey;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Parcelable;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.XmlUtils;
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Objects;
+
+// TODO(b/266704763): clean this up and stop creating separate files for each value, the code here
+//  is copied from UserManagerService, however it doesn't currently handle setting different
+//  restrictions for the same package in different users, it also will not remove the files for
+//  outdated restrictions, this will all get fixed when we save it as part of the policies file
+//  rather than in its own files.
+final class BundlePolicySerializer extends PolicySerializer<Bundle> {
+
+    private static final String RESTRICTIONS_FILE_PREFIX = "AppRestrictions_";
+    private static final String XML_SUFFIX = ".xml";
+
+    private static final String TAG_RESTRICTIONS = "restrictions";
+    private static final String TAG_ENTRY = "entry";
+    private static final String TAG_VALUE = "value";
+    private static final String ATTR_KEY = "key";
+    private static final String ATTR_VALUE_TYPE = "type";
+    private static final String ATTR_MULTIPLE = "m";
+
+    private static final String ATTR_TYPE_STRING_ARRAY = "sa";
+    private static final String ATTR_TYPE_STRING = "s";
+    private static final String ATTR_TYPE_BOOLEAN = "b";
+    private static final String ATTR_TYPE_INTEGER = "i";
+    private static final String ATTR_TYPE_BUNDLE = "B";
+    private static final String ATTR_TYPE_BUNDLE_ARRAY = "BA";
+
+    @Override
+    void saveToXml(@NonNull PolicyKey policyKey, TypedXmlSerializer serializer,
+            String attributeName, @NonNull Bundle value) throws IOException {
+        Objects.requireNonNull(value);
+        Objects.requireNonNull(policyKey);
+        if (!(policyKey instanceof PackagePolicyKey)) {
+            throw new IllegalArgumentException("policyKey is not of type "
+                    + "PackagePolicyKey");
+        }
+        String packageName = ((PackagePolicyKey) policyKey).getPackageName();
+        String fileName = packageToRestrictionsFileName(packageName, value);
+        writeApplicationRestrictionsLAr(fileName, value);
+        serializer.attribute(/* namespace= */ null, attributeName, fileName);
+    }
+
+    @Nullable
+    @Override
+    BundlePolicyValue readFromXml(TypedXmlPullParser parser, String attributeName) {
+        String fileName = parser.getAttributeValue(/* namespace= */ null, attributeName);
+
+        return new BundlePolicyValue(readApplicationRestrictions(fileName));
+    }
+
+    private static String packageToRestrictionsFileName(String packageName, Bundle restrictions) {
+        return RESTRICTIONS_FILE_PREFIX + packageName + Objects.hash(restrictions) + XML_SUFFIX;
+    }
+
+    @GuardedBy("mAppRestrictionsLock")
+    private static Bundle readApplicationRestrictions(String fileName) {
+        AtomicFile restrictionsFile =
+                new AtomicFile(new File(Environment.getDataSystemDirectory(), fileName));
+        return readApplicationRestrictions(restrictionsFile);
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mAppRestrictionsLock")
+    static Bundle readApplicationRestrictions(AtomicFile restrictionsFile) {
+        final Bundle restrictions = new Bundle();
+        final ArrayList<String> values = new ArrayList<>();
+        if (!restrictionsFile.getBaseFile().exists()) {
+            return restrictions;
+        }
+
+        FileInputStream fis = null;
+        try {
+            fis = restrictionsFile.openRead();
+            final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
+            XmlUtils.nextElement(parser);
+            if (parser.getEventType() != XmlPullParser.START_TAG) {
+                Slog.e(DevicePolicyEngine.TAG, "Unable to read restrictions file "
+                        + restrictionsFile.getBaseFile());
+                return restrictions;
+            }
+            while (parser.next() != XmlPullParser.END_DOCUMENT) {
+                readEntry(restrictions, values, parser);
+            }
+        } catch (IOException | XmlPullParserException e) {
+            Slog.w(DevicePolicyEngine.TAG, "Error parsing " + restrictionsFile.getBaseFile(), e);
+        } finally {
+            IoUtils.closeQuietly(fis);
+        }
+        return restrictions;
+    }
+
+    private static void readEntry(Bundle restrictions, ArrayList<String> values,
+            TypedXmlPullParser parser) throws XmlPullParserException, IOException {
+        int type = parser.getEventType();
+        if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_ENTRY)) {
+            String key = parser.getAttributeValue(null, ATTR_KEY);
+            String valType = parser.getAttributeValue(null, ATTR_VALUE_TYPE);
+            int count = parser.getAttributeInt(null, ATTR_MULTIPLE, -1);
+            if (count != -1) {
+                values.clear();
+                while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+                    if (type == XmlPullParser.START_TAG
+                            && parser.getName().equals(TAG_VALUE)) {
+                        values.add(parser.nextText().trim());
+                        count--;
+                    }
+                }
+                String [] valueStrings = new String[values.size()];
+                values.toArray(valueStrings);
+                restrictions.putStringArray(key, valueStrings);
+            } else if (ATTR_TYPE_BUNDLE.equals(valType)) {
+                restrictions.putBundle(key, readBundleEntry(parser, values));
+            } else if (ATTR_TYPE_BUNDLE_ARRAY.equals(valType)) {
+                final int outerDepth = parser.getDepth();
+                ArrayList<Bundle> bundleList = new ArrayList<>();
+                while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+                    Bundle childBundle = readBundleEntry(parser, values);
+                    bundleList.add(childBundle);
+                }
+                restrictions.putParcelableArray(key,
+                        bundleList.toArray(new Bundle[bundleList.size()]));
+            } else {
+                String value = parser.nextText().trim();
+                if (ATTR_TYPE_BOOLEAN.equals(valType)) {
+                    restrictions.putBoolean(key, Boolean.parseBoolean(value));
+                } else if (ATTR_TYPE_INTEGER.equals(valType)) {
+                    restrictions.putInt(key, Integer.parseInt(value));
+                } else {
+                    restrictions.putString(key, value);
+                }
+            }
+        }
+    }
+
+    private static Bundle readBundleEntry(TypedXmlPullParser parser, ArrayList<String> values)
+            throws IOException, XmlPullParserException {
+        Bundle childBundle = new Bundle();
+        int outerDepth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            readEntry(childBundle, values, parser);
+        }
+        return childBundle;
+    }
+
+    private static void writeApplicationRestrictionsLAr(String fileName, Bundle restrictions) {
+        AtomicFile restrictionsFile = new AtomicFile(
+                new File(Environment.getDataSystemDirectory(), fileName));
+        writeApplicationRestrictionsLAr(restrictions, restrictionsFile);
+    }
+
+    static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) {
+        FileOutputStream fos = null;
+        try {
+            fos = restrictionsFile.startWrite();
+            final TypedXmlSerializer serializer = Xml.resolveSerializer(fos);
+            serializer.startDocument(null, true);
+            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+            serializer.startTag(null, TAG_RESTRICTIONS);
+            writeBundle(restrictions, serializer);
+            serializer.endTag(null, TAG_RESTRICTIONS);
+
+            serializer.endDocument();
+            restrictionsFile.finishWrite(fos);
+        } catch (Exception e) {
+            restrictionsFile.failWrite(fos);
+            Slog.e(DevicePolicyEngine.TAG, "Error writing application restrictions list", e);
+        }
+    }
+
+    private static void writeBundle(Bundle restrictions, TypedXmlSerializer serializer)
+            throws IOException {
+        for (String key : restrictions.keySet()) {
+            Object value = restrictions.get(key);
+            serializer.startTag(null, TAG_ENTRY);
+            serializer.attribute(null, ATTR_KEY, key);
+
+            if (value instanceof Boolean) {
+                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BOOLEAN);
+                serializer.text(value.toString());
+            } else if (value instanceof Integer) {
+                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_INTEGER);
+                serializer.text(value.toString());
+            } else if (value == null || value instanceof String) {
+                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING);
+                serializer.text(value != null ? (String) value : "");
+            } else if (value instanceof Bundle) {
+                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
+                writeBundle((Bundle) value, serializer);
+            } else if (value instanceof Parcelable[]) {
+                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE_ARRAY);
+                Parcelable[] array = (Parcelable[]) value;
+                for (Parcelable parcelable : array) {
+                    if (!(parcelable instanceof Bundle)) {
+                        throw new IllegalArgumentException("bundle-array can only hold Bundles");
+                    }
+                    serializer.startTag(null, TAG_ENTRY);
+                    serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_BUNDLE);
+                    writeBundle((Bundle) parcelable, serializer);
+                    serializer.endTag(null, TAG_ENTRY);
+                }
+            } else {
+                serializer.attribute(null, ATTR_VALUE_TYPE, ATTR_TYPE_STRING_ARRAY);
+                String[] values = (String[]) value;
+                serializer.attributeInt(null, ATTR_MULTIPLE, values.length);
+                for (String choice : values) {
+                    serializer.startTag(null, TAG_VALUE);
+                    serializer.text(choice != null ? choice : "");
+                    serializer.endTag(null, TAG_VALUE);
+                }
+            }
+            serializer.endTag(null, TAG_ENTRY);
+        }
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ComponentNamePolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/ComponentNamePolicySerializer.java
index d400000..d1c6bcb 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ComponentNamePolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ComponentNamePolicySerializer.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.ComponentNamePolicyValue;
+import android.app.admin.PolicyKey;
 import android.content.ComponentName;
 import android.util.Log;
 
@@ -32,9 +34,8 @@
     private static final String ATTR_CLASS_NAME = ":class-name";
 
     @Override
-    void saveToXml(
-            TypedXmlSerializer serializer, String attributeNamePrefix, @NonNull ComponentName value)
-            throws IOException {
+    void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer, String attributeNamePrefix,
+            @NonNull ComponentName value) throws IOException {
         Objects.requireNonNull(value);
         serializer.attribute(
                 /* namespace= */ null,
@@ -46,7 +47,7 @@
 
     @Nullable
     @Override
-    ComponentName readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
+    ComponentNamePolicyValue readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
         String packageName = parser.getAttributeValue(
                 /* namespace= */ null, attributeNamePrefix + ATTR_PACKAGE_NAME);
         String className = parser.getAttributeValue(
@@ -55,6 +56,6 @@
             Log.e(DevicePolicyEngine.TAG, "Error parsing ComponentName policy.");
             return null;
         }
-        return new ComponentName(packageName, className);
+        return new ComponentNamePolicyValue(new ComponentName(packageName, className));
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DefaultPolicyKey.java b/services/devicepolicy/java/com/android/server/devicepolicy/DefaultPolicyKey.java
deleted file mode 100644
index ab0fc99..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DefaultPolicyKey.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.devicepolicy;
-
-import com.android.modules.utils.TypedXmlPullParser;
-
-/**
- * Default implementation for {@link PolicyKey} used to identify a policy that doesn't require any
- * additional arguments to be represented in the policy engine's data structure.
- */
-final class DefaultPolicyKey extends PolicyKey {
-    private static final String ATTR_GENERIC_POLICY_KEY = "generic-policy-key";
-
-    DefaultPolicyKey(String policyKey) {
-        super(policyKey);
-    }
-
-    String getKey() {
-        return mKey;
-    }
-
-    static DefaultPolicyKey readGenericPolicyKeyFromXml(TypedXmlPullParser parser) {
-        String genericPolicyKey = parser.getAttributeValue(
-                /* namespace= */ null, ATTR_GENERIC_POLICY_KEY);
-        return new DefaultPolicyKey(genericPolicyKey);
-    }
-
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index cb3b021..71764dc 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -17,26 +17,34 @@
 package com.android.server.devicepolicy;
 
 import static android.app.admin.PolicyUpdateResult.RESULT_FAILURE_CONFLICTING_ADMIN_POLICY;
+import static android.app.admin.PolicyUpdateResult.RESULT_POLICY_CLEARED;
 import static android.app.admin.PolicyUpdateResult.RESULT_SUCCESS;
 import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_TARGET_USER_ID;
 import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_UPDATE_RESULT_KEY;
+import static android.content.pm.UserProperties.INHERIT_DEVICE_POLICY_FROM_PARENT;
+import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
 
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyState;
+import android.app.admin.PolicyKey;
 import android.app.admin.PolicyUpdatesReceiver;
+import android.app.admin.PolicyValue;
 import android.app.admin.TargetUser;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.content.pm.UserProperties;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.DeviceConfig;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.SparseArray;
@@ -57,6 +65,7 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -69,6 +78,9 @@
 final class DevicePolicyEngine {
     static final String TAG = "DevicePolicyEngine";
 
+    private static final String ENABLE_COEXISTENCE_FLAG = "enable_coexistence";
+    private static final boolean DEFAULT_ENABLE_COEXISTENCE_FLAG = true;
+
     private final Context mContext;
     private final UserManager mUserManager;
 
@@ -103,17 +115,20 @@
         mEnforcingAdmins = new SparseArray<>();
     }
 
-    // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
     /**
-     * Set the policy for the provided {@code policyDefinition}
-     * (see {@link PolicyDefinition}) and {@code enforcingAdmin} to the provided {@code value}.
+     * Set the policy for the provided {@code policyDefinition} (see {@link PolicyDefinition}) and
+     * {@code enforcingAdmin} to the provided {@code value}.
+     *
+     * <p>If {@code skipEnforcePolicy} is true, it sets the policies in the internal data structure
+     * but doesn't call the enforcing logic.
+     *
      */
     <V> void setLocalPolicy(
             @NonNull PolicyDefinition<V> policyDefinition,
             @NonNull EnforcingAdmin enforcingAdmin,
-            @NonNull V value,
-            int userId) {
-
+            @NonNull PolicyValue<V> value,
+            int userId,
+            boolean skipEnforcePolicy) {
         Objects.requireNonNull(policyDefinition);
         Objects.requireNonNull(enforcingAdmin);
         Objects.requireNonNull(value);
@@ -121,6 +136,12 @@
         synchronized (mLock) {
             PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);
 
+            if (policyDefinition.isNonCoexistablePolicy()) {
+                setNonCoexistableLocalPolicy(policyDefinition, localPolicyState, enforcingAdmin,
+                        value, userId, skipEnforcePolicy);
+                return;
+            }
+
             boolean hasGlobalPolicies = hasGlobalPolicyLocked(policyDefinition);
             boolean policyChanged;
             if (hasGlobalPolicies) {
@@ -133,25 +154,73 @@
                 policyChanged = localPolicyState.addPolicy(enforcingAdmin, value);
             }
 
-            if (policyChanged) {
-                onLocalPolicyChanged(policyDefinition, enforcingAdmin, userId);
+            // No need to notify admins as no new policy is actually enforced, we're just filling in
+            // the data structures.
+            if (!skipEnforcePolicy) {
+                if (policyChanged) {
+                    onLocalPolicyChanged(policyDefinition, enforcingAdmin, userId);
+                }
+                boolean policyEnforced = Objects.equals(
+                        localPolicyState.getCurrentResolvedPolicy(), value);
+                sendPolicyResultToAdmin(
+                        enforcingAdmin,
+                        policyDefinition,
+                        // TODO: we're always sending this for now, should properly handle errors.
+                        policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
+                        userId);
             }
 
-            boolean policyEnforced = Objects.equals(
-                    localPolicyState.getCurrentResolvedPolicy(), value);
-            sendPolicyResultToAdmin(
-                    enforcingAdmin,
-                    policyDefinition,
-                    // TODO: we're always sending this for now, should properly handle errors.
-                    policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
-                    userId);
-
             updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin);
 
             write();
+
+            applyToInheritableProfiles(policyDefinition, enforcingAdmin, value, userId);
         }
     }
 
+    /**
+     * Sets a non-coexistable policy, meaning it doesn't get resolved against other policies set
+     * by other admins, and no callbacks are sent to admins, this is just storing and
+     * enforcing the policy.
+     *
+     * <p>Passing a {@code null} value means the policy set by this admin should be removed.
+     */
+    private <V> void setNonCoexistableLocalPolicy(
+            PolicyDefinition<V> policyDefinition,
+            PolicyState<V> localPolicyState,
+            EnforcingAdmin enforcingAdmin,
+            @Nullable PolicyValue<V> value,
+            int userId,
+            boolean skipEnforcePolicy) {
+        if (value == null) {
+            localPolicyState.removePolicy(enforcingAdmin);
+        } else {
+            localPolicyState.addPolicy(enforcingAdmin, value);
+        }
+        if (!skipEnforcePolicy) {
+            enforcePolicy(policyDefinition, value, userId);
+        }
+        if (localPolicyState.getPoliciesSetByAdmins().isEmpty()) {
+            removeLocalPolicyStateLocked(policyDefinition, userId);
+        }
+        updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin);
+        write();
+    }
+
+    // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
+    /**
+     * Set the policy for the provided {@code policyDefinition}
+     * (see {@link PolicyDefinition}) and {@code enforcingAdmin} to the provided {@code value}.
+     */
+    <V> void setLocalPolicy(
+            @NonNull PolicyDefinition<V> policyDefinition,
+            @NonNull EnforcingAdmin enforcingAdmin,
+            @NonNull PolicyValue<V> value,
+            int userId) {
+        setLocalPolicy(
+                policyDefinition, enforcingAdmin, value, userId, /* skipEnforcePolicy= */ false);
+    }
+
     // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
     /**
      * Removes any previously set policy for the provided {@code policyDefinition}
@@ -170,6 +239,12 @@
             }
             PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);
 
+            if (policyDefinition.isNonCoexistablePolicy()) {
+                setNonCoexistableLocalPolicy(policyDefinition, localPolicyState, enforcingAdmin,
+                        /* value= */ null, userId, /* skipEnforcePolicy= */ false);
+                return;
+            }
+
             boolean policyChanged;
             if (hasGlobalPolicyLocked(policyDefinition)) {
                 PolicyState<V> globalPolicyState = getGlobalPolicyStateLocked(policyDefinition);
@@ -185,12 +260,11 @@
             }
 
             // For a removePolicy to be enforced, it means no current policy exists
-            boolean policyEnforced = localPolicyState.getCurrentResolvedPolicy() == null;
             sendPolicyResultToAdmin(
                     enforcingAdmin,
                     policyDefinition,
                     // TODO: we're always sending this for now, should properly handle errors.
-                    policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
+                    RESULT_POLICY_CLEARED,
                     userId);
 
             if (localPolicyState.getPoliciesSetByAdmins().isEmpty()) {
@@ -200,10 +274,52 @@
             updateDeviceAdminServiceOnPolicyRemoveLocked(enforcingAdmin);
 
             write();
+
+            applyToInheritableProfiles(policyDefinition, enforcingAdmin, /*value */ null, userId);
         }
     }
 
     /**
+     * If any of child user has property {@link UserProperties#INHERIT_DEVICE_POLICY_FROM_PARENT}
+     * set then propagate the policy to it if value is not null
+     * else remove the policy from child.
+     */
+    private <V> void applyToInheritableProfiles(PolicyDefinition<V> policyDefinition,
+            EnforcingAdmin enforcingAdmin, PolicyValue<V> value, int userId) {
+        if (policyDefinition.isInheritable()) {
+            Binder.withCleanCallingIdentity(() -> {
+                List<UserInfo> userInfos = mUserManager.getProfiles(userId);
+                for (UserInfo childUserInfo : userInfos) {
+                    int childUserId = childUserInfo.getUserHandle().getIdentifier();
+                    if (isProfileOfUser(childUserId, userId)
+                            && isInheritDevicePolicyFromParent(childUserInfo)) {
+                        if (value != null) {
+                            setLocalPolicy(policyDefinition, enforcingAdmin, value, childUserId);
+                        } else {
+                            removeLocalPolicy(policyDefinition, enforcingAdmin, childUserId);
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Checks if given parentUserId is direct parent of childUserId.
+     */
+    private boolean isProfileOfUser(int childUserId, int parentUserId) {
+        UserInfo parentInfo = mUserManager.getProfileParent(childUserId);
+        return childUserId != parentUserId && parentInfo != null
+                && parentInfo.getUserHandle().getIdentifier() == parentUserId;
+    }
+
+    private boolean isInheritDevicePolicyFromParent(UserInfo userInfo) {
+        UserProperties userProperties = mUserManager.getUserProperties(userInfo.getUserHandle());
+        return userProperties != null && mUserManager.getUserProperties(userInfo.getUserHandle())
+                .getInheritDevicePolicy() == INHERIT_DEVICE_POLICY_FROM_PARENT;
+    }
+
+    /**
      * Enforces the new policy and notifies relevant admins.
      */
     private <V> void onLocalPolicyChanged(
@@ -234,6 +350,18 @@
                     userId);
         }
     }
+
+    /**
+     * Set the policy for the provided {@code policyDefinition}
+     * (see {@link PolicyDefinition}) and {@code enforcingAdmin} to the provided {@code value}.
+     */
+    <V> void setGlobalPolicy(
+            @NonNull PolicyDefinition<V> policyDefinition,
+            @NonNull EnforcingAdmin enforcingAdmin,
+            @NonNull PolicyValue<V> value) {
+        setGlobalPolicy(policyDefinition, enforcingAdmin, value, /* skipEnforcePolicy= */ false);
+    }
+
     // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values
     /**
      * Set the policy for the provided {@code policyDefinition}
@@ -242,7 +370,8 @@
     <V> void setGlobalPolicy(
             @NonNull PolicyDefinition<V> policyDefinition,
             @NonNull EnforcingAdmin enforcingAdmin,
-            @NonNull V value) {
+            @NonNull PolicyValue<V> value,
+            boolean skipEnforcePolicy) {
 
         Objects.requireNonNull(policyDefinition);
         Objects.requireNonNull(enforcingAdmin);
@@ -252,23 +381,28 @@
             PolicyState<V> globalPolicyState = getGlobalPolicyStateLocked(policyDefinition);
 
             boolean policyChanged = globalPolicyState.addPolicy(enforcingAdmin, value);
-            if (policyChanged) {
-                onGlobalPolicyChanged(policyDefinition, enforcingAdmin);
+            boolean policyAppliedOnAllUsers = applyGlobalPolicyOnUsersWithLocalPoliciesLocked(
+                    policyDefinition, enforcingAdmin, value, skipEnforcePolicy);
+
+            // No need to notify admins as no new policy is actually enforced, we're just filling in
+            // the data structures.
+            if (!skipEnforcePolicy) {
+                if (policyChanged) {
+                    onGlobalPolicyChanged(policyDefinition, enforcingAdmin);
+                }
+
+                boolean policyAppliedGlobally = Objects.equals(
+                        globalPolicyState.getCurrentResolvedPolicy(), value);
+                boolean policyApplied = policyAppliedGlobally && policyAppliedOnAllUsers;
+
+                sendPolicyResultToAdmin(
+                        enforcingAdmin,
+                        policyDefinition,
+                        // TODO: we're always sending this for now, should properly handle errors.
+                        policyApplied ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
+                        UserHandle.USER_ALL);
             }
 
-            boolean policyEnforcedOnAllUsers = enforceGlobalPolicyOnUsersWithLocalPoliciesLocked(
-                    policyDefinition, enforcingAdmin, value);
-            boolean policyEnforcedGlobally = Objects.equals(
-                    globalPolicyState.getCurrentResolvedPolicy(), value);
-            boolean policyEnforced = policyEnforcedGlobally && policyEnforcedOnAllUsers;
-
-            sendPolicyResultToAdmin(
-                    enforcingAdmin,
-                    policyDefinition,
-                    // TODO: we're always sending this for now, should properly handle errors.
-                    policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
-                    UserHandle.USER_ALL);
-
             updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin);
 
             write();
@@ -295,17 +429,14 @@
                 onGlobalPolicyChanged(policyDefinition, enforcingAdmin);
             }
 
-            boolean policyEnforcedOnAllUsers = enforceGlobalPolicyOnUsersWithLocalPoliciesLocked(
-                    policyDefinition, enforcingAdmin, /* value= */ null);
-            // For a removePolicy to be enforced, it means no current policy exists
-            boolean policyEnforcedGlobally = policyState.getCurrentResolvedPolicy() == null;
-            boolean policyEnforced = policyEnforcedGlobally && policyEnforcedOnAllUsers;
+            applyGlobalPolicyOnUsersWithLocalPoliciesLocked(
+                    policyDefinition, enforcingAdmin, /* value= */ null, /* enforcePolicy= */ true);
 
             sendPolicyResultToAdmin(
                     enforcingAdmin,
                     policyDefinition,
                     // TODO: we're always sending this for now, should properly handle errors.
-                    policyEnforced ? RESULT_SUCCESS : RESULT_FAILURE_CONFLICTING_ADMIN_POLICY,
+                    RESULT_POLICY_CLEARED,
                     UserHandle.USER_ALL);
 
             if (policyState.getPoliciesSetByAdmins().isEmpty()) {
@@ -346,15 +477,16 @@
      *
      * <p>Returns {@code true} if the policy is enforced successfully on all users.
      */
-    private <V> boolean enforceGlobalPolicyOnUsersWithLocalPoliciesLocked(
+    private <V> boolean applyGlobalPolicyOnUsersWithLocalPoliciesLocked(
             @NonNull PolicyDefinition<V> policyDefinition,
             @NonNull EnforcingAdmin enforcingAdmin,
-            @Nullable V value) {
+            @Nullable PolicyValue<V> value,
+            boolean skipEnforcePolicy) {
         // Global only policies can't be applied locally, return early.
         if (policyDefinition.isGlobalOnlyPolicy()) {
             return true;
         }
-        boolean isAdminPolicyEnforced = true;
+        boolean isAdminPolicyApplied = true;
         for (int i = 0; i < mLocalPolicies.size(); i++) {
             int userId = mLocalPolicies.keyAt(i);
             if (!hasLocalPolicyLocked(policyDefinition, userId)) {
@@ -366,9 +498,11 @@
 
             boolean policyChanged = localPolicyState.resolvePolicy(
                     globalPolicyState.getPoliciesSetByAdmins());
-            if (policyChanged) {
+            if (policyChanged && !skipEnforcePolicy) {
                 enforcePolicy(
-                        policyDefinition, localPolicyState.getCurrentResolvedPolicy(), userId);
+                        policyDefinition,
+                        localPolicyState.getCurrentResolvedPolicy(),
+                        userId);
                 sendPolicyChangedToAdmins(
                         localPolicyState,
                         enforcingAdmin,
@@ -378,10 +512,10 @@
                         userId);
 
             }
-            isAdminPolicyEnforced &= Objects.equals(
+            isAdminPolicyApplied &= Objects.equals(
                     value, localPolicyState.getCurrentResolvedPolicy());
         }
-        return isAdminPolicyEnforced;
+        return isAdminPolicyApplied;
     }
 
     /**
@@ -392,14 +526,16 @@
         Objects.requireNonNull(policyDefinition);
 
         synchronized (mLock) {
+            PolicyValue<V> resolvedValue = null;
             if (hasLocalPolicyLocked(policyDefinition, userId)) {
-                return getLocalPolicyStateLocked(
+                resolvedValue = getLocalPolicyStateLocked(
                         policyDefinition, userId).getCurrentResolvedPolicy();
             }
             if (hasGlobalPolicyLocked(policyDefinition)) {
-                return getGlobalPolicyStateLocked(policyDefinition).getCurrentResolvedPolicy();
+                resolvedValue = getGlobalPolicyStateLocked(
+                        policyDefinition).getCurrentResolvedPolicy();
             }
-            return null;
+            return resolvedValue == null ? null : resolvedValue.getValue();
         }
     }
 
@@ -420,13 +556,30 @@
                 return null;
             }
             return getLocalPolicyStateLocked(policyDefinition, userId)
-                    .getPoliciesSetByAdmins().get(enforcingAdmin);
+                    .getPoliciesSetByAdmins().get(enforcingAdmin).getValue();
         }
     }
 
     /**
-     * Returns the policies set by the given admin that share the same {@link PolicyKey#getKey()} as
-     * the provided {@code policyDefinition}.
+     * Retrieves the values set for the provided {@code policyDefinition} by each admin.
+     */
+    @NonNull
+    <V> LinkedHashMap<EnforcingAdmin, PolicyValue<V>> getLocalPoliciesSetByAdmins(
+            @NonNull PolicyDefinition<V> policyDefinition,
+            int userId) {
+        Objects.requireNonNull(policyDefinition);
+
+        synchronized (mLock) {
+            if (!hasLocalPolicyLocked(policyDefinition, userId)) {
+                return new LinkedHashMap<>();
+            }
+            return getLocalPolicyStateLocked(policyDefinition, userId).getPoliciesSetByAdmins();
+        }
+    }
+
+    /**
+     * Returns the policies set by the given admin that share the same
+     * {@link PolicyKey#getIdentifier()} as the provided {@code policyDefinition}.
      *
      * <p>For example, getLocalPolicyKeysSetByAdmin(PERMISSION_GRANT, admin) returns all permission
      * grants set by the given admin.
@@ -450,7 +603,7 @@
             }
             Set<PolicyKey> keys = new HashSet<>();
             for (PolicyKey key : mLocalPolicies.get(userId).keySet()) {
-                if (key.hasSameKeyAs(policyDefinition.getPolicyKey())
+                if (key.hasSameIdentifierAs(policyDefinition.getPolicyKey())
                         && mLocalPolicies.get(userId).get(key).getPoliciesSetByAdmins()
                         .containsKey(enforcingAdmin)) {
                     keys.add(key);
@@ -545,11 +698,12 @@
         }
     }
 
-    private <V> void enforcePolicy(
-            PolicyDefinition<V> policyDefinition, @Nullable V policyValue, int userId) {
+    private <V> void enforcePolicy(PolicyDefinition<V> policyDefinition,
+            @Nullable PolicyValue<V> policyValue, int userId) {
         // null policyValue means remove any enforced policies, ensure callbacks handle this
         // properly
-        policyDefinition.enforcePolicy(policyValue, mContext, userId);
+        policyDefinition.enforcePolicy(
+                policyValue == null ? null : policyValue.getValue(), mContext, userId);
     }
 
     private <V> void sendPolicyResultToAdmin(
@@ -688,6 +842,47 @@
         }
     }
 
+    void handleUserCreated(UserInfo user) {
+        enforcePoliciesOnInheritableProfilesIfApplicable(user);
+    }
+
+    private void enforcePoliciesOnInheritableProfilesIfApplicable(UserInfo user) {
+        if (!user.isProfile()) {
+            return;
+        }
+
+        Binder.withCleanCallingIdentity(() -> {
+            UserProperties userProperties = mUserManager.getUserProperties(user.getUserHandle());
+            if (userProperties == null || userProperties.getInheritDevicePolicy()
+                    != INHERIT_DEVICE_POLICY_FROM_PARENT) {
+                return;
+            }
+
+            int userId = user.id;
+            // Apply local policies present on parent to newly created child profile.
+            UserInfo parentInfo = mUserManager.getProfileParent(userId);
+            if (parentInfo == null || parentInfo.getUserHandle().getIdentifier() == userId) return;
+
+            for (Map.Entry<PolicyKey, PolicyState<?>> entry : mLocalPolicies.get(
+                    parentInfo.getUserHandle().getIdentifier()).entrySet()) {
+                enforcePolicyOnUser(userId, entry.getValue());
+            }
+        });
+    }
+
+    private <V> void enforcePolicyOnUser(int userId, PolicyState<V> policyState) {
+        if (!policyState.getPolicyDefinition().isInheritable()) {
+            return;
+        }
+        for (Map.Entry<EnforcingAdmin, PolicyValue<V>> enforcingAdminEntry :
+                policyState.getPoliciesSetByAdmins().entrySet()) {
+            setLocalPolicy(policyState.getPolicyDefinition(),
+                    enforcingAdminEntry.getKey(),
+                    enforcingAdminEntry.getValue(),
+                    userId);
+        }
+    }
+
     /**
      * Handles internal state related to a user getting started.
      */
@@ -723,6 +918,34 @@
     }
 
     /**
+     * Returns all current enforced policies set on the device, and the individual values set by
+     * each admin. Global policies are returned under {@link UserHandle#ALL}.
+     */
+    @NonNull
+    DevicePolicyState getDevicePolicyState() {
+        Map<UserHandle, Map<PolicyKey, android.app.admin.PolicyState<?>>> policies =
+                new HashMap<>();
+        for (int i = 0; i < mLocalPolicies.size(); i++) {
+            UserHandle user = UserHandle.of(mLocalPolicies.keyAt(i));
+            policies.put(user, new HashMap<>());
+            for (PolicyKey policyKey : mLocalPolicies.valueAt(i).keySet()) {
+                policies.get(user).put(
+                        policyKey,
+                        mLocalPolicies.valueAt(i).get(policyKey).getParcelablePolicyState());
+            }
+        }
+        if (!mGlobalPolicies.isEmpty()) {
+            policies.put(UserHandle.ALL, new HashMap<>());
+            for (PolicyKey policyKey : mGlobalPolicies.keySet()) {
+                policies.get(UserHandle.ALL).put(
+                        policyKey,
+                        mGlobalPolicies.get(policyKey).getParcelablePolicyState());
+            }
+        }
+        return new DevicePolicyState(policies);
+    }
+
+    /**
      * Reestablishes the service that handles
      * {@link DevicePolicyManager#ACTION_DEVICE_ADMIN_SERVICE} in the enforcing admin if the package
      * was updated, as a package update results in the persistent connection getting reset.
@@ -748,11 +971,6 @@
     private void updateDeviceAdminServiceOnPolicyAddLocked(@NonNull EnforcingAdmin enforcingAdmin) {
         int userId = enforcingAdmin.getUserId();
 
-        // A connection is established with DPCs as soon as they are provisioned, so no need to
-        // connect when a policy is set.
-        if (enforcingAdmin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
-            return;
-        }
         if (mEnforcingAdmins.contains(userId)
                 && mEnforcingAdmins.get(userId).contains(enforcingAdmin)) {
             return;
@@ -763,6 +981,11 @@
         }
         mEnforcingAdmins.get(enforcingAdmin.getUserId()).add(enforcingAdmin);
 
+        // A connection is established with DPCs as soon as they are provisioned, so no need to
+        // connect when a policy is set.
+        if (enforcingAdmin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
+            return;
+        }
         mDeviceAdminServiceController.startServiceForAdmin(
                 enforcingAdmin.getPackageName(),
                 userId,
@@ -775,18 +998,10 @@
      */
     private void updateDeviceAdminServiceOnPolicyRemoveLocked(
             @NonNull EnforcingAdmin enforcingAdmin) {
-        // TODO(b/263364434): centralise handling in one place.
-        // DPCs rely on a constant connection being established as soon as they are provisioned,
-        // so we shouldn't disconnect it even if they no longer have policies set.
-        if (enforcingAdmin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
-            return;
-        }
         if (doesAdminHavePolicies(enforcingAdmin)) {
             return;
         }
-
         int userId = enforcingAdmin.getUserId();
-
         if (mEnforcingAdmins.contains(userId)) {
             mEnforcingAdmins.get(userId).remove(enforcingAdmin);
             if (mEnforcingAdmins.get(userId).isEmpty()) {
@@ -794,6 +1009,12 @@
             }
         }
 
+        // TODO(b/263364434): centralise handling in one place.
+        // DPCs rely on a constant connection being established as soon as they are provisioned,
+        // so we shouldn't disconnect it even if they no longer have policies set.
+        if (enforcingAdmin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
+            return;
+        }
         mDeviceAdminServiceController.stopServiceForAdmin(
                 enforcingAdmin.getPackageName(),
                 userId,
@@ -840,21 +1061,70 @@
         }
     }
 
+    /**
+     * Clear all policies set in the policy engine.
+     *
+     * <p>Note that this doesn't clear any enforcements, it only clears the data structures.
+     */
+    void clearAllPolicies() {
+        synchronized (mLock) {
+            clear();
+            write();
+        }
+    }
     private void clear() {
         synchronized (mLock) {
             mGlobalPolicies.clear();
             mLocalPolicies.clear();
+            mEnforcingAdmins.clear();
         }
     }
 
+    // TODO: we need to listen for user removal and package removal and update out internal policy
+    //  map and enforcing admins for this is be accurate.
+    boolean hasActivePolicies() {
+        return mEnforcingAdmins.size() > 0;
+    }
+
+    /**
+     * Returns {@code true} if the coexistence flag is enabled or:
+     * <ul>
+     * <li>If the provided package is an admin with existing policies
+     * <li>A new admin and no other admin have policies set
+     * <li>More than one admin have policies set
+     */
+    boolean canAdminAddPolicies(String packageName, int userId) {
+        if (isCoexistenceFlagEnabled()) {
+            return true;
+        }
+
+        if (mEnforcingAdmins.contains(userId)
+                && mEnforcingAdmins.get(userId).stream().anyMatch(admin ->
+                admin.getPackageName().equals(packageName))) {
+            return true;
+        }
+
+        int numOfEnforcingAdmins = 0;
+        for (int i = 0; i < mEnforcingAdmins.size(); i++) {
+            numOfEnforcingAdmins += mEnforcingAdmins.get(i).size();
+        }
+        return numOfEnforcingAdmins == 0 || numOfEnforcingAdmins > 1;
+    }
+
+    private boolean isCoexistenceFlagEnabled() {
+        return DeviceConfig.getBoolean(
+                NAMESPACE_DEVICE_POLICY_MANAGER,
+                ENABLE_COEXISTENCE_FLAG,
+                DEFAULT_ENABLE_COEXISTENCE_FLAG);
+    }
+
     private class DevicePoliciesReaderWriter {
-        private static final String DEVICE_POLICIES_XML = "device_policies.xml";
+        private static final String DEVICE_POLICIES_XML = "device_policy_state.xml";
         private static final String TAG_LOCAL_POLICY_ENTRY = "local-policy-entry";
         private static final String TAG_GLOBAL_POLICY_ENTRY = "global-policy-entry";
         private static final String TAG_ADMINS_POLICY_ENTRY = "admins-policy-entry";
         private static final String TAG_ENFORCING_ADMINS_ENTRY = "enforcing-admins-entry";
         private static final String ATTR_USER_ID = "user-id";
-        private static final String ATTR_POLICY_ID = "policy-id";
 
         private final File mFile;
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c67ffd5..f5a1b80 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -21,6 +21,7 @@
 import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS;
 import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL;
 import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY;
 import static android.Manifest.permission.QUERY_ADMIN_POLICY;
 import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
 import static android.Manifest.permission.SET_TIME;
@@ -29,7 +30,9 @@
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_DEFAULT;
+import static android.app.AppOpsManager.OPSTR_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION;
 import static android.app.AppOpsManager.OPSTR_SYSTEM_EXEMPT_FROM_APP_STANDBY;
+import static android.app.AppOpsManager.OPSTR_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS;
 import static android.app.admin.DeviceAdminInfo.HEADLESS_DEVICE_OWNER_MODE_AFFILIATED;
 import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED;
 import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
@@ -40,6 +43,7 @@
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
 import static android.app.admin.DevicePolicyManager.ACTION_SYSTEM_UPDATE_POLICY_CHANGED;
+import static android.app.admin.DevicePolicyManager.AUTO_TIMEZONE_POLICY;
 import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
 import static android.app.admin.DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL;
 import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
@@ -54,7 +58,9 @@
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
 import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
+import static android.app.admin.DevicePolicyManager.EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION;
 import static android.app.admin.DevicePolicyManager.EXEMPT_FROM_APP_STANDBY;
+import static android.app.admin.DevicePolicyManager.EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS;
 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE;
 import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_IDS;
 import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
@@ -203,6 +209,9 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
+import android.app.admin.BooleanPolicyValue;
+import android.app.admin.BundlePolicyValue;
+import android.app.admin.ComponentNamePolicyValue;
 import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DeviceAdminReceiver;
 import android.app.admin.DevicePolicyCache;
@@ -217,11 +226,15 @@
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.admin.DevicePolicyManagerLiteInternal;
 import android.app.admin.DevicePolicySafetyChecker;
+import android.app.admin.DevicePolicyState;
 import android.app.admin.DevicePolicyStringResource;
 import android.app.admin.DeviceStateCache;
 import android.app.admin.FactoryResetProtectionPolicy;
 import android.app.admin.FullyManagedDeviceProvisioningParams;
 import android.app.admin.IDevicePolicyManager;
+import android.app.admin.IntegerPolicyValue;
+import android.app.admin.IntentFilterPolicyKey;
+import android.app.admin.LockTaskPolicy;
 import android.app.admin.ManagedProfileProvisioningParams;
 import android.app.admin.ManagedSubscriptionsPolicy;
 import android.app.admin.NetworkEvent;
@@ -230,10 +243,13 @@
 import android.app.admin.ParcelableResource;
 import android.app.admin.PasswordMetrics;
 import android.app.admin.PasswordPolicy;
+import android.app.admin.PolicyKey;
+import android.app.admin.PolicyValue;
 import android.app.admin.PreferentialNetworkServiceConfig;
 import android.app.admin.SecurityLog;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.app.admin.StartInstallingUpdateCallback;
+import android.app.admin.StringSetPolicyValue;
 import android.app.admin.SystemUpdateInfo;
 import android.app.admin.SystemUpdatePolicy;
 import android.app.admin.UnsafeStateException;
@@ -278,6 +294,7 @@
 import android.content.pm.StringParceledListSlice;
 import android.content.pm.UserInfo;
 import android.content.pm.UserPackage;
+import android.content.pm.parsing.FrameworkParsingPackageUtils;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.database.Cursor;
@@ -340,7 +357,6 @@
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.ParcelableKeyGenParameterSpec;
 import android.stats.devicepolicy.DevicePolicyEnums;
-import android.telecom.TelecomManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
@@ -431,6 +447,7 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -703,6 +720,12 @@
     static {
         APPLICATION_EXEMPTION_CONSTANTS_TO_APP_OPS.put(
                 EXEMPT_FROM_APP_STANDBY, OPSTR_SYSTEM_EXEMPT_FROM_APP_STANDBY);
+        APPLICATION_EXEMPTION_CONSTANTS_TO_APP_OPS.put(
+                EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS,
+                OPSTR_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS);
+        APPLICATION_EXEMPTION_CONSTANTS_TO_APP_OPS.put(
+                EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION,
+                OPSTR_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION);
     }
 
     /**
@@ -732,11 +755,18 @@
                     + "management app's authentication policy";
     private static final String NOT_SYSTEM_CALLER_MSG = "Only the system can %s";
 
+    // ENABLE_DEVICE_POLICY_ENGINE_FLAG must be enabled before this could be enabled.
     private static final String PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG =
             "enable_permission_based_access";
-    private static final String ENABLE_COEXISTENCE_FLAG = "enable_coexistence";
     private static final boolean DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG = false;
-    private static final boolean DEFAULT_ENABLE_COEXISTENCE_FLAG = false;
+
+    // This must be enabled before PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG is enabled, the reason
+    // we're not just relying on PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG to enable the policy engine
+    // is that we might want to enable it before the permission changes are ready if we want to test
+    // it on DPCs.
+    // Once this is enabled, it can no longer be disabled in production
+    private static final String ENABLE_DEVICE_POLICY_ENGINE_FLAG = "enable_device_policy_engine";
+    private static final boolean DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FLAG = false;
 
     // TODO(b/258425381) remove the flag after rollout.
     private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running";
@@ -750,6 +780,10 @@
     private static final String HEADLESS_FLAG = "headless";
     private static final boolean DEFAULT_HEADLESS_FLAG = true;
 
+    // TODO(b/266831522) remove the flag after rollout.
+    private static final String APPLICATION_EXEMPTIONS_FLAG = "application_exemptions";
+    private static final boolean DEFAULT_APPLICATION_EXEMPTIONS_FLAG = true;
+
     /**
      * This feature flag is checked once after boot and this value us used until the next reboot to
      * avoid needing to handle the flag changing on the fly.
@@ -1292,10 +1326,12 @@
                     && (owner.getPackageName().equals(packageName))) {
                 startOwnerService(userHandle, "package-broadcast");
             }
-            if (isCoexistenceFlagEnabled()) {
+            if (shouldMigrateToDevicePolicyEngine()) {
+                migratePoliciesToDevicePolicyEngine();
+            }
+            if (isDevicePolicyEngineFlagEnabled()) {
                 mDevicePolicyEngine.handlePackageChanged(packageName, userHandle);
             }
-
             // Persist updates if the removed package was an admin or delegate.
             if (removedAdmin || removedDelegate) {
                 saveSettingsLocked(policy.mUserId);
@@ -1985,7 +2021,7 @@
         mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener());
 
         mDeviceManagementResourcesProvider.load();
-        if (isCoexistenceFlagEnabled()) {
+        if (isDevicePolicyEngineFlagEnabled()) {
             mDevicePolicyEngine.load();
         }
 
@@ -3116,6 +3152,11 @@
                 synchronized (getLockObject()) {
                     migrateToProfileOnOrganizationOwnedDeviceIfCompLocked();
                     applyProfileRestrictionsIfDeviceOwnerLocked();
+
+                    // TODO: Is this the right place to trigger the migration?
+                    if (shouldMigrateToDevicePolicyEngine()) {
+                        migratePoliciesToDevicePolicyEngine();
+                    }
                 }
                 maybeStartSecurityLogMonitorOnActivityManagerReady();
                 break;
@@ -3324,7 +3365,7 @@
         updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfigs);
 
         startOwnerService(userId, "start-user");
-        if (isCoexistenceFlagEnabled()) {
+        if (isDevicePolicyEngineFlagEnabled()) {
             mDevicePolicyEngine.handleStartUser(userId);
         }
     }
@@ -3349,7 +3390,7 @@
 
     void handleUnlockUser(int userId) {
         startOwnerService(userId, "unlock-user");
-        if (isCoexistenceFlagEnabled()) {
+        if (isDevicePolicyEngineFlagEnabled()) {
             mDevicePolicyEngine.handleUnlockUser(userId);
         }
     }
@@ -3361,7 +3402,7 @@
     void handleStopUser(int userId) {
         updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT));
         mDeviceAdminServiceController.stopServicesForUser(userId, /* actionForLog= */ "stop-user");
-        if (isCoexistenceFlagEnabled()) {
+        if (isDevicePolicyEngineFlagEnabled()) {
             mDevicePolicyEngine.handleStopUser(userId);
         }
     }
@@ -3469,7 +3510,8 @@
      * @param refreshing true = update an active admin, no error
      */
     @Override
-    public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
+    public void setActiveAdmin(
+            ComponentName adminReceiver, boolean refreshing, int userHandle) {
         if (!mHasFeature) {
             return;
         }
@@ -3486,6 +3528,11 @@
         synchronized (getLockObject()) {
             checkActiveAdminPrecondition(adminReceiver, info, policy);
             mInjector.binderWithCleanCallingIdentity(() -> {
+                if (!canAddActiveAdminIfPolicyEngineEnabled(
+                        adminReceiver.getPackageName(), userHandle)) {
+                    throw new IllegalStateException("Can't add non-coexistable admin.");
+                }
+
                 final ActiveAdmin existingAdmin
                         = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
                 if (!refreshing && existingAdmin != null) {
@@ -7110,11 +7157,20 @@
      * @param factoryReset null: legacy behaviour, false: attempt to remove user, true: attempt to
      *                     factory reset
      */
-    private void wipeDataNoLock(ComponentName admin, int flags, String internalReason,
-            @NonNull String wipeReasonForUser, int userId, boolean calledOnParentInstance,
+    private void wipeDataNoLock(@Nullable ComponentName admin, int flags, String internalReason,
+            String wipeReasonForUser, int userId, boolean calledOnParentInstance,
             @Nullable Boolean factoryReset) {
         wtfIfInLock();
-
+        final String adminPackage;
+        if (admin != null) {
+            adminPackage = admin.getPackageName();
+        } else {
+            int callerId = mInjector.binderGetCallingUid();
+            String[] adminPackages = mInjector.getPackageManager().getPackagesForUid(callerId);
+            Preconditions.checkState(adminPackages.length > 0,
+                    "Caller %s does not have any associated packages", callerId);
+            adminPackage = adminPackages[0];
+        }
         mInjector.binderWithCleanCallingIdentity(() -> {
             // First check whether the admin is allowed to wipe the device/user/profile.
             final String restriction;
@@ -7133,7 +7189,7 @@
             boolean isSystemUser = userId == UserHandle.USER_SYSTEM;
             boolean wipeDevice;
             if (factoryReset == null || !mInjector.isChangeEnabled(EXPLICIT_WIPE_BEHAVIOUR,
-                    admin.getPackageName(),
+                    adminPackage,
                     userId)) {
                 // Legacy mode
                 wipeDevice = isSystemUser;
@@ -8220,14 +8276,14 @@
                     caller));
         }
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             mDevicePolicyEngine.setGlobalPolicy(
                     PolicyDefinition.AUTO_TIMEZONE,
                     // TODO(b/260573124): add correct enforcing admin when permission changes are
                     //  merged.
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(
                             caller.getComponentName(), caller.getUserId()),
-                    enabled);
+                    new BooleanPolicyValue(enabled));
         } else {
             mInjector.binderWithCleanCallingIdentity(() ->
                     mInjector.settingsGlobalPutInt(Global.AUTO_TIME_ZONE, enabled ? 1 : 0));
@@ -8779,9 +8835,10 @@
     @Override
     public boolean hasDeviceOwner() {
         final CallerIdentity caller = getCallerIdentity();
-        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller)
-                        || canManageUsers(caller) || isFinancedDeviceOwner(caller)
-                        || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+        Preconditions.checkCallAuthorization(
+                isDefaultDeviceOwner(caller) || canManageUsers(caller) || isFinancedDeviceOwner(
+                        caller) || hasCallingOrSelfPermission(
+                        permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
         return mOwners.hasDeviceOwner();
     }
 
@@ -8789,10 +8846,16 @@
         return isDeviceOwner(admin.info.getComponent(), admin.getUserHandle().getIdentifier());
     }
 
-    public boolean isDeviceOwner(ComponentName who, int userId) {
+    /**
+     * Check if the user is a Device Owner
+     *
+     * @param who    component to check against
+     * @param userId user to check
+     * @return if the user is a Device Owner
+     */
+    public boolean isDeviceOwner(@Nullable ComponentName who, int userId) {
         synchronized (getLockObject()) {
-            return mOwners.hasDeviceOwner()
-                    && mOwners.getDeviceOwnerUserId() == userId
+            return mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userId
                     && mOwners.getDeviceOwnerComponent().equals(who);
         }
     }
@@ -8841,9 +8904,16 @@
         }
     }
 
-    public boolean isProfileOwner(ComponentName who, int userId) {
-        final ComponentName profileOwner = mInjector.binderWithCleanCallingIdentity(() ->
-                getProfileOwnerAsUser(userId));
+    /**
+     * Check if {@link userId} is a Profile Owner
+     *
+     * @param who    component to check against
+     * @param userId user to check
+     * @return if the user is a Profile Owner
+     */
+    public boolean isProfileOwner(@Nullable ComponentName who, int userId) {
+        final ComponentName profileOwner = mInjector.binderWithCleanCallingIdentity(
+                () -> getProfileOwnerAsUser(userId));
         return who != null && who.equals(profileOwner);
     }
 
@@ -9321,7 +9391,11 @@
 
     @Override
     public CharSequence getDeviceOwnerLockScreenInfo() {
-        return mLockPatternUtils.getDeviceOwnerInfo();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(
+                isDefaultDeviceOwner(caller) || isProfileOwnerOfOrganizationOwnedDevice(caller));
+        return mInjector.binderWithCleanCallingIdentity(() ->
+            mLockPatternUtils.getDeviceOwnerInfo());
     }
 
     private void clearUserPoliciesLocked(int userId) {
@@ -10312,11 +10386,11 @@
                 || isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller));
 
         final int userHandle = caller.getUserId();
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             mDevicePolicyEngine.setLocalPolicy(
                     PolicyDefinition.PERSISTENT_PREFERRED_ACTIVITY(filter),
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userHandle),
-                    activity,
+                    new ComponentNamePolicyValue(activity),
                     userHandle);
         } else {
             synchronized (getLockObject()) {
@@ -10350,7 +10424,7 @@
 
         final int userHandle = caller.getUserId();
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             clearPackagePersistentPreferredActivitiesFromPolicyEngine(
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userHandle),
                     packageName,
@@ -10386,13 +10460,13 @@
                 admin,
                 userId);
         for (PolicyKey key : keys) {
-            if (!(key instanceof PersistentPreferredActivityPolicyKey)) {
+            if (!(key instanceof IntentFilterPolicyKey)) {
                 throw new IllegalStateException("PolicyKey for PERSISTENT_PREFERRED_ACTIVITY is not"
                         + "of type PersistentPreferredActivityPolicyKey");
             }
-            PersistentPreferredActivityPolicyKey parsedKey =
-                    (PersistentPreferredActivityPolicyKey) key;
-            IntentFilter filter = Objects.requireNonNull(parsedKey.getFilter());
+            IntentFilterPolicyKey parsedKey =
+                    (IntentFilterPolicyKey) key;
+            IntentFilter filter = Objects.requireNonNull(parsedKey.getIntentFilter());
 
             ComponentName preferredActivity = mDevicePolicyEngine.getLocalPolicySetByAdmin(
                     PolicyDefinition.PERSISTENT_PREFERRED_ACTIVITY(filter),
@@ -10450,25 +10524,79 @@
 
     @Override
     public void setApplicationRestrictions(ComponentName who, String callerPackage,
-            String packageName, Bundle settings) {
+            String packageName, Bundle restrictions) {
         final CallerIdentity caller = getCallerIdentity(who, callerPackage);
         Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                 && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
                 || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS)));
         checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_APPLICATION_RESTRICTIONS);
 
+        if (useDevicePolicyEngine(caller, DELEGATION_APP_RESTRICTIONS)) {
+            // This check is eventually made in UMS, checking here to fail early.
+            String validationResult =
+                    FrameworkParsingPackageUtils.validateName(packageName, false, false);
+            if (validationResult != null) {
+                throw new IllegalArgumentException("Invalid package name: " + validationResult);
+            }
+
+            EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                    who == null
+                            ? new ComponentName(caller.getPackageName(), "Delegate")
+                            : who,
+                    caller.getUserId());
+
+            if (restrictions == null || restrictions.isEmpty()) {
+                mDevicePolicyEngine.removeLocalPolicy(
+                        PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                        admin,
+                        caller.getUserId());
+            } else {
+                mDevicePolicyEngine.setLocalPolicy(
+                        PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                        admin,
+                        new BundlePolicyValue(restrictions),
+                        caller.getUserId());
+            }
+            setBackwardsCompatibleAppRestrictions(
+                    packageName, restrictions, caller.getUserHandle());
+        } else {
+            mInjector.binderWithCleanCallingIdentity(() -> {
+                mUserManager.setApplicationRestrictions(packageName, restrictions,
+                        caller.getUserHandle());
+            });
+        }
+
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.SET_APPLICATION_RESTRICTIONS)
+                .setAdmin(caller.getPackageName())
+                .setBoolean(/* isDelegate */ who == null)
+                .setStrings(packageName)
+                .write();
+    }
+
+    /**
+     * Set app restrictions in user manager to keep backwards compatibility for the old
+     * getApplicationRestrictions API.
+     */
+    private void setBackwardsCompatibleAppRestrictions(
+            String packageName, Bundle restrictions, UserHandle userHandle) {
+        Bundle restrictionsToApply = restrictions == null || restrictions.isEmpty()
+                ? getAppRestrictionsSetByAnyAdmin(packageName, userHandle)
+                : restrictions;
         mInjector.binderWithCleanCallingIdentity(() -> {
-            mUserManager.setApplicationRestrictions(packageName, settings,
-                    caller.getUserHandle());
-            DevicePolicyEventLogger
-                    .createEvent(DevicePolicyEnums.SET_APPLICATION_RESTRICTIONS)
-                    .setAdmin(caller.getPackageName())
-                    .setBoolean(/* isDelegate */ who == null)
-                    .setStrings(packageName)
-                    .write();
+            mUserManager.setApplicationRestrictions(packageName, restrictionsToApply, userHandle);
         });
     }
 
+    private Bundle getAppRestrictionsSetByAnyAdmin(String packageName, UserHandle userHandle) {
+        LinkedHashMap<EnforcingAdmin, PolicyValue<Bundle>> policies =
+                mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+                        PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                        userHandle.getIdentifier());
+        return policies.isEmpty()
+                ? null : policies.entrySet().stream().findAny().get().getValue().getValue();
+    }
+
     @Override
     public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent,
             PersistableBundle args, boolean parent) {
@@ -11303,6 +11431,11 @@
         }
 
         final int userId = user.id;
+
+        if (isDevicePolicyEngineFlagEnabled()) {
+            mDevicePolicyEngine.handleUserCreated(user);
+        }
+
         if (token != null) {
             synchronized (getLockObject()) {
                 if (mPendingUserCreatedCallbackTokens.contains(token)) {
@@ -11403,8 +11536,8 @@
     }
 
     private boolean isAdminAffectedByRestriction(
-            ComponentName admin, String userRestriction, int userId) {
-        switch(mUserManager.getUserRestrictionSource(userRestriction, UserHandle.of(userId))) {
+            @Nullable ComponentName admin, String userRestriction, int userId) {
+        switch (mUserManager.getUserRestrictionSource(userRestriction, UserHandle.of(userId))) {
             case UserManager.RESTRICTION_NOT_SET:
                 return false;
             case UserManager.RESTRICTION_SOURCE_DEVICE_OWNER:
@@ -11672,13 +11805,28 @@
                 && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
                 || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS)));
 
-        return mInjector.binderWithCleanCallingIdentity(() -> {
-            Bundle bundle = mUserManager.getApplicationRestrictions(packageName,
-                    caller.getUserHandle());
-           // if no restrictions were saved, mUserManager.getApplicationRestrictions
-           // returns null, but DPM method should return an empty Bundle as per JavaDoc
-           return bundle != null ? bundle : Bundle.EMPTY;
-        });
+        if (useDevicePolicyEngine(caller, DELEGATION_APP_RESTRICTIONS)) {
+            EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                    who != null ? who : new ComponentName(callerPackage, "Delegate"),
+                    caller.getUserId());
+
+            LinkedHashMap<EnforcingAdmin, PolicyValue<Bundle>> policies =
+                    mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+                            PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                            caller.getUserId());
+            if (policies.isEmpty() || !policies.containsKey(admin)) {
+                return Bundle.EMPTY;
+            }
+            return policies.get(admin).getValue();
+        } else {
+            return mInjector.binderWithCleanCallingIdentity(() -> {
+                Bundle bundle = mUserManager.getApplicationRestrictions(packageName,
+                        caller.getUserHandle());
+                // if no restrictions were saved, mUserManager.getApplicationRestrictions
+                // returns null, but DPM method should return an empty Bundle as per JavaDoc
+                return bundle != null ? bundle : Bundle.EMPTY;
+            });
+        }
     }
 
     /**
@@ -12329,7 +12477,7 @@
                 || isFinancedDeviceOwner(caller)))
                 || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_BLOCK_UNINSTALL)));
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, DELEGATION_BLOCK_UNINSTALL)) {
             // TODO(b/260573124): Add correct enforcing admin when permission changes are
             //  merged, and don't forget to handle delegates! Enterprise admins assume
             //  component name isn't null.
@@ -12339,7 +12487,7 @@
             mDevicePolicyEngine.setLocalPolicy(
                     PolicyDefinition.PACKAGE_UNINSTALL_BLOCKED(packageName),
                     admin,
-                    uninstallBlocked,
+                    new BooleanPolicyValue(uninstallBlocked),
                     caller.getUserId());
         } else {
             final int userId = caller.getUserId();
@@ -12893,7 +13041,7 @@
             checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_PACKAGES);
         }
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
                     who, caller.getUserId());
             if (packages.length == 0) {
@@ -12910,7 +13058,7 @@
                 if (currentPolicy == null) {
                     policy = new LockTaskPolicy(Set.of(packages));
                 } else {
-                    policy = currentPolicy.clone();
+                    policy = new LockTaskPolicy(currentPolicy);
                     policy.setPackages(Set.of(packages));
                 }
 
@@ -12947,7 +13095,7 @@
             enforceCanCallLockTaskLocked(caller);
         }
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
                     PolicyDefinition.LOCK_TASK, userHandle);
             if (policy == null) {
@@ -12975,9 +13123,8 @@
         }
 
         final int userId = mInjector.userHandleGetCallingUserId();
-        // TODO(b/260560985): This is not the right check, as the flag could be enabled but there
-        //  could be an admin that hasn't targeted U.
-        if (isCoexistenceFlagEnabled()) {
+        // Is it ok to just check that no active policies exist currently?
+        if (mDevicePolicyEngine.hasActivePolicies()) {
             LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
                     PolicyDefinition.LOCK_TASK, userId);
             if (policy == null) {
@@ -13011,7 +13158,7 @@
             enforceCanSetLockTaskFeaturesOnFinancedDevice(caller, flags);
             checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_FEATURES);
         }
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userHandle);
             LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicySetByAdmin(
                     PolicyDefinition.LOCK_TASK,
@@ -13021,7 +13168,7 @@
                 throw new IllegalArgumentException("Can't set a lock task flags without setting "
                         + "lock task packages first.");
             }
-            LockTaskPolicy policy = currentPolicy.clone();
+            LockTaskPolicy policy = new LockTaskPolicy(currentPolicy);
             policy.setFlags(flags);
 
             mDevicePolicyEngine.setLocalPolicy(
@@ -13052,7 +13199,7 @@
             enforceCanCallLockTaskLocked(caller);
         }
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
                     PolicyDefinition.LOCK_TASK, userHandle);
             if (policy == null) {
@@ -14189,6 +14336,45 @@
         public boolean isUserOrganizationManaged(@UserIdInt int userHandle) {
             return getDeviceStateCache().isUserOrganizationManaged(userHandle);
         }
+
+        @Override
+        public boolean isApplicationExemptionsFlagEnabled() {
+            return DeviceConfig.getBoolean(
+                    NAMESPACE_DEVICE_POLICY_MANAGER,
+                    APPLICATION_EXEMPTIONS_FLAG,
+                    DEFAULT_APPLICATION_EXEMPTIONS_FLAG);
+        }
+
+        @Override
+        public Map<String, Bundle> getApplicationRestrictionsPerAdmin(
+                String packageName, int userId) {
+            LinkedHashMap<EnforcingAdmin, PolicyValue<Bundle>> policies =
+                    mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+                            PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                            userId);
+            Map<String, Bundle> restrictions = new HashMap<>();
+            for (EnforcingAdmin admin : policies.keySet()) {
+                restrictions.put(admin.getPackageName(), policies.get(admin).getValue());
+            }
+            if (!restrictions.isEmpty()) {
+                return restrictions;
+            }
+
+            return mInjector.binderWithCleanCallingIdentity(() -> {
+                // Could be a device that hasn't migrated yet, so just return any restrictions saved
+                // in userManager.
+                Bundle bundle = mUserManager.getApplicationRestrictions(
+                        packageName, UserHandle.of(userId));
+                if (bundle == null || bundle.isEmpty()) {
+                    return new HashMap<>();
+                }
+                ActiveAdmin admin = getMostProbableDPCAdminForLocalPolicy(userId);
+                if (admin == null) {
+                    return new HashMap<>();
+                }
+                return Map.of(admin.info.getPackageName(), bundle);
+            });
+        }
     }
 
     private Intent createShowAdminSupportIntent(int userId) {
@@ -14716,7 +14902,11 @@
                 enforcePermissionGrantStateOnFinancedDevice(packageName, permission);
             }
         }
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, DELEGATION_PERMISSION_GRANT)) {
+            // TODO(b/266924257): decide how to handle the internal state if the package doesn't
+            //  exist, or the permission isn't requested by the app, because we could end up with
+            //  inconsistent state between the policy engine and package manager. Also a package
+            //  might get removed or has it's permission updated after we've set the policy.
             mDevicePolicyEngine.setLocalPolicy(
                     PolicyDefinition.PERMISSION_GRANT(packageName, permission),
                     // TODO(b/260573124): Add correct enforcing admin when permission changes are
@@ -14724,7 +14914,7 @@
                     //  component name isn't null.
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(
                             caller.getComponentName(), caller.getUserId()),
-                    grantState,
+                    new IntegerPolicyValue(grantState),
                     caller.getUserId());
             // TODO: update javadoc to reflect that callback no longer return success/failure
             callback.sendResult(Bundle.EMPTY);
@@ -14811,44 +15001,50 @@
                 enforcePermissionGrantStateOnFinancedDevice(packageName, permission);
             }
             return mInjector.binderWithCleanCallingIdentity(() -> {
-                int granted;
-                if (getTargetSdk(caller.getPackageName(), caller.getUserId())
-                        < android.os.Build.VERSION_CODES.Q) {
-                    // The per-Q behavior was to not check the app-ops state.
-                    granted = mIPackageManager.checkPermission(permission, packageName,
-                            caller.getUserId());
-                } else {
-                    try {
-                        int uid = mInjector.getPackageManager().getPackageUidAsUser(packageName,
-                                caller.getUserId());
-                        if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
-                                PermissionChecker.PID_UNKNOWN, uid, packageName)
-                                        != PermissionChecker.PERMISSION_GRANTED) {
-                            granted = PackageManager.PERMISSION_DENIED;
-                        } else {
-                            granted = PackageManager.PERMISSION_GRANTED;
-                        }
-                    } catch (NameNotFoundException e) {
-                        // Package does not exit
-                        return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
-                    }
-                }
-                int permFlags = mInjector.getPackageManager().getPermissionFlags(
-                        permission, packageName, caller.getUserHandle());
-                if ((permFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED)
-                        != PackageManager.FLAG_PERMISSION_POLICY_FIXED) {
-                    // Not controlled by policy
-                    return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
-                } else {
-                    // Policy controlled so return result based on permission grant state
-                    return granted == PackageManager.PERMISSION_GRANTED
-                            ? DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
-                            : DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
-                }
+                return getPermissionGrantStateForUser(
+                        packageName, permission, caller, caller.getUserId());
             });
         }
     }
 
+    private int getPermissionGrantStateForUser(
+            String packageName, String permission, CallerIdentity caller, int userId)
+            throws RemoteException {
+        int granted;
+        if (getTargetSdk(caller.getPackageName(), caller.getUserId())
+                < android.os.Build.VERSION_CODES.Q) {
+            // The per-Q behavior was to not check the app-ops state.
+            granted = mIPackageManager.checkPermission(permission, packageName, userId);
+        } else {
+            try {
+                int uid = mInjector.getPackageManager().getPackageUidAsUser(
+                        packageName, userId);
+                if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+                        PermissionChecker.PID_UNKNOWN, uid, packageName)
+                        != PermissionChecker.PERMISSION_GRANTED) {
+                    granted = PackageManager.PERMISSION_DENIED;
+                } else {
+                    granted = PackageManager.PERMISSION_GRANTED;
+                }
+            } catch (NameNotFoundException e) {
+                // Package does not exit
+                return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
+            }
+        }
+        int permFlags = mInjector.getPackageManager().getPermissionFlags(
+                permission, packageName, UserHandle.of(userId));
+        if ((permFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED)
+                != PackageManager.FLAG_PERMISSION_POLICY_FIXED) {
+            // Not controlled by policy
+            return DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
+        } else {
+            // Policy controlled so return result based on permission grant state
+            return granted == PackageManager.PERMISSION_GRANTED
+                    ? DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
+                    : DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
+        }
+    }
+
     boolean isPackageInstalledForUser(String packageName, int userHandle) {
         return mInjector.binderWithCleanCallingIdentity(() -> {
             try {
@@ -15388,16 +15584,27 @@
     }
 
     @Override
-    public void setOrganizationName(@NonNull ComponentName who, CharSequence text) {
+    public void setOrganizationName(@Nullable ComponentName who, CharSequence text) {
         if (!mHasFeature) {
             return;
         }
-        Objects.requireNonNull(who, "ComponentName is null");
-        final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+        CallerIdentity caller = getCallerIdentity(who);
+        ActiveAdmin admin = null;
+
+        if (isPermissionCheckFlagEnabled()) {
+            EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
+                    who,
+                    MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
+                    caller.getUserId());
+            admin = enforcingAdmin.getActiveAdmin();
+        } else {
+            Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+        }
 
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+            if (!isPermissionCheckFlagEnabled()) {
+                admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+            }
             if (!TextUtils.equals(admin.organizationName, text)) {
                 admin.organizationName = (text == null || text.length() == 0)
                         ? null : text.toString();
@@ -15407,20 +15614,29 @@
     }
 
     @Override
-    public CharSequence getOrganizationName(@NonNull ComponentName who) {
+    public CharSequence getOrganizationName(@Nullable ComponentName who) {
         if (!mHasFeature) {
             return null;
         }
-        Objects.requireNonNull(who, "ComponentName is null");
+        CallerIdentity caller = getCallerIdentity(who);
+        ActiveAdmin admin = null;
 
-        final CallerIdentity caller = getCallerIdentity(who);
-        Preconditions.checkCallingUser(isManagedProfile(caller.getUserId()));
-        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
+        if (isPermissionCheckFlagEnabled()) {
+            EnforcingAdmin enforcingAdmin = enforceCanQueryAndGetEnforcingAdmin(
+                    who,
+                    MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
+                    caller.getUserId());
+            admin = enforcingAdmin.getActiveAdmin();
+        } else {
+            Preconditions.checkCallingUser(isManagedProfile(caller.getUserId()));
+            Preconditions.checkCallAuthorization(isDeviceOwner(caller) || isProfileOwner(caller));
 
-        synchronized (getLockObject()) {
-            ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
-            return admin.organizationName;
+            synchronized (getLockObject()) {
+                admin = getProfileOwnerOrDeviceOwnerLocked(caller.getUserId());
+            }
         }
+
+        return admin.organizationName;
     }
 
     /**
@@ -16106,6 +16322,11 @@
         // The removed admin might have disabled camera, so update user
         // restrictions.
         pushUserRestrictions(userHandle);
+
+        // The removed admin might've been stopping the migration if it was targeting pre Android U
+        if (shouldMigrateToDevicePolicyEngine()) {
+            migratePoliciesToDevicePolicyEngine();
+        }
     }
 
     @Override
@@ -17999,7 +18220,7 @@
         checkCanExecuteOrThrowUnsafe(
                 DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES);
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             Binder.withCleanCallingIdentity(() -> {
                 if (packages.isEmpty()) {
                     removeUserControlDisabledPackages(caller);
@@ -18033,7 +18254,7 @@
                     //  merged.
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(
                             caller.getComponentName(), caller.getUserId()),
-                    packages);
+                    new StringSetPolicyValue(packages));
         } else {
             mDevicePolicyEngine.setLocalPolicy(
                     PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
@@ -18041,7 +18262,7 @@
                     //  merged.
                     EnforcingAdmin.createEnterpriseEnforcingAdmin(
                             caller.getComponentName(), caller.getUserId()),
-                    packages,
+                    new StringSetPolicyValue(packages),
                     caller.getUserId());
         }
     }
@@ -18079,7 +18300,7 @@
         Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller)
                 || isFinancedDeviceOwner(caller));
 
-        if (isCoexistenceEnabled(caller)) {
+        if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
             // This retrieves the policy for the calling user only, DOs for example can't know
             // what's enforced globally or on another user.
             Set<String> packages = mDevicePolicyEngine.getResolvedPolicy(
@@ -18435,9 +18656,9 @@
                         .addExtras(extras)
                         .build();
 
-        mInjector.getNotificationManager().notifyAsUser(
+        mHandler.post(() -> mInjector.getNotificationManager().notifyAsUser(
                 null, SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED, notification,
-                UserHandle.of(getProfileParentId(profileUserId)));
+                UserHandle.of(getProfileParentId(profileUserId))));
     }
 
     private String getPersonalAppSuspensionButtonText() {
@@ -20044,22 +20265,26 @@
             MANAGE_DEVICE_POLICY_ACROSS_USERS,
             MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
             SET_TIME,
-            SET_TIME_ZONE);
+            SET_TIME_ZONE,
+            MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY);
     private static final List<String> FINANCED_DEVICE_OWNER_PERMISSIONS = List.of(
             MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL,
             MANAGE_DEVICE_POLICY_ACROSS_USERS,
-            MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
+            MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
+            MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY);
     private static final List<String> PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE_PERMISSIONS =
             List.of(
                 MANAGE_DEVICE_POLICY_ACROSS_USERS,
                 MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
                 SET_TIME,
-                SET_TIME_ZONE);
+                SET_TIME_ZONE,
+                MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY);
     private static final List<String> PROFILE_OWNER_ON_USER_0_PERMISSIONS  = List.of(
             SET_TIME,
             SET_TIME_ZONE);
     private static final List<String> PROFILE_OWNER_PERMISSIONS  = List.of(
-            MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL);
+            MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL,
+            MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY);
 
     private static final HashMap<Integer, List<String>> DPC_PERMISSIONS = new HashMap<>();
     {
@@ -20077,9 +20302,53 @@
     private static final HashMap<String, String> CROSS_USER_PERMISSIONS =
             new HashMap<>();
     {
-        // Auto time is intrinsically global so there is no cross-user permission.
+        // Time and Timezone is intrinsically global so there is no cross-user permission.
         CROSS_USER_PERMISSIONS.put(SET_TIME, null);
         CROSS_USER_PERMISSIONS.put(SET_TIME_ZONE, null);
+        // Organisation identity policy will involve data of other organisations on the device and
+        // therefore the FULL cross-user permission is required.
+        CROSS_USER_PERMISSIONS.put(MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY,
+                MANAGE_DEVICE_POLICY_ACROSS_USERS_FULL);
+    }
+
+    /**
+     * Checks if the calling process has been granted permission to apply a device policy on a
+     * specific user.
+     * The given permission will be checked along with its associated cross-user permission if it
+     * exists and the target user is different to the calling user.
+     * Returns the {@link ActiveAdmin} of the caller.
+     *
+     * @param permission The name of the permission being checked.
+     * @param targetUserId The userId of the user which the caller needs permission to act on.
+     * @throws SecurityException if the caller has not been granted the given permission,
+     * the associated cross-user permission if the caller's user is different to the target user.
+     */
+    private EnforcingAdmin enforcePermissionAndGetEnforcingAdmin(@Nullable ComponentName admin,
+            String permission, int targetUserId) {
+        enforcePermission(permission, targetUserId);
+        return getEnforcingAdminForCaller(admin, getCallerIdentity());
+    }
+
+    /**
+     * Checks whether the calling process has been granted permission to query a device policy on
+     * a specific user.
+     * The given permission will be checked along with its associated cross-user permission if it
+     * exists and the target user is different to the calling user.
+     *
+     * @param permission The name of the permission being checked.
+     * @param targetUserId The userId of the user which the caller needs permission to act on.
+     * @throws SecurityException if the caller has not been granted the given permission,
+     * the associated cross-user permission if the caller's user is different to the target user.
+     */
+    private EnforcingAdmin enforceCanQueryAndGetEnforcingAdmin(@Nullable ComponentName admin,
+            String permission, int targetUserId) {
+        enforceCanQuery(permission, targetUserId);
+        return getEnforcingAdminForCaller(admin, getCallerIdentity());
+    }
+
+    private static final HashMap<String, String> POLICY_IDENTIFIER_TO_PERMISSION = new HashMap<>();
+    {
+        POLICY_IDENTIFIER_TO_PERMISSION.put(AUTO_TIMEZONE_POLICY, SET_TIME_ZONE);
     }
 
     /**
@@ -20091,7 +20360,7 @@
      * @param permission The name of the permission being checked.
      * @param targetUserId The userId of the user which the caller needs permission to act on.
      * @throws SecurityException if the caller has not been granted the given permission,
-     * the associtated cross-user permission if the caller's user is different to the target user.
+     * the associated cross-user permission if the caller's user is different to the target user.
      */
     private void enforcePermission(String permission, int targetUserId)
             throws SecurityException {
@@ -20106,13 +20375,15 @@
     }
 
     /**
-     * Return whether the calling process has been granted permission to query a device policy on
+     * Checks whether the calling process has been granted permission to query a device policy on
      * a specific user.
+     * The given permission will be checked along with its associated cross-user permission if it
+     * exists and the target user is different to the calling user.
      *
      * @param permission The name of the permission being checked.
      * @param targetUserId The userId of the user which the caller needs permission to act on.
      * @throws SecurityException if the caller has not been granted the given permission,
-     * the associatated cross-user permission if the caller's user is different to the target user
+     * the associated cross-user permission if the caller's user is different to the target user
      * and if the user has not been granted {@link QUERY_ADMIN_POLICY}.
      */
     private void enforceCanQuery(String permission, int targetUserId) throws SecurityException {
@@ -20177,10 +20448,15 @@
         }
         // Check if the caller is an active admin that uses a certain policy.
         if (ACTIVE_ADMIN_POLICIES.containsKey(permission)) {
-            return getActiveAdminForCallerLocked(
-                    null, ACTIVE_ADMIN_POLICIES.get(permission), false) != null;
+            try {
+                return getActiveAdminForCallerLocked(
+                        null, ACTIVE_ADMIN_POLICIES.get(permission), false) != null;
+            } catch (SecurityException e) {
+                // A security exception means there is not an active admin with permission and
+                // therefore
+                return false;
+            }
         }
-
         return false;
     }
 
@@ -20210,6 +20486,22 @@
         return false;
     }
 
+    private EnforcingAdmin getEnforcingAdminForCaller(@Nullable ComponentName who,
+            CallerIdentity caller) {
+        int userId = caller.getUserId();
+        ActiveAdmin admin = null;
+        synchronized (getLockObject()) {
+            admin = getActiveAdminUncheckedLocked(who, userId);
+        }
+        if (isDeviceOwner(caller) || isProfileOwner(caller)) {
+            return EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userId, admin);
+        }
+        if (getActiveAdminUncheckedLocked(who, userId) != null) {
+            return EnforcingAdmin.createDeviceAdminEnforcingAdmin(who, userId, admin);
+        }
+        return  EnforcingAdmin.createEnforcingAdmin(caller.getPackageName(), userId);
+    }
+
     private boolean isPermissionCheckFlagEnabled() {
         return DeviceConfig.getBoolean(
                 NAMESPACE_DEVICE_POLICY_MANAGER,
@@ -20217,20 +20509,6 @@
                 DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG);
     }
 
-    // TODO(b/260560985): properly gate coexistence changes
-    private boolean isCoexistenceEnabled(CallerIdentity caller) {
-        return isCoexistenceFlagEnabled()
-                && mInjector.isChangeEnabled(
-                        ENABLE_COEXISTENCE_CHANGE, caller.getPackageName(), caller.getUserId());
-    }
-
-    private boolean isCoexistenceFlagEnabled() {
-        return DeviceConfig.getBoolean(
-                NAMESPACE_DEVICE_POLICY_MANAGER,
-                ENABLE_COEXISTENCE_FLAG,
-                DEFAULT_ENABLE_COEXISTENCE_FLAG);
-    }
-
     private static boolean isKeepProfilesRunningFlagEnabled() {
         return DeviceConfig.getBoolean(
                 NAMESPACE_DEVICE_POLICY_MANAGER,
@@ -20383,7 +20661,7 @@
             final long id = mInjector.binderClearCallingIdentity();
             try {
                 int parentUserId = getProfileParentId(caller.getUserId());
-                installOemDefaultDialerAndMessagesApp(parentUserId, caller.getUserId());
+                installOemDefaultDialerAndSmsApp(caller.getUserId());
                 updateTelephonyCrossProfileIntentFilters(parentUserId, caller.getUserId(), true);
             } finally {
                 mInjector.binderRestoreCallingIdentity(id);
@@ -20391,32 +20669,31 @@
         }
     }
 
-    private void installOemDefaultDialerAndMessagesApp(int sourceUserId, int targetUserId) {
+    private void installOemDefaultDialerAndSmsApp(int targetUserId) {
         try {
-            UserHandle sourceUserHandle = UserHandle.of(sourceUserId);
-            TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
-            String dialerAppPackage = telecomManager.getDefaultDialerPackage(
-                    sourceUserHandle);
-            String messagesAppPackage = SmsApplication.getDefaultSmsApplicationAsUser(mContext,
-                    true, sourceUserHandle).getPackageName();
-            if (dialerAppPackage != null) {
-                mIPackageManager.installExistingPackageAsUser(dialerAppPackage, targetUserId,
-                        PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+            String defaultDialerPackageName = getDefaultRoleHolderPackageName(
+                    com.android.internal.R.string.config_defaultDialer);
+            String defaultSmsPackageName = getDefaultRoleHolderPackageName(
+                    com.android.internal.R.string.config_defaultSms);
+
+            if (defaultDialerPackageName != null) {
+                mIPackageManager.installExistingPackageAsUser(defaultDialerPackageName,
+                        targetUserId, PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
                         PackageManager.INSTALL_REASON_POLICY, null);
             } else {
                 Slogf.w(LOG_TAG, "Couldn't install dialer app, dialer app package is null");
             }
 
-            if (messagesAppPackage != null) {
-                mIPackageManager.installExistingPackageAsUser(messagesAppPackage, targetUserId,
+            if (defaultSmsPackageName != null) {
+                mIPackageManager.installExistingPackageAsUser(defaultSmsPackageName, targetUserId,
                         PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
                         PackageManager.INSTALL_REASON_POLICY, null);
             } else {
-                Slogf.w(LOG_TAG, "Couldn't install messages app, messages app package is null");
+                Slogf.w(LOG_TAG, "Couldn't install sms app, sms app package is null");
             }
         } catch (RemoteException re) {
             // shouldn't happen
-            Slogf.wtf(LOG_TAG, "Failed to install dialer/messages app", re);
+            Slogf.wtf(LOG_TAG, "Failed to install dialer/sms app", re);
         }
     }
 
@@ -20475,4 +20752,363 @@
             }
         }
     }
+
+    @Override
+    public DevicePolicyState getDevicePolicyState() {
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+        return mInjector.binderWithCleanCallingIdentity(mDevicePolicyEngine::getDevicePolicyState);
+    }
+
+    @Override
+    public boolean triggerDevicePolicyEngineMigration(boolean forceMigration) {
+        Preconditions.checkCallAuthorization(
+                hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            boolean canForceMigration = forceMigration && !hasNonTestOnlyActiveAdmins();
+            if (!canForceMigration && !shouldMigrateToDevicePolicyEngine()) {
+                return false;
+            }
+            return migratePoliciesToDevicePolicyEngine();
+        });
+    }
+
+    private boolean hasNonTestOnlyActiveAdmins() {
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            for (UserInfo userInfo : mUserManager.getUsers()) {
+                List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
+                if (activeAdmins == null) {
+                    continue;
+                }
+                for (ComponentName admin : activeAdmins) {
+                    if (!isAdminTestOnlyLocked(admin, userInfo.id)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        });
+    }
+
+    // TODO(b/266808047): handle DeviceAdmin migration when there is no DPCs on the device
+    private boolean shouldMigrateToDevicePolicyEngine() {
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            if (!isDevicePolicyEngineFlagEnabled()) {
+                return false;
+            }
+            if (mOwners.isMigratedToPolicyEngine()) {
+                return false;
+            }
+            // We're only checking if existing DPCs are not targeting U, regardless of what
+            // DeviceAdmins are targeting, as they can access very limited APIs, and we'll ensure
+            // that these APIs maintain the current behaviour of strictest applies.
+            boolean hasDPCs = false;
+            for (UserInfo userInfo : mUserManager.getUsers()) {
+                List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
+                if (activeAdmins == null) {
+                    continue;
+                }
+                for (ComponentName admin : activeAdmins) {
+                    if ((isProfileOwner(admin, userInfo.id) || isDeviceOwner(admin, userInfo.id))) {
+                        if (!mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE,
+                                admin.getPackageName(), userInfo.id)) {
+                            return false;
+                        }
+                        hasDPCs = true;
+                    }
+                }
+            }
+            return hasDPCs;
+        });
+    }
+
+    /**
+     * @return {@code true} if policies were migrated successfully, {@code false} otherwise.
+     */
+    private boolean migratePoliciesToDevicePolicyEngine() {
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            try {
+                Slogf.i(LOG_TAG, "Started device policies migration to the device policy engine.");
+                migrateAutoTimezonePolicy();
+                migratePermissionGrantStatePolicies();
+                // TODO(b/258811766): add migration logic for all policies
+
+                mOwners.markMigrationToPolicyEngine();
+                return true;
+            } catch (Exception e) {
+                mDevicePolicyEngine.clearAllPolicies();
+                Slogf.e(LOG_TAG, e, "Error occurred during device policy migration, will "
+                        + "reattempt on the next system server restart.");
+                return false;
+            }
+        });
+    }
+
+    private void migrateAutoTimezonePolicy() {
+        Slogf.i(LOG_TAG, "Skipping Migration of AUTO_TIMEZONE policy to device policy engine,"
+                + "as no way to identify if the value was set by the admin or the user.");
+    }
+
+    private void migratePermissionGrantStatePolicies() {
+        Slogf.i(LOG_TAG, "Migrating PERMISSION_GRANT policy to device policy engine.");
+        for (UserInfo userInfo : mUserManager.getUsers()) {
+            ActiveAdmin admin = getMostProbableDPCAdminForLocalPolicy(userInfo.id);
+            if (admin == null) {
+                Slogf.i(LOG_TAG, "No admin found that can set permission grant state on user "
+                        + userInfo.id);
+                continue;
+            }
+            for (PackageInfo packageInfo : getInstalledPackagesOnUser(userInfo.id)) {
+                if (packageInfo.requestedPermissions == null) {
+                    continue;
+                }
+                for (String permission : packageInfo.requestedPermissions) {
+                    if (!isRuntimePermission(permission)) {
+                        continue;
+                    }
+                    int grantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
+                    try {
+                        grantState = getPermissionGrantStateForUser(
+                                packageInfo.packageName, permission,
+                                new CallerIdentity(
+                                        mInjector.binderGetCallingUid(),
+                                        admin.info.getComponent().getPackageName(),
+                                        admin.info.getComponent()),
+                                userInfo.id);
+                    } catch (RemoteException e) {
+                        Slogf.e(LOG_TAG, e, "Error retrieving permission grant state for %s "
+                                        + "and %s", packageInfo.packageName, permission);
+                    }
+                    if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) {
+                        // Not Controlled by a policy
+                        continue;
+                    }
+
+                    mDevicePolicyEngine.setLocalPolicy(
+                            PolicyDefinition.PERMISSION_GRANT(packageInfo.packageName,
+                                    permission),
+                            EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                                    admin.info.getComponent(),
+                                    admin.getUserHandle().getIdentifier()),
+                            new IntegerPolicyValue(grantState),
+                            userInfo.id,
+                            /* skipEnforcePolicy= */ true);
+                }
+            }
+        }
+    }
+
+    private List<PackageInfo> getInstalledPackagesOnUser(int userId) {
+        return mInjector.binderWithCleanCallingIdentity(() ->
+                mContext.getPackageManager().getInstalledPackagesAsUser(
+                        PackageManager.PackageInfoFlags.of(
+                                PackageManager.GET_PERMISSIONS), userId));
+    }
+
+    /**
+     * Returns the most probable admin to have set a global policy according to the following
+     * heuristics:
+     *
+     * <ul>
+     * <li>The device owner on any user</li>
+     * <li>The org owned profile owner on any user</li>
+     * <li>The profile owner on any user</li>
+     * </ul>
+     */
+    @Nullable
+    // TODO(b/266928216): Check what the admin capabilities are when deciding which admin to return.
+    private ActiveAdmin getMostProbableDPCAdminForGlobalPolicy() {
+        synchronized (getLockObject()) {
+            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
+            if (deviceOwner != null) {
+                return deviceOwner;
+            }
+
+            List<UserInfo> users = mUserManager.getUsers();
+            for (UserInfo userInfo : users) {
+                if (isProfileOwnerOfOrganizationOwnedDevice(userInfo.id)) {
+                    return getProfileOwnerAdminLocked(userInfo.id);
+                }
+            }
+
+            for (UserInfo userInfo : users) {
+                ActiveAdmin profileOwner = getProfileOwnerLocked(userInfo.id);
+                if (profileOwner != null) {
+                    return profileOwner;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Returns the most probable admin to have set a policy on the given {@code userId} according
+     * to the following heuristics:
+     *
+     * <ul>
+     * <li>The device owner on the given userId</li>
+     * <li>The profile owner on the given userId</li>
+     * <li>The org owned profile owner of which the given userId is its parent</li>
+     * <li>The profile owner of which the given userId is its parent</li>
+     * <li>The device owner on any user</li>
+     * <li>The profile owner on any user</li>
+     * </ul>
+     */
+    @Nullable
+    // TODO(b/266928216): Check what the admin capabilities are when deciding which admin to return.
+    private ActiveAdmin getMostProbableDPCAdminForLocalPolicy(int userId) {
+        synchronized (getLockObject()) {
+            ActiveAdmin localDeviceOwner = getDeviceOwnerLocked(userId);
+            if (localDeviceOwner != null) {
+                return localDeviceOwner;
+            }
+
+            ActiveAdmin localProfileOwner = getProfileOwnerLocked(userId);
+            if (localProfileOwner != null) {
+                return localProfileOwner;
+            }
+
+            int[] profileIds = mUserManager.getProfileIds(userId, /* enabledOnly= */ false);
+            for (int id : profileIds) {
+                if (id == userId) {
+                    continue;
+                }
+                if (isProfileOwnerOfOrganizationOwnedDevice(id)) {
+                    return getProfileOwnerAdminLocked(id);
+                }
+            }
+
+            for (int id : profileIds) {
+                if (id == userId) {
+                    continue;
+                }
+                if (isManagedProfile(id)) {
+                    return getProfileOwnerAdminLocked(id);
+                }
+            }
+
+            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
+            if (deviceOwner != null) {
+                return deviceOwner;
+            }
+
+            for (UserInfo userInfo : mUserManager.getUsers()) {
+                ActiveAdmin profileOwner = getProfileOwnerLocked(userInfo.id);
+                if (profileOwner != null) {
+                    return profileOwner;
+                }
+            }
+            return null;
+        }
+    }
+
+    // We need to add a mapping of policyId to permission in POLICY_IDENTIFIER_TO_PERMISSION
+    // for each migrated permission.
+    private List<ActiveAdmin> getNonDPCActiveAdminsForPolicyLocked(String policyIdentifier) {
+        String permission = POLICY_IDENTIFIER_TO_PERMISSION.get(policyIdentifier);
+        if (permission == null) {
+            Slogf.e(LOG_TAG, "Can't find a permission for %s in POLICY_IDENTIFIER_TO_PERMISSION",
+                    policyIdentifier);
+            return new ArrayList<>();
+        }
+        if (!ACTIVE_ADMIN_POLICIES.containsKey(permission)) {
+            return new ArrayList<>();
+        }
+
+        List<ActiveAdmin> admins = new ArrayList<>();
+        for (UserInfo userInfo : mUserManager.getUsers()) {
+            List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
+            for (ComponentName admin : activeAdmins) {
+                if (isDeviceOwner(admin, userInfo.id) || isProfileOwner(admin, userInfo.id)) {
+                    continue;
+                }
+                DevicePolicyData policy = getUserDataUnchecked(userInfo.id);
+                if (isActiveAdminWithPolicyForUserLocked(
+                        policy.mAdminMap.get(admin), ACTIVE_ADMIN_POLICIES.get(permission),
+                        userInfo.id)) {
+                    admins.add(policy.mAdminMap.get(admin));
+                }
+            }
+        }
+        return admins;
+    }
+
+    // TODO: This can actually accept an EnforcingAdmin that gets created in the permission check
+    //  method.
+    private boolean useDevicePolicyEngine(CallerIdentity caller, @Nullable String delegateScope) {
+        if (!isCallerActiveAdminOrDelegate(caller, delegateScope)) {
+            if (!isDevicePolicyEngineFlagEnabled()) {
+                throw new IllegalStateException("Non DPC caller can't set device policies.");
+            }
+            if (hasDPCsNotSupportingCoexistence()) {
+                throw new IllegalStateException("Non DPC caller can't set device policies with "
+                        + "existing legacy admins on the device.");
+            }
+            return true;
+        } else {
+            return isDevicePolicyEngineFlagEnabled() && !hasDPCsNotSupportingCoexistence();
+        }
+    }
+
+    private boolean isDevicePolicyEngineFlagEnabled() {
+        return DeviceConfig.getBoolean(
+                NAMESPACE_DEVICE_POLICY_MANAGER,
+                ENABLE_DEVICE_POLICY_ENGINE_FLAG,
+                DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FLAG);
+    }
+
+    private boolean hasDPCsNotSupportingCoexistence() {
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            for (UserInfo userInfo : mUserManager.getUsers()) {
+                List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
+                if (activeAdmins == null) {
+                    continue;
+                }
+                for (ComponentName admin : activeAdmins) {
+                    if ((isProfileOwner(admin, userInfo.id) || isDeviceOwner(admin, userInfo.id))
+                            && !mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE,
+                            admin.getPackageName(), userInfo.id)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        });
+    }
+
+    // TODO: this can actually accept an EnforcingAdmin that gets created in the permission
+    //  check method.
+    private boolean isCallerActiveAdminOrDelegate(
+            CallerIdentity caller, @Nullable String delegateScope) {
+        return mInjector.binderWithCleanCallingIdentity(() -> {
+            List<ComponentName> activeAdmins = getActiveAdmins(caller.getUserId());
+            if (activeAdmins != null) {
+                for (ComponentName admin : activeAdmins) {
+                    if (admin.getPackageName().equals(caller.getPackageName())) {
+                        return true;
+                    }
+                }
+            }
+            return delegateScope != null && isCallerDelegate(caller, delegateScope);
+        });
+    }
+
+    // TODO(b/266808047): This will return false for DeviceAdmins not targetting U, which is
+    //  inconsistent with the migration logic that allows migration with old DeviceAdmins.
+    private boolean canAddActiveAdminIfPolicyEngineEnabled(String packageName, int userId) {
+        if (!isDevicePolicyEngineFlagEnabled()) {
+            return true;
+        }
+        if (hasDPCsNotSupportingCoexistence()) {
+            return true;
+        }
+        if (mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, packageName, userId)) {
+            // This will always return true unless we turn off coexistence, in which case it will
+            // return true if no current admins exist, or more than one admin exist
+            return mDevicePolicyEngine.canAdminAddPolicies(packageName, userId);
+        }
+        // Is it ok to just check that no active policies exist currently, or should we return false
+        // if the policy engine was ever used?
+        return !mDevicePolicyEngine.hasActivePolicies();
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
index da895f4..10e972d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
@@ -18,7 +18,13 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.Authority;
+import android.app.admin.UnknownAuthority;
+import android.app.admin.DeviceAdminAuthority;
+import android.app.admin.DpcAuthority;
+import android.app.admin.RoleAuthority;
 import android.content.ComponentName;
+import android.os.UserHandle;
 
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
@@ -63,6 +69,7 @@
     private Set<String> mAuthorities;
     private final int mUserId;
     private final boolean mIsRoleAuthority;
+    private final ActiveAdmin mActiveAdmin;
 
     static EnforcingAdmin createEnforcingAdmin(@NonNull String packageName, int userId) {
         Objects.requireNonNull(packageName);
@@ -73,14 +80,31 @@
             @NonNull ComponentName componentName, int userId) {
         Objects.requireNonNull(componentName);
         return new EnforcingAdmin(
-                componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY), userId);
+                componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY), userId,
+                /* activeAdmin=*/ null);
+    }
+
+    static EnforcingAdmin createEnterpriseEnforcingAdmin(
+            @NonNull ComponentName componentName, int userId, ActiveAdmin activeAdmin) {
+        Objects.requireNonNull(componentName);
+        return new EnforcingAdmin(
+                componentName.getPackageName(), componentName, Set.of(DPC_AUTHORITY), userId,
+                activeAdmin);
     }
 
     static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId) {
         Objects.requireNonNull(componentName);
         return new EnforcingAdmin(
                 componentName.getPackageName(), componentName, Set.of(DEVICE_ADMIN_AUTHORITY),
-                userId);
+                userId, /* activeAdmin=*/ null);
+    }
+
+    static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId,
+            ActiveAdmin activeAdmin) {
+        Objects.requireNonNull(componentName);
+        return new EnforcingAdmin(
+                componentName.getPackageName(), componentName, Set.of(DEVICE_ADMIN_AUTHORITY),
+                userId, activeAdmin);
     }
 
     static String getRoleAuthorityOf(String roleName) {
@@ -88,7 +112,8 @@
     }
 
     private EnforcingAdmin(
-            String packageName, ComponentName componentName, Set<String> authorities, int userId) {
+            String packageName, ComponentName componentName, Set<String> authorities, int userId,
+            ActiveAdmin activeAdmin) {
         Objects.requireNonNull(packageName);
         Objects.requireNonNull(componentName);
         Objects.requireNonNull(authorities);
@@ -99,6 +124,7 @@
         mComponentName = componentName;
         mAuthorities = new HashSet<>(authorities);
         mUserId = userId;
+        mActiveAdmin = activeAdmin;
     }
 
     private EnforcingAdmin(String packageName, int userId) {
@@ -111,6 +137,7 @@
         mComponentName = null;
         // authorities will be loaded when needed
         mAuthorities = null;
+        mActiveAdmin = null;
     }
 
     private static Set<String> getRoleAuthoritiesOrDefault(String packageName, int userId) {
@@ -156,6 +183,34 @@
         return mUserId;
     }
 
+    @Nullable
+    public ActiveAdmin getActiveAdmin() {
+        return mActiveAdmin;
+    }
+
+    @NonNull
+    android.app.admin.EnforcingAdmin getParcelableAdmin() {
+        Authority authority;
+        if (mIsRoleAuthority) {
+            Set<String> roles = getRoles(mPackageName, mUserId);
+            if (roles.isEmpty()) {
+                authority = UnknownAuthority.UNKNOWN_AUTHORITY;
+            } else {
+                authority = new RoleAuthority(roles);
+            }
+        } else if (mAuthorities.contains(DPC_AUTHORITY)) {
+            authority = DpcAuthority.DPC_AUTHORITY;
+        } else if (mAuthorities.contains(DEVICE_ADMIN_AUTHORITY)) {
+            authority = DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY;
+        } else {
+            authority = UnknownAuthority.UNKNOWN_AUTHORITY;
+        }
+        return new android.app.admin.EnforcingAdmin(
+                mPackageName,
+                authority,
+                UserHandle.of(mUserId));
+    }
+
     /**
      * For two EnforcingAdmins to be equal they must:
      *
@@ -224,7 +279,7 @@
             String className = parser.getAttributeValue(/* namespace= */ null, ATTR_CLASS_NAME);
             ComponentName componentName = new ComponentName(packageName, className);
             Set<String> authorities = Set.of(authoritiesStr.split(ATTR_AUTHORITIES_SEPARATOR));
-            return new EnforcingAdmin(packageName, componentName, authorities, userId);
+            return new EnforcingAdmin(packageName, componentName, authorities, userId, null);
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java b/services/devicepolicy/java/com/android/server/devicepolicy/FlagUnion.java
similarity index 64%
rename from services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java
rename to services/devicepolicy/java/com/android/server/devicepolicy/FlagUnion.java
index a051a2b..6c4be21 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/IntegerUnion.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/FlagUnion.java
@@ -17,24 +17,32 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.NonNull;
+import android.app.admin.IntegerPolicyValue;
+import android.app.admin.PolicyValue;
 
 import java.util.LinkedHashMap;
 import java.util.Objects;
 
-final class IntegerUnion extends ResolutionMechanism<Integer> {
+final class FlagUnion extends ResolutionMechanism<Integer> {
 
     @Override
-    Integer resolve(@NonNull LinkedHashMap<EnforcingAdmin, Integer> adminPolicies) {
+    IntegerPolicyValue resolve(
+            @NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<Integer>> adminPolicies) {
         Objects.requireNonNull(adminPolicies);
         if (adminPolicies.isEmpty()) {
             return null;
         }
 
         Integer unionOfPolicies = 0;
-        for (Integer policy : adminPolicies.values()) {
-            unionOfPolicies |= policy;
+        for (PolicyValue<Integer> policy : adminPolicies.values()) {
+            unionOfPolicies |= policy.getValue();
         }
-        return unionOfPolicies;
+        return new IntegerPolicyValue(unionOfPolicies);
+    }
+
+    @Override
+    android.app.admin.FlagUnion getParcelableResolutionMechanism() {
+        return android.app.admin.FlagUnion.FLAG_UNION;
     }
 
     @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java
index d5949dd..bff6d32 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/IntegerPolicySerializer.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.IntegerPolicyValue;
+import android.app.admin.PolicyKey;
 import android.util.Log;
 
 import com.android.modules.utils.TypedXmlPullParser;
@@ -31,17 +33,18 @@
 final class IntegerPolicySerializer extends PolicySerializer<Integer> {
 
     @Override
-    void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Integer value)
-            throws IOException {
+    void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer, String attributeName,
+            @NonNull Integer value) throws IOException {
         Objects.requireNonNull(value);
         serializer.attributeInt(/* namespace= */ null, attributeName, value);
     }
 
     @Nullable
     @Override
-    Integer readFromXml(TypedXmlPullParser parser, String attributeName) {
+    IntegerPolicyValue readFromXml(TypedXmlPullParser parser, String attributeName) {
         try {
-            return parser.getAttributeInt(/* namespace= */ null, attributeName);
+            return new IntegerPolicyValue(
+                    parser.getAttributeInt(/* namespace= */ null, attributeName));
         } catch (XmlPullParserException e) {
             Log.e(DevicePolicyEngine.TAG, "Error parsing Integer policy value", e);
             return null;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java
deleted file mode 100644
index d3e8de4..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicy.java
+++ /dev/null
@@ -1,139 +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.server.devicepolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.admin.DevicePolicyManager;
-import android.util.Log;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-final class LockTaskPolicy {
-    static final int DEFAULT_LOCK_TASK_FLAG = DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
-    private Set<String> mPackages = new HashSet<>();
-    private int mFlags = DEFAULT_LOCK_TASK_FLAG;
-
-    @NonNull
-    Set<String> getPackages() {
-        return mPackages;
-    }
-
-    int getFlags() {
-        return mFlags;
-    }
-
-    LockTaskPolicy(Set<String> packages) {
-        Objects.requireNonNull(packages);
-        mPackages.addAll(packages);
-    }
-
-    private LockTaskPolicy(Set<String> packages, int flags) {
-        Objects.requireNonNull(packages);
-        mPackages = new HashSet<>(packages);
-        mFlags = flags;
-    }
-
-    void setPackages(@NonNull Set<String> packages) {
-        Objects.requireNonNull(packages);
-        mPackages = new HashSet<>(packages);
-    }
-
-    void setFlags(int flags) {
-        mFlags = flags;
-    }
-
-    @Override
-    public LockTaskPolicy clone() {
-        LockTaskPolicy policy = new LockTaskPolicy(mPackages);
-        policy.setFlags(mFlags);
-        return policy;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        LockTaskPolicy other = (LockTaskPolicy) o;
-        return Objects.equals(mPackages, other.mPackages)
-                && mFlags == other.mFlags;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mPackages, mFlags);
-    }
-
-    @Override
-    public String toString() {
-        return "mPackages= " + String.join(", ", mPackages) + "; mFlags= " + mFlags;
-    }
-
-    static final class LockTaskPolicySerializer extends PolicySerializer<LockTaskPolicy> {
-
-        private static final String ATTR_PACKAGES = ":packages";
-        private static final String ATTR_PACKAGES_SEPARATOR = ";";
-        private static final String ATTR_FLAGS = ":flags";
-
-        @Override
-        void saveToXml(TypedXmlSerializer serializer, String attributeNamePrefix,
-                @NonNull LockTaskPolicy value) throws IOException {
-            Objects.requireNonNull(value);
-            if (value.mPackages == null || value.mPackages.isEmpty()) {
-                throw new IllegalArgumentException("Error saving LockTaskPolicy to file, lock task "
-                        + "packages must be present");
-            }
-            serializer.attribute(
-                    /* namespace= */ null,
-                    attributeNamePrefix + ATTR_PACKAGES,
-                    String.join(ATTR_PACKAGES_SEPARATOR, value.mPackages));
-            serializer.attributeInt(
-                    /* namespace= */ null,
-                    attributeNamePrefix + ATTR_FLAGS,
-                    value.mFlags);
-        }
-
-        @Override
-        LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
-            String packagesStr = parser.getAttributeValue(
-                    /* namespace= */ null,
-                    attributeNamePrefix + ATTR_PACKAGES);
-            if (packagesStr == null) {
-                Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value.");
-                return null;
-            }
-            Set<String> packages = Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
-            try {
-                int flags = parser.getAttributeInt(
-                        /* namespace= */ null,
-                        attributeNamePrefix + ATTR_FLAGS);
-                return new LockTaskPolicy(packages, flags);
-            } catch (XmlPullParserException e) {
-                Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value", e);
-                return null;
-            }
-        }
-    }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java
new file mode 100644
index 0000000..3265b61
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/LockTaskPolicySerializer.java
@@ -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.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.app.admin.LockTaskPolicy;
+import android.app.admin.PolicyKey;
+import android.util.Log;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Set;
+
+final class LockTaskPolicySerializer extends PolicySerializer<LockTaskPolicy> {
+
+    private static final String ATTR_PACKAGES = ":packages";
+    private static final String ATTR_PACKAGES_SEPARATOR = ";";
+    private static final String ATTR_FLAGS = ":flags";
+
+    @Override
+    void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer, String attributeNamePrefix,
+            @NonNull LockTaskPolicy value) throws IOException {
+        Objects.requireNonNull(value);
+        if (value.getPackages() == null || value.getPackages().isEmpty()) {
+            throw new IllegalArgumentException("Error saving LockTaskPolicy to file, lock task "
+                    + "packages must be present");
+        }
+        serializer.attribute(
+                /* namespace= */ null,
+                attributeNamePrefix + ATTR_PACKAGES,
+                String.join(ATTR_PACKAGES_SEPARATOR, value.getPackages()));
+        serializer.attributeInt(
+                /* namespace= */ null,
+                attributeNamePrefix + ATTR_FLAGS,
+                value.getFlags());
+    }
+
+    @Override
+    LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
+        String packagesStr = parser.getAttributeValue(
+                /* namespace= */ null,
+                attributeNamePrefix + ATTR_PACKAGES);
+        if (packagesStr == null) {
+            Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value.");
+            return null;
+        }
+        Set<String> packages = Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
+        try {
+            int flags = parser.getAttributeInt(
+                    /* namespace= */ null,
+                    attributeNamePrefix + ATTR_FLAGS);
+            return new LockTaskPolicy(packages, flags);
+        } catch (XmlPullParserException e) {
+            Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value", e);
+            return null;
+        }
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/MostRecent.java b/services/devicepolicy/java/com/android/server/devicepolicy/MostRecent.java
new file mode 100644
index 0000000..423a497
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/MostRecent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+
+import android.annotation.NonNull;
+import android.app.admin.PolicyValue;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+final class MostRecent<V> extends ResolutionMechanism<V> {
+
+    @Override
+    PolicyValue<V> resolve(@NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminPolicies) {
+        List<Map.Entry<EnforcingAdmin, PolicyValue<V>>> policiesList = new ArrayList<>(
+                adminPolicies.entrySet());
+        return policiesList.isEmpty() ? null : policiesList.get(policiesList.size() - 1).getValue();
+    }
+
+    @Override
+    android.app.admin.MostRecent<V> getParcelableResolutionMechanism() {
+        return new android.app.admin.MostRecent<V>();
+    }
+
+    @Override
+    public String toString() {
+        return "MostRecent {}";
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java b/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
index edb3d2e..7e8eaa7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/MostRestrictive.java
@@ -17,6 +17,7 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.NonNull;
+import android.app.admin.PolicyValue;
 
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -24,28 +25,34 @@
 
 final class MostRestrictive<V> extends ResolutionMechanism<V> {
 
-    private List<V> mMostToLeastRestrictive;
+    private List<PolicyValue<V>> mMostToLeastRestrictive;
 
-    MostRestrictive(@NonNull List<V> mostToLeastRestrictive) {
+    MostRestrictive(@NonNull List<PolicyValue<V>> mostToLeastRestrictive) {
         mMostToLeastRestrictive = mostToLeastRestrictive;
     }
 
     @Override
-    V resolve(@NonNull LinkedHashMap<EnforcingAdmin, V> adminPolicies) {
+    PolicyValue<V> resolve(@NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminPolicies) {
         if (adminPolicies.isEmpty()) {
             return null;
         }
-        for (V value : mMostToLeastRestrictive) {
+        for (PolicyValue<V> value : mMostToLeastRestrictive) {
             if (adminPolicies.containsValue(value)) {
                 return value;
             }
         }
         // Return first set policy if none can be found in known values
-        Map.Entry<EnforcingAdmin, V> policy = adminPolicies.entrySet().stream().findFirst().get();
+        Map.Entry<EnforcingAdmin, PolicyValue<V>> policy =
+                adminPolicies.entrySet().stream().findFirst().get();
         return policy.getValue();
     }
 
     @Override
+    android.app.admin.MostRestrictive<V> getParcelableResolutionMechanism() {
+        return new android.app.admin.MostRestrictive<V>(mMostToLeastRestrictive);
+    }
+
+    @Override
     public String toString() {
         return "MostRestrictive { mMostToLeastRestrictive= " + mMostToLeastRestrictive + " }";
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 581a199..3ca158d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -579,6 +579,19 @@
         }
     }
 
+    void markMigrationToPolicyEngine() {
+        synchronized (mData) {
+            mData.mMigratedToPolicyEngine = true;
+            mData.writeDeviceOwner();
+        }
+    }
+
+    boolean isMigratedToPolicyEngine() {
+        synchronized (mData) {
+            return mData.mMigratedToPolicyEngine;
+        }
+    }
+
     @GuardedBy("mData")
     void pushToAppOpsLocked() {
         if (!mSystemReady) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
index 3040af2..63b250d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -66,6 +66,7 @@
     private static final String TAG_DEVICE_OWNER_TYPE = "device-owner-type";
     private static final String TAG_DEVICE_OWNER_PROTECTED_PACKAGES =
             "device-owner-protected-packages";
+    private static final String TAG_POLICY_ENGINE_MIGRATION = "policy-engine-migration";
 
     private static final String ATTR_NAME = "name";
     private static final String ATTR_PACKAGE = "package";
@@ -84,6 +85,8 @@
             "isPoOrganizationOwnedDevice";
     private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value";
 
+    private static final String ATTR_MIGRATED_TO_POLICY_ENGINE = "migratedToPolicyEngine";
+
     // Internal state for the device owner package.
     OwnerInfo mDeviceOwner;
     int mDeviceOwnerUserId = UserHandle.USER_NULL;
@@ -109,6 +112,8 @@
     SystemUpdateInfo mSystemUpdateInfo;
     private final PolicyPathProvider mPathProvider;
 
+    boolean mMigratedToPolicyEngine = false;
+
     OwnersData(PolicyPathProvider pathProvider) {
         mPathProvider = pathProvider;
     }
@@ -389,6 +394,11 @@
                 }
                 out.endTag(null, TAG_FREEZE_PERIOD_RECORD);
             }
+
+            out.startTag(null, TAG_POLICY_ENGINE_MIGRATION);
+            out.attributeBoolean(null, ATTR_MIGRATED_TO_POLICY_ENGINE, mMigratedToPolicyEngine);
+            out.endTag(null, TAG_POLICY_ENGINE_MIGRATION);
+
         }
 
         @Override
@@ -444,6 +454,9 @@
                     }
                     mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
                     break;
+                case TAG_POLICY_ENGINE_MIGRATION:
+                    mMigratedToPolicyEngine = parser.getAttributeBoolean(
+                            null, ATTR_MIGRATED_TO_POLICY_ENGINE, false);
                 default:
                     Slog.e(TAG, "Unexpected tag: " + tag);
                     return false;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PackageSpecificPolicyKey.java b/services/devicepolicy/java/com/android/server/devicepolicy/PackageSpecificPolicyKey.java
deleted file mode 100644
index 1665830..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PackageSpecificPolicyKey.java
+++ /dev/null
@@ -1,101 +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.server.devicepolicy;
-
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PACKAGE_NAME;
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY;
-
-import android.annotation.Nullable;
-import android.os.Bundle;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * Class used to identify a policy that relates to a certain package in the policy engine's data
- * structure.
- */
-final class PackageSpecificPolicyKey extends PolicyKey {
-    private static final String ATTR_POLICY_KEY = "policy-key";
-    private static final String ATTR_PACKAGE_NAME = "package-name";
-    private static final String ATTR_PERMISSION_NAME = "permission-name";
-
-    private final String mPackageName;
-
-    PackageSpecificPolicyKey(String key, String packageName) {
-        super(key);
-        mPackageName = Objects.requireNonNull((packageName));
-    }
-
-    PackageSpecificPolicyKey(String key) {
-        super(key);
-        mPackageName = null;
-    }
-
-    @Nullable
-    String getPackageName() {
-        return mPackageName;
-    }
-
-    @Override
-    void saveToXml(TypedXmlSerializer serializer) throws IOException {
-        serializer.attribute(/* namespace= */ null, ATTR_POLICY_KEY, mKey);
-        serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName);
-    }
-
-    @Override
-    PackageSpecificPolicyKey readFromXml(TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_KEY);
-        String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME);
-        String permissionName = parser.getAttributeValue(
-                /* namespace= */ null, ATTR_PERMISSION_NAME);
-        return new PackageSpecificPolicyKey(policyKey, packageName);
-    }
-
-    @Override
-    void writeToBundle(Bundle bundle) {
-        super.writeToBundle(bundle);
-        Bundle extraPolicyParams = new Bundle();
-        extraPolicyParams.putString(EXTRA_PACKAGE_NAME, mPackageName);
-        bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        PackageSpecificPolicyKey other = (PackageSpecificPolicyKey) o;
-        return Objects.equals(mKey, other.mKey)
-                && Objects.equals(mPackageName, other.mPackageName);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mKey, mPackageName);
-    }
-
-    @Override
-    public String toString() {
-        return "mPolicyKey= " + mKey + "; mPackageName= " + mPackageName;
-    }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PermissionGrantStatePolicyKey.java b/services/devicepolicy/java/com/android/server/devicepolicy/PermissionGrantStatePolicyKey.java
deleted file mode 100644
index b7d805e..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PermissionGrantStatePolicyKey.java
+++ /dev/null
@@ -1,113 +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.server.devicepolicy;
-
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PACKAGE_NAME;
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_PERMISSION_NAME;
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY;
-
-import android.annotation.Nullable;
-import android.os.Bundle;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * Class used to identify a PermissionGrantState policy in the policy engine's data structure.
- */
-final class PermissionGrantStatePolicyKey extends PolicyKey {
-    private static final String ATTR_POLICY_KEY = "policy-key";
-    private static final String ATTR_PACKAGE_NAME = "package-name";
-    private static final String ATTR_PERMISSION_NAME = "permission-name";
-
-    private final String mPackageName;
-    private final String mPermissionName;
-
-    PermissionGrantStatePolicyKey(String key, String packageName, String permissionName) {
-        super(key);
-        mPackageName = Objects.requireNonNull((packageName));
-        mPermissionName = Objects.requireNonNull((permissionName));
-    }
-
-    PermissionGrantStatePolicyKey(String key) {
-        super(key);
-        mPackageName = null;
-        mPermissionName = null;
-    }
-
-    @Nullable
-    String getPackageName() {
-        return mPackageName;
-    }
-
-    @Nullable
-    String getPermissionName() {
-        return mPermissionName;
-    }
-
-    @Override
-    void saveToXml(TypedXmlSerializer serializer) throws IOException {
-        serializer.attribute(/* namespace= */ null, ATTR_POLICY_KEY, mKey);
-        serializer.attribute(/* namespace= */ null, ATTR_PACKAGE_NAME, mPackageName);
-        serializer.attribute(/* namespace= */ null, ATTR_PERMISSION_NAME, mPermissionName);
-    }
-
-    @Override
-    PermissionGrantStatePolicyKey readFromXml(TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_KEY);
-        String packageName = parser.getAttributeValue(/* namespace= */ null, ATTR_PACKAGE_NAME);
-        String permissionName = parser.getAttributeValue(
-                /* namespace= */ null, ATTR_PERMISSION_NAME);
-        return new PermissionGrantStatePolicyKey(policyKey, packageName, permissionName);
-    }
-
-    @Override
-    void writeToBundle(Bundle bundle) {
-        super.writeToBundle(bundle);
-        Bundle extraPolicyParams = new Bundle();
-        extraPolicyParams.putString(EXTRA_PACKAGE_NAME, mPackageName);
-        extraPolicyParams.putString(EXTRA_PERMISSION_NAME, mPermissionName);
-        bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        PermissionGrantStatePolicyKey other = (PermissionGrantStatePolicyKey) o;
-        return Objects.equals(mKey, other.mKey)
-                && Objects.equals(mPackageName, other.mPackageName)
-                && Objects.equals(mPermissionName, other.mPermissionName);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mKey, mPackageName, mPermissionName);
-    }
-
-    @Override
-    public String toString() {
-        return "mPolicyKey= " + mKey + "; mPackageName= " + mPackageName + "; mPermissionName= "
-                + mPermissionName;
-    }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PersistentPreferredActivityPolicyKey.java b/services/devicepolicy/java/com/android/server/devicepolicy/PersistentPreferredActivityPolicyKey.java
deleted file mode 100644
index f8c07595..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PersistentPreferredActivityPolicyKey.java
+++ /dev/null
@@ -1,99 +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.server.devicepolicy;
-
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_INTENT_FILTER;
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_BUNDLE_KEY;
-
-import android.annotation.Nullable;
-import android.content.IntentFilter;
-import android.os.Bundle;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-import com.android.server.IntentResolver;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * Class used to identify a PersistentPreferredActivity policy in the policy engine's data
- * structure.
- */
-final class PersistentPreferredActivityPolicyKey extends PolicyKey {
-    private static final String ATTR_POLICY_KEY = "policy-key";
-    private IntentFilter mFilter;
-
-    PersistentPreferredActivityPolicyKey(String policyKey, IntentFilter filter) {
-        super(policyKey);
-        mFilter = Objects.requireNonNull((filter));
-    }
-
-    PersistentPreferredActivityPolicyKey(String policyKey) {
-        super(policyKey);
-        mFilter = null;
-    }
-
-    @Nullable
-    IntentFilter getFilter() {
-        return mFilter;
-    }
-
-    @Override
-    void saveToXml(TypedXmlSerializer serializer) throws IOException {
-        serializer.attribute(/* namespace= */ null, ATTR_POLICY_KEY, mKey);
-        mFilter.writeToXml(serializer);
-    }
-
-    @Override
-    PersistentPreferredActivityPolicyKey readFromXml(TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        String policyKey = parser.getAttributeValue(/* namespace= */ null, ATTR_POLICY_KEY);
-        IntentFilter filter = new IntentFilter();
-        filter.readFromXml(parser);
-        return new PersistentPreferredActivityPolicyKey(policyKey, filter);
-    }
-
-    @Override
-    void writeToBundle(Bundle bundle) {
-        super.writeToBundle(bundle);
-        Bundle extraPolicyParams = new Bundle();
-        extraPolicyParams.putParcelable(EXTRA_INTENT_FILTER, mFilter);
-        bundle.putBundle(EXTRA_POLICY_BUNDLE_KEY, extraPolicyParams);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        PersistentPreferredActivityPolicyKey other = (PersistentPreferredActivityPolicyKey) o;
-        return Objects.equals(mKey, other.mKey)
-                && IntentResolver.filterEquals(mFilter, other.mFilter);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mKey, mFilter);
-    }
-
-    @Override
-    public String toString() {
-        return "mKey= " + mKey + "; mFilter= " + mFilter;
-    }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index ab1658f..ab6f732 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -18,10 +18,20 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.BooleanPolicyValue;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.IntegerPolicyValue;
+import android.app.admin.IntentFilterPolicyKey;
+import android.app.admin.LockTaskPolicy;
+import android.app.admin.NoArgsPolicyKey;
+import android.app.admin.PackagePermissionPolicyKey;
+import android.app.admin.PackagePolicyKey;
+import android.app.admin.PolicyKey;
+import android.app.admin.PolicyValue;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.os.Bundle;
 
 import com.android.internal.util.function.QuadFunction;
 import com.android.modules.utils.TypedXmlPullParser;
@@ -44,35 +54,50 @@
     // Only use this flag if a policy can not be applied globally.
     private static final int POLICY_FLAG_LOCAL_ONLY_POLICY = 1 << 1;
 
+    // Only use this flag if a policy is inheritable by child profile from parent.
+    private static final int POLICY_FLAG_INHERITABLE = 1 << 2;
+
+    // Use this flag if admin policies should be treated independently of each other and should not
+    // have any resolution logic applied, this should only be used for very limited policies were
+    // this would make sense and the enforcing logic should handle it appropriately, e.g.
+    // application restrictions set by different admins for a single package should not be merged,
+    // but saved and queried independent of each other.
+    // Currently, support is  added for local only policies, if you need to add a non coexistable
+    // global policy please add support.
+    private static final int POLICY_FLAG_NON_COEXISTABLE_POLICY = 1 << 3;
+
     private static final MostRestrictive<Boolean> FALSE_MORE_RESTRICTIVE = new MostRestrictive<>(
-            List.of(false, true));
+            List.of(new BooleanPolicyValue(false), new BooleanPolicyValue(true)));
 
     private static final MostRestrictive<Boolean> TRUE_MORE_RESTRICTIVE = new MostRestrictive<>(
-            List.of(true, false));
+            List.of(new BooleanPolicyValue(true), new BooleanPolicyValue(false)));
 
     static PolicyDefinition<Boolean> AUTO_TIMEZONE = new PolicyDefinition<>(
-            new DefaultPolicyKey(DevicePolicyManager.AUTO_TIMEZONE_POLICY),
-            // auto timezone is enabled by default, hence disabling it is more restrictive.
-            FALSE_MORE_RESTRICTIVE,
+            new NoArgsPolicyKey(DevicePolicyManager.AUTO_TIMEZONE_POLICY),
+            // auto timezone is disabled by default, hence enabling it is more restrictive.
+            TRUE_MORE_RESTRICTIVE,
             POLICY_FLAG_GLOBAL_ONLY_POLICY,
             (Boolean value, Context context, Integer userId, PolicyKey policyKey) ->
                     PolicyEnforcerCallbacks.setAutoTimezoneEnabled(value, context),
             new BooleanPolicySerializer());
 
     // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
-    // actual permission grant policy with the correct arguments (packageName and permission name)
+    // actual policy with the correct arguments (packageName and permission name)
     // when reading the policies from xml.
     static final PolicyDefinition<Integer> GENERIC_PERMISSION_GRANT =
             new PolicyDefinition<>(
-                    new PermissionGrantStatePolicyKey(
-                            DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY),
+                    new PackagePermissionPolicyKey(DevicePolicyManager.PERMISSION_GRANT_POLICY),
                     // TODO: is this really the best mechanism, what makes denied more
                     //  restrictive than
                     //  granted?
                     new MostRestrictive<>(
-                            List.of(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED,
-                                    DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
-                                    DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT)),
+                            List.of(
+                                    new IntegerPolicyValue(
+                                            DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED),
+                                    new IntegerPolicyValue(
+                                            DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED),
+                                    new IntegerPolicyValue(
+                                            DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT))),
                     POLICY_FLAG_LOCAL_ONLY_POLICY,
                     PolicyEnforcerCallbacks::setPermissionGrantState,
                     new IntegerPolicySerializer());
@@ -87,14 +112,14 @@
             return GENERIC_PERMISSION_GRANT;
         }
         return GENERIC_PERMISSION_GRANT.createPolicyDefinition(
-                new PermissionGrantStatePolicyKey(
-                        DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY,
+                new PackagePermissionPolicyKey(
+                        DevicePolicyManager.PERMISSION_GRANT_POLICY,
                         packageName,
                         permissionName));
     }
 
     static PolicyDefinition<LockTaskPolicy> LOCK_TASK = new PolicyDefinition<>(
-            new DefaultPolicyKey(DevicePolicyManager.LOCK_TASK_POLICY),
+            new NoArgsPolicyKey(DevicePolicyManager.LOCK_TASK_POLICY),
             new TopPriority<>(List.of(
                     // TODO(b/258166155): add correct device lock role name
                     EnforcingAdmin.getRoleAuthorityOf("DeviceLock"),
@@ -102,21 +127,22 @@
             POLICY_FLAG_LOCAL_ONLY_POLICY,
             (LockTaskPolicy value, Context context, Integer userId, PolicyKey policyKey) ->
                     PolicyEnforcerCallbacks.setLockTask(value, context, userId),
-            new LockTaskPolicy.LockTaskPolicySerializer());
+            new LockTaskPolicySerializer());
 
-    static PolicyDefinition<Set<String>> USER_CONTROLLED_DISABLED_PACKAGES = new PolicyDefinition<>(
-            new DefaultPolicyKey(DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY),
-            new SetUnion<>(),
-            (Set<String> value, Context context, Integer userId, PolicyKey policyKey) ->
-                    PolicyEnforcerCallbacks.setUserControlDisabledPackages(value, userId),
-            new SetPolicySerializer<>());
+    static PolicyDefinition<Set<String>> USER_CONTROLLED_DISABLED_PACKAGES =
+            new PolicyDefinition<>(
+                    new NoArgsPolicyKey(DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY),
+                    new StringSetUnion(),
+                    (Set<String> value, Context context, Integer userId, PolicyKey policyKey) ->
+                            PolicyEnforcerCallbacks.setUserControlDisabledPackages(value, userId),
+                    new StringSetPolicySerializer());
 
     // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
-    // actual permission grant policy with the correct arguments (packageName and permission name)
-    // when reading the policies from xml.
+    // actual policy with the correct arguments (i.e. packageName) when reading the policies from
+    // xml.
     static PolicyDefinition<ComponentName> GENERIC_PERSISTENT_PREFERRED_ACTIVITY =
             new PolicyDefinition<>(
-                    new PersistentPreferredActivityPolicyKey(
+                    new IntentFilterPolicyKey(
                             DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY),
             new TopPriority<>(List.of(
                     // TODO(b/258166155): add correct device lock role name
@@ -136,16 +162,16 @@
             return GENERIC_PERSISTENT_PREFERRED_ACTIVITY;
         }
         return GENERIC_PERSISTENT_PREFERRED_ACTIVITY.createPolicyDefinition(
-                new PersistentPreferredActivityPolicyKey(
+                new IntentFilterPolicyKey(
                         DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY, intentFilter));
     }
 
     // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
-    // actual uninstall blocked policy with the correct arguments (i.e. packageName)
-    // when reading the policies from xml.
+    // actual policy with the correct arguments (i.e. packageName) when reading the policies from
+    // xml.
     static PolicyDefinition<Boolean> GENERIC_PACKAGE_UNINSTALL_BLOCKED =
             new PolicyDefinition<>(
-                    new PackageSpecificPolicyKey(
+                    new PackagePolicyKey(
                             DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY),
                     TRUE_MORE_RESTRICTIVE,
                     POLICY_FLAG_LOCAL_ONLY_POLICY,
@@ -162,19 +188,49 @@
             return GENERIC_PACKAGE_UNINSTALL_BLOCKED;
         }
         return GENERIC_PACKAGE_UNINSTALL_BLOCKED.createPolicyDefinition(
-                new PackageSpecificPolicyKey(
+                new PackagePolicyKey(
                         DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, packageName));
     }
 
+    // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
+    // actual policy with the correct arguments (i.e. packageName) when reading the policies from
+    // xml.
+    static PolicyDefinition<Bundle> GENERIC_APPLICATION_RESTRICTIONS =
+            new PolicyDefinition<>(
+                    new PackagePolicyKey(
+                            DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY),
+                    new MostRecent<>(),
+                    POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_NON_COEXISTABLE_POLICY,
+                    // Application restrictions are now stored and retrieved from DPMS, so no
+                    // enforcing is required, however DPMS calls into UM to set restrictions for
+                    // backwards compatibility.
+                    (Bundle value, Context context, Integer userId, PolicyKey policyKey) -> true,
+                    new BundlePolicySerializer());
+
+    /**
+     * Passing in {@code null} for {@code packageName} will return
+     * {@link #GENERIC_APPLICATION_RESTRICTIONS}.
+     */
+    static PolicyDefinition<Bundle> APPLICATION_RESTRICTIONS(
+            String packageName) {
+        if (packageName == null) {
+            return GENERIC_APPLICATION_RESTRICTIONS;
+        }
+        return GENERIC_APPLICATION_RESTRICTIONS.createPolicyDefinition(
+                new PackagePolicyKey(
+                        DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY, packageName));
+    }
+
     private static final Map<String, PolicyDefinition<?>> sPolicyDefinitions = Map.of(
             DevicePolicyManager.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE,
-            DevicePolicyManager.PERMISSION_GRANT_POLICY_KEY, GENERIC_PERMISSION_GRANT,
+            DevicePolicyManager.PERMISSION_GRANT_POLICY, GENERIC_PERMISSION_GRANT,
             DevicePolicyManager.LOCK_TASK_POLICY, LOCK_TASK,
             DevicePolicyManager.USER_CONTROL_DISABLED_PACKAGES_POLICY,
             USER_CONTROLLED_DISABLED_PACKAGES,
             DevicePolicyManager.PERSISTENT_PREFERRED_ACTIVITY_POLICY,
             GENERIC_PERSISTENT_PREFERRED_ACTIVITY,
-            DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, GENERIC_PACKAGE_UNINSTALL_BLOCKED
+            DevicePolicyManager.PACKAGE_UNINSTALL_BLOCKED_POLICY, GENERIC_PACKAGE_UNINSTALL_BLOCKED,
+            DevicePolicyManager.APPLICATION_RESTRICTIONS_POLICY, GENERIC_APPLICATION_RESTRICTIONS
     );
 
 
@@ -196,6 +252,10 @@
         return mPolicyKey;
     }
 
+    @NonNull
+    ResolutionMechanism<V> getResolutionMechanism() {
+        return mResolutionMechanism;
+    }
     /**
      * Returns {@code true} if the policy is a global policy by nature and can't be applied locally.
      */
@@ -210,8 +270,23 @@
         return (mPolicyFlags & POLICY_FLAG_LOCAL_ONLY_POLICY) != 0;
     }
 
+    /**
+     * Returns {@code true} if the policy is inheritable by child profiles.
+     */
+    boolean isInheritable() {
+        return (mPolicyFlags & POLICY_FLAG_INHERITABLE) != 0;
+    }
+
+    /**
+     * Returns {@code true} if the policy engine should not try to resolve policies set by different
+     * admins and should just store it and pass it on to the enforcing logic.
+     */
+    boolean isNonCoexistablePolicy() {
+        return (mPolicyFlags & POLICY_FLAG_NON_COEXISTABLE_POLICY) != 0;
+    }
+
     @Nullable
-    V resolvePolicy(LinkedHashMap<EnforcingAdmin, V> adminsPolicy) {
+    PolicyValue<V> resolvePolicy(LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminsPolicy) {
         return mResolutionMechanism.resolve(adminsPolicy);
     }
 
@@ -247,6 +322,10 @@
         mPolicyEnforcerCallback = policyEnforcerCallback;
         mPolicySerializer = policySerializer;
 
+        if (isNonCoexistablePolicy() && !isLocalOnlyPolicy()) {
+            throw new UnsupportedOperationException("Non-coexistable global policies not supported,"
+                    + "please add support.");
+        }
         // TODO: maybe use this instead of manually adding to the map
 //        sPolicyDefinitions.put(policyDefinitionKey, this);
     }
@@ -261,26 +340,27 @@
         // TODO: can we avoid casting?
         PolicyKey policyKey = readPolicyKeyFromXml(parser);
         PolicyDefinition<V> genericPolicyDefinition =
-                (PolicyDefinition<V>) sPolicyDefinitions.get(policyKey.mKey);
+                (PolicyDefinition<V>) sPolicyDefinitions.get(policyKey.getIdentifier());
         return genericPolicyDefinition.createPolicyDefinition(policyKey);
     }
 
     static <V> PolicyKey readPolicyKeyFromXml(TypedXmlPullParser parser)
             throws XmlPullParserException, IOException {
         // TODO: can we avoid casting?
-        PolicyKey policyKey = DefaultPolicyKey.readGenericPolicyKeyFromXml(parser);
-        PolicyDefinition<V> genericPolicyDefinition =
-                (PolicyDefinition<V>) sPolicyDefinitions.get(policyKey.mKey);
+        PolicyKey policyKey = PolicyKey.readGenericPolicyKeyFromXml(parser);
+        PolicyDefinition<PolicyValue<V>> genericPolicyDefinition =
+                (PolicyDefinition<PolicyValue<V>>) sPolicyDefinitions.get(
+                        policyKey.getIdentifier());
         return genericPolicyDefinition.mPolicyKey.readFromXml(parser);
     }
 
     void savePolicyValueToXml(TypedXmlSerializer serializer, String attributeName, V value)
             throws IOException {
-        mPolicySerializer.saveToXml(serializer, attributeName, value);
+        mPolicySerializer.saveToXml(mPolicyKey, serializer, attributeName, value);
     }
 
     @Nullable
-    V readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName) {
+    PolicyValue<V> readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName) {
         return mPolicySerializer.readFromXml(parser, attributeName);
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index e2aa23d..4ae7ca6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -20,6 +20,11 @@
 import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.IntentFilterPolicyKey;
+import android.app.admin.LockTaskPolicy;
+import android.app.admin.PackagePermissionPolicyKey;
+import android.app.admin.PackagePolicyKey;
+import android.app.admin.PolicyKey;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentFilter;
@@ -64,11 +69,11 @@
             @Nullable Integer grantState, @NonNull Context context, int userId,
             @NonNull PolicyKey policyKey) {
         return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
-            if (!(policyKey instanceof PermissionGrantStatePolicyKey)) {
+            if (!(policyKey instanceof PackagePermissionPolicyKey)) {
                 throw new IllegalArgumentException("policyKey is not of type "
                         + "PermissionGrantStatePolicyKey");
             }
-            PermissionGrantStatePolicyKey parsedKey = (PermissionGrantStatePolicyKey) policyKey;
+            PackagePermissionPolicyKey parsedKey = (PackagePermissionPolicyKey) policyKey;
             Objects.requireNonNull(parsedKey.getPermissionName());
             Objects.requireNonNull(parsedKey.getPackageName());
             Objects.requireNonNull(context);
@@ -156,13 +161,13 @@
             @NonNull PolicyKey policyKey) {
         Binder.withCleanCallingIdentity(() -> {
             try {
-                if (!(policyKey instanceof PersistentPreferredActivityPolicyKey)) {
+                if (!(policyKey instanceof IntentFilterPolicyKey)) {
                     throw new IllegalArgumentException("policyKey is not of type "
-                            + "PersistentPreferredActivityPolicyKey");
+                            + "IntentFilterPolicyKey");
                 }
-                PersistentPreferredActivityPolicyKey parsedKey =
-                        (PersistentPreferredActivityPolicyKey) policyKey;
-                IntentFilter filter = Objects.requireNonNull(parsedKey.getFilter());
+                IntentFilterPolicyKey parsedKey =
+                        (IntentFilterPolicyKey) policyKey;
+                IntentFilter filter = Objects.requireNonNull(parsedKey.getIntentFilter());
 
                 IPackageManager packageManager = AppGlobals.getPackageManager();
                 if (preferredActivity != null) {
@@ -184,11 +189,11 @@
             @Nullable Boolean uninstallBlocked, @NonNull Context context, int userId,
             @NonNull PolicyKey policyKey) {
         return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
-            if (!(policyKey instanceof PackageSpecificPolicyKey)) {
+            if (!(policyKey instanceof PackagePolicyKey)) {
                 throw new IllegalArgumentException("policyKey is not of type "
-                        + "PackageSpecificPolicyKey");
+                        + "PackagePolicyKey");
             }
-            PackageSpecificPolicyKey parsedKey = (PackageSpecificPolicyKey) policyKey;
+            PackagePolicyKey parsedKey = (PackagePolicyKey) policyKey;
             String packageName = Objects.requireNonNull(parsedKey.getPackageName());
             DevicePolicyManagerService.setUninstallBlockedUnchecked(
                     packageName,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyKey.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyKey.java
deleted file mode 100644
index 571f0ee..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyKey.java
+++ /dev/null
@@ -1,81 +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.server.devicepolicy;
-
-import static android.app.admin.PolicyUpdatesReceiver.EXTRA_POLICY_KEY;
-
-import android.annotation.Nullable;
-import android.os.Bundle;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * Abstract class used to identify a policy in the policy engine's data structure.
- */
-abstract class PolicyKey {
-    private static final String ATTR_GENERIC_POLICY_KEY = "generic-policy-key";
-
-    protected final String mKey;
-
-    PolicyKey(String policyKey) {
-        mKey = Objects.requireNonNull(policyKey);
-    }
-
-    String getKey() {
-        return mKey;
-    }
-
-    boolean hasSameKeyAs(PolicyKey other) {
-        if (other == null) {
-            return false;
-        }
-        return mKey.equals(other.mKey);
-    }
-
-    void saveToXml(TypedXmlSerializer serializer) throws IOException {
-        serializer.attribute(/* namespace= */ null, ATTR_GENERIC_POLICY_KEY, mKey);
-    }
-
-    PolicyKey readFromXml(TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        // No need to read anything
-        return this;
-    }
-
-    void writeToBundle(Bundle bundle) {
-        bundle.putString(EXTRA_POLICY_KEY, mKey);
-    }
-
-    @Override
-    public boolean equals(@Nullable Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        PolicyKey other = (PolicyKey) o;
-        return Objects.equals(mKey, other.mKey);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mKey);
-    }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java
index 528d3b0..0ef431f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicySerializer.java
@@ -17,6 +17,8 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.NonNull;
+import android.app.admin.PolicyKey;
+import android.app.admin.PolicyValue;
 
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
@@ -24,7 +26,8 @@
 import java.io.IOException;
 
 abstract class PolicySerializer<V> {
-    abstract void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull V value)
+    abstract void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer,
+            String attributeName, @NonNull V value)
             throws IOException;
-    abstract V readFromXml(TypedXmlPullParser parser, String attributeName);
+    abstract PolicyValue<V> readFromXml(TypedXmlPullParser parser, String attributeName);
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
index db0a623..3a792d8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.admin.PolicyValue;
 import android.util.Log;
 
 import com.android.internal.util.XmlUtils;
@@ -40,8 +41,9 @@
     private static final String ATTR_RESOLVED_POLICY = "resolved-policy";
 
     private final PolicyDefinition<V> mPolicyDefinition;
-    private final LinkedHashMap<EnforcingAdmin, V> mPoliciesSetByAdmins = new LinkedHashMap<>();
-    private V mCurrentResolvedPolicy;
+    private final LinkedHashMap<EnforcingAdmin, PolicyValue<V>> mPoliciesSetByAdmins =
+            new LinkedHashMap<>();
+    private PolicyValue<V> mCurrentResolvedPolicy;
 
     PolicyState(@NonNull PolicyDefinition<V> policyDefinition) {
         mPolicyDefinition = Objects.requireNonNull(policyDefinition);
@@ -49,8 +51,8 @@
 
     private PolicyState(
             @NonNull PolicyDefinition<V> policyDefinition,
-            @NonNull LinkedHashMap<EnforcingAdmin, V> policiesSetByAdmins,
-            V currentEnforcedPolicy) {
+            @NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<V>> policiesSetByAdmins,
+            PolicyValue<V> currentEnforcedPolicy) {
         Objects.requireNonNull(policyDefinition);
         Objects.requireNonNull(policiesSetByAdmins);
 
@@ -62,8 +64,14 @@
     /**
      * Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
      */
-    boolean addPolicy(@NonNull EnforcingAdmin admin, @NonNull V policy) {
-        mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), Objects.requireNonNull(policy));
+    boolean addPolicy(@NonNull EnforcingAdmin admin, @NonNull PolicyValue<V> policy) {
+        Objects.requireNonNull(admin);
+        Objects.requireNonNull(policy);
+
+        //LinkedHashMap doesn't update the insertion order of existing keys, removing the existing
+        // key will cause it to update.
+        mPoliciesSetByAdmins.remove(admin);
+        mPoliciesSetByAdmins.put(admin, policy);
 
         return resolvePolicy();
     }
@@ -78,8 +86,8 @@
      * Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
      */
     boolean addPolicy(
-            @NonNull EnforcingAdmin admin, @NonNull V policy,
-            LinkedHashMap<EnforcingAdmin, V> globalPoliciesSetByAdmins) {
+            @NonNull EnforcingAdmin admin, @NonNull PolicyValue<V> policy,
+            LinkedHashMap<EnforcingAdmin, PolicyValue<V>> globalPoliciesSetByAdmins) {
         mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), Objects.requireNonNull(policy));
 
         return resolvePolicy(globalPoliciesSetByAdmins);
@@ -109,7 +117,7 @@
      */
     boolean removePolicy(
             @NonNull EnforcingAdmin admin,
-            LinkedHashMap<EnforcingAdmin, V> globalPoliciesSetByAdmins) {
+            LinkedHashMap<EnforcingAdmin, PolicyValue<V>> globalPoliciesSetByAdmins) {
         Objects.requireNonNull(admin);
 
         if (mPoliciesSetByAdmins.remove(admin) == null) {
@@ -128,13 +136,17 @@
      *
      * Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
      */
-    boolean resolvePolicy(LinkedHashMap<EnforcingAdmin, V> globalPoliciesSetByAdmins) {
+    boolean resolvePolicy(LinkedHashMap<EnforcingAdmin, PolicyValue<V>> globalPoliciesSetByAdmins) {
+        //Non coexistable policies don't need resolving
+        if (mPolicyDefinition.isNonCoexistablePolicy()) {
+            return false;
+        }
         // Add global policies first then override with local policies for the same admin.
-        LinkedHashMap<EnforcingAdmin, V> mergedPolicies =
+        LinkedHashMap<EnforcingAdmin, PolicyValue<V>> mergedPolicies =
                 new LinkedHashMap<>(globalPoliciesSetByAdmins);
         mergedPolicies.putAll(mPoliciesSetByAdmins);
 
-        V resolvedPolicy = mPolicyDefinition.resolvePolicy(mergedPolicies);
+        PolicyValue<V> resolvedPolicy = mPolicyDefinition.resolvePolicy(mergedPolicies);
         boolean policyChanged = !Objects.equals(resolvedPolicy, mCurrentResolvedPolicy);
         mCurrentResolvedPolicy = resolvedPolicy;
 
@@ -142,12 +154,16 @@
     }
 
     @NonNull
-    LinkedHashMap<EnforcingAdmin, V> getPoliciesSetByAdmins() {
+    LinkedHashMap<EnforcingAdmin, PolicyValue<V>> getPoliciesSetByAdmins() {
         return new LinkedHashMap<>(mPoliciesSetByAdmins);
     }
 
     private boolean resolvePolicy() {
-        V resolvedPolicy = mPolicyDefinition.resolvePolicy(mPoliciesSetByAdmins);
+        //Non coexistable policies don't need resolving
+        if (mPolicyDefinition.isNonCoexistablePolicy()) {
+            return false;
+        }
+        PolicyValue<V> resolvedPolicy = mPolicyDefinition.resolvePolicy(mPoliciesSetByAdmins);
         boolean policyChanged = !Objects.equals(resolvedPolicy, mCurrentResolvedPolicy);
         mCurrentResolvedPolicy = resolvedPolicy;
 
@@ -155,10 +171,20 @@
     }
 
     @Nullable
-    V getCurrentResolvedPolicy() {
+    PolicyValue<V> getCurrentResolvedPolicy() {
         return mCurrentResolvedPolicy;
     }
 
+    android.app.admin.PolicyState<V> getParcelablePolicyState() {
+        LinkedHashMap<android.app.admin.EnforcingAdmin, PolicyValue<V>> adminPolicies =
+                new LinkedHashMap<>();
+        for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
+            adminPolicies.put(admin.getParcelableAdmin(), mPoliciesSetByAdmins.get(admin));
+        }
+        return new android.app.admin.PolicyState<>(adminPolicies, mCurrentResolvedPolicy,
+                mPolicyDefinition.getResolutionMechanism().getParcelableResolutionMechanism());
+    }
+
     @Override
     public String toString() {
         return "PolicyState { mPolicyDefinition= " + mPolicyDefinition + ", mPoliciesSetByAdmins= "
@@ -171,14 +197,14 @@
 
         if (mCurrentResolvedPolicy != null) {
             mPolicyDefinition.savePolicyValueToXml(
-                    serializer, ATTR_RESOLVED_POLICY, mCurrentResolvedPolicy);
+                    serializer, ATTR_RESOLVED_POLICY, mCurrentResolvedPolicy.getValue());
         }
 
         for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
             serializer.startTag(/* namespace= */ null, TAG_ADMIN_POLICY_ENTRY);
 
             mPolicyDefinition.savePolicyValueToXml(
-                    serializer, ATTR_POLICY_VALUE, mPoliciesSetByAdmins.get(admin));
+                    serializer, ATTR_POLICY_VALUE, mPoliciesSetByAdmins.get(admin).getValue());
 
             serializer.startTag(/* namespace= */ null, TAG_ENFORCING_ADMIN_ENTRY);
             admin.saveToXml(serializer);
@@ -193,15 +219,15 @@
 
         PolicyDefinition<V> policyDefinition = PolicyDefinition.readFromXml(parser);
 
-        V currentResolvedPolicy = policyDefinition.readPolicyValueFromXml(
+        PolicyValue<V> currentResolvedPolicy = policyDefinition.readPolicyValueFromXml(
                 parser, ATTR_RESOLVED_POLICY);
 
-        LinkedHashMap<EnforcingAdmin, V> policiesSetByAdmins = new LinkedHashMap<>();
+        LinkedHashMap<EnforcingAdmin, PolicyValue<V>> policiesSetByAdmins = new LinkedHashMap<>();
         int outerDepth = parser.getDepth();
         while (XmlUtils.nextElementWithin(parser, outerDepth)) {
             String tag = parser.getName();
             if (TAG_ADMIN_POLICY_ENTRY.equals(tag)) {
-                V value = policyDefinition.readPolicyValueFromXml(
+                PolicyValue<V> value = policyDefinition.readPolicyValueFromXml(
                         parser, ATTR_POLICY_VALUE);
                 EnforcingAdmin admin;
                 int adminPolicyDepth = parser.getDepth();
@@ -216,4 +242,8 @@
         }
         return new PolicyState<V>(policyDefinition, policiesSetByAdmins, currentResolvedPolicy);
     }
+
+    PolicyDefinition<V> getPolicyDefinition() {
+        return mPolicyDefinition;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java b/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
index 7b720bc..c321aa1 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/ResolutionMechanism.java
@@ -17,10 +17,12 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.Nullable;
+import android.app.admin.PolicyValue;
 
 import java.util.LinkedHashMap;
 
 abstract class ResolutionMechanism<V> {
     @Nullable
-    abstract V resolve(LinkedHashMap<EnforcingAdmin, V> adminPolicies);
+    abstract PolicyValue<V> resolve(LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminPolicies);
+    abstract android.app.admin.ResolutionMechanism<V> getParcelableResolutionMechanism();
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SetPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/SetPolicySerializer.java
deleted file mode 100644
index 736627b..0000000
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SetPolicySerializer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.devicepolicy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import java.io.IOException;
-import java.util.Objects;
-import java.util.Set;
-
-// TODO(scottjonathan): Replace with actual implementation
-final class SetPolicySerializer<V> extends PolicySerializer<Set<V>> {
-
-    @Override
-    void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Set<V> value)
-            throws IOException {
-        Objects.requireNonNull(value);
-    }
-
-    @Nullable
-    @Override
-    Set<V> readFromXml(TypedXmlPullParser parser, String attributeName) {
-        return null;
-    }
-}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/StringSetPolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/StringSetPolicySerializer.java
new file mode 100644
index 0000000..dc6592d
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/StringSetPolicySerializer.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.PolicyKey;
+import android.app.admin.PolicyValue;
+import android.app.admin.StringSetPolicyValue;
+import android.util.Log;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Set;
+
+// TODO(scottjonathan): Replace with generic set implementation
+final class StringSetPolicySerializer extends PolicySerializer<Set<String>> {
+    private static final String ATTR_VALUES = ":strings";
+    private static final String ATTR_VALUES_SEPARATOR = ";";
+
+    @Override
+    void saveToXml(PolicyKey policyKey, TypedXmlSerializer serializer, String attributeNamePrefix,
+            @NonNull Set<String> value) throws IOException {
+        Objects.requireNonNull(value);
+        serializer.attribute(
+                /* namespace= */ null,
+                attributeNamePrefix + ATTR_VALUES,
+                String.join(ATTR_VALUES_SEPARATOR, value));
+    }
+
+    @Nullable
+    @Override
+    PolicyValue<Set<String>> readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
+        String valuesStr = parser.getAttributeValue(
+                /* namespace= */ null,
+                attributeNamePrefix + ATTR_VALUES);
+        if (valuesStr == null) {
+            Log.e(DevicePolicyEngine.TAG, "Error parsing StringSet policy value.");
+            return null;
+        }
+        Set<String> values = Set.of(valuesStr.split(ATTR_VALUES_SEPARATOR));
+        return new StringSetPolicyValue(values);
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java b/services/devicepolicy/java/com/android/server/devicepolicy/StringSetUnion.java
similarity index 60%
rename from services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java
rename to services/devicepolicy/java/com/android/server/devicepolicy/StringSetUnion.java
index cf26983..5298960 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SetUnion.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/StringSetUnion.java
@@ -17,28 +17,37 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.NonNull;
+import android.app.admin.PolicyValue;
+import android.app.admin.StringSetPolicyValue;
 
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Objects;
 import java.util.Set;
 
-final class SetUnion<V> extends ResolutionMechanism<Set<V>> {
+final class StringSetUnion extends ResolutionMechanism<Set<String>> {
 
     @Override
-    Set<V> resolve(@NonNull LinkedHashMap<EnforcingAdmin, Set<V>> adminPolicies) {
+    PolicyValue<Set<String>> resolve(
+            @NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<Set<String>>> adminPolicies) {
         Objects.requireNonNull(adminPolicies);
         if (adminPolicies.isEmpty()) {
             return null;
         }
-        Set<V> unionOfPolicies = new HashSet<>();
-        for (Set<V> policy : adminPolicies.values()) {
-            unionOfPolicies.addAll(policy);
+        Set<String> unionOfPolicies = new HashSet<>();
+        for (PolicyValue<Set<String>> policy : adminPolicies.values()) {
+            unionOfPolicies.addAll(policy.getValue());
         }
-        return unionOfPolicies;
+        return new StringSetPolicyValue(unionOfPolicies);
     }
 
     @Override
+    android.app.admin.StringSetUnion getParcelableResolutionMechanism() {
+        return new android.app.admin.StringSetUnion();
+    }
+
+
+    @Override
     public String toString() {
         return "SetUnion {}";
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java b/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java
index 571cf64..839840b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/TopPriority.java
@@ -17,6 +17,7 @@
 package com.android.server.devicepolicy;
 
 import android.annotation.NonNull;
+import android.app.admin.PolicyValue;
 
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -34,7 +35,7 @@
     }
 
     @Override
-    V resolve(@NonNull LinkedHashMap<EnforcingAdmin, V> adminPolicies) {
+    PolicyValue<V> resolve(@NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminPolicies) {
         if (adminPolicies.isEmpty()) {
             return null;
         }
@@ -46,11 +47,17 @@
             }
         }
         // Return first set policy if no known authority is found
-        Map.Entry<EnforcingAdmin, V> policy = adminPolicies.entrySet().stream().findFirst().get();
+        Map.Entry<EnforcingAdmin, PolicyValue<V>> policy =
+                adminPolicies.entrySet().stream().findFirst().get();
         return policy.getValue();
     }
 
     @Override
+    android.app.admin.TopPriority<V> getParcelableResolutionMechanism() {
+        return new android.app.admin.TopPriority<>(mHighestToLowestPriorityAuthorities);
+    }
+
+    @Override
     public String toString() {
         return "TopPriority { mHighestToLowestPriorityAuthorities= "
                 + mHighestToLowestPriorityAuthorities + " }";
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 9c9b363..81a5472 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -419,6 +419,17 @@
     return nowUs - monoTsUs;
 }
 
+static const char* loadingStateToString(incfs::LoadingState state) {
+    switch (state) {
+        case (incfs::LoadingState::Full):
+            return "Full";
+        case (incfs::LoadingState::MissingBlocks):
+            return "MissingBlocks";
+        default:
+            return "error obtaining loading state";
+    }
+}
+
 void IncrementalService::onDump(int fd) {
     dprintf(fd, "Incremental is %s\n", incfs::enabled() ? "ENABLED" : "DISABLED");
     dprintf(fd, "IncFs features: 0x%x\n", int(mIncFs->features()));
@@ -453,9 +464,13 @@
             }
             dprintf(fd, "    storages (%d): {\n", int(mnt.storages.size()));
             for (auto&& [storageId, storage] : mnt.storages) {
-                dprintf(fd, "      [%d] -> [%s] (%d %% loaded) \n", storageId, storage.name.c_str(),
+                auto&& ifs = getIfsLocked(storageId);
+                dprintf(fd, "      [%d] -> [%s] (%d %% loaded)(%s) \n", storageId,
+                        storage.name.c_str(),
                         (int)(getLoadingProgressFromPath(mnt, storage.name.c_str()).getProgress() *
-                              100));
+                              100),
+                        ifs ? loadingStateToString(mIncFs->isEverythingFullyLoaded(ifs->control))
+                            : "error obtaining ifs");
             }
             dprintf(fd, "    }\n");
 
@@ -2816,6 +2831,12 @@
 
 binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mountId, int newStatus) {
     if (!isValid()) {
+        if (newStatus == IDataLoaderStatusListener::DATA_LOADER_BOUND) {
+            // Async "bound" came to already destroyed stub.
+            // Unbind immediately to avoid invalid stub sitting around in DataLoaderManagerService.
+            mService.mDataLoaderManager->unbindFromDataLoader(mountId);
+            return binder::Status::ok();
+        }
         return binder::Status::
                 fromServiceSpecificError(-EINVAL, "onStatusChange came to invalid DataLoaderStub");
     }
diff --git a/services/java/com/android/server/BootUserInitializer.java b/services/java/com/android/server/BootUserInitializer.java
deleted file mode 100644
index 3d71739..0000000
--- a/services/java/com/android/server/BootUserInitializer.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server;
-
-import android.annotation.UserIdInt;
-import android.content.ContentResolver;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-
-import com.android.server.am.ActivityManagerService;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.utils.Slogf;
-import com.android.server.utils.TimingsTraceAndSlog;
-
-/**
- * Class responsible for booting the device in the proper user on headless system user mode.
- *
- */
-// TODO(b/204091126): STOPSHIP - provide proper APIs
-final class BootUserInitializer {
-
-    private static final String TAG = BootUserInitializer.class.getSimpleName();
-
-     // TODO(b/204091126): STOPSHIP - set to false or dynamic value
-    private static final boolean DEBUG = true;
-
-    private final ActivityManagerService mAms;
-    private final ContentResolver mContentResolver;
-
-    BootUserInitializer(ActivityManagerService am, ContentResolver contentResolver) {
-        mAms = am;
-        mContentResolver = contentResolver;
-    }
-
-    public void init(TimingsTraceAndSlog t) {
-        Slogf.i(TAG, "init())");
-
-        // TODO(b/204091126): in the long term, we need to decide who's reponsible for that,
-        // this class or the setup wizard app
-        provisionHeadlessSystemUser();
-
-        unlockSystemUser(t);
-
-        try {
-            t.traceBegin("getBootUser");
-            int bootUser = LocalServices.getService(UserManagerInternal.class).getBootUser();
-            t.traceEnd();
-            t.traceBegin("switchToBootUser-" + bootUser);
-            switchToBootUser(bootUser);
-            t.traceEnd();
-        } catch (UserManager.CheckedUserOperationException e) {
-            Slogf.wtf(TAG, "Failed to created boot user", e);
-        }
-    }
-
-    /* TODO(b/261791491): STOPSHIP - SUW should be responsible for this. */
-    private void provisionHeadlessSystemUser() {
-        if (isDeviceProvisioned()) {
-            Slogf.d(TAG, "provisionHeadlessSystemUser(): already provisioned");
-            return;
-        }
-
-        Slogf.i(TAG, "Marking USER_SETUP_COMPLETE for system user");
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.USER_SETUP_COMPLETE, 1);
-        Slogf.i(TAG, "Marking DEVICE_PROVISIONED for system user");
-        Settings.Global.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1);
-    }
-
-    private boolean isDeviceProvisioned() {
-        try {
-            return Settings.Global.getInt(mContentResolver,
-                    Settings.Global.DEVICE_PROVISIONED) == 1;
-        } catch (Exception e) {
-            Slogf.wtf(TAG, "DEVICE_PROVISIONED setting not found.", e);
-            return false;
-        }
-    }
-
-    // NOTE: Mostly copied from Automotive's InitialUserSetter
-    private void unlockSystemUser(TimingsTraceAndSlog t) {
-        Slogf.i(TAG, "Unlocking system user");
-        t.traceBegin("unlock-system-user");
-        try {
-            // This is for force changing state into RUNNING_LOCKED. Otherwise unlock does not
-            // update the state and USER_SYSTEM unlock happens twice.
-            t.traceBegin("am.startUser");
-            boolean started = mAms.startUserInBackgroundWithListener(UserHandle.USER_SYSTEM,
-                            /* listener= */ null);
-            t.traceEnd();
-            if (!started) {
-                Slogf.w(TAG, "could not restart system user in background; trying unlock instead");
-                t.traceBegin("am.unlockUser");
-                boolean unlocked = mAms.unlockUser(UserHandle.USER_SYSTEM, /* token= */ null,
-                        /* secret= */ null, /* listener= */ null);
-                t.traceEnd();
-                if (!unlocked) {
-                    Slogf.w(TAG, "could not unlock system user either");
-                    return;
-                }
-            }
-        } finally {
-            t.traceEnd();
-        }
-    }
-
-    private void switchToBootUser(@UserIdInt int bootUserId) {
-        Slogf.i(TAG, "Switching to boot user %d", bootUserId);
-        boolean started = mAms.startUserInForegroundWithListener(bootUserId,
-                /* unlockListener= */ null);
-        if (!started) {
-            Slogf.wtf(TAG, "Failed to start user %d in foreground", bootUserId);
-        }
-    }
-}
diff --git a/services/java/com/android/server/HsumBootUserInitializer.java b/services/java/com/android/server/HsumBootUserInitializer.java
new file mode 100644
index 0000000..a1853b4
--- /dev/null
+++ b/services/java/com/android/server/HsumBootUserInitializer.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server;
+
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import com.android.server.am.ActivityManagerService;
+import com.android.server.pm.UserManagerInternal;
+import com.android.server.utils.Slogf;
+import com.android.server.utils.TimingsTraceAndSlog;
+
+/**
+ * Class responsible for booting the device in the proper user on headless system user mode.
+ *
+ */
+final class HsumBootUserInitializer {
+
+    private static final String TAG = HsumBootUserInitializer.class.getSimpleName();
+
+    private final UserManagerInternal mUmi;
+    private final ActivityManagerService mAms;
+    private final ContentResolver mContentResolver;
+
+    private final ContentObserver mDeviceProvisionedObserver =
+            new ContentObserver(new Handler(Looper.getMainLooper())) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    // Set USER_SETUP_COMPLETE for the (headless) system user only when the device
+                    // has been set up at least once.
+                    if (isDeviceProvisioned()) {
+                        Slogf.i(TAG, "Marking USER_SETUP_COMPLETE for system user");
+                        Settings.Secure.putInt(mContentResolver,
+                                Settings.Secure.USER_SETUP_COMPLETE, 1);
+                        mContentResolver.unregisterContentObserver(mDeviceProvisionedObserver);
+                    }
+                }
+            };
+
+    /** Whether this device should always have a non-removable MainUser, including at first boot. */
+    private final boolean mShouldAlwaysHaveMainUser;
+
+    /** Static factory method for creating a {@link HsumBootUserInitializer} instance. */
+    public static @Nullable HsumBootUserInitializer createInstance(ActivityManagerService am,
+            ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser) {
+
+        if (!UserManager.isHeadlessSystemUserMode()) {
+            return null;
+        }
+        return new HsumBootUserInitializer(
+                LocalServices.getService(UserManagerInternal.class),
+                am, contentResolver, shouldAlwaysHaveMainUser);
+    }
+
+    private HsumBootUserInitializer(UserManagerInternal umi, ActivityManagerService am,
+            ContentResolver contentResolver, boolean shouldAlwaysHaveMainUser) {
+        mUmi = umi;
+        mAms = am;
+        mContentResolver = contentResolver;
+        mShouldAlwaysHaveMainUser = shouldAlwaysHaveMainUser;
+    }
+
+    /**
+     * Initialize this object, and create MainUser if needed.
+     *
+     * <p>Should be called before PHASE_SYSTEM_SERVICES_READY as services' setups may require
+     * MainUser, but probably after PHASE_LOCK_SETTINGS_READY since that may be needed for user
+     * creation.
+     */
+    public void init(TimingsTraceAndSlog t) {
+        Slogf.i(TAG, "init())");
+
+        if (mShouldAlwaysHaveMainUser) {
+            t.traceBegin("createMainUserIfNeeded");
+            createMainUserIfNeeded();
+            t.traceEnd();
+        }
+    }
+
+    private void createMainUserIfNeeded() {
+        final int mainUser = mUmi.getMainUserId();
+        if (mainUser != UserHandle.USER_NULL) {
+            Slogf.d(TAG, "Found existing MainUser, userId=%d", mainUser);
+            return;
+        }
+
+        Slogf.d(TAG, "Creating a new MainUser");
+        try {
+            final UserInfo newInitialUser = mUmi.createUserEvenWhenDisallowed(
+                    /* name= */ null, // null will appear as "Owner" in on-demand localisation
+                    UserManager.USER_TYPE_FULL_SECONDARY,
+                    UserInfo.FLAG_ADMIN | UserInfo.FLAG_MAIN,
+                    /* disallowedPackages= */ null,
+                    /* token= */ null);
+            if (newInitialUser == null) {
+                Slogf.wtf(TAG, "Initial bootable MainUser creation failed: returned null");
+            } else {
+                Slogf.i(TAG, "Successfully created MainUser, userId=%d", newInitialUser.id);
+            }
+        } catch (UserManager.CheckedUserOperationException e) {
+            Slogf.wtf(TAG, "Initial bootable MainUser creation failed", e);
+        }
+    }
+
+    /**
+     * Put the device into the correct user state: unlock the system and switch to the boot user.
+     *
+     * <p>Should only call once PHASE_THIRD_PARTY_APPS_CAN_START is reached to ensure that
+     * privileged apps have had the chance to set the boot user, if applicable.
+     */
+    public void systemRunning(TimingsTraceAndSlog t) {
+        observeDeviceProvisioning();
+        unlockSystemUser(t);
+
+        try {
+            t.traceBegin("getBootUser");
+            final int bootUser = mUmi.getBootUser();
+            t.traceEnd();
+            t.traceBegin("switchToBootUser-" + bootUser);
+            switchToBootUser(bootUser);
+            t.traceEnd();
+        } catch (UserManager.CheckedUserOperationException e) {
+            Slogf.wtf(TAG, "Failed to switch to boot user since there isn't one.");
+        }
+    }
+
+    private void observeDeviceProvisioning() {
+        if (isDeviceProvisioned()) {
+            return;
+        }
+
+        mContentResolver.registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+                false,
+                mDeviceProvisionedObserver
+        );
+    }
+
+    private boolean isDeviceProvisioned() {
+        try {
+            return Settings.Global.getInt(mContentResolver,
+                    Settings.Global.DEVICE_PROVISIONED) == 1;
+        } catch (Exception e) {
+            Slogf.wtf(TAG, "DEVICE_PROVISIONED setting not found.", e);
+            return false;
+        }
+    }
+
+    // NOTE: Mostly copied from Automotive's InitialUserSetter
+    // TODO(b/266158156): Refactor how starting/unlocking works for the System.
+    private void unlockSystemUser(TimingsTraceAndSlog t) {
+        Slogf.i(TAG, "Unlocking system user");
+        t.traceBegin("unlock-system-user");
+        try {
+            // This is for force changing state into RUNNING_LOCKED. Otherwise unlock does not
+            // update the state and USER_SYSTEM unlock happens twice.
+            t.traceBegin("am.startUser");
+            final boolean started = mAms.startUserInBackgroundWithListener(UserHandle.USER_SYSTEM,
+                            /* listener= */ null);
+            t.traceEnd();
+            if (!started) {
+                Slogf.w(TAG, "could not restart system user in background; trying unlock instead");
+                t.traceBegin("am.unlockUser");
+                final boolean unlocked = mAms.unlockUser(UserHandle.USER_SYSTEM, /* token= */ null,
+                        /* secret= */ null, /* listener= */ null);
+                t.traceEnd();
+                if (!unlocked) {
+                    Slogf.w(TAG, "could not unlock system user either");
+                }
+            }
+        } finally {
+            t.traceEnd();
+        }
+    }
+
+    private void switchToBootUser(@UserIdInt int bootUserId) {
+        Slogf.i(TAG, "Switching to boot user %d", bootUserId);
+        final boolean started = mAms.startUserInForegroundWithListener(bootUserId,
+                /* unlockListener= */ null);
+        if (!started) {
+            Slogf.wtf(TAG, "Failed to start user %d in foreground", bootUserId);
+        }
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a15c6d2..b117cae 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -38,6 +38,7 @@
 import android.app.SystemServiceRegistry;
 import android.app.admin.DevicePolicySafetyChecker;
 import android.app.usage.UsageStatsManagerInternal;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -75,7 +76,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
@@ -142,6 +142,7 @@
 import com.android.server.lights.LightsService;
 import com.android.server.locales.LocaleManagerService;
 import com.android.server.location.LocationManagerService;
+import com.android.server.location.altitude.AltitudeService;
 import com.android.server.logcat.LogcatManagerService;
 import com.android.server.media.MediaRouterService;
 import com.android.server.media.metrics.MediaMetricsManagerService;
@@ -427,6 +428,9 @@
             "com.android.server.sdksandbox.SdkSandboxManagerService$Lifecycle";
     private static final String AD_SERVICES_MANAGER_SERVICE_CLASS =
             "com.android.server.adservices.AdServicesManagerService$Lifecycle";
+    private static final String ON_DEVICE_PERSONALIZATION_SYSTEM_SERVICE_CLASS =
+            "com.android.server.ondevicepersonalization."
+                    + "OnDevicePersonalizationSystemService$Lifecycle";
     private static final String UPDATABLE_DEVICE_CONFIG_SERVICE_CLASS =
             "com.android.server.deviceconfig.DeviceConfigInit$Lifecycle";
 
@@ -1789,6 +1793,10 @@
         }
         t.traceEnd();
 
+        t.traceBegin("ArtManagerLocal");
+        DexOptHelper.initializeArtManagerLocal(context, mPackageManagerService);
+        t.traceEnd();
+
         t.traceBegin("UpdatePackagesIfNeeded");
         try {
             Watchdog.getInstance().pauseWatchingCurrentThread("dexopt");
@@ -2116,6 +2124,14 @@
             }
             t.traceEnd();
 
+            t.traceBegin("StartAltitudeService");
+            try {
+                mSystemServiceManager.startService(AltitudeService.Lifecycle.class);
+            } catch (Throwable e) {
+                reportWtf("starting AltitudeService service", e);
+            }
+            t.traceEnd();
+
             t.traceBegin("StartLocationTimeZoneManagerService");
             try {
                 mSystemServiceManager.startService(LOCATION_TIME_ZONE_MANAGER_SERVICE_CLASS);
@@ -2619,6 +2635,11 @@
         mSystemServiceManager.startService(AD_SERVICES_MANAGER_SERVICE_CLASS);
         t.traceEnd();
 
+        // OnDevicePersonalizationSystemService
+        t.traceBegin("StartOnDevicePersonalizationSystemService");
+        mSystemServiceManager.startService(ON_DEVICE_PERSONALIZATION_SYSTEM_SERVICE_CLASS);
+        t.traceEnd();
+
         if (safeMode) {
             mActivityManagerService.enterSafeMode();
         }
@@ -2694,6 +2715,18 @@
         mSystemServiceManager.startBootPhase(t, SystemService.PHASE_LOCK_SETTINGS_READY);
         t.traceEnd();
 
+        // Create initial user if needed, which should be done early since some system services rely
+        // on it in their setup, but likely needs to be done after LockSettingsService is ready.
+        final HsumBootUserInitializer hsumBootUserInitializer =
+                HsumBootUserInitializer.createInstance(
+                        mActivityManagerService, mContentResolver,
+                        context.getResources().getBoolean(R.bool.config_isMainUserPermanentAdmin));
+        if (hsumBootUserInitializer != null) {
+            t.traceBegin("HsumBootUserInitializer.init");
+            hsumBootUserInitializer.init(t);
+            t.traceEnd();
+        }
+
         t.traceBegin("StartBootPhaseSystemServicesReady");
         mSystemServiceManager.startBootPhase(t, SystemService.PHASE_SYSTEM_SERVICES_READY);
         t.traceEnd();
@@ -2737,10 +2770,6 @@
         mSystemServiceManager.startService(PermissionPolicyService.class);
         t.traceEnd();
 
-        t.traceBegin("ArtManagerLocal");
-        DexOptHelper.initializeArtManagerLocal(context, mPackageManagerService);
-        t.traceEnd();
-
         t.traceBegin("MakePackageManagerServiceReady");
         mPackageManagerService.systemReady();
         t.traceEnd();
@@ -2883,6 +2912,27 @@
                 t.traceEnd();
             }
 
+            if (isWatch) {
+                t.traceBegin("StartWearService");
+                String wearServiceComponentNameString =
+                    context.getString(R.string.config_wearServiceComponent);
+
+                if (!TextUtils.isEmpty(wearServiceComponentNameString)) {
+                    ComponentName wearServiceComponentName = ComponentName.unflattenFromString(
+                        wearServiceComponentNameString);
+
+                    if (wearServiceComponentName != null) {
+                        Intent intent = new Intent();
+                        intent.setComponent(wearServiceComponentName);
+                        intent.addFlags(Intent.FLAG_DIRECT_BOOT_AUTO);
+                        context.startServiceAsUser(intent, UserHandle.SYSTEM);
+                    } else {
+                        Slog.d(TAG, "Null wear service component name.");
+                    }
+                }
+                t.traceEnd();
+            }
+
             // Enable airplane mode in safe mode. setAirplaneMode() cannot be called
             // earlier as it sends broadcasts to other services.
             // TODO: This may actually be too late if radio firmware already started leaking
@@ -2961,10 +3011,10 @@
             mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
             t.traceEnd();
 
-            if (UserManager.isHeadlessSystemUserMode() && !isAutomotive) {
-                // TODO(b/204091126): remove isAutomotive check once the workflow is finalized
-                t.traceBegin("BootUserInitializer");
-                new BootUserInitializer(mActivityManagerService, mContentResolver).init(t);
+            if (hsumBootUserInitializer != null && !isAutomotive) {
+                // TODO(b/261924826): remove isAutomotive check once the workflow is finalized
+                t.traceBegin("HsumBootUserInitializer.systemRunning");
+                hsumBootUserInitializer.systemRunning(t);
                 t.traceEnd();
             }
 
diff --git a/services/manifest_services.xml b/services/manifest_services.xml
new file mode 100644
index 0000000..7638915
--- /dev/null
+++ b/services/manifest_services.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="framework">
+    <hal format="aidl">
+        <name>android.frameworks.location.altitude</name>
+        <version>1</version>
+        <fqname>IAltitudeService/default</fqname>
+    </hal>
+</manifest>
diff --git a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
index f2cff62..af85eba 100644
--- a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
+++ b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
@@ -27,6 +27,7 @@
 import android.os.UserHandle
 import android.util.SparseBooleanArray
 import android.util.SparseIntArray
+import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.util.ArrayUtils
 import com.android.internal.util.function.pooled.PooledLambda
 import com.android.server.appop.AppOpsCheckingServiceInterface
@@ -67,10 +68,32 @@
         }
     }
 
+    @VisibleForTesting
+    override fun writeState() {
+        // TODO Not yet implemented
+    }
+
+    override fun readState() {
+        // TODO Not yet implemented
+    }
+
+    @VisibleForTesting
+    override fun shutdown() {
+        // TODO Not yet implemented
+    }
+
+    override fun systemReady() {
+        // TODO Not yet implemented
+    }
+
     override fun getNonDefaultUidModes(uid: Int): SparseIntArray {
         return opNameMapToOpIntMap(getUidModes(uid))
     }
 
+    override fun getNonDefaultPackageModes(packageName: String, userId: Int): SparseIntArray {
+        return opNameMapToOpIntMap(getPackageModes(packageName, userId))
+    }
+
     override fun getUidMode(uid: Int, op: Int): Int {
         val appId = UserHandle.getAppId(uid)
         val userId = UserHandle.getUserId(uid)
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index c7e9371..61f8681 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -21,6 +21,7 @@
 import android.compat.annotation.ChangeId
 import android.compat.annotation.EnabledAfter
 import android.content.Context
+import android.content.pm.PackageInstaller
 import android.content.pm.PackageManager
 import android.content.pm.PackageManagerInternal
 import android.content.pm.PermissionGroupInfo
@@ -735,7 +736,7 @@
     private fun grantRequestedRuntimePermissions(
         packageState: PackageState,
         userId: Int,
-        permissionNames: List<String>
+        permissionNames: IndexedList<String>
     ) {
         service.mutateState {
             permissionNames.forEachIndexed { _, permissionName ->
@@ -1813,7 +1814,15 @@
             val packageState =
                 packageManagerInternal.getPackageStateInternal(androidPackage.packageName)!!
             // TODO: Add allowlisting
-            grantRequestedRuntimePermissions(packageState, userId, params.grantedPermissions)
+            grantRequestedRuntimePermissions(
+                packageState,
+                userId,
+                params.permissionStates.mapNotNullIndexed { _, permissionName, permissionState ->
+                    permissionName.takeIf {
+                        permissionState == PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED
+                    }
+                }
+            )
         }
     }
 
@@ -2023,6 +2032,8 @@
      */
     private inner class OnPermissionFlagsChangedListener :
         UidPermissionPolicy.OnPermissionFlagsChangedListener() {
+        private var isPermissionFlagsChanged = false
+
         private val runtimePermissionChangedUids = IntSet()
         // Mapping from UID to whether only notifications permissions are revoked.
         private val runtimePermissionRevokedUids = IntBooleanMap()
@@ -2046,6 +2057,8 @@
             oldFlags: Int,
             newFlags: Int
         ) {
+            isPermissionFlagsChanged = true
+
             val uid = UserHandle.getUid(userId, appId)
             val permission = service.getState {
                 with(policy) { getPermissions()[permissionName] }
@@ -2072,6 +2085,11 @@
         }
 
         override fun onStateMutated() {
+            if (isPermissionFlagsChanged) {
+                PackageManager.invalidatePackageInfoCache()
+                isPermissionFlagsChanged = false
+            }
+
             runtimePermissionChangedUids.forEachIndexed { _, uid ->
                 onPermissionsChangeListeners.onPermissionsChanged(uid)
             }
diff --git a/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
index a9884dd..59551a3 100644
--- a/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/UidPermissionPolicy.kt
@@ -196,7 +196,9 @@
 
         val changedPermissionNames = IndexedSet<String>()
         trimPermissions(packageName, changedPermissionNames)
-        trimPermissionStates(appId)
+        if (appId in newState.systemState.appIds) {
+            trimPermissionStates(appId)
+        }
         changedPermissionNames.forEachIndexed { _, permissionName ->
             evaluatePermissionStateForAllPackages(permissionName, null)
         }
@@ -782,6 +784,7 @@
                     }
                 }
             } else {
+                val wasGrantedByLegacy = newFlags.hasBits(PermissionFlags.LEGACY_GRANTED)
                 newFlags = newFlags andInv PermissionFlags.LEGACY_GRANTED
                 val wasGrantedByImplicit = newFlags.hasBits(PermissionFlags.IMPLICIT_GRANTED)
                 val isLeanbackNotificationsPermission = newState.systemState.isLeanback &&
@@ -805,10 +808,16 @@
                 } else {
                     newFlags = newFlags andInv PermissionFlags.IMPLICIT_GRANTED
                 }
+                if ((wasGrantedByLegacy || wasGrantedByImplicit) && !shouldGrantByImplicit) {
+                    // The permission was granted from a compatibility grant or an implicit grant,
+                    // however this flag might still be set if the user denied this permission in
+                    // the settings. Hence upon app upgrade and when this permission is no longer
+                    // LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke the permission, we want to
+                    // remove this flag so that the app can request the permission again.
+                    newFlags = newFlags andInv PermissionFlags.APP_OP_REVOKED
+                }
                 val hasImplicitFlag = newFlags.hasBits(PermissionFlags.IMPLICIT)
                 if (!isImplicitPermission && hasImplicitFlag) {
-                    // TODO: We might not want to remove the IMPLICIT flag
-                    // for NOTIFICATION_PERMISSIONS
                     newFlags = newFlags andInv PermissionFlags.IMPLICIT
                     var shouldRetainAsNearbyDevices = false
                     if (permissionName in NEARBY_DEVICES_PERMISSIONS) {
@@ -994,12 +1003,7 @@
         permissionName: String
     ): Boolean? {
         val permissionAllowlist = newState.systemState.permissionAllowlist
-        // TODO(b/261913353): STOPSHIP: Add AndroidPackage.apexModuleName.
-        // val apexModuleName = androidPackage.apexModuleName
-        val apexModuleName = permissionAllowlist.apexPrivilegedAppAllowlists
-            .firstNotNullOfOrNullIndexed { _, apexModuleName, apexAllowlist ->
-                if (packageState.packageName in apexAllowlist) apexModuleName else null
-            }
+        val apexModuleName = packageState.apexModuleName
         val packageName = packageState.packageName
         return when {
             packageState.isVendor -> permissionAllowlist.getVendorPrivilegedAppAllowlistState(
@@ -1066,7 +1070,7 @@
         state: AccessState = newState,
         action: (PackageState) -> Unit
     ) {
-        val packageNames = state.systemState.appIds[appId]
+        val packageNames = state.systemState.appIds[appId]!!
         packageNames.forEachIndexed { _, packageName ->
             val packageState = state.systemState.packageStates[packageName]!!
             if (packageState.androidPackage != null) {
@@ -1190,9 +1194,7 @@
             // Special permission for the recents app.
             return true
         }
-        // TODO(b/261913353): STOPSHIP: Add AndroidPackage.apexModuleName.
-        // This should be androidPackage.apexModuleName instead
-        if (permission.isModule && androidPackage.packageName != null) {
+        if (permission.isModule && packageState.apexModuleName != null) {
             // Special permission granted for APKs inside APEX modules.
             return true
         }
@@ -1397,11 +1399,11 @@
             Manifest.permission.READ_MEDIA_VIDEO,
         )
 
-        // TODO: also add the permission NEARBY_WIFI_DEVICES to this set
         private val NEARBY_DEVICES_PERMISSIONS = indexedSetOf(
             Manifest.permission.BLUETOOTH_ADVERTISE,
             Manifest.permission.BLUETOOTH_CONNECT,
-            Manifest.permission.BLUETOOTH_SCAN
+            Manifest.permission.BLUETOOTH_SCAN,
+            Manifest.permission.NEARBY_WIFI_DEVICES
         )
 
         private val NOTIFICATIONS_PERMISSIONS = indexedSetOf(
diff --git a/services/proguard.flags b/services/proguard.flags
index ba4560f..c133044 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -103,7 +103,7 @@
 -keep,allowoptimization,allowaccessmodification class com.android.server.storage.AppFuseBridge { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.tv.TvInputHal { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbAlsaJackDetector { *; }
--keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbMidiDevice { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbAlsaMidiDevice { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorController$OnVibrationCompleteListener { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorManagerService$OnSyncedVibrationCompleteListener { *; }
 -keepclasseswithmembers,allowoptimization,allowaccessmodification class com.android.server.** {
diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index 1abcf38..bfbc0f5 100644
--- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -267,7 +267,7 @@
         LocalServices.removeServiceForTest(PackageManagerInternal.class);
         LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
         mBackupEligibilityRules = new BackupEligibilityRules(mPackageManager,
-                LocalServices.getService(PackageManagerInternal.class), USER_ID,
+                LocalServices.getService(PackageManagerInternal.class), USER_ID, mContext,
                 BACKUP_DESTINATION);
     }
 
diff --git a/services/searchui/java/com/android/server/searchui/SearchUiManagerService.java b/services/searchui/java/com/android/server/searchui/SearchUiManagerService.java
index 524002a..29ad537 100644
--- a/services/searchui/java/com/android/server/searchui/SearchUiManagerService.java
+++ b/services/searchui/java/com/android/server/searchui/SearchUiManagerService.java
@@ -125,6 +125,26 @@
                     (service) -> service.queryLocked(sessionId, query, callback));
         }
 
+        public void registerEmptyQueryResultUpdateCallback(@NonNull SearchSessionId sessionId,
+                @NonNull ISearchCallback callback) {
+            runForUserLocked("registerEmptyQueryResultUpdateCallback", sessionId,
+                    (service) -> service.registerEmptyQueryResultUpdateCallbackLocked(sessionId,
+                            callback));
+        }
+
+        public void unregisterEmptyQueryResultUpdateCallback(@NonNull SearchSessionId sessionId,
+                @NonNull ISearchCallback callback) {
+            runForUserLocked("unregisterEmptyQueryResultUpdateCallback", sessionId,
+                    (service) -> service.unregisterEmptyQueryResultUpdateCallbackLocked(sessionId,
+                            callback));
+        }
+
+        @Override
+        public void requestEmptyQueryResultUpdate(@NonNull SearchSessionId sessionId) {
+            runForUserLocked("requestEmptyQueryResultUpdate", sessionId,
+                    (service) -> service.requestEmptyQueryResultUpdateLocked(sessionId));
+        }
+
         @Override
         public void destroySearchSession(@NonNull SearchSessionId sessionId) {
             runForUserLocked("destroySearchSession", sessionId,
diff --git a/services/searchui/java/com/android/server/searchui/SearchUiPerUserService.java b/services/searchui/java/com/android/server/searchui/SearchUiPerUserService.java
index 4c31978..0d70fff 100644
--- a/services/searchui/java/com/android/server/searchui/SearchUiPerUserService.java
+++ b/services/searchui/java/com/android/server/searchui/SearchUiPerUserService.java
@@ -149,6 +149,48 @@
     }
 
     /**
+     * Registers a callback for continuous updates of search targets for empty query result used for
+     * zero state.
+     */
+    @GuardedBy("mLock")
+    public void registerEmptyQueryResultUpdateCallbackLocked(@NonNull SearchSessionId sessionId,
+            @NonNull ISearchCallback callback) {
+        final SearchSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+        if (sessionInfo == null) return;
+        final boolean serviceExists = resolveService(sessionId,
+                s -> s.onRegisterEmptyQueryResultUpdateCallback(sessionId, callback));
+        if (serviceExists) {
+            sessionInfo.addCallbackLocked(callback);
+        }
+    }
+
+    /**
+     * Unregisters a callback for continuous updates of search targets for empty query result
+     * used for zero state.
+     */
+    @GuardedBy("mLock")
+    public void unregisterEmptyQueryResultUpdateCallbackLocked(@NonNull SearchSessionId sessionId,
+            @NonNull ISearchCallback callback) {
+        final SearchSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+        if (sessionInfo == null) return;
+        final boolean serviceExists = resolveService(sessionId,
+                s -> s.onUnregisterEmptyQueryResultUpdateCallback(sessionId, callback));
+        if (serviceExists) {
+            sessionInfo.removeCallbackLocked(callback);
+        }
+    }
+
+    /**
+     * Requests a new set of search targets for empty query result used for zero state.
+     */
+    @GuardedBy("mLock")
+    public void requestEmptyQueryResultUpdateLocked(@NonNull SearchSessionId sessionId) {
+        final SearchSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+        if (sessionInfo == null) return;
+        resolveService(sessionId, s->s.onRequestEmptyQueryResultUpdate(sessionId));
+    }
+
+    /**
      * Notifies the service of the end of an existing search session.
      */
     @GuardedBy("mLock")
@@ -310,18 +352,7 @@
         final IBinder.DeathRecipient mDeathRecipient;
 
         private final RemoteCallbackList<ISearchCallback> mCallbacks =
-                new RemoteCallbackList<ISearchCallback>() {
-                    @Override
-                    public void onCallbackDied(ISearchCallback callback) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Binder died for session Id=" + mSessionId
-                                    + " and callback=" + callback.asBinder());
-                        }
-                        if (mCallbacks.getRegisteredCallbackCount() == 0) {
-                            destroy();
-                        }
-                    }
-                };
+                new RemoteCallbackList<>();
 
         SearchSessionInfo(
                 @NonNull final SearchSessionId id,
@@ -337,6 +368,22 @@
             mDeathRecipient = deathRecipient;
         }
 
+        void addCallbackLocked(ISearchCallback callback) {
+            if (DEBUG) {
+                Slog.d(TAG, "Storing callback for session Id=" + mSessionId
+                        + " and callback=" + callback.asBinder());
+            }
+            mCallbacks.register(callback);
+        }
+
+        void removeCallbackLocked(ISearchCallback callback) {
+            if (DEBUG) {
+                Slog.d(TAG, "Removing callback for session Id=" + mSessionId
+                        + " and callback=" + callback.asBinder());
+            }
+            mCallbacks.unregister(callback);
+        }
+
         boolean linkToDeath() {
             try {
                 mToken.linkToDeath(mDeathRecipient, 0);
@@ -369,6 +416,9 @@
                         + callbackCount + " callbacks.");
             }
             service.onCreateSearchSessionLocked(mSearchContext, mSessionId, token);
+            mCallbacks.broadcast(
+                    callback -> service.registerEmptyQueryResultUpdateCallbackLocked(mSessionId,
+                            callback));
         }
     }
 }
diff --git a/services/tests/BackgroundInstallControlServiceTests/OWNERS b/services/tests/BackgroundInstallControlServiceTests/OWNERS
new file mode 100644
index 0000000..ca84550
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/transparency/OWNERS
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/Android.bp b/services/tests/BackgroundInstallControlServiceTests/host/Android.bp
new file mode 100644
index 0000000..4fcdbfc
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_test_host {
+    name: "BackgroundInstallControlServiceHostTest",
+    srcs: ["src/**/*.java"],
+    libs: [
+        "tradefed",
+        "compatibility-tradefed",
+        "compatibility-host-util",
+    ],
+    data: [
+        ":BackgroundInstallControlServiceTestApp",
+        ":BackgroundInstallControlMockApp1",
+        ":BackgroundInstallControlMockApp2",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+}
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/AndroidTest.xml b/services/tests/BackgroundInstallControlServiceTests/host/AndroidTest.xml
new file mode 100644
index 0000000..1e7a78a
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/AndroidTest.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.
+-->
+<configuration description="Background Install Control Service integration test">
+    <option name="test-suite-tag" value="apct" />
+
+    <!-- Service is not exposed to apps. Disable SELinux for testing purpose. -->
+    <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="install-arg" value="-t" />
+        <option name="test-file-name" value="BackgroundInstallControlServiceTestApp.apk" />
+    </target_preparer>
+
+    <!-- Load additional APKs onto device -->
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file"
+                key="BackgroundInstallControlMockApp1.apk"
+                value="/data/local/tmp/BackgroundInstallControlMockApp1.apk" />
+        <option name="push-file"
+                key="BackgroundInstallControlMockApp2.apk"
+                value="/data/local/tmp/BackgroundInstallControlMockApp2.apk" />
+    </target_preparer>
+
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="BackgroundInstallControlServiceHostTest.jar" />
+    </test>
+</configuration>
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/src/com/android/server/pm/test/BackgroundInstallControlServiceHostTest.java b/services/tests/BackgroundInstallControlServiceTests/host/src/com/android/server/pm/test/BackgroundInstallControlServiceHostTest.java
new file mode 100644
index 0000000..7450607
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/src/com/android/server/pm/test/BackgroundInstallControlServiceHostTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+// TODO: Add @Presubmit
+@RunWith(DeviceJUnit4ClassRunner.class)
+public final class BackgroundInstallControlServiceHostTest extends BaseHostJUnit4Test {
+    private static final String PACKAGE_NAME = "com.android.server.pm.test.app";
+
+    private static final String MOCK_PACKAGE_NAME_1 = "com.android.servicestests.apps.bicmockapp1";
+    private static final String MOCK_PACKAGE_NAME_2 = "com.android.servicestests.apps.bicmockapp2";
+
+    private static final String TEST_DATA_DIR = "/data/local/tmp/";
+
+    private static final String MOCK_APK_FILE_1 = "BackgroundInstallControlMockApp1.apk";
+    private static final String MOCK_APK_FILE_2 = "BackgroundInstallControlMockApp2.apk";
+
+    @Test
+    public void testGetMockBackgroundInstalledPackages() throws Exception {
+        installPackage(TEST_DATA_DIR  + MOCK_APK_FILE_1);
+        installPackage(TEST_DATA_DIR + MOCK_APK_FILE_2);
+
+        assertThat(getDevice().getAppPackageInfo(MOCK_PACKAGE_NAME_1)).isNotNull();
+        assertThat(getDevice().getAppPackageInfo(MOCK_PACKAGE_NAME_2)).isNotNull();
+
+        assertThat(getDevice().setProperty("debug.transparency.bg-install-apps",
+                    MOCK_PACKAGE_NAME_1 + "," + MOCK_PACKAGE_NAME_2)).isTrue();
+        runDeviceTest("testGetMockBackgroundInstalledPackages");
+        assertThat(getDevice().uninstallPackage(MOCK_PACKAGE_NAME_1)).isNull();
+        assertThat(getDevice().uninstallPackage(MOCK_PACKAGE_NAME_2)).isNull();
+
+        assertThat(getDevice().getAppPackageInfo(MOCK_PACKAGE_NAME_1)).isNull();
+        assertThat(getDevice().getAppPackageInfo(MOCK_PACKAGE_NAME_2)).isNull();
+    }
+
+    private void installPackage(String path) throws DeviceNotAvailableException {
+        String cmd = "pm install -t --force-queryable " + path;
+        CommandResult result = getDevice().executeShellV2Command(cmd);
+        assertThat(result.getStatus() == CommandStatus.SUCCESS).isTrue();
+    }
+
+    private void runDeviceTest(String method) throws DeviceNotAvailableException {
+        var options = new DeviceTestRunOptions(PACKAGE_NAME);
+        options.setTestClassName(PACKAGE_NAME + ".BackgroundInstallControlServiceTest");
+        options.setTestMethodName(method);
+        runDeviceTests(options);
+    }
+}
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/Android.bp b/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/Android.bp
new file mode 100644
index 0000000..9b39f2d
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test_helper_app {
+    name: "BackgroundInstallControlServiceTestApp",
+    manifest: "AndroidManifest.xml",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.core",
+        "compatibility-device-util-axt",
+        "junit",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+    platform_apis: true,
+    dex_preopt: {
+        enabled: false,
+    },
+}
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/AndroidManifest.xml b/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..1fa1f84
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/AndroidManifest.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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.server.pm.test.app">
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:label="APCT tests for background install control service"
+        android:targetPackage="com.android.server.pm.test.app" />
+</manifest>
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/src/com/android/server/pm/test/app/BackgroundInstallControlServiceTest.java b/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/src/com/android/server/pm/test/app/BackgroundInstallControlServiceTest.java
new file mode 100644
index 0000000..b74e561
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/test-app/BackgroundInstallControlServiceTestApp/src/com/android/server/pm/test/app/BackgroundInstallControlServiceTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.test.app;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.pm.IBackgroundInstallControlService;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@RunWith(AndroidJUnit4.class)
+public class BackgroundInstallControlServiceTest {
+    private static final String TAG = "BackgroundInstallControlServiceTest";
+
+    private IBackgroundInstallControlService mIBics;
+
+    @Before
+    public void setUp() {
+        mIBics = IBackgroundInstallControlService.Stub.asInterface(
+                ServiceManager.getService(Context.BACKGROUND_INSTALL_CONTROL_SERVICE));
+        assertThat(mIBics).isNotNull();
+    }
+
+    @Test
+    public void testGetMockBackgroundInstalledPackages() throws RemoteException {
+        ParceledListSlice<PackageInfo> slice = mIBics.getBackgroundInstalledPackages(
+                    PackageManager.MATCH_ALL,
+                    UserHandle.USER_ALL);
+        assertThat(slice).isNotNull();
+
+        var packageList = slice.getList();
+        assertThat(packageList).isNotNull();
+        assertThat(packageList).hasSize(2);
+
+        var expectedPackageNames = Set.of("com.android.servicestests.apps.bicmockapp1",
+                "com.android.servicestests.apps.bicmockapp2");
+        var actualPackageNames = packageList.stream().map((packageInfo) -> packageInfo.packageName)
+                .collect(Collectors.toSet());
+        assertThat(actualPackageNames).containsExactlyElementsIn(expectedPackageNames);
+    }
+}
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/Android.bp b/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/Android.bp
new file mode 100644
index 0000000..7804f4c
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_defaults {
+    name: "bic-mock-app-defaults",
+    test_suites: ["device-tests"],
+
+    srcs: ["**/*.java"],
+
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+}
+
+android_test_helper_app {
+    name: "BackgroundInstallControlMockApp1",
+    defaults: ["bic-mock-app-defaults"],
+    aaptflags: [
+        "--rename-manifest-package com.android.servicestests.apps.bicmockapp1",
+    ],
+}
+
+android_test_helper_app {
+    name: "BackgroundInstallControlMockApp2",
+    defaults: ["bic-mock-app-defaults"],
+    aaptflags: [
+        "--rename-manifest-package com.android.servicestests.apps.bicmockapp2",
+    ],
+}
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/AndroidManifest.xml b/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/AndroidManifest.xml
new file mode 100644
index 0000000..3cb39db
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.servicestests.apps.bicmockapp">
+
+    <application android:hasCode="false">
+    </application>
+</manifest>
diff --git a/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/res/values/strings.xml b/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/res/values/strings.xml
new file mode 100644
index 0000000..984152f
--- /dev/null
+++ b/services/tests/BackgroundInstallControlServiceTests/host/test-app/MockApp/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this placeholder file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="placeholder">placeholder</string>
+</resources>
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java
deleted file mode 100644
index 98655c8..0000000
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.pm;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.when;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.platform.test.annotations.Presubmit;
-import android.util.AtomicFile;
-import android.util.Slog;
-import android.util.Xml;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.os.BackgroundThread;
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import libcore.io.IoUtils;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@Presubmit
-public class PackageInstallerSessionTest {
-    @Rule
-    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
-    private File mTmpDir;
-    private AtomicFile mSessionsFile;
-    private static final String TAG_SESSIONS = "sessions";
-
-    @Mock
-    PackageManagerService mMockPackageManagerInternal;
-
-    @Mock
-    Computer mSnapshot;
-
-    @Before
-    public void setUp() throws Exception {
-        mTmpDir = mTemporaryFolder.newFolder("PackageInstallerSessionTest");
-        mSessionsFile = new AtomicFile(
-                new File(mTmpDir.getAbsolutePath() + "/sessions.xml"), "package-session");
-        MockitoAnnotations.initMocks(this);
-        when(mSnapshot.getPackageUid(anyString(), anyLong(), anyInt())).thenReturn(0);
-        when(mMockPackageManagerInternal.snapshotComputer()).thenReturn(mSnapshot);
-    }
-
-    @Test
-    public void testWriteAndRestoreSessionXmlSimpleSession() {
-        PackageInstallerSession session = createSimpleSession();
-        dumpSession(session);
-        List<PackageInstallerSession> restored = restoreSessions();
-        assertEquals(1, restored.size());
-        assertSessionsEquivalent(session, restored.get(0));
-    }
-
-    @Test
-    public void testWriteAndRestoreSessionXmlStagedSession() {
-        PackageInstallerSession session = createStagedSession();
-        dumpSession(session);
-        List<PackageInstallerSession> restored = restoreSessions();
-        assertEquals(1, restored.size());
-        assertSessionsEquivalent(session, restored.get(0));
-    }
-
-    @Test
-    public void testWriteAndRestoreSessionXmlGrantedPermission() {
-        PackageInstallerSession session = createSessionWithGrantedPermissions();
-        dumpSession(session);
-        List<PackageInstallerSession> restored = restoreSessions();
-        assertEquals(1, restored.size());
-        assertSessionsEquivalent(session, restored.get(0));
-    }
-
-    @Test
-    public void testWriteAndRestoreSessionXmlMultiPackageSessions() {
-        PackageInstallerSession session = createMultiPackageParentSession(123, new int[]{234, 345});
-        PackageInstallerSession childSession1 = createMultiPackageChildSession(234, 123);
-        PackageInstallerSession childSession2 = createMultiPackageChildSession(345, 123);
-        List<PackageInstallerSession> sessionGroup =
-                Arrays.asList(session, childSession1, childSession2);
-        dumpSessions(sessionGroup);
-        List<PackageInstallerSession> restored = restoreSessions();
-        assertEquals(3, restored.size());
-        assertSessionsEquivalent(sessionGroup, restored);
-    }
-
-    private PackageInstallerSession createSimpleSession() {
-        return createSession(false, false, 123, false, PackageInstaller.SessionInfo.INVALID_ID,
-                null);
-    }
-
-    private PackageInstallerSession createStagedSession() {
-        return createSession(true, false, 123, false, PackageInstaller.SessionInfo.INVALID_ID,
-                null);
-    }
-
-    private PackageInstallerSession createSessionWithGrantedPermissions() {
-        return createSession(false, true, 123, false, PackageInstaller.SessionInfo.INVALID_ID,
-                null);
-    }
-
-    private PackageInstallerSession createMultiPackageParentSession(int sessionId,
-                                                                    int[] childSessionIds) {
-        return createSession(false, false, sessionId, true,
-                PackageInstaller.SessionInfo.INVALID_ID, childSessionIds);
-    }
-
-    private PackageInstallerSession createMultiPackageChildSession(int sessionId,
-                                                                   int parentSessionId) {
-        return createSession(false, false, sessionId, false, parentSessionId, null);
-    }
-
-    private PackageInstallerSession createSession(boolean staged, boolean withGrantedPermissions,
-                                                  int sessionId, boolean isMultiPackage,
-                                                  int parentSessionId, int[] childSessionIds) {
-        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
-                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-        if (staged) {
-            params.isStaged = true;
-        }
-        if (withGrantedPermissions) {
-            params.grantedRuntimePermissions = new String[]{"permission1", "permission2"};
-        }
-        if (isMultiPackage) {
-            params.isMultiPackage = true;
-        }
-        InstallSource installSource = InstallSource.create("testInstallInitiator",
-                "testInstallOriginator", "testInstaller", -1, "testUpdateOwner",
-                "testAttributionTag", PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
-        return new PackageInstallerSession(
-                /* callback */ null,
-                /* context */null,
-                /* pm */ mMockPackageManagerInternal,
-                /* sessionProvider */ null,
-                /* silentUpdatePolicy */ null,
-                /* looper */ BackgroundThread.getHandler().getLooper(),
-                /* stagingManager */ null,
-                /* sessionId */ sessionId,
-                /* userId */  456,
-                /* installerUid */ -1,
-                /* installSource */ installSource,
-                /* sessionParams */ params,
-                /* createdMillis */ 0L,
-                /* committedMillis */ 0L,
-                /* stageDir */ mTmpDir,
-                /* stageCid */ null,
-                /* files */ null,
-                /* checksums */ null,
-                /* prepared */ true,
-                /* committed */ true,
-                /* destroyed */ staged ? true : false,
-                /* sealed */ false,  // Setting to true would trigger some PM logic.
-                /* childSessionIds */ childSessionIds != null ? childSessionIds : new int[0],
-                /* parentSessionId */ parentSessionId,
-                /* isReady */ staged ? true : false,
-                /* isFailed */ false,
-                /* isApplied */false,
-                /* stagedSessionErrorCode */
-                PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
-                /* stagedSessionErrorMessage */ "some error");
-    }
-
-    private void dumpSession(PackageInstallerSession session) {
-        dumpSessions(Arrays.asList(session));
-    }
-
-    private void dumpSessions(List<PackageInstallerSession> sessions) {
-        FileOutputStream fos = null;
-        try {
-            fos = mSessionsFile.startWrite();
-
-            TypedXmlSerializer out = Xml.resolveSerializer(fos);
-            out.startDocument(null, true);
-            out.startTag(null, TAG_SESSIONS);
-            for (PackageInstallerSession session : sessions) {
-                session.write(out, mTmpDir);
-            }
-            out.endTag(null, TAG_SESSIONS);
-            out.endDocument();
-
-            mSessionsFile.finishWrite(fos);
-            Slog.d("PackageInstallerSessionTest", new String(mSessionsFile.readFully()));
-        } catch (IOException e) {
-            if (fos != null) {
-                mSessionsFile.failWrite(fos);
-            }
-        }
-    }
-
-    // This is roughly the logic used in PackageInstallerService to read the session. Note that
-    // this test stresses readFromXml method from PackageInstallerSession, and doesn't cover the
-    // PackageInstallerService portion of the parsing.
-    private List<PackageInstallerSession> restoreSessions() {
-        List<PackageInstallerSession> ret = new ArrayList<>();
-        FileInputStream fis = null;
-        try {
-            fis = mSessionsFile.openRead();
-            TypedXmlPullParser in = Xml.resolvePullParser(fis);
-
-            int type;
-            while ((type = in.next()) != END_DOCUMENT) {
-                if (type == START_TAG) {
-                    final String tag = in.getName();
-                    if (PackageInstallerSession.TAG_SESSION.equals(tag)) {
-                        final PackageInstallerSession session;
-                        try {
-                            session = PackageInstallerSession.readFromXml(in, null,
-                                    null, mMockPackageManagerInternal,
-                                    BackgroundThread.getHandler().getLooper(), null,
-                                    mTmpDir, null, null);
-                            ret.add(session);
-                        } catch (Exception e) {
-                            Slog.e("PackageInstallerSessionTest", "Exception ", e);
-                            continue;
-                        }
-                    }
-                }
-            }
-        } catch (FileNotFoundException e) {
-            // Missing sessions are okay, probably first boot
-        } catch (IOException | XmlPullParserException e) {
-
-        } finally {
-            IoUtils.closeQuietly(fis);
-        }
-        return ret;
-    }
-
-    private void assertSessionParamsEquivalent(PackageInstaller.SessionParams expected,
-                                               PackageInstaller.SessionParams actual) {
-        assertEquals(expected.mode, actual.mode);
-        assertEquals(expected.installFlags, actual.installFlags);
-        assertEquals(expected.installLocation, actual.installLocation);
-        assertEquals(expected.installReason, actual.installReason);
-        assertEquals(expected.sizeBytes, actual.sizeBytes);
-        assertEquals(expected.appPackageName, actual.appPackageName);
-        assertEquals(expected.appIcon, actual.appIcon);
-        assertEquals(expected.originatingUri, actual.originatingUri);
-        assertEquals(expected.originatingUid, actual.originatingUid);
-        assertEquals(expected.referrerUri, actual.referrerUri);
-        assertEquals(expected.abiOverride, actual.abiOverride);
-        assertEquals(expected.volumeUuid, actual.volumeUuid);
-        assertArrayEquals(expected.grantedRuntimePermissions, actual.grantedRuntimePermissions);
-        assertEquals(expected.installerPackageName, actual.installerPackageName);
-        assertEquals(expected.isMultiPackage, actual.isMultiPackage);
-        assertEquals(expected.isStaged, actual.isStaged);
-    }
-
-    private void assertSessionsEquivalent(List<PackageInstallerSession> expected,
-                                          List<PackageInstallerSession> actual) {
-        assertEquals(expected.size(), actual.size());
-        for (PackageInstallerSession expectedSession : expected) {
-            boolean foundSession = false;
-            for (PackageInstallerSession actualSession : actual) {
-                if (expectedSession.sessionId == actualSession.sessionId) {
-                    // We should only encounter each expected session once.
-                    assertFalse(foundSession);
-                    foundSession = true;
-                    assertSessionsEquivalent(expectedSession, actualSession);
-                }
-            }
-            assertTrue(foundSession);
-        }
-    }
-
-    private void assertSessionsEquivalent(PackageInstallerSession expected,
-                                          PackageInstallerSession actual) {
-        assertEquals(expected.sessionId, actual.sessionId);
-        assertEquals(expected.userId, actual.userId);
-        assertSessionParamsEquivalent(expected.params, actual.params);
-        assertEquals(expected.getInstallerUid(), actual.getInstallerUid());
-        assertEquals(expected.getInstallerPackageName(), actual.getInstallerPackageName());
-        assertInstallSourcesEquivalent(expected.getInstallSource(), actual.getInstallSource());
-        assertEquals(expected.stageDir.getAbsolutePath(), actual.stageDir.getAbsolutePath());
-        assertEquals(expected.stageCid, actual.stageCid);
-        assertEquals(expected.isPrepared(), actual.isPrepared());
-        assertEquals(expected.isStaged(), actual.isStaged());
-        assertEquals(expected.isSessionApplied(), actual.isSessionApplied());
-        assertEquals(expected.isSessionFailed(), actual.isSessionFailed());
-        assertEquals(expected.isSessionReady(), actual.isSessionReady());
-        assertEquals(expected.getSessionErrorCode(), actual.getSessionErrorCode());
-        assertEquals(expected.getSessionErrorMessage(),
-                actual.getSessionErrorMessage());
-        assertEquals(expected.isPrepared(), actual.isPrepared());
-        assertEquals(expected.isCommitted(), actual.isCommitted());
-        assertEquals(expected.isPreapprovalRequested(), actual.isPreapprovalRequested());
-        assertEquals(expected.createdMillis, actual.createdMillis);
-        assertEquals(expected.isSealed(), actual.isSealed());
-        assertEquals(expected.isMultiPackage(), actual.isMultiPackage());
-        assertEquals(expected.hasParentSessionId(), actual.hasParentSessionId());
-        assertEquals(expected.getParentSessionId(), actual.getParentSessionId());
-        assertArrayEquals(expected.getChildSessionIds(), actual.getChildSessionIds());
-    }
-
-    private void assertInstallSourcesEquivalent(InstallSource expected, InstallSource actual) {
-        assertEquals(expected.mInstallerPackageName, actual.mInstallerPackageName);
-        assertEquals(expected.mInitiatingPackageName, actual.mInitiatingPackageName);
-        assertEquals(expected.mOriginatingPackageName, actual.mOriginatingPackageName);
-    }
-}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
new file mode 100644
index 0000000..d760dc7
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageInstallerSessionTest.kt
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.pm
+
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageInstaller
+import android.content.pm.PackageInstaller.SessionParams
+import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DEFAULT
+import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_DENIED
+import android.content.pm.PackageInstaller.SessionParams.PERMISSION_STATE_GRANTED
+import android.content.pm.PackageManager
+import android.os.Parcel
+import android.platform.test.annotations.Presubmit
+import android.util.AtomicFile
+import android.util.Slog
+import android.util.Xml
+import com.android.internal.os.BackgroundThread
+import com.android.server.testutils.whenever
+import com.google.common.truth.Truth.assertThat
+import libcore.io.IoUtils
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.MockitoAnnotations
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.io.IOException
+
+@Presubmit
+class PackageInstallerSessionTest {
+
+    companion object {
+        private const val TAG_SESSIONS = "sessions"
+    }
+
+    @JvmField
+    @Rule
+    var mTemporaryFolder = TemporaryFolder()
+
+    private lateinit var mTmpDir: File
+    private lateinit var mSessionsFile: AtomicFile
+
+    @Mock
+    lateinit var mMockPackageManagerInternal: PackageManagerService
+
+    @Mock
+    lateinit var mSnapshot: Computer
+
+    @Before
+    @Throws(Exception::class)
+    fun setUp() {
+        mTmpDir = mTemporaryFolder.newFolder("PackageInstallerSessionTest")
+        mSessionsFile = AtomicFile(
+            File(mTmpDir.getAbsolutePath() + "/sessions.xml"), "package-session"
+        )
+        MockitoAnnotations.initMocks(this)
+        whenever(mSnapshot.getPackageUid(anyString(), anyLong(), anyInt())) { 0 }
+        whenever(mMockPackageManagerInternal.snapshotComputer()) { mSnapshot }
+    }
+
+    @Test
+    fun testWriteAndRestoreSessionXmlSimpleSession() {
+        writeRestoreAssert(listOf(createSession()))
+    }
+
+    @Test
+    fun testWriteAndRestoreSessionXmlStagedSession() {
+        writeRestoreAssert(listOf(createSession(staged = true)))
+    }
+
+    @Test
+    fun testWriteAndRestoreSessionXmlLegacyGrantedPermission() {
+        val sessions = createSession {
+            @Suppress("DEPRECATION")
+            it.setGrantedRuntimePermissions(arrayOf("permission1", "permission2"))
+        }.let(::listOf)
+
+        val restored = writeRestoreAssert(sessions)
+        assertThat(restored.single().params.legacyGrantedRuntimePermissions).asList()
+            .containsExactly("permission1", "permission2")
+    }
+
+    @Test
+    fun testWriteAndRestoreSessionXmlPermissionState() {
+        val sessions = createSession {
+            it.setPermissionState("grantPermission", PERMISSION_STATE_GRANTED)
+                .setPermissionState("denyPermission", PERMISSION_STATE_DENIED)
+                .setPermissionState("grantToDefaultPermission", PERMISSION_STATE_GRANTED)
+                .setPermissionState("grantToDefaultPermission", PERMISSION_STATE_DEFAULT)
+                .setPermissionState("denyToDefaultPermission", PERMISSION_STATE_DENIED)
+                .setPermissionState("denyToDefaultPermission", PERMISSION_STATE_DEFAULT)
+                .setPermissionState("grantToDenyPermission", PERMISSION_STATE_GRANTED)
+                .setPermissionState("grantToDenyPermission", PERMISSION_STATE_DENIED)
+                .setPermissionState("denyToGrantPermission", PERMISSION_STATE_DENIED)
+                .setPermissionState("denyToGrantPermission", PERMISSION_STATE_GRANTED)
+        }.let(::listOf)
+
+        writeRestoreAssert(sessions).single().params.run {
+            assertThat(legacyGrantedRuntimePermissions).asList()
+                .containsExactly("grantPermission", "denyToGrantPermission")
+            assertThat(finalPermissionStates)
+                .containsExactlyEntriesIn(mapOf(
+                    "grantPermission" to PERMISSION_STATE_GRANTED,
+                    "denyToGrantPermission" to PERMISSION_STATE_GRANTED,
+                    // Fullscreen Intent is auto-granted if the caller has no opinion
+                    Manifest.permission.USE_FULL_SCREEN_INTENT to PERMISSION_STATE_GRANTED,
+                    "denyPermission" to PERMISSION_STATE_DENIED,
+                    "grantToDenyPermission" to PERMISSION_STATE_DENIED,
+                ))
+        }
+    }
+
+    @Test
+    fun testWriteAndRestoreSessionXmlMultiPackageSessions() {
+        val session = createSession(
+            sessionId = 123,
+            multiPackage = true,
+            childSessionIds = listOf(234, 345)
+        )
+        val childSession1 = createSession(sessionId = 234, parentSessionId = 123)
+        val childSession2 = createSession(sessionId = 345, parentSessionId = 123)
+        writeRestoreAssert(listOf(session, childSession1, childSession2))
+    }
+
+    private fun createSession(
+        staged: Boolean = false,
+        sessionId: Int = 123,
+        multiPackage: Boolean = false,
+        parentSessionId: Int = PackageInstaller.SessionInfo.INVALID_ID,
+        childSessionIds: List<Int> = emptyList(),
+        block: (SessionParams) -> Unit = {},
+    ): PackageInstallerSession {
+        val params = SessionParams(SessionParams.MODE_FULL_INSTALL).apply {
+            isStaged = staged
+            isMultiPackage = multiPackage
+            block(this)
+        }
+
+        val installSource = InstallSource.create(
+            "testInstallInitiator",
+            "testInstallOriginator", "testInstaller", -1, "testUpdateOwner",
+            "testAttributionTag", PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED
+        )
+
+        return PackageInstallerSession(
+            /* callback */ null,
+            /* context */ null,
+            /* pm */ mMockPackageManagerInternal,
+            /* sessionProvider */ null,
+            /* silentUpdatePolicy */ null,
+            /* looper */ BackgroundThread.getHandler().looper,
+            /* stagingManager */ null,
+            /* sessionId */ sessionId,
+            /* userId */ 456,
+            /* installerUid */ -1,
+            /* installSource */ installSource,
+            /* sessionParams */ params,
+            /* createdMillis */ 0L,
+            /* committedMillis */ 0L,
+            /* stageDir */ mTmpDir,
+            /* stageCid */ null,
+            /* files */ null,
+            /* checksums */ null,
+            /* prepared */ true,
+            /* committed */ true,
+            /* destroyed */ staged,
+            /* sealed */ false, // Setting to true would trigger some PM logic.
+            /* childSessionIds */ childSessionIds.toIntArray(),
+            /* parentSessionId */ parentSessionId,
+            /* isReady */ staged,
+            /* isFailed */ false,
+            /* isApplied */ false,
+            /* stagedSessionErrorCode */ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
+            /* stagedSessionErrorMessage */ "some error"
+        )
+    }
+
+    private fun writeRestoreAssert(sessions: List<PackageInstallerSession>) =
+        writeSessions(sessions)
+            .run { restoreSessions() }
+            .also { assertEquals(sessions, it) }
+
+    private fun writeSessions(sessions: List<PackageInstallerSession>) {
+        var fos: FileOutputStream? = null
+        try {
+            fos = mSessionsFile.startWrite()
+            Xml.resolveSerializer(fos).apply {
+                startDocument(null, true)
+                startTag(null, TAG_SESSIONS)
+                for (session in sessions) {
+                    session.write(this, mTmpDir)
+                }
+                endTag(null, TAG_SESSIONS)
+                endDocument()
+            }
+            mSessionsFile.finishWrite(fos)
+            Slog.d("PackageInstallerSessionTest", String(mSessionsFile.readFully()))
+        } catch (e: IOException) {
+            mSessionsFile.failWrite(fos)
+        }
+    }
+
+    // This is roughly the logic used in PackageInstallerService to read the session. Note that
+    // this test stresses readFromXml method from PackageInstallerSession, and doesn't cover the
+    // PackageInstallerService portion of the parsing.
+    private fun restoreSessions(): List<PackageInstallerSession> {
+        val ret: MutableList<PackageInstallerSession> = ArrayList()
+        var fis: FileInputStream? = null
+        try {
+            fis = mSessionsFile.openRead()
+            val parser = Xml.resolvePullParser(fis)
+            var type: Int
+            while (parser.next().also { type = it } != XmlPullParser.END_DOCUMENT) {
+                if (type == XmlPullParser.START_TAG) {
+                    val tag = parser.name
+                    if (PackageInstallerSession.TAG_SESSION == tag) {
+                        val session: PackageInstallerSession
+                        try {
+                            session = PackageInstallerSession.readFromXml(
+                                parser,
+                                mock(PackageInstallerService.InternalCallback::class.java),
+                                mock(Context::class.java),
+                                mMockPackageManagerInternal,
+                                BackgroundThread.getHandler().looper,
+                                mock(StagingManager::class.java),
+                                mTmpDir,
+                                mock(PackageSessionProvider::class.java),
+                                mock(SilentUpdatePolicy::class.java)
+                            )
+                            ret.add(session)
+                        } catch (e: Exception) {
+                            Slog.e("PackageInstallerSessionTest", "Exception ", e)
+                            continue
+                        }
+                    }
+                }
+            }
+        } catch (_: FileNotFoundException) {
+            // Missing sessions are okay, probably first boot
+        } catch (_: IOException) {
+        } catch (_: XmlPullParserException) {
+        } finally {
+            IoUtils.closeQuietly(fis)
+        }
+        return ret
+    }
+
+    private fun assertSessionParamsEquivalent(expected: SessionParams, actual: SessionParams) {
+        assertThat(expected.mode).isEqualTo(actual.mode)
+        assertThat(expected.installFlags).isEqualTo(actual.installFlags)
+        assertThat(expected.installLocation).isEqualTo(actual.installLocation)
+        assertThat(expected.installReason).isEqualTo(actual.installReason)
+        assertThat(expected.sizeBytes).isEqualTo(actual.sizeBytes)
+        assertThat(expected.appPackageName).isEqualTo(actual.appPackageName)
+        assertThat(expected.appIcon).isEqualTo(actual.appIcon)
+        assertThat(expected.originatingUri).isEqualTo(actual.originatingUri)
+        assertThat(expected.originatingUid).isEqualTo(actual.originatingUid)
+        assertThat(expected.referrerUri).isEqualTo(actual.referrerUri)
+        assertThat(expected.abiOverride).isEqualTo(actual.abiOverride)
+        assertThat(expected.volumeUuid).isEqualTo(actual.volumeUuid)
+        assertThat(expected.finalPermissionStates).isEqualTo(actual.finalPermissionStates)
+        assertThat(expected.installerPackageName).isEqualTo(actual.installerPackageName)
+        assertThat(expected.isMultiPackage).isEqualTo(actual.isMultiPackage)
+        assertThat(expected.isStaged).isEqualTo(actual.isStaged)
+    }
+
+    private fun assertEquals(
+        expected: List<PackageInstallerSession>,
+        actual: List<PackageInstallerSession>
+    ) {
+        assertThat(expected).hasSize(actual.size)
+        expected.sortedBy { it.sessionId }.zip(actual.sortedBy { it.sessionId })
+            .forEach { (expected, actual) ->
+                assertEquals(expected, actual)
+            }
+    }
+
+    private fun assertEquals(expected: PackageInstallerSession, actual: PackageInstallerSession) {
+        // Check both the restored params and an unparcelized variant to ensure parcelling works
+        assertSessionParamsEquivalent(expected.params, actual.params)
+        assertSessionParamsEquivalent(expected.params, actual.params.let {
+            val parcel = Parcel.obtain()
+            it.writeToParcel(parcel, 0)
+            parcel.setDataPosition(0)
+            SessionParams.CREATOR.createFromParcel(parcel).also {
+                parcel.recycle()
+            }
+        })
+
+        assertThat(expected.sessionId).isEqualTo(actual.sessionId)
+        assertThat(expected.userId).isEqualTo(actual.userId)
+        assertThat(expected.installerUid).isEqualTo(actual.installerUid)
+        assertThat(expected.installerPackageName).isEqualTo(actual.installerPackageName)
+        assertInstallSourcesEquivalent(expected.installSource, actual.installSource)
+        assertThat(expected.stageDir.absolutePath).isEqualTo(actual.stageDir.absolutePath)
+        assertThat(expected.stageCid).isEqualTo(actual.stageCid)
+        assertThat(expected.isPrepared).isEqualTo(actual.isPrepared)
+        assertThat(expected.isStaged).isEqualTo(actual.isStaged)
+        assertThat(expected.isSessionApplied).isEqualTo(actual.isSessionApplied)
+        assertThat(expected.isSessionFailed).isEqualTo(actual.isSessionFailed)
+        assertThat(expected.isSessionReady).isEqualTo(actual.isSessionReady)
+        assertThat(expected.sessionErrorCode).isEqualTo(actual.sessionErrorCode)
+        assertThat(expected.sessionErrorMessage).isEqualTo(actual.sessionErrorMessage)
+        assertThat(expected.isPrepared).isEqualTo(actual.isPrepared)
+        assertThat(expected.isCommitted).isEqualTo(actual.isCommitted)
+        assertThat(expected.isPreapprovalRequested).isEqualTo(actual.isPreapprovalRequested)
+        assertThat(expected.createdMillis).isEqualTo(actual.createdMillis)
+        assertThat(expected.isSealed).isEqualTo(actual.isSealed)
+        assertThat(expected.isMultiPackage).isEqualTo(actual.isMultiPackage)
+        assertThat(expected.hasParentSessionId()).isEqualTo(actual.hasParentSessionId())
+        assertThat(expected.parentSessionId).isEqualTo(actual.parentSessionId)
+        assertThat(expected.childSessionIds).asList()
+            .containsExactlyElementsIn(actual.childSessionIds.toList())
+    }
+
+    private fun assertInstallSourcesEquivalent(expected: InstallSource, actual: InstallSource) {
+        assertThat(expected.mInstallerPackageName).isEqualTo(actual.mInstallerPackageName)
+        assertThat(expected.mInitiatingPackageName).isEqualTo(actual.mInitiatingPackageName)
+        assertThat(expected.mOriginatingPackageName).isEqualTo(actual.mOriginatingPackageName)
+    }
+}
\ No newline at end of file
diff --git a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
index 7b361d3..1dcd0b9 100644
--- a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
+++ b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.contains;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.eq;
@@ -39,6 +40,7 @@
 import android.security.rkp.IStoreUpgradedKeyCallback;
 import android.security.rkp.service.RegistrationProxy;
 import android.security.rkp.service.RemotelyProvisionedKey;
+import android.security.rkp.service.RkpProxyException;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -48,8 +50,9 @@
 import org.mockito.stubbing.Answer;
 import org.mockito.stubbing.VoidAnswer4;
 
-import java.time.Duration;
+import java.lang.reflect.Field;
 import java.util.Arrays;
+import java.util.Map;
 import java.util.concurrent.Executor;
 
 /**
@@ -104,7 +107,7 @@
     }
 
     @Test
-    public void getKeyHandlesError() throws Exception {
+    public void getKeyHandlesArbitraryException() throws Exception {
         Exception expectedException = new Exception("oops!");
         doAnswer(
                 answerGetKeyAsync((keyId, cancelSignal, executor, receiver) ->
@@ -112,11 +115,38 @@
                 .when(mRegistrationProxy).getKeyAsync(eq(0), any(), any(), any());
         IGetKeyCallback callback = mock(IGetKeyCallback.class);
         mRegistration.getKey(0, callback);
-        verify(callback).onError(eq(expectedException.getMessage()));
+        verify(callback).onError(eq(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN), eq("oops!"));
         verifyNoMoreInteractions(callback);
     }
 
     @Test
+    public void getKeyMapsRkpErrorsCorrectly() throws Exception {
+        Map<Byte, Integer> expectedConversions = Map.of(
+                IGetKeyCallback.ErrorCode.ERROR_UNKNOWN,
+                RkpProxyException.ERROR_UNKNOWN,
+                IGetKeyCallback.ErrorCode.ERROR_REQUIRES_SECURITY_PATCH,
+                RkpProxyException.ERROR_REQUIRES_SECURITY_PATCH,
+                IGetKeyCallback.ErrorCode.ERROR_PENDING_INTERNET_CONNECTIVITY,
+                RkpProxyException.ERROR_PENDING_INTERNET_CONNECTIVITY,
+                IGetKeyCallback.ErrorCode.ERROR_PERMANENT,
+                RkpProxyException.ERROR_PERMANENT);
+
+        for (Field errorField: IGetKeyCallback.ErrorCode.class.getFields()) {
+            byte error = (Byte) errorField.get(null);
+            Exception expectedException = new RkpProxyException(expectedConversions.get(error),
+                    errorField.getName());
+            doAnswer(
+                    answerGetKeyAsync((keyId, cancelSignal, executor, receiver) ->
+                            executor.execute(() -> receiver.onError(expectedException))))
+                    .when(mRegistrationProxy).getKeyAsync(eq(0), any(), any(), any());
+            IGetKeyCallback callback = mock(IGetKeyCallback.class);
+            mRegistration.getKey(0, callback);
+            verify(callback).onError(eq(error), contains(errorField.getName()));
+            verifyNoMoreInteractions(callback);
+        }
+    }
+
+    @Test
     public void getKeyCancelDuringProxyOperation() throws Exception {
         IGetKeyCallback callback = mock(IGetKeyCallback.class);
         doAnswer(
@@ -179,7 +209,8 @@
 
         IGetKeyCallback callback = mock(IGetKeyCallback.class);
         mRegistration.getKey(0, callback);
-        verify(callback).onError(eq(expectedException.getMessage()));
+        verify(callback).onError(eq(IGetKeyCallback.ErrorCode.ERROR_UNKNOWN),
+                eq(expectedException.getMessage()));
         assertThrows(IllegalArgumentException.class, () -> mRegistration.cancelGetKey(callback));
         verifyNoMoreInteractions(callback);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 9b04ae4..31cfa78 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -271,7 +271,8 @@
         verify(mMockIActivityManager).registerUidObserver(
                 uidObserverArgumentCaptor.capture(),
                 eq(ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_IDLE
-                        | ActivityManager.UID_OBSERVER_ACTIVE),
+                        | ActivityManager.UID_OBSERVER_ACTIVE
+                        | ActivityManager.UID_OBSERVER_CACHED),
                 eq(ActivityManager.PROCESS_STATE_UNKNOWN),
                 isNull());
         verify(mMockIAppOpsService).startWatchingMode(
@@ -1364,6 +1365,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidGone(UID_10_1, true);
@@ -1381,6 +1384,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(0)).unblockAlarmsForUid(anyInt());
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(1)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidActive(UID_10_1);
@@ -1398,6 +1403,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidIdle(UID_10_1, true);
@@ -1415,8 +1422,49 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(0)).unblockAlarmsForUid(anyInt());
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(1)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
+        mIUidObserver.onUidCachedChanged(UID_10_1, true);
+
+        waitUntilMainHandlerDrain();
+        waitUntilMainHandlerDrain();
+        verify(l, times(0)).updateAllJobs();
+        verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
+        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+        verify(l, times(0)).updateBackgroundRestrictedForUidPackage(anyInt(), anyString(),
+                anyBoolean());
+
+        verify(l, times(0)).updateAllAlarms();
+        verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1));
+        verify(l, times(0)).unblockAllUnrestrictedAlarms();
+        verify(l, times(0)).unblockAlarmsForUid(anyInt());
+        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(1)).removeListenerAlarmsForCachedUid(UID_10_1);
+        reset(l);
+
+        mIUidObserver.onUidCachedChanged(UID_10_1, false);
+
+        waitUntilMainHandlerDrain();
+        waitUntilMainHandlerDrain();
+        verify(l, times(0)).updateAllJobs();
+        verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
+        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+        verify(l, times(0)).updateBackgroundRestrictedForUidPackage(anyInt(), anyString(),
+                anyBoolean());
+
+        verify(l, times(0)).updateAllAlarms();
+        verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1));
+        verify(l, times(0)).unblockAllUnrestrictedAlarms();
+        verify(l, times(0)).unblockAlarmsForUid(anyInt());
+        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+        reset(l);
+
+
         // Without battery saver.
         mPowerSaveMode = false;
         mPowerSaveObserver.accept(getPowerSaveState());
@@ -1433,6 +1481,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(0)).unblockAlarmsForUid(anyInt());
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidActive(UID_10_1);
@@ -1450,6 +1500,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidGone(UID_10_1, true);
@@ -1467,6 +1519,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(0)).unblockAlarmsForUid(anyInt());
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(1)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidActive(UID_10_1);
@@ -1484,6 +1538,8 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
 
         mIUidObserver.onUidIdle(UID_10_1, true);
@@ -1501,6 +1557,46 @@
         verify(l, times(0)).unblockAllUnrestrictedAlarms();
         verify(l, times(0)).unblockAlarmsForUid(anyInt());
         verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(1)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+        reset(l);
+
+        mIUidObserver.onUidCachedChanged(UID_10_1, true);
+
+        waitUntilMainHandlerDrain();
+        waitUntilMainHandlerDrain();
+        verify(l, times(0)).updateAllJobs();
+        verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
+        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+        verify(l, times(0)).updateBackgroundRestrictedForUidPackage(anyInt(), anyString(),
+                anyBoolean());
+
+        verify(l, times(0)).updateAllAlarms();
+        verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1));
+        verify(l, times(0)).unblockAllUnrestrictedAlarms();
+        verify(l, times(0)).unblockAlarmsForUid(anyInt());
+        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(1)).removeListenerAlarmsForCachedUid(UID_10_1);
+        reset(l);
+
+        mIUidObserver.onUidCachedChanged(UID_10_1, false);
+
+        waitUntilMainHandlerDrain();
+        waitUntilMainHandlerDrain();
+        verify(l, times(0)).updateAllJobs();
+        verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
+        verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
+        verify(l, times(0)).updateBackgroundRestrictedForUidPackage(anyInt(), anyString(),
+                anyBoolean());
+
+        verify(l, times(0)).updateAllAlarms();
+        verify(l, times(0)).updateAlarmsForUid(eq(UID_10_1));
+        verify(l, times(0)).unblockAllUnrestrictedAlarms();
+        verify(l, times(0)).unblockAlarmsForUid(anyInt());
+        verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
+        verify(l, times(0)).removeAlarmsForUid(UID_10_1);
+        verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
         reset(l);
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/DumpableDumperRule.java b/services/tests/mockingservicestests/src/com/android/server/DumpableDumperRule.java
index a0687f6..6e6d55b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DumpableDumperRule.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DumpableDumperRule.java
@@ -15,6 +15,7 @@
  */
 package com.android.server;
 
+import android.annotation.Nullable;
 import android.util.Dumpable;
 import android.util.Log;
 
@@ -40,6 +41,8 @@
 
     private final List<Dumpable> mDumpables = new ArrayList<>();
 
+    private @Nullable String mTestName;
+
     /**
      * Adds a {@link Dumpable} to be logged if the test case fails.
      */
@@ -47,15 +50,24 @@
         mDumpables.add(dumpable);
     }
 
+    /**
+     * Gets the name of the test being executed.
+     */
+    public @Nullable String getTestName() {
+        return mTestName;
+    }
+
     @Override
     public Statement apply(Statement base, Description description) {
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
+                mTestName = description.getDisplayName();
                 try {
                     base.evaluate();
                 } catch (Throwable t) {
-                    dumpOnFailure(description.getMethodName());
+                    dumpOnFailure(mTestName);
+                    mTestName = null;
                     throw t;
                 }
             }
diff --git a/services/tests/mockingservicestests/src/com/android/server/ExtendedMockitoTestCase.java b/services/tests/mockingservicestests/src/com/android/server/ExtendedMockitoTestCase.java
index 693a96d..48483a1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/ExtendedMockitoTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/ExtendedMockitoTestCase.java
@@ -17,6 +17,7 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
+import android.annotation.Nullable;
 import android.util.Log;
 
 import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
@@ -28,9 +29,12 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.rules.RuleChain;
+import org.mockito.Mockito;
 import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
 
+import java.lang.reflect.Constructor;
+
 /**
  * Base class to make it easier to write tests that uses {@code ExtendedMockito}.
  *
@@ -39,7 +43,25 @@
 
     private static final String TAG = ExtendedMockitoTestCase.class.getSimpleName();
 
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    /**
+     * Number of invocations, used to force a failure on {@link #forceFailure(int, Class, String)}.
+     */
+    private static int sInvocationsCounter;
+
+    /**
+     * Sessions follow the "Highlander Rule": There can be only one!
+     *
+     * <p>So, we keep track of that and force-close it if needed.
+     */
+    @Nullable
+    private static MockitoSession sHighlanderSession;
+
+    /**
+     * Points to where the current session was created.
+     */
+    private static Exception sSessionCreationLocation;
 
     private MockitoSession mSession;
 
@@ -51,16 +73,43 @@
             .outerRule(mDumpableDumperRule)
             .around(mExpect);
 
+    public ExtendedMockitoTestCase() {
+        sInvocationsCounter++;
+    }
+
     @Before
-    public void startSession() {
-        if (DEBUG) {
-            Log.d(TAG, "startSession()");
+    public final void startSession() {
+        if (VERBOSE) {
+            Log.v(TAG, "startSession() for " + getTestName() + " on thread "
+                    + Thread.currentThread() + "; sHighlanderSession=" + sHighlanderSession);
         }
+        createSessionLocation();
+        finishHighlanderSessionIfNeeded("startSession()");
         StaticMockitoSessionBuilder builder = mockitoSession()
                 .initMocks(this)
-                .strictness(Strictness.LENIENT);
+                .strictness(getSessionStrictness());
         initializeSession(builder);
-        mSession = builder.startMocking();
+        sHighlanderSession = mSession = builder.startMocking();
+    }
+
+    private void createSessionLocation() {
+        try {
+            sSessionCreationLocation = new Exception(getTestName());
+        } catch (Exception e) {
+            // Better safe than sorry...
+            Log.e(TAG, "Could not create sSessionCreationLocation with " + getTestName()
+                    + " on thread " + Thread.currentThread(), e);
+            sSessionCreationLocation = e;
+        }
+    }
+
+    /**
+     * Gets the session strictness.
+     *
+     * @return {@link Strictness.LENIENT} by default; subclasses can override.
+     */
+    protected Strictness getSessionStrictness() {
+        return Strictness.LENIENT;
     }
 
     /**
@@ -69,29 +118,127 @@
      * <p>Typically used to define which classes should have static methods mocked or spied.
      */
     protected void initializeSession(StaticMockitoSessionBuilder builder) {
-        if (DEBUG) {
-            Log.d(TAG, "initializeSession()");
+        if (VERBOSE) {
+            Log.v(TAG, "initializeSession()");
         }
     }
 
     @After
-    public final void finishSession() {
+    public final void finishSession() throws Exception {
+        if (false) { // For obvious reasons, should NEVER be merged as true
+            forceFailure(1, RuntimeException.class, "to simulate an unfinished session");
+        }
+
+        // mSession.finishMocking() must ALWAYS be called (hence the over-protective try/finally
+        // statements), otherwise it would cause failures on future tests as mockito
+        // cannot start a session when a previous one is not finished
+        try {
+            if (VERBOSE) {
+                Log.v(TAG, "finishSession() for " + getTestName() + " on thread "
+                        + Thread.currentThread() + "; sHighlanderSession=" + sHighlanderSession);
+
+            }
+        } finally {
+            sHighlanderSession = null;
+            finishSessionMocking();
+            afterSessionFinished();
+        }
+    }
+
+    /**
+     * Called after the mockito session was finished
+     *
+     * <p>This method should be used by subclasses that MUST do their cleanup after the session is
+     * finished (as methods marked with {@link After} in the subclasses would be called BEFORE
+     * that).
+     */
+    protected void afterSessionFinished() {
+        if (VERBOSE) {
+            Log.v(TAG, "afterSessionFinished()");
+        }
+    }
+
+    private void finishSessionMocking() {
         if (mSession == null) {
-            Log.w(TAG, "finishSession(): no session");
+            Log.w(TAG, getClass().getSimpleName() + ".finishSession(): no session");
             return;
         }
         try {
-            if (DEBUG) {
-                Log.d(TAG, "finishSession()");
+            mSession.finishMocking();
+        } finally {
+            // Shouldn't need to set mSession to null as JUnit always instantiate a new object,
+            // but it doesn't hurt....
+            mSession = null;
+            // When using inline mock maker, clean up inline mocks to prevent OutOfMemory
+            // errors. See https://github.com/mockito/mockito/issues/1614 and b/259280359.
+            Mockito.framework().clearInlineMocks();
+        }
+    }
+
+    private void finishHighlanderSessionIfNeeded(String where) {
+        if (sHighlanderSession == null) {
+            if (VERBOSE) {
+                Log.v(TAG, "finishHighlanderSessionIfNeeded(): sHighlanderSession already null");
+            }
+            return;
+        }
+
+        if (sSessionCreationLocation != null) {
+            if (VERBOSE) {
+                Log.e(TAG, where + ": There can be only one! Closing unfinished session, "
+                        + "created at", sSessionCreationLocation);
+            } else {
+                Log.e(TAG, where + ": There can be only one! Closing unfinished session, "
+                        + "created at " +  sSessionCreationLocation);
+            }
+        } else {
+            Log.e(TAG, where + ": There can be only one! Closing unfinished session created at "
+                    + "unknown location");
+        }
+        try {
+            sHighlanderSession.finishMocking();
+        } catch (Throwable t) {
+            if (VERBOSE) {
+                Log.e(TAG, "Failed to close unfinished session on " + getTestName(), t);
+            } else {
+                Log.e(TAG, "Failed to close unfinished session on " + getTestName() + ": " + t);
             }
         } finally {
-            // mSession.finishMocking() must ALWAYS be called (hence the over-protective try/finally
-            // statements), otherwise it would cause failures on future tests as mockito
-            // cannot start a session when a previous one is not finished
-            mSession.finishMocking();
+            if (VERBOSE) {
+                Log.v(TAG, "Resetting sHighlanderSession at finishHighlanderSessionIfNeeded()");
+            }
+            sHighlanderSession = null;
         }
     }
 
+    /**
+     * Forces a failure at the given invocation of a test method by throwing an exception.
+     */
+    protected final <T extends Throwable> void forceFailure(int invocationCount,
+            Class<T> failureClass, String reason) throws T {
+        if (sInvocationsCounter != invocationCount) {
+            Log.d(TAG, "forceFailure(" + invocationCount + "): no-op on invocation #"
+                    + sInvocationsCounter);
+            return;
+        }
+        String message = "Throwing on invocation #" + sInvocationsCounter + ": " + reason;
+        Log.e(TAG, message);
+        T throwable;
+        try {
+            Constructor<T> constructor = failureClass.getConstructor(String.class);
+            throwable = constructor.newInstance("Throwing on invocation #" + sInvocationsCounter
+                    + ": " + reason);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Could not create exception of class " + failureClass
+                    + " using msg='" + message + "' as constructor");
+        }
+        throw throwable;
+    }
+
+    protected final @Nullable String getTestName() {
+        return mDumpableDumperRule.getTestName();
+    }
+
     protected final StandardSubjectBuilder expectWithMessage(String msg) {
         return mExpect.withMessage(msg);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index 3b20735..000283e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -18,6 +18,7 @@
 import static android.Manifest.permission.SCHEDULE_EXACT_ALARM;
 import static android.app.AlarmManager.ELAPSED_REALTIME;
 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
+import static android.app.AlarmManager.EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_COMPAT;
 import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
@@ -48,7 +49,6 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 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.when;
@@ -159,6 +159,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.dx.mockito.inline.extended.MockedVoidMethod;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsService;
@@ -167,6 +168,7 @@
 import com.android.server.AppStateTracker;
 import com.android.server.AppStateTrackerImpl;
 import com.android.server.DeviceIdleInternal;
+import com.android.server.ExtendedMockitoTestCase;
 import com.android.server.LocalServices;
 import com.android.server.SystemClockTime.TimeConfidence;
 import com.android.server.SystemService;
@@ -179,7 +181,6 @@
 
 import libcore.util.EmptyArray;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -187,7 +188,6 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
-import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
 import org.mockito.stubbing.Answer;
 
@@ -202,17 +202,21 @@
 import java.util.function.LongConsumer;
 
 @Presubmit
+@SuppressWarnings("GuardedBy")  // This test enforces synchronous behavior.
 @RunWith(AndroidJUnit4.class)
-public class AlarmManagerServiceTest {
+public final class AlarmManagerServiceTest extends ExtendedMockitoTestCase {
     private static final String TAG = AlarmManagerServiceTest.class.getSimpleName();
     private static final int SYSTEM_UI_UID = 12345;
     private static final int TEST_CALLING_USER = UserHandle.getUserId(TEST_CALLING_UID);
     private static final int TEST_CALLING_UID_2 = TEST_CALLING_UID + 1;
+    private static final int[] ALARM_TYPES =
+            {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
 
     private long mAppStandbyWindow;
     private long mAllowWhileIdleWindow;
     private AlarmManagerService mService;
     private AppStandbyInternal.AppIdleStateChangeListener mAppStandbyListener;
+    private AppStateTrackerImpl.Listener mListener;
     private AlarmManagerService.UninstallReceiver mPackageChangesReceiver;
     private AlarmManagerService.ChargingReceiver mChargingReceiver;
     private IAppOpsCallback mIAppOpsCallback;
@@ -255,7 +259,6 @@
     DeviceConfig.Properties mDeviceConfigProperties;
     HashSet<String> mDeviceConfigKeys = new HashSet<>();
 
-    private MockitoSession mMockingSession;
     private Injector mInjector;
     private volatile long mNowElapsedTest;
     private volatile long mNowRtcTest;
@@ -408,26 +411,31 @@
         }
     }
 
+    @Override
+    protected Strictness getSessionStrictness() {
+        return Strictness.WARN;
+    }
+
+    @Override
+    protected void initializeSession(StaticMockitoSessionBuilder builder) {
+        builder
+            .spyStatic(ActivityManager.class)
+            .mockStatic(CompatChanges.class)
+            .spyStatic(DateFormat.class)
+            .spyStatic(DeviceConfig.class)
+            .mockStatic(LocalServices.class)
+            .spyStatic(Looper.class)
+            .mockStatic(MetricsHelper.class)
+            .mockStatic(PermissionChecker.class)
+            .mockStatic(PermissionManagerService.class)
+            .mockStatic(ServiceManager.class)
+            .mockStatic(Settings.Global.class)
+            .mockStatic(SystemProperties.class)
+            .spyStatic(UserHandle.class);
+    }
+
     @Before
     public final void setUp() {
-        mMockingSession = mockitoSession()
-                .initMocks(this)
-                .spyStatic(ActivityManager.class)
-                .mockStatic(CompatChanges.class)
-                .spyStatic(DateFormat.class)
-                .spyStatic(DeviceConfig.class)
-                .mockStatic(LocalServices.class)
-                .spyStatic(Looper.class)
-                .mockStatic(MetricsHelper.class)
-                .mockStatic(PermissionChecker.class)
-                .mockStatic(PermissionManagerService.class)
-                .mockStatic(ServiceManager.class)
-                .mockStatic(Settings.Global.class)
-                .mockStatic(SystemProperties.class)
-                .spyStatic(UserHandle.class)
-                .strictness(Strictness.WARN)
-                .startMocking();
-
         doReturn(mIActivityManager).when(ActivityManager::getService);
         doReturn(mDeviceIdleInternal).when(
                 () -> LocalServices.getService(DeviceIdleInternal.class));
@@ -512,10 +520,16 @@
         setTareEnabled(EconomyManager.ENABLED_MODE_OFF);
         mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW;
         mAllowWhileIdleWindow = mService.mConstants.ALLOW_WHILE_IDLE_WINDOW;
-        ArgumentCaptor<AppStandbyInternal.AppIdleStateChangeListener> captor =
+
+        ArgumentCaptor<AppStandbyInternal.AppIdleStateChangeListener> idleListenerCaptor =
                 ArgumentCaptor.forClass(AppStandbyInternal.AppIdleStateChangeListener.class);
-        verify(mAppStandbyInternal).addListener(captor.capture());
-        mAppStandbyListener = captor.getValue();
+        verify(mAppStandbyInternal).addListener(idleListenerCaptor.capture());
+        mAppStandbyListener = idleListenerCaptor.getValue();
+
+        final ArgumentCaptor<AppStateTrackerImpl.Listener> trackerListenerCaptor =
+                ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
+        verify(mAppStateTracker).addListener(trackerListenerCaptor.capture());
+        mListener = trackerListenerCaptor.getValue();
 
         final ArgumentCaptor<AlarmManagerService.ChargingReceiver> chargingReceiverCaptor =
                 ArgumentCaptor.forClass(AlarmManagerService.ChargingReceiver.class);
@@ -610,8 +624,13 @@
     }
 
     private void setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener) {
-        mService.setImpl(type, triggerTime, WINDOW_EXACT, 0, null, listener, "test",
-                FLAG_STANDALONE, null, null, TEST_CALLING_UID, TEST_CALLING_PACKAGE, null, 0);
+        setTestAlarmWithListener(type, triggerTime, listener, WINDOW_EXACT, TEST_CALLING_UID);
+    }
+
+    private void setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener,
+            long windowLength, int callingUid) {
+        mService.setImpl(type, triggerTime, windowLength, 0, null, listener, "test",
+                FLAG_STANDALONE, null, null, callingUid, TEST_CALLING_PACKAGE, null, 0);
     }
 
     private PendingIntent getNewMockPendingIntent() {
@@ -635,6 +654,15 @@
         return mockPi;
     }
 
+    private IAlarmListener getNewListener(Runnable onAlarm) {
+        return new IAlarmListener.Stub() {
+            @Override
+            public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+                onAlarm.run();
+            }
+        };
+    }
+
     private void setDeviceConfigInt(String key, int val) {
         mDeviceConfigKeys.add(key);
         doReturn(val).when(mDeviceConfigProperties).getInt(eq(key), anyInt());
@@ -1210,10 +1238,6 @@
 
     @Test
     public void testAlarmRestrictedByFAS() throws Exception {
-        final ArgumentCaptor<AppStateTrackerImpl.Listener> listenerArgumentCaptor =
-                ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
-        verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
-
         final PendingIntent alarmPi = getNewMockPendingIntent();
         when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID,
                 TEST_CALLING_PACKAGE)).thenReturn(true);
@@ -1228,7 +1252,7 @@
         mTestTimer.expire();
         assertNotNull(restrictedAlarms.get(TEST_CALLING_UID));
 
-        listenerArgumentCaptor.getValue().unblockAlarmsForUid(TEST_CALLING_UID);
+        mListener.unblockAlarmsForUid(TEST_CALLING_UID);
         verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), any(),
                 any(Handler.class), isNull(), any());
         assertNull(restrictedAlarms.get(TEST_CALLING_UID));
@@ -1236,11 +1260,6 @@
 
     @Test
     public void alarmsRemovedOnAppStartModeDisabled() {
-        final ArgumentCaptor<AppStateTrackerImpl.Listener> listenerArgumentCaptor =
-                ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
-        verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
-        final AppStateTrackerImpl.Listener listener = listenerArgumentCaptor.getValue();
-
         final PendingIntent alarmPi1 = getNewMockPendingIntent();
         final PendingIntent alarmPi2 = getNewMockPendingIntent();
 
@@ -1251,7 +1270,7 @@
 
         when(mActivityManagerInternal.isAppStartModeDisabled(TEST_CALLING_UID,
                 TEST_CALLING_PACKAGE)).thenReturn(true);
-        listener.removeAlarmsForUid(TEST_CALLING_UID);
+        mListener.removeAlarmsForUid(TEST_CALLING_UID);
         assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
     }
 
@@ -1302,9 +1321,8 @@
     @Test
     public void alarmCountOnSetPi() {
         final int numAlarms = 103;
-        final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
         for (int i = 1; i <= numAlarms; i++) {
-            setTestAlarm(types[i % 4], mNowElapsedTest + i, getNewMockPendingIntent());
+            setTestAlarm(ALARM_TYPES[i % 4], mNowElapsedTest + i, getNewMockPendingIntent());
             assertEquals(i, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
         }
     }
@@ -1312,13 +1330,9 @@
     @Test
     public void alarmCountOnSetListener() {
         final int numAlarms = 103;
-        final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
         for (int i = 1; i <= numAlarms; i++) {
-            setTestAlarmWithListener(types[i % 4], mNowElapsedTest + i, new IAlarmListener.Stub() {
-                @Override
-                public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
-                }
-            });
+            setTestAlarmWithListener(ALARM_TYPES[i % 4], mNowElapsedTest + i,
+                    getNewListener(() -> {}));
             assertEquals(i, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
         }
     }
@@ -1343,12 +1357,7 @@
         final int numAlarms = 8; // This test is slow
         for (int i = 0; i < numAlarms; i++) {
             setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 10,
-                    new IAlarmListener.Stub() {
-                        @Override
-                        public void doAlarm(IAlarmCompleteListener callback)
-                                throws RemoteException {
-                        }
-                    });
+                    getNewListener(() -> {}));
         }
         int expired = 0;
         while (expired < numAlarms) {
@@ -1381,12 +1390,9 @@
     public void alarmCountOnExceptionWhileCallingListener() throws Exception {
         final int numAlarms = 5; // This test is slow
         for (int i = 0; i < numAlarms; i++) {
-            final IAlarmListener listener = new IAlarmListener.Stub() {
-                @Override
-                public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
-                    throw new RemoteException("For testing behavior on exception");
-                }
-            };
+            final IAlarmListener listener = getNewListener(() -> {
+                throw new RuntimeException("For testing behavior on exception");
+            });
             setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 10, listener);
         }
         int expired = 0;
@@ -1473,7 +1479,7 @@
 
     @Test
     public void alarmTypes() throws Exception {
-        final int[] typesToSet = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, RTC_WAKEUP, RTC};
+        final int[] typesToSet = ALARM_TYPES;
         final int[] typesExpected = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME,
                 ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
         assertAlarmTypeConversion(typesToSet, typesExpected);
@@ -1512,11 +1518,7 @@
         final int numAlarms = 10;
         final IAlarmListener[] listeners = new IAlarmListener[numAlarms];
         for (int i = 0; i < numAlarms; i++) {
-            listeners[i] = new IAlarmListener.Stub() {
-                @Override
-                public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
-                }
-            };
+            listeners[i] = getNewListener(() -> {});
             setTestAlarmWithListener(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + i, listeners[i]);
         }
         assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
@@ -1559,13 +1561,10 @@
         final int numAlarms = 5;
         final AtomicInteger alarmsFired = new AtomicInteger(0);
         for (int i = 0; i < numAlarms; i++) {
-            final IAlarmListener listener = new IAlarmListener.Stub() {
-                @Override
-                public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
-                    alarmsFired.incrementAndGet();
-                    mService.mPendingNonWakeupAlarms.clear();
-                }
-            };
+            final IAlarmListener listener = getNewListener(() -> {
+                alarmsFired.incrementAndGet();
+                mService.mPendingNonWakeupAlarms.clear();
+            });
             setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 5, listener);
         }
         doReturn(true).when(mService).checkAllowNonWakeupDelayLocked(anyLong());
@@ -1953,11 +1952,6 @@
 
     @Test
     public void batterySaverThrottling() {
-        final ArgumentCaptor<AppStateTrackerImpl.Listener> listenerArgumentCaptor =
-                ArgumentCaptor.forClass(AppStateTrackerImpl.Listener.class);
-        verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
-        final AppStateTrackerImpl.Listener listener = listenerArgumentCaptor.getValue();
-
         when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
                 TEST_CALLING_PACKAGE)).thenReturn(true);
 
@@ -1967,12 +1961,12 @@
 
         when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
                 TEST_CALLING_PACKAGE)).thenReturn(false);
-        listener.updateAllAlarms();
+        mListener.updateAllAlarms();
         assertEquals(mNowElapsedTest + 7, mTestTimer.getElapsed());
 
         when(mAppStateTracker.areAlarmsRestrictedByBatterySaver(TEST_CALLING_UID,
                 TEST_CALLING_PACKAGE)).thenReturn(true);
-        listener.updateAlarmsForUid(TEST_CALLING_UID);
+        mListener.updateAlarmsForUid(TEST_CALLING_UID);
         assertEquals(mNowElapsedTest + INDEFINITE_DELAY, mTestTimer.getElapsed());
     }
 
@@ -2226,6 +2220,7 @@
     private void mockChangeEnabled(long changeId, boolean enabled) {
         doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(),
                 any(UserHandle.class)));
+        doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyInt()));
     }
 
     @Test
@@ -3750,11 +3745,69 @@
         testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_RARE);
     }
 
-    @After
-    public void tearDown() {
-        if (mMockingSession != null) {
-            mMockingSession.finishMocking();
+    @Test
+    public void exactListenerAlarmsRemovedOnCached() {
+        mockChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, true);
+
+        setTestAlarmWithListener(ELAPSED_REALTIME, 31, getNewListener(() -> {}), WINDOW_EXACT,
+                TEST_CALLING_UID);
+        setTestAlarmWithListener(RTC, 42, getNewListener(() -> {}), 56, TEST_CALLING_UID);
+        setTestAlarm(ELAPSED_REALTIME, 54, WINDOW_EXACT, getNewMockPendingIntent(), 0, 0,
+                TEST_CALLING_UID, null);
+        setTestAlarm(RTC, 49, 154, getNewMockPendingIntent(), 0, 0, TEST_CALLING_UID, null);
+
+        setTestAlarmWithListener(ELAPSED_REALTIME, 21, getNewListener(() -> {}), WINDOW_EXACT,
+                TEST_CALLING_UID_2);
+        setTestAlarmWithListener(RTC, 412, getNewListener(() -> {}), 561, TEST_CALLING_UID_2);
+        setTestAlarm(ELAPSED_REALTIME, 26, WINDOW_EXACT, getNewMockPendingIntent(), 0, 0,
+                TEST_CALLING_UID_2, null);
+        setTestAlarm(RTC, 549, 234, getNewMockPendingIntent(), 0, 0, TEST_CALLING_UID_2, null);
+
+        assertEquals(8, mService.mAlarmStore.size());
+
+        mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID);
+        assertEquals(7, mService.mAlarmStore.size());
+
+        mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2);
+        assertEquals(6, mService.mAlarmStore.size());
+    }
+
+    @Test
+    public void alarmCountOnListenerCached() {
+        mockChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, true);
+
+        // Set some alarms for TEST_CALLING_UID.
+        final int numExactListenerUid1 = 14;
+        for (int i = 0; i < numExactListenerUid1; i++) {
+            setTestAlarmWithListener(ALARM_TYPES[i % 4], mNowElapsedTest + i,
+                    getNewListener(() -> {}));
         }
+        setTestAlarmWithListener(RTC, 42, getNewListener(() -> {}), 56, TEST_CALLING_UID);
+        setTestAlarm(ELAPSED_REALTIME, 54, getNewMockPendingIntent());
+        setTestAlarm(RTC, 49, 154, getNewMockPendingIntent(), 0, 0, TEST_CALLING_UID, null);
+
+        // Set some alarms for TEST_CALLING_UID_2.
+        final int numExactListenerUid2 = 9;
+        for (int i = 0; i < numExactListenerUid2; i++) {
+            setTestAlarmWithListener(ALARM_TYPES[i % 4], mNowElapsedTest + i,
+                    getNewListener(() -> {}), WINDOW_EXACT, TEST_CALLING_UID_2);
+        }
+        setTestAlarmWithListener(RTC, 412, getNewListener(() -> {}), 561, TEST_CALLING_UID_2);
+        setTestAlarm(RTC_WAKEUP, 26, WINDOW_EXACT, getNewMockPendingIntent(), 0, 0,
+                TEST_CALLING_UID_2, null);
+
+        assertEquals(numExactListenerUid1 + 3, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        assertEquals(numExactListenerUid2 + 2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
+
+        mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID);
+        assertEquals(3, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+
+        mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2);
+        assertEquals(2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
+    }
+
+    @Override
+    public void afterSessionFinished() {
         LocalServices.removeServiceForTest(AlarmManagerInternal.class);
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java
index 961fc18..1c0989c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java
@@ -247,7 +247,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return mAppOpsService;
         }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index 4a40b5f..419351d4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -1069,7 +1069,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return mAppOpsService;
         }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
new file mode 100644
index 0000000..7c5d96e
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.os.Process.myPid;
+import static android.os.Process.myUid;
+
+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.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManagerInternal;
+import android.app.IApplicationThread;
+import android.app.usage.UsageStatsManagerInternal;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManagerInternal;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.util.Log;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.DropBoxManagerInternal;
+import com.android.server.LocalServices;
+import com.android.server.am.ActivityManagerService.Injector;
+import com.android.server.appop.AppOpsService;
+import com.android.server.wm.ActivityTaskManagerInternal;
+import com.android.server.wm.ActivityTaskManagerService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.util.Arrays;
+
+
+/**
+ * Tests to verify process starts are completed or timeout correctly
+ */
+@MediumTest
+@SuppressWarnings("GuardedBy")
+public class AsyncProcessStartTest {
+    private static final String TAG = "AsyncProcessStartTest";
+
+    private static final String PACKAGE = "com.foo";
+
+    @Rule
+    public final ApplicationExitInfoTest.ServiceThreadRule
+            mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
+
+    private Context mContext;
+    private HandlerThread mHandlerThread;
+
+    @Mock
+    private AppOpsService mAppOpsService;
+    @Mock
+    private DropBoxManagerInternal mDropBoxManagerInt;
+    @Mock
+    private PackageManagerInternal mPackageManagerInt;
+    @Mock
+    private UsageStatsManagerInternal mUsageStatsManagerInt;
+    @Mock
+    private ActivityManagerInternal mActivityManagerInt;
+    @Mock
+    private ActivityTaskManagerInternal mActivityTaskManagerInt;
+    @Mock
+    private BatteryStatsService mBatteryStatsService;
+
+    private ActivityManagerService mRealAms;
+    private ActivityManagerService mAms;
+
+    private ProcessList mRealProcessList = new ProcessList();
+    private ProcessList mProcessList;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+
+        LocalServices.removeServiceForTest(DropBoxManagerInternal.class);
+        LocalServices.addService(DropBoxManagerInternal.class, mDropBoxManagerInt);
+
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt);
+
+        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+        LocalServices.addService(ActivityManagerInternal.class, mActivityManagerInt);
+
+        LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
+        LocalServices.addService(ActivityTaskManagerInternal.class, mActivityTaskManagerInt);
+
+        doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent();
+        doReturn(true).when(mActivityTaskManagerInt).attachApplication(any());
+        doNothing().when(mActivityTaskManagerInt).onProcessMapped(anyInt(), any());
+
+        mRealAms = new ActivityManagerService(
+                new TestInjector(mContext), mServiceThreadRule.getThread());
+        mRealAms.mActivityTaskManager = new ActivityTaskManagerService(mContext);
+        mRealAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper());
+        mRealAms.mAtmInternal = mActivityTaskManagerInt;
+        mRealAms.mPackageManagerInt = mPackageManagerInt;
+        mRealAms.mUsageStatsService = mUsageStatsManagerInt;
+        mRealAms.mProcessesReady = true;
+        mAms = spy(mRealAms);
+        mRealProcessList.mService = mAms;
+        mProcessList = spy(mRealProcessList);
+
+        doAnswer((invocation) -> {
+            Log.v(TAG, "Intercepting isProcStartValidLocked() for "
+                    + Arrays.toString(invocation.getArguments()));
+            return null;
+        }).when(mProcessList).isProcStartValidLocked(any(), anyLong());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mHandlerThread.quit();
+    }
+
+    private class TestInjector extends Injector {
+        TestInjector(Context context) {
+            super(context);
+        }
+
+        @Override
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
+            return mAppOpsService;
+        }
+
+        @Override
+        public Handler getUiHandler(ActivityManagerService service) {
+            return mHandlerThread.getThreadHandler();
+        }
+
+        @Override
+        public ProcessList getProcessList(ActivityManagerService service) {
+            return mRealProcessList;
+        }
+
+        @Override
+        public BatteryStatsService getBatteryStatsService() {
+            return mBatteryStatsService;
+        }
+    }
+
+    private ProcessRecord makeActiveProcessRecord(String packageName, boolean wedge)
+            throws Exception {
+        final ApplicationInfo ai = makeApplicationInfo(packageName);
+        return makeActiveProcessRecord(ai, wedge);
+    }
+
+    private ProcessRecord makeActiveProcessRecord(ApplicationInfo ai, boolean wedge)
+            throws Exception {
+        final IApplicationThread thread = mock(IApplicationThread.class);
+        final IBinder threadBinder = new Binder();
+        doReturn(threadBinder).when(thread).asBinder();
+        doAnswer((invocation) -> {
+            Log.v(TAG, "Intercepting bindApplication() for "
+                    + Arrays.toString(invocation.getArguments()));
+            if (!wedge) {
+                mRealAms.finishAttachApplication(0);
+            }
+            return null;
+        }).when(thread).bindApplication(
+                any(), any(),
+                any(), any(),
+                any(), any(),
+                any(), any(),
+                any(),
+                any(), anyInt(),
+                anyBoolean(), anyBoolean(),
+                anyBoolean(), anyBoolean(), any(),
+                any(), any(), any(),
+                any(), any(),
+                any(), any(),
+                any(),
+                anyLong(), anyLong());
+
+        final ProcessRecord r = spy(new ProcessRecord(mAms, ai, ai.processName, ai.uid));
+        r.setPid(myPid());
+        r.setStartUid(myUid());
+        r.setHostingRecord(new HostingRecord(HostingRecord.HOSTING_TYPE_BROADCAST));
+        r.makeActive(thread, mAms.mProcessStats);
+        doNothing().when(r).killLocked(any(), any(), anyInt(), anyInt(), anyBoolean(),
+                anyBoolean());
+
+        return r;
+    }
+
+    static ApplicationInfo makeApplicationInfo(String packageName) {
+        final ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = packageName;
+        ai.processName = packageName;
+        ai.uid = myUid();
+        return ai;
+    }
+
+    /**
+     * Verify that we don't kill a normal process
+     */
+    @Test
+    public void testNormal() throws Exception {
+        ProcessRecord app = startProcessAndWait(false);
+
+        verify(app, never()).killLocked(any(), anyInt(), anyBoolean());
+    }
+
+    /**
+     * Verify that we kill a wedged process after the process start timeout
+     */
+    @Test
+    public void testWedged() throws Exception {
+        ProcessRecord app = startProcessAndWait(true);
+
+        verify(app).killLocked(any(), anyInt(), anyBoolean());
+    }
+
+    private ProcessRecord startProcessAndWait(boolean wedge) throws Exception {
+        final ProcessRecord app = makeActiveProcessRecord(PACKAGE, wedge);
+        final ApplicationInfo appInfo = makeApplicationInfo(PACKAGE);
+
+        mProcessList.handleProcessStartedLocked(app, app.getPid(), /* usingWrapper */ false,
+                /* expectedStartSeq */ 0, /* procAttached */ false);
+
+        app.getThread().bindApplication(PACKAGE, appInfo,
+                null, null,
+                null,
+                null,
+                null, null,
+                null,
+                null, 0,
+                false, false,
+                true, false,
+                null,
+                null, null,
+                null,
+                null, null, null,
+                null, null,
+                0, 0);
+
+        // Sleep until timeout should have triggered
+        SystemClock.sleep(ActivityManagerService.PROC_START_TIMEOUT + 1000);
+
+        return app;
+    }
+}
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 e0f9be4..ad224df5 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -60,11 +60,13 @@
 import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.BundleMerger;
+import android.os.DropBoxManager;
 import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.IndentingPrintWriter;
+import android.util.Pair;
 
 import androidx.test.filters.SmallTest;
 
@@ -978,6 +980,59 @@
     }
 
     @Test
+    public void testDeliveryGroupPolicy_merged_matchingFilter() {
+        final long now = SystemClock.elapsedRealtime();
+        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast1 = createDropboxBroadcast(
+                "TAG_A", now, 2);
+        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast2 = createDropboxBroadcast(
+                "TAG_B", now + 1000, 4);
+        final Pair<Intent, BroadcastOptions> dropboxEntryBroadcast3 = createDropboxBroadcast(
+                "TAG_A", now + 2000, 7);
+
+        // Halt all processing so that we get a consistent view
+        mHandlerThread.getLooper().getQueue().postSyncBarrier();
+
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast1.first,
+                dropboxEntryBroadcast1.second));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast2.first,
+                dropboxEntryBroadcast2.second));
+        mImpl.enqueueBroadcastLocked(makeBroadcastRecord(dropboxEntryBroadcast3.first,
+                dropboxEntryBroadcast3.second));
+
+        final BroadcastProcessQueue queue = mImpl.getProcessQueue(PACKAGE_GREEN,
+                getUidForPackage(PACKAGE_GREEN));
+        // dropboxEntryBroadcast1 and dropboxEntryBroadcast3 should be merged as they use the same
+        // tag and there shouldn't be a change to dropboxEntryBroadcast2.
+        final Pair<Intent, BroadcastOptions> expectedMergedBroadcast = createDropboxBroadcast(
+                "TAG_A", now + 2000, 10);
+        verifyPendingRecords(queue, List.of(
+                dropboxEntryBroadcast2.first, expectedMergedBroadcast.first));
+    }
+
+    private Pair<Intent, BroadcastOptions> createDropboxBroadcast(String tag, long timestampMs,
+            int droppedCount) {
+        final Intent dropboxEntryAdded = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
+        dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_TAG, tag);
+        dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_TIME, timestampMs);
+        dropboxEntryAdded.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, droppedCount);
+
+        final BundleMerger extrasMerger = new BundleMerger();
+        extrasMerger.setDefaultMergeStrategy(BundleMerger.STRATEGY_FIRST);
+        extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_TIME,
+                BundleMerger.STRATEGY_COMPARABLE_MAX);
+        extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
+                BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);
+        final IntentFilter matchingFilter = new IntentFilter(
+                DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
+        matchingFilter.addExtra(DropBoxManager.EXTRA_TAG, tag);
+        final BroadcastOptions optionsDropboxEntryAdded = BroadcastOptions.makeBasic()
+                .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED)
+                .setDeliveryGroupMatchingFilter(matchingFilter)
+                .setDeliveryGroupExtrasMerger(extrasMerger);
+        return Pair.create(dropboxEntryAdded, optionsDropboxEntryAdded);
+    }
+
+    @Test
     public void testVerifyEnqueuedTime_withReplacePending() {
         final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
         userPresent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
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 5e4ba88..458c9cfc 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -372,7 +372,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return mAppOpsService;
         }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
index 766ba72..434d200 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
@@ -793,7 +793,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return mAppOpsService;
         }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
index 64e39ef..3fd0e07 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
@@ -49,6 +49,7 @@
 import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -63,6 +64,8 @@
  */
 @Presubmit
 @RunWith(MockitoJUnitRunner.class)
+@Ignore("TODO(b/226641572): this test is broken and it cannot use ExtendedMockitoTestCase as it "
+        + "uses TestableDeviceConfigRule, which creates its own mockito session")
 public final class CachedAppOptimizerTest {
 
     private ServiceThread mThread;
@@ -1157,7 +1160,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return mAppOpsService;
         }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 9f7b72c..fb05699 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -17,7 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
-import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL;
 import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
 import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
@@ -38,6 +38,7 @@
 import static android.app.ActivityManager.PROCESS_STATE_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING;
 import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
@@ -226,6 +227,15 @@
         }
     }
 
+    private static void assertBfsl(ProcessRecord app) {
+        assertEquals(PROCESS_CAPABILITY_BFSL,
+                app.mState.getSetCapability() & PROCESS_CAPABILITY_BFSL);
+    }
+
+    private static void assertNoBfsl(ProcessRecord app) {
+        assertEquals(0, app.mState.getSetCapability() & PROCESS_CAPABILITY_BFSL);
+    }
+
     /**
      * Replace the process LRU with the given processes.
      * @param apps
@@ -264,6 +274,7 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, PERSISTENT_PROC_ADJ,
                 SCHED_GROUP_RESTRICTED);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -335,6 +346,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, FOREGROUND_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -447,6 +459,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -460,6 +473,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -471,7 +485,7 @@
         ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(sService);
         s.startRequested = true;
         s.isForeground = true;
-        s.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+        s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
         s.setShortFgsInfo(SystemClock.uptimeMillis());
 
         // SHORT_SERVICE FGS will get IMP_FG and a slightly different recent-adjustment.
@@ -480,16 +494,15 @@
                     MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
             app.mServices.startService(s);
             app.mServices.setHasForegroundServices(true,
-                    ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+                    FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
             app.mState.setLastTopTime(SystemClock.uptimeMillis());
             sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
 
             updateOomAdj(app);
 
-            assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND,
+            assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE,
                     PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1, SCHED_GROUP_DEFAULT);
-            // Should get network access.
-            assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0);
+            assertNoBfsl(app);
         }
 
         // SHORT_SERVICE, but no longer recent.
@@ -497,7 +510,7 @@
             ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
                     MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
             app.mServices.setHasForegroundServices(true,
-                    ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+                    FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
             app.mServices.startService(s);
             app.mState.setLastTopTime(SystemClock.uptimeMillis()
                     - sService.mConstants.TOP_TO_FGS_GRACE_DURATION);
@@ -505,17 +518,16 @@
 
             updateOomAdj(app);
 
-            assertProcStates(app, PROCESS_STATE_IMPORTANT_FOREGROUND,
+            assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE,
                     PERCEPTIBLE_MEDIUM_APP_ADJ + 1, SCHED_GROUP_DEFAULT);
-            // Still should get network access.
-            assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) != 0);
+            assertNoBfsl(app);
         }
 
         // SHORT_SERVICE, timed out already.
         s = ServiceRecord.newEmptyInstanceForTest(sService);
         s.startRequested = true;
         s.isForeground = true;
-        s.foregroundServiceType = ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+        s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
         s.setShortFgsInfo(SystemClock.uptimeMillis()
                 - sService.mConstants.mShortFgsTimeoutDuration
                 - sService.mConstants.mShortFgsProcStateExtraWaitDuration);
@@ -523,7 +535,7 @@
             ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
                     MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
             app.mServices.setHasForegroundServices(true,
-                    ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
+                    FOREGROUND_SERVICE_TYPE_SHORT_SERVICE, /* hasNoneType=*/false);
             app.mServices.startService(s);
             app.mState.setLastTopTime(SystemClock.uptimeMillis()
                     - sService.mConstants.TOP_TO_FGS_GRACE_DURATION);
@@ -533,9 +545,7 @@
 
             // Procstate should be lower than FGS. (It should be SERVICE)
             assertEquals(app.mState.getSetProcState(), PROCESS_STATE_SERVICE);
-
-            // Shouldn't have the network capability now.
-            assertTrue((app.mState.getSetCapability() & PROCESS_CAPABILITY_NETWORK) == 0);
+            assertNoBfsl(app);
         }
     }
 
@@ -564,6 +574,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE,
                 PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -925,6 +936,7 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, VISIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -940,6 +952,7 @@
         updateOomAdj(client, app);
 
         assertEquals(FOREGROUND_APP_ADJ, app.mState.getSetAdj());
+        assertNoBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -973,6 +986,8 @@
 
         assertEquals(PROCESS_STATE_BOUND_FOREGROUND_SERVICE, app.mState.getSetProcState());
         assertEquals(PROCESS_STATE_PERSISTENT, client.mState.getSetProcState());
+        assertBfsl(client);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -988,6 +1003,7 @@
         updateOomAdj(app);
 
         assertEquals(PROCESS_STATE_TRANSIENT_BACKGROUND, app.mState.getSetProcState());
+        assertNoBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1002,7 +1018,92 @@
         sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(client, app);
 
+        assertEquals(PROCESS_STATE_FOREGROUND_SERVICE, client.mState.getSetProcState());
+        assertBfsl(client);
         assertEquals(PROCESS_STATE_FOREGROUND_SERVICE, app.mState.getSetProcState());
+        assertBfsl(app);
+    }
+
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testUpdateOomAdj_DoOne_Service_ImportantFgService_ShortFgs() {
+        // Client has a SHORT_SERVICE FGS, which isn't allowed BFSL.
+        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+        ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+                MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+        bindService(app, client, null, 0, mock(IBinder.class));
+
+        // In order to trick OomAdjuster to think it has a short-service, we need this logic.
+        ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(sService);
+        s.startRequested = true;
+        s.isForeground = true;
+        s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+        s.setShortFgsInfo(SystemClock.uptimeMillis());
+        client.mServices.startService(s);
+        client.mState.setLastTopTime(SystemClock.uptimeMillis());
+
+        client.mServices.setHasForegroundServices(true, FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+                /* hasNoneType=*/false);
+        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+        updateOomAdj(client, app);
+
+        // Client only has a SHORT_FGS, so it doesn't have BFSL, and that's propagated.
+        assertEquals(PROCESS_STATE_FOREGROUND_SERVICE, client.mState.getSetProcState());
+        assertNoBfsl(client);
+        assertEquals(PROCESS_STATE_FOREGROUND_SERVICE, app.mState.getSetProcState());
+        assertNoBfsl(app);
+    }
+
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testUpdateOomAdj_DoOne_Service_BoundForegroundService_with_ShortFgs() {
+
+        // app2, which is bound by app1 (which makes it BFGS)
+        // but it also has a short-fgs.
+        ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP3_PID, MOCKAPP3_UID,
+                MOCKAPP3_PROCESSNAME, MOCKAPP3_PACKAGENAME, false));
+
+        // In order to trick OomAdjuster to think it has a short-service, we need this logic.
+        ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(sService);
+        s.startRequested = true;
+        s.isForeground = true;
+        s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+        s.setShortFgsInfo(SystemClock.uptimeMillis());
+        app2.mServices.startService(s);
+        app2.mState.setLastTopTime(SystemClock.uptimeMillis());
+
+        app2.mServices.setHasForegroundServices(true, FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+                /* hasNoneType=*/false);
+        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+        updateOomAdj(app2);
+
+        // Client only has a SHORT_FGS, so it doesn't have BFSL, and that's propagated.
+        assertEquals(PROCESS_STATE_FOREGROUND_SERVICE, app2.mState.getSetProcState());
+        assertNoBfsl(app2);
+
+        // Now, create a BFGS process (app1), and make it bind to app 2
+
+        // Persistent process
+        ProcessRecord pers = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+        pers.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
+
+        // app1, which is bound by pers (which makes it BFGS)
+        ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+                MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+
+        bindService(app1, pers, null, Context.BIND_FOREGROUND_SERVICE, mock(IBinder.class));
+        bindService(app2, app1, null, 0, mock(IBinder.class));
+
+        updateOomAdj(pers, app1, app2);
+
+        assertEquals(PROCESS_STATE_BOUND_FOREGROUND_SERVICE, app1.mState.getSetProcState());
+        assertBfsl(app1);
+
+        // Now, app2 gets BFSL from app1.
+        assertEquals(PROCESS_STATE_FOREGROUND_SERVICE, app2.mState.getSetProcState());
+        assertBfsl(app2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1022,11 +1123,13 @@
         doReturn(null).when(sService.mBackupTargets).get(anyInt());
 
         assertEquals(BACKUP_APP_ADJ, app.mState.getSetAdj());
+        assertNoBfsl(app);
 
         client.mState.setMaxAdj(PERSISTENT_PROC_ADJ);
         updateOomAdj(app);
 
         assertEquals(PERSISTENT_SERVICE_ADJ, app.mState.getSetAdj());
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1172,6 +1275,7 @@
         updateOomAdj(client, app);
 
         assertEquals(PROCESS_STATE_IMPORTANT_BACKGROUND, app.mState.getSetProcState());
+        assertNoBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1231,6 +1335,42 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+    }
+
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testUpdateOomAdj_DoOne_Provider_FgService_ShortFgs() {
+        // Client has a SHORT_SERVICE FGS, which isn't allowed BFSL.
+        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+        ProcessRecord client = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
+                MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
+
+        // In order to trick OomAdjuster to think it has a short-service, we need this logic.
+        ServiceRecord s = ServiceRecord.newEmptyInstanceForTest(sService);
+        s.startRequested = true;
+        s.isForeground = true;
+        s.foregroundServiceType = FOREGROUND_SERVICE_TYPE_SHORT_SERVICE;
+        s.setShortFgsInfo(SystemClock.uptimeMillis());
+        client.mServices.startService(s);
+        client.mState.setLastTopTime(SystemClock.uptimeMillis());
+
+        client.mServices.setHasForegroundServices(true, FOREGROUND_SERVICE_TYPE_SHORT_SERVICE,
+                /* hasNoneType=*/false);
+        bindProvider(app, client, null, null, false);
+        sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
+        updateOomAdj(client, app);
+
+        // Client only has a SHORT_FGS, so it doesn't have BFSL, and that's propagated.
+        assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE,
+                PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1,
+                SCHED_GROUP_DEFAULT);
+        assertNoBfsl(client);
+        assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE,
+                PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1,
+                SCHED_GROUP_DEFAULT);
+        assertNoBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1299,6 +1439,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1318,6 +1459,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1346,6 +1488,9 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(client2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(client);
+        assertBfsl(client2);
 
         client2.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false);
         sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
@@ -1354,6 +1499,9 @@
         assertEquals(PROCESS_STATE_CACHED_EMPTY, client2.mState.getSetProcState());
         assertEquals(PROCESS_STATE_CACHED_EMPTY, client.mState.getSetProcState());
         assertEquals(PROCESS_STATE_CACHED_EMPTY, app.mState.getSetProcState());
+        assertNoBfsl(app);
+        assertNoBfsl(client);
+        assertNoBfsl(client2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1378,6 +1526,9 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(client2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(client);
+        assertBfsl(client2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1402,6 +1553,9 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(client2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(client);
+        assertBfsl(client2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1437,6 +1591,11 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(client4, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(client);
+        assertBfsl(client2);
+        assertBfsl(client3);
+        assertBfsl(client4);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1461,6 +1620,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1542,6 +1702,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1567,6 +1728,7 @@
 
         assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1586,6 +1748,7 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1606,6 +1769,7 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1625,6 +1789,7 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1645,6 +1810,7 @@
 
         assertProcStates(app, PROCESS_STATE_BOUND_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1672,6 +1838,8 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app1);
+        assertBfsl(app2);
 
         bindService(app1, client1, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class));
         bindService(app2, client2, null, Context.BIND_SCHEDULE_LIKE_TOP_APP, mock(IBinder.class));
@@ -1688,6 +1856,7 @@
                 SCHED_GROUP_TOP_APP);
         assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1770,6 +1939,7 @@
 
         assertProcStates(app1, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app1);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1790,6 +1960,7 @@
 
         assertProcStates(app1, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app1);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1912,6 +2083,7 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1931,6 +2103,8 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(app2);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -1964,6 +2138,9 @@
         assertEquals(false, app.mState.isEmpty());
         assertEquals(false, app2.mState.isEmpty());
         assertEquals(false, app3.mState.isEmpty());
+        assertBfsl(app);
+        assertBfsl(app2);
+        assertBfsl(app3);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -2001,6 +2178,11 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app5, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(app2);
+        assertBfsl(app3);
+        // 4 is IMP_FG
+        assertBfsl(app5);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -2038,6 +2220,11 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app5, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(app2);
+        assertBfsl(app3);
+        // 4 is IMP_FG
+        assertBfsl(app5);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -2075,6 +2262,11 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app5, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(app2);
+        assertBfsl(app3);
+        // 4 is IMP_FG
+        assertBfsl(app5);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -2096,7 +2288,7 @@
         sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(app, client, client2, client3);
 
-        final int expected = PROCESS_CAPABILITY_ALL;
+        final int expected = PROCESS_CAPABILITY_ALL & ~PROCESS_CAPABILITY_BFSL;
         assertEquals(expected, client.mState.getSetCapability());
         assertEquals(expected, client2.mState.getSetCapability());
         assertEquals(expected, app.mState.getSetCapability());
@@ -2137,6 +2329,11 @@
                 SCHED_GROUP_DEFAULT);
         assertProcStates(app5, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT);
+        assertBfsl(app);
+        assertBfsl(app2);
+        assertBfsl(app3);
+        // 4 is IMP_FG
+        assertBfsl(app5);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -2444,6 +2641,15 @@
         assertEquals(expectedProcState, state.getSetProcState());
         assertEquals(expectedAdj, state.getSetAdj());
         assertEquals(expectedSchedGroup, state.getSetSchedGroup());
+
+        // Below BFGS should never have BFSL.
+        if (expectedProcState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+            assertNoBfsl(app);
+        }
+        // Above FGS should always have BFSL.
+        if (expectedProcState < PROCESS_STATE_FOREGROUND_SERVICE) {
+            assertBfsl(app);
+        }
     }
 
     private void assertProcStates(ProcessRecord app, boolean expectedCached,
@@ -2453,5 +2659,14 @@
         assertEquals(expectedProcState, state.getSetProcState());
         assertEquals(expectedAdj, state.getSetAdj());
         assertEquals(expectedAdjType, state.getAdjType());
+
+        // Below BFGS should never have BFSL.
+        if (expectedProcState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+            assertNoBfsl(app);
+        }
+        // Above FGS should always have BFSL.
+        if (expectedProcState < PROCESS_STATE_FOREGROUND_SERVICE) {
+            assertBfsl(app);
+        }
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 52027e7..f86e464 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -57,7 +57,6 @@
 import com.android.server.LocalServices;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageStateInternal;
-import com.android.server.testutils.MockitoUtilsKt;
 
 import org.junit.After;
 import org.junit.Before;
@@ -80,12 +79,14 @@
 
     private static final String TAG = AppOpsServiceTest.class.getSimpleName();
     // State will be persisted into this XML file.
-    private static final String APP_OPS_FILENAME = "appops-service-test.xml";
+    private static final String APP_OPS_FILENAME = "appops.test.xml";
+    private static final String APP_OPS_ACCESSES_FILENAME = "appops_accesses.test.xml";
 
     private static final Context sContext = InstrumentationRegistry.getTargetContext();
     private static final String sMyPackageName = sContext.getOpPackageName();
 
-    private File mAppOpsFile;
+    private File mStorageFile;
+    private File mRecentAccessesFile;
     private Handler mHandler;
     private AppOpsService mAppOpsService;
     private int mMyUid;
@@ -93,7 +94,8 @@
     private StaticMockitoSession mMockingSession;
 
     private void setupAppOpsService() {
-        mAppOpsService = new AppOpsService(mAppOpsFile, mHandler, spy(sContext));
+        mAppOpsService = new AppOpsService(mRecentAccessesFile, mStorageFile, mHandler,
+                spy(sContext));
         mAppOpsService.mHistoricalRegistry.systemReady(sContext.getContentResolver());
 
         // Always approve all permission checks
@@ -103,11 +105,10 @@
 
     @Before
     public void setUp() {
-        mAppOpsFile = new File(sContext.getFilesDir(), APP_OPS_FILENAME);
-        if (mAppOpsFile.exists()) {
-            // Start with a clean state (persisted into XML).
-            mAppOpsFile.delete();
-        }
+        mStorageFile = new File(sContext.getFilesDir(), APP_OPS_FILENAME);
+        mRecentAccessesFile = new File(sContext.getFilesDir(), APP_OPS_ACCESSES_FILENAME);
+        mStorageFile.delete();
+        mRecentAccessesFile.delete();
 
         HandlerThread handlerThread = new HandlerThread(TAG);
         handlerThread.start();
@@ -212,10 +213,12 @@
         mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
         mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null,
                 false);
-        mAppOpsService.writeState();
+
+        mAppOpsService.shutdown();
 
         // Create a new app ops service which will initialize its state from XML.
         setupAppOpsService();
+        mAppOpsService.readState();
 
         // Query the state of the 2nd service.
         List<PackageOps> loggedOps = getLoggedOps();
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 9eed6ad..5474c20 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._NUM_OP;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -39,12 +40,13 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.UserPackage;
 import android.content.res.AssetManager;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
-import android.util.SparseIntArray;
 import android.util.Xml;
 
 import androidx.test.InstrumentationRegistry;
@@ -57,6 +59,7 @@
 import com.android.server.SystemServerInitThreadPool;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
+import com.android.server.pm.pkg.PackageStateInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -85,7 +88,6 @@
     private static final String APP_OPS_VERSION_1_ASSET_PATH =
             "AppOpsUpgradeTest/appops-version-1.xml";
     private static final String APP_OPS_FILENAME = "appops-test.xml";
-    private static final int NON_DEFAULT_OPS_IN_FILE = 4;
 
     private static final Context sContext = InstrumentationRegistry.getTargetContext();
     private static final File sAppOpsFile = new File(sContext.getFilesDir(), APP_OPS_FILENAME);
@@ -104,6 +106,9 @@
     @Mock
     private Handler mHandler;
 
+    private Object mLock = new Object();
+    private SparseArray<int[]> mSwitchedOps;
+
     private static void extractAppOpsFile(String assetPath) {
         sAppOpsFile.getParentFile().mkdirs();
         try (FileOutputStream out = new FileOutputStream(sAppOpsFile);
@@ -121,42 +126,6 @@
         }
     }
 
-    private void assertSameModes(SparseArray<AppOpsService.UidState> uidStates,
-            int op1, int op2) {
-        int numberOfNonDefaultOps = 0;
-        final int defaultModeOp1 = AppOpsManager.opToDefaultMode(op1);
-        final int defaultModeOp2 = AppOpsManager.opToDefaultMode(op2);
-        for (int i = 0; i < uidStates.size(); i++) {
-            final AppOpsService.UidState uidState = uidStates.valueAt(i);
-            SparseIntArray opModes = uidState.getNonDefaultUidModes();
-            if (opModes != null) {
-                final int uidMode1 = opModes.get(op1, defaultModeOp1);
-                final int uidMode2 = opModes.get(op2, defaultModeOp2);
-                assertEquals(uidMode1, uidMode2);
-                if (uidMode1 != defaultModeOp1) {
-                    numberOfNonDefaultOps++;
-                }
-            }
-            if (uidState.pkgOps == null) {
-                continue;
-            }
-            for (int j = 0; j < uidState.pkgOps.size(); j++) {
-                final AppOpsService.Ops ops = uidState.pkgOps.valueAt(j);
-                if (ops == null) {
-                    continue;
-                }
-                final AppOpsService.Op _op1 = ops.get(op1);
-                final AppOpsService.Op _op2 = ops.get(op2);
-                final int mode1 = (_op1 == null) ? defaultModeOp1 : _op1.getMode();
-                final int mode2 = (_op2 == null) ? defaultModeOp2 : _op2.getMode();
-                assertEquals(mode1, mode2);
-                if (mode1 != defaultModeOp1) {
-                    numberOfNonDefaultOps++;
-                }
-            }
-        }
-        assertEquals(numberOfNonDefaultOps, NON_DEFAULT_OPS_IN_FILE);
-    }
 
     @Before
     public void setUp() {
@@ -188,6 +157,24 @@
 
         // Stub out package calls to disable AppOpsService#updatePermissionRevokedCompat
         doReturn(null).when(mPackageManager).getPackagesForUid(anyInt());
+
+        doReturn(new ArrayMap<String, PackageStateInternal>()).when(mPackageManagerInternal)
+                .getPackageStates();
+
+        doReturn(new int[] {0}).when(mUserManagerInternal).getUserIds();
+
+        // Build mSwitchedOps
+        mSwitchedOps = buildSwitchedOpsArray();
+    }
+
+    private SparseArray<int[]> buildSwitchedOpsArray() {
+        SparseArray<int[]> switchedOps = new SparseArray<>();
+        for (int switchedCode = 0; switchedCode < _NUM_OP; switchedCode++) {
+            int switchCode = AppOpsManager.opToSwitch(switchedCode);
+            switchedOps.put(switchCode,
+                    ArrayUtils.appendInt(switchedOps.get(switchCode), switchedCode));
+        }
+        return switchedOps;
     }
 
     @After
@@ -199,13 +186,31 @@
     public void upgradeRunAnyInBackground() {
         extractAppOpsFile(APP_OPS_UNVERSIONED_ASSET_PATH);
 
-        AppOpsService testService = new AppOpsService(sAppOpsFile, mHandler, mTestContext);
+        AppOpsCheckingServiceImpl testService = new AppOpsCheckingServiceImpl(sAppOpsFile, mLock,
+                mHandler, mTestContext, mSwitchedOps);
+        testService.readState();
 
         testService.upgradeRunAnyInBackgroundLocked();
-        assertSameModes(testService.mUidStates, AppOpsManager.OP_RUN_IN_BACKGROUND,
+
+        assertSameModes(testService, AppOpsManager.OP_RUN_IN_BACKGROUND,
                 AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
     }
 
+    private void assertSameModes(AppOpsCheckingServiceImpl testService, int op1, int op2) {
+        for (int uid : testService.getUidsWithNonDefaultModes()) {
+            assertEquals(
+                    testService.getUidMode(uid, op1),
+                    testService.getUidMode(uid, op2)
+            );
+        }
+        for (UserPackage pkg : testService.getPackagesWithNonDefaultModes()) {
+            assertEquals(
+                    testService.getPackageMode(pkg.packageName, op1, pkg.userId),
+                    testService.getPackageMode(pkg.packageName, op2, pkg.userId)
+            );
+        }
+    }
+
     private static int getModeInFile(int uid) {
         switch (uid) {
             case 10198:
@@ -244,7 +249,9 @@
             return UserHandle.getUid(userId, appIds[index]);
         }).when(mPackageManagerInternal).getPackageUid(anyString(), anyLong(), anyInt());
 
-        AppOpsService testService = new AppOpsService(sAppOpsFile, mHandler, mTestContext);
+        AppOpsCheckingServiceImpl testService = new AppOpsCheckingServiceImpl(sAppOpsFile, mLock,
+                mHandler, mTestContext, mSwitchedOps);
+        testService.readState();
 
         testService.upgradeScheduleExactAlarmLocked();
 
@@ -259,8 +266,8 @@
                 } else {
                     expectedMode = previousMode;
                 }
-                final AppOpsService.UidState uidState = testService.mUidStates.get(uid);
-                assertEquals(expectedMode, uidState.getUidMode(OP_SCHEDULE_EXACT_ALARM));
+                int mode = testService.getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
+                assertEquals(expectedMode, mode);
             }
         }
 
@@ -268,9 +275,8 @@
         int[] unrelatedUidsInFile = {10225, 10178};
 
         for (int uid : unrelatedUidsInFile) {
-            final AppOpsService.UidState uidState = testService.mUidStates.get(uid);
-            assertEquals(AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM),
-                    uidState.getUidMode(OP_SCHEDULE_EXACT_ALARM));
+            int mode = testService.getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
+            assertEquals(AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM), mode);
         }
     }
 
@@ -278,8 +284,9 @@
     public void upgradeFromNoFile() {
         assertFalse(sAppOpsFile.exists());
 
-        AppOpsService testService = spy(
-                new AppOpsService(sAppOpsFile, mHandler, mTestContext));
+        AppOpsCheckingServiceImpl testService = spy(new AppOpsCheckingServiceImpl(sAppOpsFile,
+                mLock, mHandler, mTestContext, mSwitchedOps));
+        testService.readState();
 
         doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
         doNothing().when(testService).upgradeScheduleExactAlarmLocked();
@@ -296,7 +303,7 @@
 
         AppOpsDataParser parser = new AppOpsDataParser(sAppOpsFile);
         assertTrue(parser.parse());
-        assertEquals(AppOpsService.CURRENT_VERSION, parser.mVersion);
+        assertEquals(AppOpsCheckingServiceImpl.CURRENT_VERSION, parser.mVersion);
     }
 
     @Test
@@ -306,8 +313,9 @@
         assertTrue(parser.parse());
         assertEquals(AppOpsDataParser.NO_VERSION, parser.mVersion);
 
-        AppOpsService testService = spy(
-                new AppOpsService(sAppOpsFile, mHandler, mTestContext));
+        AppOpsCheckingServiceImpl testService = spy(new AppOpsCheckingServiceImpl(sAppOpsFile,
+                mLock, mHandler, mTestContext, mSwitchedOps));
+        testService.readState();
 
         doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
         doNothing().when(testService).upgradeScheduleExactAlarmLocked();
@@ -320,7 +328,7 @@
 
         testService.writeState();
         assertTrue(parser.parse());
-        assertEquals(AppOpsService.CURRENT_VERSION, parser.mVersion);
+        assertEquals(AppOpsCheckingServiceImpl.CURRENT_VERSION, parser.mVersion);
     }
 
     @Test
@@ -330,8 +338,9 @@
         assertTrue(parser.parse());
         assertEquals(1, parser.mVersion);
 
-        AppOpsService testService = spy(
-                new AppOpsService(sAppOpsFile, mHandler, mTestContext));
+        AppOpsCheckingServiceImpl testService = spy(new AppOpsCheckingServiceImpl(sAppOpsFile,
+                mLock, mHandler, mTestContext, mSwitchedOps));
+        testService.readState();
 
         doNothing().when(testService).upgradeRunAnyInBackgroundLocked();
         doNothing().when(testService).upgradeScheduleExactAlarmLocked();
@@ -344,7 +353,7 @@
 
         testService.writeState();
         assertTrue(parser.parse());
-        assertEquals(AppOpsService.CURRENT_VERSION, parser.mVersion);
+        assertEquals(AppOpsCheckingServiceImpl.CURRENT_VERSION, parser.mVersion);
     }
 
     /**
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
new file mode 100644
index 0000000..327fc19
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.annotation.NonNull;
+import android.app.backup.BackupHelper;
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
+
+import static org.mockito.Mockito.when;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Set;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class SystemBackupAgentTest {
+    private static final int NON_SYSTEM_USER_ID = 10;
+
+    private TestableSystemBackupAgent mSystemBackupAgent;
+
+    @Mock private Context mContextMock;
+    @Mock private UserManager mUserManagerMock;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mSystemBackupAgent = new TestableSystemBackupAgent();
+        when(mContextMock.getSystemService(UserManager.class)).thenReturn(mUserManagerMock);
+    }
+
+    @Test
+    public void onCreate_systemUser_addsAllHelpers() {
+        UserHandle userHandle = new UserHandle(UserHandle.USER_SYSTEM);
+        when(mUserManagerMock.isProfile()).thenReturn(false);
+
+        mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
+
+        assertThat(mSystemBackupAgent.mAddedHelpers)
+                .containsExactly(
+                        "account_sync_settings",
+                        "preferred_activities",
+                        "notifications",
+                        "permissions",
+                        "usage_stats",
+                        "shortcut_manager",
+                        "account_manager",
+                        "slices",
+                        "people",
+                        "app_locales",
+                        "app_gender");
+    }
+
+    @Test
+    public void onCreate_profileUser_addsProfileEligibleHelpers() {
+        UserHandle userHandle = new UserHandle(NON_SYSTEM_USER_ID);
+        when(mUserManagerMock.isProfile()).thenReturn(true);
+
+        mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
+
+        assertThat(mSystemBackupAgent.mAddedHelpers)
+                .containsExactly(
+                        "account_sync_settings",
+                        "notifications",
+                        "permissions",
+                        "app_locales");
+    }
+
+    @Test
+    public void onCreate_nonSystemUser_addsNonSystemEligibleHelpers() {
+        UserHandle userHandle = new UserHandle(NON_SYSTEM_USER_ID);
+        when(mUserManagerMock.isProfile()).thenReturn(false);
+
+        mSystemBackupAgent.onCreate(userHandle, /* backupDestination= */ 0);
+
+        assertThat(mSystemBackupAgent.mAddedHelpers)
+                .containsExactly(
+                        "account_sync_settings",
+                        "preferred_activities",
+                        "notifications",
+                        "permissions",
+                        "app_locales",
+                        "account_manager",
+                        "usage_stats",
+                        "shortcut_manager");
+    }
+
+    private class TestableSystemBackupAgent extends SystemBackupAgent {
+        final Set<String> mAddedHelpers = new ArraySet<>();
+
+        @Override
+        public void addHelper(String keyPrefix, BackupHelper helper) {
+            mAddedHelpers.add(keyPrefix);
+        }
+
+        @Override
+        public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+            return mContextMock;
+        }
+
+        @Override
+        public Object getSystemService(@ServiceName @NonNull String name) {
+            return null;
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
index 6093f4b..0306655 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/BackupEligibilityRulesTest.java
@@ -25,6 +25,7 @@
 
 import android.app.backup.BackupAnnotations.BackupDestination;
 import android.compat.testing.PlatformCompatChangeRule;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -35,6 +36,7 @@
 import android.content.pm.SigningInfo;
 import android.os.Process;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -64,11 +66,17 @@
     private static final Signature SIGNATURE_2 = generateSignature((byte) 2);
     private static final Signature SIGNATURE_3 = generateSignature((byte) 3);
     private static final Signature SIGNATURE_4 = generateSignature((byte) 4);
+    private static final int NON_SYSTEM_USER = 10;
 
     @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule();
 
     @Mock private PackageManagerInternal mMockPackageManagerInternal;
-    @Mock private PackageManager mPackageManager;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private Context mContext;
+    @Mock
+    private UserManager mUserManager;
 
     private BackupEligibilityRules mBackupEligibilityRules;
     private int mUserId;
@@ -78,6 +86,7 @@
         MockitoAnnotations.initMocks(this);
 
         mUserId = UserHandle.USER_SYSTEM;
+        mockContextForFullUser();
         mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD);
     }
 
@@ -95,6 +104,70 @@
     }
 
     @Test
+    public void appIsEligibleForBackup_systemUid_nonSystemUser_notAllowedPackage_returnsFalse()
+            throws Exception {
+        setUpForNonSystemUser();
+
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemUid_nonSystemUser_allowedPackage_returnsTrue()
+            throws Exception {
+        setUpForNonSystemUser();
+
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = UserBackupManagerService.WALLPAPER_PACKAGE;
+
+        boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemUid_profileUser_notAllowedPackage_returnsFalse()
+            throws Exception {
+        setUpForProfileUser();
+
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+
+        boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_systemUid_profileUser_allowedPackage_returnsTrue()
+            throws Exception {
+        setUpForProfileUser();
+
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+        applicationInfo.uid = Process.SYSTEM_UID;
+        applicationInfo.backupAgentName = CUSTOM_BACKUP_AGENT_NAME;
+        applicationInfo.packageName = UserBackupManagerService.PACKAGE_MANAGER_SENTINEL;
+
+        boolean isEligible = mBackupEligibilityRules.appIsEligibleForBackup(applicationInfo);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
     public void appIsEligibleForBackup_systemAppWithoutCustomBackupAgent_returnsFalse()
             throws Exception {
         ApplicationInfo applicationInfo = new ApplicationInfo();
@@ -790,7 +863,7 @@
     private BackupEligibilityRules getBackupEligibilityRules(
             @BackupDestination int backupDestination) {
         return new BackupEligibilityRules(mPackageManager, mMockPackageManagerInternal, mUserId,
-                backupDestination);
+                mContext, backupDestination);
     }
 
     private static Signature generateSignature(byte i) {
@@ -813,4 +886,26 @@
         return new Property(PackageManager.PROPERTY_ALLOW_ADB_BACKUP, allowAdbBackup,
                 TEST_PACKAGE_NAME, /* className */ "");
     }
+
+    private void setUpForNonSystemUser() {
+        mUserId = NON_SYSTEM_USER;
+        mockContextForFullUser();
+        mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD);
+    }
+
+    private void setUpForProfileUser() {
+        mUserId = NON_SYSTEM_USER;
+        mockContextForProfile();
+        mBackupEligibilityRules = getBackupEligibilityRules(BackupDestination.CLOUD);
+    }
+
+    private void mockContextForProfile() {
+        when(mUserManager.isProfile()).thenReturn(true);
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+    }
+
+    private void mockContextForFullUser() {
+        when(mUserManager.isProfile()).thenReturn(false);
+        when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 30c6975..3399565 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -149,7 +149,7 @@
                 fileMetadata);
         RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
                 mPackageManagerStub, false /* allowApks */, fileMetadata, signatures,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
         assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
@@ -163,7 +163,7 @@
                 fileMetadata);
         restorePolicy = tarBackupReader.chooseRestorePolicy(
                 mPackageManagerStub, false /* allowApks */, fileMetadata, signatures,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE);
         assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME);
@@ -226,7 +226,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 true /* allowApks */, new FileMetadata(), null /* signatures */,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         verifyZeroInteractions(mBackupManagerMonitorMock);
@@ -247,7 +247,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 true /* allowApks */, info, new Signature[0] /* signatures */,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -272,7 +272,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 true /* allowApks */, info, new Signature[0] /* signatures */,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -298,7 +298,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -323,7 +323,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -350,7 +350,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -385,7 +385,7 @@
 
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, new FileMetadata(), signatures,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -424,7 +424,7 @@
                 packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, new FileMetadata(), signatures,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -462,7 +462,7 @@
                 packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, new FileMetadata(), signatures,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -504,7 +504,7 @@
                 packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, info, signatures, mMockPackageManagerInternal,
-                mUserId);
+                mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
@@ -548,7 +548,7 @@
                 packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 true /* allowApks */, info, signatures, mMockPackageManagerInternal,
-                mUserId);
+                mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK);
         verifyNoMoreInteractions(mBackupManagerMonitorMock);
@@ -588,7 +588,7 @@
                 packageInfo.packageName);
         RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                 false /* allowApks */, info, signatures, mMockPackageManagerInternal,
-                mUserId);
+                mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
         ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index 57e873d..6e63315 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -19,13 +19,15 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -41,6 +43,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
+import android.os.SystemProperties;
 import android.os.test.TestLooper;
 import android.util.FloatProperty;
 import android.view.Display;
@@ -55,6 +58,7 @@
 import com.android.server.am.BatteryStatsService;
 import com.android.server.display.RampAnimator.DualRampAnimator;
 import com.android.server.display.color.ColorDisplayService;
+import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.testutils.OffsettableClock;
 
@@ -75,15 +79,20 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public final class DisplayPowerController2Test {
-    private static final String UNIQUE_DISPLAY_ID = "unique_id_test123";
     private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY;
+    private static final String UNIQUE_ID = "unique_id_test123";
+    private static final int FOLLOWER_DISPLAY_ID = DISPLAY_ID + 1;
+    private static final String FOLLOWER_UNIQUE_ID = "unique_id_456";
+    private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1;
+    private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789";
 
     private MockitoSession mSession;
     private OffsettableClock mClock;
     private TestLooper mTestLooper;
     private Handler mHandler;
-    private DisplayPowerController2.Injector mInjector;
     private Context mContextSpy;
+    private DisplayPowerControllerHolder mHolder;
+    private Sensor mProxSensor;
 
     @Mock
     private DisplayPowerCallbacks mDisplayPowerCallbacksMock;
@@ -92,30 +101,14 @@
     @Mock
     private DisplayBlanker mDisplayBlankerMock;
     @Mock
-    private HighBrightnessModeMetadata mHighBrightnessModeMetadataMock;
-    @Mock
-    private LogicalDisplay mLogicalDisplayMock;
-    @Mock
-    private DisplayDevice mDisplayDeviceMock;
-    @Mock
     private BrightnessTracker mBrightnessTrackerMock;
     @Mock
-    private BrightnessSetting mBrightnessSettingMock;
-    @Mock
     private WindowManagerPolicy mWindowManagerPolicyMock;
     @Mock
     private PowerManager mPowerManagerMock;
     @Mock
     private Resources mResourcesMock;
     @Mock
-    private DisplayDeviceConfig mDisplayDeviceConfigMock;
-    @Mock
-    private DisplayPowerState mDisplayPowerStateMock;
-    @Mock
-    private DualRampAnimator<DisplayPowerState> mDualRampAnimatorMock;
-    @Mock
-    private WakelockController mWakelockController;
-    @Mock
     private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock;
 
     @Captor
@@ -126,6 +119,7 @@
         mSession = ExtendedMockito.mockitoSession()
                 .initMocks(this)
                 .strictness(Strictness.LENIENT)
+                .spyStatic(SystemProperties.class)
                 .spyStatic(LocalServices.class)
                 .spyStatic(BatteryStatsService.class)
                 .startMocking();
@@ -133,52 +127,21 @@
         mClock = new OffsettableClock.Stopped();
         mTestLooper = new TestLooper(mClock::now);
         mHandler = new Handler(mTestLooper.getLooper());
-        mInjector = new DisplayPowerController2.Injector() {
-            @Override
-            DisplayPowerController2.Clock getClock() {
-                return mClock::now;
-            }
-
-            @Override
-            DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
-                    int displayId, int displayState) {
-                return mDisplayPowerStateMock;
-            }
-
-            @Override
-            DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
-                    FloatProperty<DisplayPowerState> firstProperty,
-                    FloatProperty<DisplayPowerState> secondProperty) {
-                return mDualRampAnimatorMock;
-            }
-
-            @Override
-            WakelockController getWakelockController(int displayId,
-                    DisplayPowerCallbacks displayPowerCallbacks) {
-                return mWakelockController;
-            }
-
-            @Override
-            DisplayPowerProximityStateController getDisplayPowerProximityStateController(
-                    WakelockController wakelockController, DisplayDeviceConfig displayDeviceConfig,
-                    Looper looper, Runnable nudgeUpdatePowerState, int displayId,
-                    SensorManager sensorManager) {
-                return new DisplayPowerProximityStateController(wakelockController,
-                        displayDeviceConfig, looper, nudgeUpdatePowerState, displayId,
-                        sensorManager, /* injector= */ null);
-            }
-        };
-
         addLocalServiceMock(WindowManagerPolicy.class, mWindowManagerPolicyMock);
 
         when(mContextSpy.getSystemService(eq(PowerManager.class))).thenReturn(mPowerManagerMock);
         when(mContextSpy.getResources()).thenReturn(mResourcesMock);
 
+        doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
+                SystemProperties.set(anyString(), any()));
         doAnswer((Answer<ColorDisplayService.ColorDisplayServiceInternal>) invocationOnMock ->
                 mCdsiMock).when(() -> LocalServices.getService(
                 ColorDisplayService.ColorDisplayServiceInternal.class));
-        doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
-                BatteryStatsService.getService());
+        doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
+
+        mProxSensor = setUpProxSensor();
+
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
     }
 
     @After
@@ -189,72 +152,53 @@
 
     @Test
     public void testReleaseProxSuspendBlockersOnExit() throws Exception {
-        setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
-
-        Sensor proxSensor = setUpProxSensor();
-
-        DisplayPowerController2 dpc = new DisplayPowerController2(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
-
-        when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
         // send a display power request
         DisplayPowerRequest dpr = new DisplayPowerRequest();
         dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
         dpr.useProximitySensor = true;
-        dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
 
         // Run updatePowerState to start listener for the prox sensor
         advanceTime(1);
 
-        SensorEventListener listener = getSensorEventListener(proxSensor);
+        SensorEventListener listener = getSensorEventListener(mProxSensor);
         assertNotNull(listener);
 
-        listener.onSensorChanged(TestUtils.createSensorEvent(proxSensor, 5 /* lux */));
+        listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, 5 /* lux */));
         advanceTime(1);
 
         // two times, one for unfinished business and one for proximity
-        verify(mWakelockController).acquireWakelock(
+        verify(mHolder.wakelockController).acquireWakelock(
                 WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS);
-        verify(mWakelockController).acquireWakelock(
+        verify(mHolder.wakelockController).acquireWakelock(
                 WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
 
-
-        dpc.stop();
+        mHolder.dpc.stop();
         advanceTime(1);
         // two times, one for unfinished business and one for proximity
-        verify(mWakelockController).acquireWakelock(
+        verify(mHolder.wakelockController).acquireWakelock(
                 WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS);
-        verify(mWakelockController).acquireWakelock(
+        verify(mHolder.wakelockController).acquireWakelock(
                 WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
     }
 
     @Test
-    public void testProximitySensorListenerNotRegisteredForNonDefaultDisplay() throws Exception {
-        setUpDisplay(1, UNIQUE_DISPLAY_ID);
-
-        Sensor proxSensor = setUpProxSensor();
-
-        DisplayPowerController2 dpc = new DisplayPowerController2(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
-
-        when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
+    public void testProximitySensorListenerNotRegisteredForNonDefaultDisplay() {
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
         // send a display power request
         DisplayPowerRequest dpr = new DisplayPowerRequest();
         dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
         dpr.useProximitySensor = true;
-        dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+        final DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
+        followerDpc.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
 
         // Run updatePowerState
         advanceTime(1);
 
         verify(mSensorManagerMock, never()).registerListener(any(SensorEventListener.class),
-                eq(proxSensor), anyInt(), any(Handler.class));
+                eq(mProxSensor), anyInt(), any(Handler.class));
     }
 
     /**
@@ -284,56 +228,394 @@
         return mSensorEventListenerCaptor.getValue();
     }
 
-    private void setUpDisplay(int displayId, String uniqueId) {
+    private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
+            DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock) {
         DisplayInfo info = new DisplayInfo();
         DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
 
-        when(mLogicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
-        when(mLogicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(mDisplayDeviceMock);
-        when(mLogicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
-        when(mLogicalDisplayMock.isEnabledLocked()).thenReturn(true);
-        when(mLogicalDisplayMock.isInTransitionLocked()).thenReturn(false);
-        when(mDisplayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
-        when(mDisplayDeviceMock.getUniqueId()).thenReturn(uniqueId);
-        when(mDisplayDeviceMock.getDisplayDeviceConfig()).thenReturn(mDisplayDeviceConfigMock);
-        when(mDisplayDeviceConfigMock.getProximitySensor()).thenReturn(
+        when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
+        when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
+        when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
+        when(logicalDisplayMock.isEnabledLocked()).thenReturn(true);
+        when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
+        when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
+        when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
+        when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
+        when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
                 new DisplayDeviceConfig.SensorData() {
                     {
                         type = Sensor.STRING_TYPE_PROXIMITY;
                         name = null;
                     }
                 });
-        when(mDisplayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
+        when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
+        when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
+        when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
+                new DisplayDeviceConfig.SensorData());
+        when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
+                new DisplayDeviceConfig.SensorData());
     }
 
     @Test
-    public void testDisplayBrightnessFollowers() {
-        setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
+    public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
 
-        DisplayPowerController2 defaultDpc = new DisplayPowerController2(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
-        DisplayPowerController2 followerDpc = new DisplayPowerController2(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
 
-        defaultDpc.addDisplayBrightnessFollower(followerDpc);
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
 
-        defaultDpc.setBrightness(0.3f);
-        assertEquals(defaultDpc.getBrightnessInfo().brightness,
-                followerDpc.getBrightnessInfo().brightness, 0);
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
 
-        defaultDpc.setBrightness(0.6f);
-        assertEquals(defaultDpc.getBrightnessInfo().brightness,
-                followerDpc.getBrightnessInfo().brightness, 0);
+        // Test different float scale values
+        float leadBrightness = 0.3f;
+        float followerBrightness = 0.4f;
+        float nits = 300;
+        when(mHolder.automaticBrightnessController.convertToNits(leadBrightness)).thenReturn(nits);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(followerBrightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness);
+        listener.onBrightnessChanged(leadBrightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
+                anyFloat());
 
-        float brightness = 0.1f;
-        defaultDpc.clearDisplayBrightnessFollowers();
-        defaultDpc.setBrightness(brightness);
-        assertNotEquals(brightness, followerDpc.getBrightnessInfo().brightness, 0);
+        clearInvocations(mHolder.animator, followerDpc.animator);
+
+        // Test the same float scale value
+        float brightness = 0.6f;
+        nits = 600;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowers_FollowerDoesNotSupportNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+
+        float brightness = 0.3f;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(300f);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat()))
+                .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+
+        float brightness = 0.3f;
+        when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowers_NeitherDpcSupportsNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+
+        float brightness = 0.3f;
+        when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat()))
+                .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+
+    @Test
+    public void testDisplayBrightnessFollowersRemoval() {
+        DisplayPowerControllerHolder followerDpc = createDisplayPowerController(FOLLOWER_DISPLAY_ID,
+                FOLLOWER_UNIQUE_ID);
+        DisplayPowerControllerHolder secondFollowerDpc = createDisplayPowerController(
+                SECOND_FOLLOWER_DISPLAY_ID, SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        secondFollowerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        // Set the initial brightness on the DPC we're going to remove so we have a fixed value for
+        // it to return to.
+        listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(followerDpc.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue();
+        final float initialFollowerBrightness = 0.3f;
+        when(followerDpc.brightnessSetting.getBrightness()).thenReturn(initialFollowerBrightness);
+        followerListener.onBrightnessChanged(initialFollowerBrightness);
+        advanceTime(1);
+        verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness),
+                anyFloat(), anyFloat());
+
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+        mHolder.dpc.addDisplayBrightnessFollower(secondFollowerDpc.dpc);
+        clearInvocations(followerDpc.animator);
+
+        // Validate both followers are correctly registered and receiving brightness updates
+        float brightness = 0.6f;
+        float nits = 600;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+
+        clearInvocations(mHolder.animator, followerDpc.animator, secondFollowerDpc.animator);
+
+        // Remove the first follower and validate it goes back to its original brightness.
+        mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc);
+        advanceTime(1);
+        verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness),
+                anyFloat(), anyFloat());
+        clearInvocations(followerDpc.animator);
+
+        // Change the brightness of the lead display and validate only the second follower responds
+        brightness = 0.7f;
+        nits = 700;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
+        verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+            String uniqueId) {
+        final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
+        final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
+        final AutomaticBrightnessController automaticBrightnessController =
+                mock(AutomaticBrightnessController.class);
+        final WakelockController wakelockController = mock(WakelockController.class);
+        final BrightnessMappingStrategy brightnessMappingStrategy =
+                mock(BrightnessMappingStrategy.class);
+        final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+
+        TestInjector injector = new TestInjector(displayPowerState, animator,
+                automaticBrightnessController, wakelockController, brightnessMappingStrategy,
+                hysteresisLevels);
+
+        final LogicalDisplay display = mock(LogicalDisplay.class);
+        final DisplayDevice device = mock(DisplayDevice.class);
+        final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class);
+        final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
+        final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
+
+        setUpDisplay(displayId, uniqueId, display, device, config);
+
+        final DisplayPowerController2 dpc = new DisplayPowerController2(
+                mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
+                mSensorManagerMock, mDisplayBlankerMock, display,
+                mBrightnessTrackerMock, brightnessSetting, () -> {},
+                hbmMetadata);
+
+        return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
+                automaticBrightnessController, wakelockController);
+    }
+
+    /**
+     * A class for holding a DisplayPowerController under test and all the mocks specifically
+     * related to it.
+     */
+    private static class DisplayPowerControllerHolder {
+        public final DisplayPowerController2 dpc;
+        public final DisplayPowerState displayPowerState;
+        public final BrightnessSetting brightnessSetting;
+        public final DualRampAnimator<DisplayPowerState> animator;
+        public final AutomaticBrightnessController automaticBrightnessController;
+        public final WakelockController wakelockController;
+
+        DisplayPowerControllerHolder(DisplayPowerController2 dpc,
+                DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
+                DualRampAnimator<DisplayPowerState> animator,
+                AutomaticBrightnessController automaticBrightnessController,
+                WakelockController wakelockController) {
+            this.dpc = dpc;
+            this.displayPowerState = displayPowerState;
+            this.brightnessSetting = brightnessSetting;
+            this.animator = animator;
+            this.automaticBrightnessController = automaticBrightnessController;
+            this.wakelockController = wakelockController;
+        }
+    }
+
+    private class TestInjector extends DisplayPowerController2.Injector {
+        private final DisplayPowerState mDisplayPowerState;
+        private final DualRampAnimator<DisplayPowerState> mAnimator;
+        private final AutomaticBrightnessController mAutomaticBrightnessController;
+        private final WakelockController mWakelockController;
+        private final BrightnessMappingStrategy mBrightnessMappingStrategy;
+        private final HysteresisLevels mHysteresisLevels;
+
+        TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
+                AutomaticBrightnessController automaticBrightnessController,
+                WakelockController wakelockController,
+                BrightnessMappingStrategy brightnessMappingStrategy,
+                HysteresisLevels hysteresisLevels) {
+            mDisplayPowerState = dps;
+            mAnimator = animator;
+            mAutomaticBrightnessController = automaticBrightnessController;
+            mWakelockController = wakelockController;
+            mBrightnessMappingStrategy = brightnessMappingStrategy;
+            mHysteresisLevels = hysteresisLevels;
+        }
+
+        @Override
+        DisplayPowerController2.Clock getClock() {
+            return mClock::now;
+        }
+
+        @Override
+        DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
+                int displayId, int displayState) {
+            return mDisplayPowerState;
+        }
+
+        @Override
+        DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
+                FloatProperty<DisplayPowerState> firstProperty,
+                FloatProperty<DisplayPowerState> secondProperty) {
+            return mAnimator;
+        }
+
+        @Override
+        WakelockController getWakelockController(int displayId,
+                DisplayPowerCallbacks displayPowerCallbacks) {
+            return mWakelockController;
+        }
+
+        @Override
+        DisplayPowerProximityStateController getDisplayPowerProximityStateController(
+                WakelockController wakelockController, DisplayDeviceConfig displayDeviceConfig,
+                Looper looper, Runnable nudgeUpdatePowerState, int displayId,
+                SensorManager sensorManager) {
+            return new DisplayPowerProximityStateController(wakelockController,
+                    displayDeviceConfig, looper, nudgeUpdatePowerState, displayId,
+                    sensorManager, /* injector= */ null);
+        }
+
+        @Override
+        AutomaticBrightnessController getAutomaticBrightnessController(
+                AutomaticBrightnessController.Callbacks callbacks, Looper looper,
+                SensorManager sensorManager, Sensor lightSensor,
+                BrightnessMappingStrategy interactiveModeBrightnessMapper,
+                int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
+                float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
+                long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
+                boolean resetAmbientLuxAfterWarmUpConfig,
+                HysteresisLevels ambientBrightnessThresholds,
+                HysteresisLevels screenBrightnessThresholds,
+                HysteresisLevels ambientBrightnessThresholdsIdle,
+                HysteresisLevels screenBrightnessThresholdsIdle, Context context,
+                HighBrightnessModeController hbmController,
+                BrightnessThrottler brightnessThrottler,
+                BrightnessMappingStrategy idleModeBrightnessMapper,
+                int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux,
+                float userBrightness) {
+            return mAutomaticBrightnessController;
+        }
+
+        @Override
+        BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
+                DisplayDeviceConfig displayDeviceConfig,
+                DisplayWhiteBalanceController displayWhiteBalanceController) {
+            return mBrightnessMappingStrategy;
+        }
+
+        @Override
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold) {
+            return mHysteresisLevels;
+        }
+
+        @Override
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
+            return mHysteresisLevels;
+        }
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 6bf5b62..a8c3e4e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -19,14 +19,15 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -40,7 +41,9 @@
 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.PowerManager;
+import android.os.SystemProperties;
 import android.os.test.TestLooper;
 import android.util.FloatProperty;
 import android.view.Display;
@@ -55,6 +58,7 @@
 import com.android.server.am.BatteryStatsService;
 import com.android.server.display.RampAnimator.DualRampAnimator;
 import com.android.server.display.color.ColorDisplayService;
+import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.testutils.OffsettableClock;
 
@@ -75,15 +79,20 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public final class DisplayPowerControllerTest {
-    private static final String UNIQUE_DISPLAY_ID = "unique_id_test123";
     private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY;
+    private static final String UNIQUE_ID = "unique_id_test123";
+    private static final int FOLLOWER_DISPLAY_ID = DISPLAY_ID + 1;
+    private static final String FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_456";
+    private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1;
+    private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789";
 
     private MockitoSession mSession;
     private OffsettableClock mClock;
     private TestLooper mTestLooper;
     private Handler mHandler;
-    private DisplayPowerController.Injector mInjector;
     private Context mContextSpy;
+    private DisplayPowerControllerHolder mHolder;
+    private Sensor mProxSensor;
 
     @Mock
     private DisplayPowerCallbacks mDisplayPowerCallbacksMock;
@@ -92,28 +101,14 @@
     @Mock
     private DisplayBlanker mDisplayBlankerMock;
     @Mock
-    private LogicalDisplay mLogicalDisplayMock;
-    @Mock
-    private DisplayDevice mDisplayDeviceMock;
-    @Mock
-    private HighBrightnessModeMetadata mHighBrightnessModeMetadataMock;
-    @Mock
     private BrightnessTracker mBrightnessTrackerMock;
     @Mock
-    private BrightnessSetting mBrightnessSettingMock;
-    @Mock
     private WindowManagerPolicy mWindowManagerPolicyMock;
     @Mock
     private PowerManager mPowerManagerMock;
     @Mock
     private Resources mResourcesMock;
     @Mock
-    private DisplayDeviceConfig mDisplayDeviceConfigMock;
-    @Mock
-    private DisplayPowerState mDisplayPowerStateMock;
-    @Mock
-    private DualRampAnimator<DisplayPowerState> mDualRampAnimatorMock;
-    @Mock
     private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock;
 
     @Captor
@@ -124,6 +119,7 @@
         mSession = ExtendedMockito.mockitoSession()
                 .initMocks(this)
                 .strictness(Strictness.LENIENT)
+                .spyStatic(SystemProperties.class)
                 .spyStatic(LocalServices.class)
                 .spyStatic(BatteryStatsService.class)
                 .startMocking();
@@ -131,36 +127,22 @@
         mClock = new OffsettableClock.Stopped();
         mTestLooper = new TestLooper(mClock::now);
         mHandler = new Handler(mTestLooper.getLooper());
-        mInjector = new DisplayPowerController.Injector() {
-            @Override
-            DisplayPowerController.Clock getClock() {
-                return mClock::now;
-            }
-
-            @Override
-            DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
-                    int displayId, int displayState) {
-                return mDisplayPowerStateMock;
-            }
-
-            @Override
-            DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
-                    FloatProperty<DisplayPowerState> firstProperty,
-                    FloatProperty<DisplayPowerState> secondProperty) {
-                return mDualRampAnimatorMock;
-            }
-        };
 
         addLocalServiceMock(WindowManagerPolicy.class, mWindowManagerPolicyMock);
 
         when(mContextSpy.getSystemService(eq(PowerManager.class))).thenReturn(mPowerManagerMock);
         when(mContextSpy.getResources()).thenReturn(mResourcesMock);
 
+        doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
+                SystemProperties.set(anyString(), any()));
         doAnswer((Answer<ColorDisplayService.ColorDisplayServiceInternal>) invocationOnMock ->
                 mCdsiMock).when(() -> LocalServices.getService(
-                        ColorDisplayService.ColorDisplayServiceInternal.class));
-        doAnswer((Answer<Void>) invocationOnMock -> null).when(() ->
-                BatteryStatsService.getService());
+                ColorDisplayService.ColorDisplayServiceInternal.class));
+        doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
+
+        mProxSensor = setUpProxSensor();
+
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
     }
 
     @After
@@ -171,72 +153,55 @@
 
     @Test
     public void testReleaseProxSuspendBlockersOnExit() throws Exception {
-        setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
-
-        Sensor proxSensor = setUpProxSensor();
-
-        DisplayPowerController dpc = new DisplayPowerController(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
-
-        when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
         // send a display power request
         DisplayPowerRequest dpr = new DisplayPowerRequest();
         dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
         dpr.useProximitySensor = true;
-        dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+        mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
 
         // Run updatePowerState to start listener for the prox sensor
         advanceTime(1);
 
-        SensorEventListener listener = getSensorEventListener(proxSensor);
+        SensorEventListener listener = getSensorEventListener(mProxSensor);
         assertNotNull(listener);
 
-        listener.onSensorChanged(TestUtils.createSensorEvent(proxSensor, 5 /* lux */));
+        listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, 5 /* lux */));
         advanceTime(1);
 
         // two times, one for unfinished business and one for proximity
         verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker(
-                dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
+                mHolder.dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
         verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker(
-                dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
+                mHolder.dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
 
-        dpc.stop();
+        mHolder.dpc.stop();
         advanceTime(1);
 
         // two times, one for unfinished business and one for proximity
         verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker(
-                dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
+                mHolder.dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID));
         verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker(
-                dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
+                mHolder.dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID));
     }
 
     @Test
-    public void testProximitySensorListenerNotRegisteredForNonDefaultDisplay() throws Exception {
-        setUpDisplay(1, UNIQUE_DISPLAY_ID);
+    public void testProximitySensorListenerNotRegisteredForNonDefaultDisplay() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
 
-        Sensor proxSensor = setUpProxSensor();
-
-        DisplayPowerController dpc = new DisplayPowerController(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
-
-        when(mDisplayPowerStateMock.getScreenState()).thenReturn(Display.STATE_ON);
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
         // send a display power request
         DisplayPowerRequest dpr = new DisplayPowerRequest();
         dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
         dpr.useProximitySensor = true;
-        dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
+        followerDpc.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */);
 
         // Run updatePowerState
         advanceTime(1);
 
         verify(mSensorManagerMock, never()).registerListener(any(SensorEventListener.class),
-                eq(proxSensor), anyInt(), any(Handler.class));
+                eq(mProxSensor), anyInt(), any(Handler.class));
     }
 
     /**
@@ -266,56 +231,371 @@
         return mSensorEventListenerCaptor.getValue();
     }
 
-    private void setUpDisplay(int displayId, String uniqueId) {
+    private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
+            DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock) {
         DisplayInfo info = new DisplayInfo();
         DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
 
-        when(mLogicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
-        when(mLogicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(mDisplayDeviceMock);
-        when(mLogicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
-        when(mLogicalDisplayMock.isEnabledLocked()).thenReturn(true);
-        when(mLogicalDisplayMock.isInTransitionLocked()).thenReturn(false);
-        when(mDisplayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
-        when(mDisplayDeviceMock.getUniqueId()).thenReturn(uniqueId);
-        when(mDisplayDeviceMock.getDisplayDeviceConfig()).thenReturn(mDisplayDeviceConfigMock);
-        when(mDisplayDeviceConfigMock.getProximitySensor()).thenReturn(
+        when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
+        when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
+        when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
+        when(logicalDisplayMock.isEnabledLocked()).thenReturn(true);
+        when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
+        when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
+        when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
+        when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
+        when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
                 new DisplayDeviceConfig.SensorData() {
                     {
                         type = Sensor.STRING_TYPE_PROXIMITY;
                         name = null;
                     }
                 });
-        when(mDisplayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
+        when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
+        when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
+        when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
+                new DisplayDeviceConfig.SensorData());
+        when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
+                new DisplayDeviceConfig.SensorData());
     }
 
     @Test
-    public void testDisplayBrightnessFollowers() {
-        setUpDisplay(DISPLAY_ID, UNIQUE_DISPLAY_ID);
+    public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
 
-        DisplayPowerController defaultDpc = new DisplayPowerController(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
-        DisplayPowerController followerDpc = new DisplayPowerController(
-                mContextSpy, mInjector, mDisplayPowerCallbacksMock, mHandler,
-                mSensorManagerMock, mDisplayBlankerMock, mLogicalDisplayMock,
-                mBrightnessTrackerMock, mBrightnessSettingMock, () -> {
-        }, mHighBrightnessModeMetadataMock);
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
 
-        defaultDpc.addDisplayBrightnessFollower(followerDpc);
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
 
-        defaultDpc.setBrightness(0.3f);
-        assertEquals(defaultDpc.getBrightnessInfo().brightness,
-                followerDpc.getBrightnessInfo().brightness, 0);
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
 
-        defaultDpc.setBrightness(0.6f);
-        assertEquals(defaultDpc.getBrightnessInfo().brightness,
-                followerDpc.getBrightnessInfo().brightness, 0);
+        // Test different float scale values
+        float leadBrightness = 0.3f;
+        float followerBrightness = 0.4f;
+        float nits = 300;
+        when(mHolder.automaticBrightnessController.convertToNits(leadBrightness)).thenReturn(nits);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(followerBrightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness);
+        listener.onBrightnessChanged(leadBrightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(),
+                anyFloat());
 
-        float brightness = 0.1f;
-        defaultDpc.clearDisplayBrightnessFollowers();
-        defaultDpc.setBrightness(brightness);
-        assertNotEquals(brightness, followerDpc.getBrightnessInfo().brightness, 0);
+        clearInvocations(mHolder.animator, followerDpc.animator);
+
+        // Test the same float scale value
+        float brightness = 0.6f;
+        nits = 600;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowers_FollowerDoesNotSupportNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+
+        float brightness = 0.3f;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(300f);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat()))
+                .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+
+        float brightness = 0.3f;
+        when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowers_NeitherDpcSupportsNits() {
+        DisplayPowerControllerHolder followerDpc =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc);
+
+        float brightness = 0.3f;
+        when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f);
+        when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat()))
+                .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDisplayBrightnessFollowersRemoval() {
+        DisplayPowerControllerHolder followerHolder =
+                createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
+        DisplayPowerControllerHolder secondFollowerHolder =
+                createDisplayPowerController(SECOND_FOLLOWER_DISPLAY_ID,
+                        SECOND_FOLLOWER_UNIQUE_DISPLAY_ID);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        followerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        secondFollowerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+
+        // Set the initial brightness on the DPC we're going to remove so we have a fixed value for
+        // it to return to.
+        listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(followerHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue();
+        final float initialFollowerBrightness = 0.3f;
+        when(followerHolder.brightnessSetting.getBrightness()).thenReturn(
+                initialFollowerBrightness);
+        followerListener.onBrightnessChanged(initialFollowerBrightness);
+        advanceTime(1);
+        verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
+                anyFloat(), anyFloat());
+
+
+        mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc);
+        mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc);
+        clearInvocations(followerHolder.animator);
+
+        // Validate both followers are correctly registered and receiving brightness updates
+        float brightness = 0.6f;
+        float nits = 600;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+        when(followerHolder.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+
+        clearInvocations(mHolder.animator, followerHolder.animator, secondFollowerHolder.animator);
+
+        // Remove the first follower and validate it goes back to its original brightness.
+        mHolder.dpc.removeDisplayBrightnessFollower(followerHolder.dpc);
+        advanceTime(1);
+        verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
+                anyFloat(), anyFloat());
+        clearInvocations(followerHolder.animator);
+
+        // Change the brightness of the lead display and validate only the second follower responds
+        brightness = 0.7f;
+        nits = 700;
+        when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+        when(followerHolder.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits))
+                .thenReturn(brightness);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+        verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+        verify(followerHolder.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat());
+        verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+    }
+
+    private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+            String uniqueId) {
+        final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
+        final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
+        final AutomaticBrightnessController automaticBrightnessController =
+                mock(AutomaticBrightnessController.class);
+        final BrightnessMappingStrategy brightnessMappingStrategy =
+                mock(BrightnessMappingStrategy.class);
+        final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+
+        DisplayPowerController.Injector injector = new TestInjector(displayPowerState, animator,
+                automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels);
+
+        final LogicalDisplay display = mock(LogicalDisplay.class);
+        final DisplayDevice device = mock(DisplayDevice.class);
+        final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class);
+        final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
+        final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
+
+        setUpDisplay(displayId, uniqueId, display, device, config);
+
+        final DisplayPowerController dpc = new DisplayPowerController(
+                mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
+                mSensorManagerMock, mDisplayBlankerMock, display,
+                mBrightnessTrackerMock, brightnessSetting, () -> {},
+                hbmMetadata);
+
+        return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
+                automaticBrightnessController);
+    }
+
+    /**
+     * A class for holding a DisplayPowerController under test and all the mocks specifically
+     * related to it.
+     */
+    private static class DisplayPowerControllerHolder {
+        public final DisplayPowerController dpc;
+        public final DisplayPowerState displayPowerState;
+        public final BrightnessSetting brightnessSetting;
+        public final DualRampAnimator<DisplayPowerState> animator;
+        public final AutomaticBrightnessController automaticBrightnessController;
+
+        DisplayPowerControllerHolder(DisplayPowerController dpc,
+                DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
+                DualRampAnimator<DisplayPowerState> animator,
+                AutomaticBrightnessController automaticBrightnessController) {
+            this.dpc = dpc;
+            this.displayPowerState = displayPowerState;
+            this.brightnessSetting = brightnessSetting;
+            this.animator = animator;
+            this.automaticBrightnessController = automaticBrightnessController;
+        }
+    }
+
+    private class TestInjector extends DisplayPowerController.Injector {
+        private final DisplayPowerState mDisplayPowerState;
+        private final DualRampAnimator<DisplayPowerState> mAnimator;
+        private final AutomaticBrightnessController mAutomaticBrightnessController;
+        private final BrightnessMappingStrategy mBrightnessMappingStrategy;
+        private final HysteresisLevels mHysteresisLevels;
+
+        TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
+                AutomaticBrightnessController automaticBrightnessController,
+                BrightnessMappingStrategy brightnessMappingStrategy,
+                HysteresisLevels hysteresisLevels) {
+            mDisplayPowerState = dps;
+            mAnimator = animator;
+            mAutomaticBrightnessController = automaticBrightnessController;
+            mBrightnessMappingStrategy = brightnessMappingStrategy;
+            mHysteresisLevels = hysteresisLevels;
+        }
+
+        @Override
+        DisplayPowerController.Clock getClock() {
+            return mClock::now;
+        }
+
+        @Override
+        DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade,
+                int displayId, int displayState) {
+            return mDisplayPowerState;
+        }
+
+        @Override
+        DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps,
+                FloatProperty<DisplayPowerState> firstProperty,
+                FloatProperty<DisplayPowerState> secondProperty) {
+            return mAnimator;
+        }
+
+        @Override
+        AutomaticBrightnessController getAutomaticBrightnessController(
+                AutomaticBrightnessController.Callbacks callbacks, Looper looper,
+                SensorManager sensorManager, Sensor lightSensor,
+                BrightnessMappingStrategy interactiveModeBrightnessMapper,
+                int lightSensorWarmUpTime, float brightnessMin, float brightnessMax,
+                float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate,
+                long brighteningLightDebounceConfig, long darkeningLightDebounceConfig,
+                boolean resetAmbientLuxAfterWarmUpConfig,
+                HysteresisLevels ambientBrightnessThresholds,
+                HysteresisLevels screenBrightnessThresholds,
+                HysteresisLevels ambientBrightnessThresholdsIdle,
+                HysteresisLevels screenBrightnessThresholdsIdle, Context context,
+                HighBrightnessModeController hbmController,
+                BrightnessThrottler brightnessThrottler,
+                BrightnessMappingStrategy idleModeBrightnessMapper,
+                int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux,
+                float userBrightness) {
+            return mAutomaticBrightnessController;
+        }
+
+        @Override
+        BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources,
+                DisplayDeviceConfig displayDeviceConfig,
+                DisplayWhiteBalanceController displayWhiteBalanceController) {
+            return mBrightnessMappingStrategy;
+        }
+
+        @Override
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold) {
+            return mHysteresisLevels;
+        }
+
+        @Override
+        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
+                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
+                float[] darkeningThresholdLevels, float minDarkeningThreshold,
+                float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
+            return mHysteresisLevels;
+        }
     }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java
index ddb6f23..3750aa0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobConcurrencyManagerTest.java
@@ -335,13 +335,14 @@
         mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
         setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
                 new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
-        for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
+        for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 3; ++i) {
             final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
             final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
             setPackageUid(sourcePkgName, uid);
             final JobStatus job = createJob(uid, sourcePkgName);
             spyOn(job);
-            doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
+            doReturn(i % 3 == 0).when(job).shouldTreatAsUserInitiatedJob();
+            doReturn(i % 3 == 1).when(job).shouldTreatAsExpeditedJob();
             if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
                 mJobConcurrencyManager.addRunningJobForTesting(job);
             } else {
@@ -350,7 +351,7 @@
         }
 
         // Waiting time is too short, so we shouldn't create any extra contexts.
-        final long remainingTimeMs = JobConcurrencyManager.DEFAULT_MAX_WAIT_EJ_MS / 2;
+        final long remainingTimeMs = JobConcurrencyManager.DEFAULT_MAX_WAIT_UI_MS / 2;
         for (int i = 0; i < mInjector.contexts.size(); ++i) {
             doReturn(true).when(mInjector.contexts.keyAt(i)).isWithinExecutionGuaranteeTime();
             doReturn(remainingTimeMs)
@@ -378,19 +379,25 @@
     }
 
     @Test
-    public void testDetermineAssignments_allPreferredUidOnly_mediumTimeLeft() throws Exception {
+    public void testDetermineAssignments_allPreferredUidOnly_mediumTimeLeft_onlyRegRunning()
+            throws Exception {
         mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
+        // Set the waiting time to be less than an EJ's min execution time.
+        mConfigBuilder.setLong(JobConcurrencyManager.KEY_MAX_WAIT_UI_MS, 2 * 60_000L);
         setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
                 new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
         final ArraySet<JobStatus> jobs = new ArraySet<>();
-        for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 2; ++i) {
+        for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 4; ++i) {
             final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
             final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
             setPackageUid(sourcePkgName, uid);
             final JobStatus job = createJob(uid, sourcePkgName);
             spyOn(job);
-            doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
-            if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
+            doReturn(i % 3 == 0).when(job).shouldTreatAsUserInitiatedJob();
+            doReturn(i % 3 == 1).when(job).shouldTreatAsExpeditedJob();
+            if (i % 3 == 2
+                    && mJobConcurrencyManager.mActiveServices.size()
+                            < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
                 mJobConcurrencyManager.addRunningJobForTesting(job);
             } else {
                 mPendingJobQueue.add(job);
@@ -398,8 +405,8 @@
             }
         }
 
-        // Waiting time is longer than the EJ waiting time, but shorter than regular job waiting
-        // time, so we should only create an extra context for an EJ.
+        // Waiting time is longer than the EJ & UI waiting time, but shorter than regular job
+        // waiting time, so we should only create 2 extra contexts (one for EJ, one for UIJ).
         final long remainingTimeMs = (JobConcurrencyManager.DEFAULT_MAX_WAIT_EJ_MS
                 + JobConcurrencyManager.DEFAULT_MAX_WAIT_REGULAR_MS) / 2;
         for (int i = 0; i < mInjector.contexts.size(); ++i) {
@@ -428,7 +435,81 @@
         for (int i = changed.size() - 1; i >= 0; --i) {
             jobs.remove(changed.valueAt(i).newJob);
         }
-        assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - 1, jobs.size());
+        // 1 EJ & 1 UIJ removed from the pending list.
+        assertEquals(3 * JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - 2, jobs.size());
+        assertEquals(2, changed.size());
+        JobStatus assignedJob1 = changed.valueAt(0).newJob;
+        JobStatus assignedJob2 = changed.valueAt(1).newJob;
+        boolean ejFirst = assignedJob1.shouldTreatAsExpeditedJob();
+        if (ejFirst) {
+            assertTrue(assignedJob1.shouldTreatAsExpeditedJob());
+            assertTrue(assignedJob2.shouldTreatAsUserInitiatedJob());
+        } else {
+            assertTrue(assignedJob1.shouldTreatAsUserInitiatedJob());
+            assertTrue(assignedJob2.shouldTreatAsExpeditedJob());
+        }
+    }
+
+    @Test
+    public void testDetermineAssignments_allPreferredUidOnly_mediumTimeLeft_onlyUiRunning()
+            throws Exception {
+        mConfigBuilder.setBoolean(JobConcurrencyManager.KEY_ENABLE_MAX_WAIT_TIME_BYPASS, true);
+        // Set the waiting time to be less than an EJ's min execution time.
+        mConfigBuilder.setLong(JobConcurrencyManager.KEY_MAX_WAIT_UI_MS, 2 * 60_000L);
+        setConcurrencyConfig(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT,
+                new TypeConfig(WORK_TYPE_BG, 0, JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT));
+        final ArraySet<JobStatus> jobs = new ArraySet<>();
+        for (int i = 0; i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT * 4; ++i) {
+            final int uid = mDefaultUserId * UserHandle.PER_USER_RANGE + i;
+            final String sourcePkgName = "com.source.package." + UserHandle.getAppId(uid);
+            setPackageUid(sourcePkgName, uid);
+            final JobStatus job = createJob(uid, sourcePkgName);
+            spyOn(job);
+            doReturn(i % 3 == 0).when(job).shouldTreatAsUserInitiatedJob();
+            doReturn(i % 3 == 1).when(job).shouldTreatAsExpeditedJob();
+            if (i % 3 == 0
+                    && mJobConcurrencyManager.mActiveServices.size()
+                            < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
+                mJobConcurrencyManager.addRunningJobForTesting(job);
+            } else {
+                mPendingJobQueue.add(job);
+                jobs.add(job);
+            }
+        }
+
+        // Waiting time is longer than the EJ & UI waiting time, but shorter than regular job
+        // waiting time, so we should only create 2 extra contexts (one for EJ, one for UIJ).
+        final long remainingTimeMs = (JobConcurrencyManager.DEFAULT_MAX_WAIT_EJ_MS
+                + JobConcurrencyManager.DEFAULT_MAX_WAIT_REGULAR_MS) / 2;
+        for (int i = 0; i < mInjector.contexts.size(); ++i) {
+            doReturn(true).when(mInjector.contexts.keyAt(i)).isWithinExecutionGuaranteeTime();
+            doReturn(remainingTimeMs)
+                    .when(mInjector.contexts.keyAt(i)).getRemainingGuaranteedTimeMs(anyLong());
+        }
+
+        final ArraySet<JobConcurrencyManager.ContextAssignment> changed = new ArraySet<>();
+        final ArraySet<JobConcurrencyManager.ContextAssignment> idle = new ArraySet<>();
+        final List<JobConcurrencyManager.ContextAssignment> preferredUidOnly = new ArrayList<>();
+        final List<JobConcurrencyManager.ContextAssignment> stoppable = new ArrayList<>();
+        final JobConcurrencyManager.AssignmentInfo assignmentInfo =
+                new JobConcurrencyManager.AssignmentInfo();
+
+        mJobConcurrencyManager.prepareForAssignmentDeterminationLocked(
+                idle, preferredUidOnly, stoppable, assignmentInfo);
+        assertEquals(remainingTimeMs, assignmentInfo.minPreferredUidOnlyWaitingTimeMs);
+        assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
+
+        mJobConcurrencyManager
+                .determineAssignmentsLocked(changed, idle, preferredUidOnly, stoppable,
+                        assignmentInfo);
+
+        assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
+        for (int i = changed.size() - 1; i >= 0; --i) {
+            jobs.remove(changed.valueAt(i).newJob);
+        }
+        // There are already UIJs running, and wait time is too long for regular jobs, so
+        // only 1 EJ removed from the pending list.
+        assertEquals(3 * JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - 1, jobs.size());
         assertEquals(1, changed.size());
         JobStatus assignedJob = changed.valueAt(0).newJob;
         assertTrue(assignedJob.shouldTreatAsExpeditedJob());
@@ -446,7 +527,8 @@
             setPackageUid(sourcePkgName, uid);
             final JobStatus job = createJob(uid, sourcePkgName);
             spyOn(job);
-            doReturn(i % 2 == 0).when(job).shouldTreatAsExpeditedJob();
+            doReturn(i % 3 == 0).when(job).shouldTreatAsUserInitiatedJob();
+            doReturn(i % 3 == 1).when(job).shouldTreatAsExpeditedJob();
             if (i < JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT) {
                 mJobConcurrencyManager.addRunningJobForTesting(job);
             } else {
@@ -481,21 +563,39 @@
                         assignmentInfo);
 
         assertEquals(JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT, preferredUidOnly.size());
-        // Depending on iteration order, we may create 1 or 2 contexts.
+        // Depending on iteration order, we may create 1-3 contexts.
         final long numAssignedJobs = changed.size();
         assertTrue(numAssignedJobs > 0);
-        assertTrue(numAssignedJobs <= 2);
+        assertTrue(numAssignedJobs <= 3);
+        int numUi = 0, numEj = 0, numReg = 0;
         for (int i = 0; i < numAssignedJobs; ++i) {
-            jobs.remove(changed.valueAt(i).newJob);
+            JobStatus assignedJob = changed.valueAt(i).newJob;
+            jobs.remove(assignedJob);
+            if (assignedJob.shouldTreatAsUserInitiatedJob()) {
+                numUi++;
+            } else if (assignedJob.shouldTreatAsExpeditedJob()) {
+                numEj++;
+            } else {
+                numReg++;
+            }
         }
         assertEquals(numAssignedJobs,
                 JobConcurrencyManager.DEFAULT_CONCURRENCY_LIMIT - jobs.size());
-        JobStatus firstAssignedJob = changed.valueAt(0).newJob;
-        if (!firstAssignedJob.shouldTreatAsExpeditedJob()) {
-            assertEquals(2, numAssignedJobs);
-            assertTrue(changed.valueAt(1).newJob.shouldTreatAsExpeditedJob());
-        } else if (numAssignedJobs == 2) {
-            assertFalse(changed.valueAt(1).newJob.shouldTreatAsExpeditedJob());
+        if (numReg > 0) {
+            assertEquals(1, numReg);
+            assertEquals(1, numEj);
+            assertEquals(1, numUi);
+            assertEquals(3, numAssignedJobs);
+        } else {
+            if (numEj > 0) {
+                assertEquals(1, numEj);
+            }
+            // If the manager looks at an EJ before a UIJ, the waiting time for the UIJ will drop
+            // to 3 minutes and be below the threshold to create a new context.
+            if (numUi > 0) {
+                assertEquals(1, numUi);
+            }
+            assertEquals(numEj + numUi, numAssignedJobs);
         }
     }
 
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 ed78e72..63a5ff1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -32,6 +32,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
@@ -209,12 +211,12 @@
                 jobInfoBuilder.build(), callingUid, sourcePkg, 0, "JSSTest", testTag);
     }
 
-    private void grantRunLongJobsPermission(boolean grant) {
+    private void grantRunUserInitiatedJobsPermission(boolean grant) {
         final int permissionStatus = grant
                 ? PermissionChecker.PERMISSION_GRANTED : PermissionChecker.PERMISSION_HARD_DENIED;
         doReturn(permissionStatus)
                 .when(() -> PermissionChecker.checkPermissionForPreflight(
-                        any(), eq(android.Manifest.permission.RUN_LONG_JOBS),
+                        any(), eq(android.Manifest.permission.RUN_USER_INITIATED_JOBS),
                         anyInt(), anyInt(), anyString()));
     }
 
@@ -282,10 +284,10 @@
                 mService.getMinJobExecutionGuaranteeMs(jobHigh));
         assertEquals(mService.mConstants.RUNTIME_MIN_GUARANTEE_MS,
                 mService.getMinJobExecutionGuaranteeMs(jobDef));
-        grantRunLongJobsPermission(false); // Without permission
+        grantRunUserInitiatedJobsPermission(false); // Without permission
         assertEquals(mService.mConstants.RUNTIME_MIN_DATA_TRANSFER_GUARANTEE_MS,
                 mService.getMinJobExecutionGuaranteeMs(jobDT));
-        grantRunLongJobsPermission(true); // With permission
+        grantRunUserInitiatedJobsPermission(true); // With permission
         doReturn(ConnectivityController.UNKNOWN_TIME)
                 .when(connectivityController).getEstimatedTransferTimeMs(any());
         assertEquals(mService.mConstants.RUNTIME_MIN_DATA_TRANSFER_GUARANTEE_MS,
@@ -303,14 +305,14 @@
         assertEquals(mService.mConstants.RUNTIME_MIN_DATA_TRANSFER_GUARANTEE_MS,
                 mService.getMinJobExecutionGuaranteeMs(jobDT));
         // UserInitiated
-        grantRunLongJobsPermission(false);
+        grantRunUserInitiatedJobsPermission(false);
         // Permission isn't granted, so it should just be treated as a regular data transfer job.
         assertEquals(mService.mConstants.RUNTIME_MIN_DATA_TRANSFER_GUARANTEE_MS,
                 mService.getMinJobExecutionGuaranteeMs(jobUIDT));
         // Permission isn't granted, so it should just be treated as a regular job.
         assertEquals(mService.mConstants.RUNTIME_MIN_GUARANTEE_MS,
                 mService.getMinJobExecutionGuaranteeMs(jobUI));
-        grantRunLongJobsPermission(true); // With permission
+        grantRunUserInitiatedJobsPermission(true); // With permission
         assertEquals(mService.mConstants.RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS,
                 mService.getMinJobExecutionGuaranteeMs(jobUI));
         doReturn(ConnectivityController.UNKNOWN_TIME)
@@ -362,14 +364,14 @@
         doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
                 .when(quotaController).getMaxJobExecutionTimeMsLocked(any());
 
-        grantRunLongJobsPermission(true);
+        grantRunUserInitiatedJobsPermission(true);
         assertEquals(mService.mConstants.RUNTIME_DATA_TRANSFER_LIMIT_MS,
                 mService.getMaxJobExecutionTimeMs(jobDT));
         assertEquals(mService.mConstants.RUNTIME_USER_INITIATED_LIMIT_MS,
                 mService.getMaxJobExecutionTimeMs(jobUI));
         assertEquals(mService.mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS,
                 mService.getMaxJobExecutionTimeMs(jobUIDT));
-        grantRunLongJobsPermission(false);
+        grantRunUserInitiatedJobsPermission(false);
         assertEquals(mService.mConstants.RUNTIME_DATA_TRANSFER_LIMIT_MS,
                 mService.getMaxJobExecutionTimeMs(jobDT));
         assertEquals(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
@@ -470,6 +472,50 @@
     }
 
     /**
+     * Confirm that
+     * returns {@code null} when for user-visible jobs stopped by the user.
+     */
+    @Test
+    public void testGetRescheduleJobForFailure_userStopped() {
+        JobStatus uiJob = createJobStatus("testGetRescheduleJobForFailure",
+                createJobInfo().setUserInitiated(true));
+        JobStatus uvJob = createJobStatus("testGetRescheduleJobForFailure", createJobInfo());
+        spyOn(uvJob);
+        doReturn(true).when(uvJob).isUserVisibleJob();
+        JobStatus regJob = createJobStatus("testGetRescheduleJobForFailure", createJobInfo());
+
+        // Reschedule for a non-user reason
+        JobStatus rescheduledUiJob = mService.getRescheduleJobForFailureLocked(uiJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL);
+        JobStatus rescheduledUvJob = mService.getRescheduleJobForFailureLocked(uvJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL);
+        JobStatus rescheduledRegJob = mService.getRescheduleJobForFailureLocked(regJob,
+                JobParameters.STOP_REASON_DEVICE_STATE,
+                JobParameters.INTERNAL_STOP_REASON_DEVICE_THERMAL);
+        assertNotNull(rescheduledUiJob);
+        assertNotNull(rescheduledUvJob);
+        assertNotNull(rescheduledRegJob);
+
+        // Reschedule for a user reason. The user-visible jobs shouldn't be rescheduled.
+        spyOn(rescheduledUvJob);
+        doReturn(true).when(rescheduledUvJob).isUserVisibleJob();
+        rescheduledUiJob = mService.getRescheduleJobForFailureLocked(rescheduledUiJob,
+                JobParameters.STOP_REASON_USER,
+                JobParameters.INTERNAL_STOP_REASON_USER_UI_STOP);
+        rescheduledUvJob = mService.getRescheduleJobForFailureLocked(rescheduledUvJob,
+                JobParameters.STOP_REASON_USER,
+                JobParameters.INTERNAL_STOP_REASON_USER_UI_STOP);
+        rescheduledRegJob = mService.getRescheduleJobForFailureLocked(rescheduledRegJob,
+                JobParameters.STOP_REASON_USER,
+                JobParameters.INTERNAL_STOP_REASON_USER_UI_STOP);
+        assertNull(rescheduledUiJob);
+        assertNull(rescheduledUvJob);
+        assertNotNull(rescheduledRegJob);
+    }
+
+    /**
      * Confirm that {@link JobSchedulerService#getRescheduleJobForPeriodic(JobStatus)} returns a job
      * with the correct delay and deadline constraints if the periodic job is scheduled with the
      * minimum possible period.
@@ -1274,14 +1320,14 @@
         mService.getJobStore().add(job2a);
         mService.getJobStore().add(job2b);
 
-        mService.stopUserVisibleJobsInternal("pkg1", 1);
+        mService.notePendingUserRequestedAppStopInternal("pkg1", 1, "test");
         assertEquals(4, mService.getPendingJobQueue().size());
         assertTrue(mService.getPendingJobQueue().contains(job1a));
         assertTrue(mService.getPendingJobQueue().contains(job1b));
         assertTrue(mService.getPendingJobQueue().contains(job2a));
         assertTrue(mService.getPendingJobQueue().contains(job2b));
 
-        mService.stopUserVisibleJobsInternal("pkg1", 0);
+        mService.notePendingUserRequestedAppStopInternal("pkg1", 0, "test");
         assertEquals(2, mService.getPendingJobQueue().size());
         assertFalse(mService.getPendingJobQueue().contains(job1a));
         assertEquals(JobScheduler.PENDING_JOB_REASON_USER, mService.getPendingJobReason(job1a));
@@ -1290,7 +1336,7 @@
         assertTrue(mService.getPendingJobQueue().contains(job2a));
         assertTrue(mService.getPendingJobQueue().contains(job2b));
 
-        mService.stopUserVisibleJobsInternal("pkg2", 0);
+        mService.notePendingUserRequestedAppStopInternal("pkg2", 0, "test");
         assertEquals(0, mService.getPendingJobQueue().size());
         assertFalse(mService.getPendingJobQueue().contains(job1a));
         assertFalse(mService.getPendingJobQueue().contains(job1b));
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index 2c47fd9..e6bc72f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -225,6 +225,33 @@
     }
 
     @Test
+    public void testIsUserVisibleJob() {
+        JobInfo jobInfo = new JobInfo.Builder(101, new ComponentName("foo", "bar"))
+                .setUserInitiated(false)
+                .build();
+        JobStatus job = createJobStatus(jobInfo);
+
+        assertFalse(job.isUserVisibleJob());
+
+        // User-initiated jobs are always user-visible unless they've been demoted.
+        jobInfo = new JobInfo.Builder(101, new ComponentName("foo", "bar"))
+                .setUserInitiated(true)
+                .build();
+        job = createJobStatus(jobInfo);
+
+        assertTrue(job.isUserVisibleJob());
+
+        job.addInternalFlags(JobStatus.INTERNAL_FLAG_DEMOTED_BY_USER);
+        assertFalse(job.isUserVisibleJob());
+
+        job.startedAsUserInitiatedJob = true;
+        assertTrue(job.isUserVisibleJob());
+
+        job.startedAsUserInitiatedJob = false;
+        assertFalse(job.isUserVisibleJob());
+    }
+
+    @Test
     public void testMediaBackupExemption_lateConstraint() {
         final JobInfo triggerContentJob = new JobInfo.Builder(42, TEST_JOB_COMPONENT)
                 .addTriggerContentUri(new JobInfo.TriggerContentUri(IMAGES_MEDIA_URI, 0))
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
index e0662c4..c197b34 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt
@@ -55,7 +55,7 @@
 
         mPms = createPackageManagerService()
         doAnswer { false }.`when`(mPms).isPackageDeviceAdmin(any(), any())
-        doAnswer { null }.`when`(mPms).freezePackageForDelete(any(), any(), any(), any())
+        doAnswer { null }.`when`(mPms).freezePackageForDelete(any(), any(), any(), any(), any())
     }
 
     private fun createPackageManagerService(): PackageManagerService {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
index 4d13981..d99af77 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageFreezerTest.kt
@@ -37,6 +37,7 @@
     companion object {
         const val TEST_PACKAGE = "com.android.test.package"
         const val TEST_REASON = "test reason"
+        const val TEST_EXIT_REASON = 1
         const val TEST_USER_ID = 0
     }
 
@@ -82,14 +83,15 @@
     fun setup() {
         rule.system().stageNominalSystemState()
         pms = spy(createPackageManagerService(TEST_PACKAGE))
-        whenever(pms.killApplication(any(), any(), any(), any()))
+        whenever(pms.killApplication(any(), any(), any(), any(), any()))
     }
 
     @Test
     fun freezePackage() {
-        val freezer = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms)
+        val freezer = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms, TEST_EXIT_REASON)
         verify(pms, times(1))
-            .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
+            .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON),
+                    eq(TEST_EXIT_REASON))
 
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
             checkPackageStartable()
@@ -101,10 +103,13 @@
 
     @Test
     fun freezePackage_twice() {
-        val freezer1 = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms)
-        val freezer2 = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms)
+        val freezer1 = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms,
+                TEST_EXIT_REASON)
+        val freezer2 = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms,
+                TEST_EXIT_REASON)
         verify(pms, times(2))
-            .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
+            .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON),
+                    eq(TEST_EXIT_REASON))
 
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
             checkPackageStartable()
@@ -121,9 +126,11 @@
 
     @Test
     fun freezePackage_withoutClosing() {
-        var freezer: PackageFreezer? = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms)
+        var freezer: PackageFreezer? = PackageFreezer(TEST_PACKAGE, TEST_USER_ID, TEST_REASON, pms,
+                TEST_EXIT_REASON)
         verify(pms, times(1))
-            .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON))
+            .killApplication(eq(TEST_PACKAGE), any(), eq(TEST_USER_ID), eq(TEST_REASON),
+                    eq(TEST_EXIT_REASON))
 
         assertThrowContainsMessage(SecurityException::class, frozenMessage(TEST_PACKAGE)) {
             checkPackageStartable()
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index d03d196..1ed2f78 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -20,6 +20,7 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.assertThrows;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -316,21 +317,10 @@
     }
 
     @Test
-    public void testGetBootUser_Headless_UserCreatedIfOnlySystemUserExists() throws Exception {
+    public void testGetBootUser_Headless_ThrowsIfOnlySystemUserExists() throws Exception {
         setSystemUserHeadless(true);
 
-        int bootUser = mUmi.getBootUser();
-
-        assertWithMessage("getStartingUser")
-                .that(bootUser).isNotEqualTo(UserHandle.USER_SYSTEM);
-
-        UserData newUser = mUsers.get(bootUser);
-        assertWithMessage("New boot user is a full user")
-                .that(newUser.info.isFull()).isTrue();
-        assertWithMessage("New boot user is an admin user")
-                .that(newUser.info.isAdmin()).isTrue();
-        assertWithMessage("New boot user is the main user")
-                .that(newUser.info.isMain()).isTrue();
+        assertThrows(UserManager.CheckedUserOperationException.class, () -> mUmi.getBootUser());
     }
 
     private void mockCurrentUser(@UserIdInt int userId) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java
index 8979585..38cf634 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorMUPANDTest.java
@@ -75,8 +75,8 @@
         assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
 
         // Make sure another user cannot be started on default display
-        int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, otherUserId, BG_VISIBLE,
-                DEFAULT_DISPLAY);
+        int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, visibleBgUserId,
+                BG_VISIBLE, DEFAULT_DISPLAY);
         assertStartUserResult(result2, USER_ASSIGNMENT_RESULT_FAILURE,
                 "when user (%d) is starting on default display after it was started by user %d",
                 otherUserId, visibleBgUserId);
@@ -119,8 +119,8 @@
         assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
 
         // Make sure another user cannot be started on default display
-        int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, otherUserId, BG_VISIBLE,
-                DEFAULT_DISPLAY);
+        int result2 = mMediator.assignUserToDisplayOnStart(otherUserId, visibleBgUserId,
+                BG_VISIBLE, DEFAULT_DISPLAY);
         assertStartUserResult(result2, USER_ASSIGNMENT_RESULT_FAILURE,
                 "when user (%d) is starting on default display after it was started by user %d",
                 otherUserId, visibleBgUserId);
@@ -128,6 +128,7 @@
 
         listener.verify();
     }
+  /* TODO: re-add
 
     @Test
     public void
@@ -226,4 +227,5 @@
 
         listener.verify();
     }
+  */
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
index 566084a..5176d68 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
@@ -44,6 +44,7 @@
 import android.util.IntArray;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
 import com.android.server.ExtendedMockitoTestCase;
 
 import org.junit.Before;
@@ -148,12 +149,6 @@
     }
 
     @Test
-    public final void testAssignUserToDisplayOnStart_invalidUserStartMode() {
-        assertThrows(IllegalArgumentException.class, () -> mMediator
-                .assignUserToDisplayOnStart(USER_ID, USER_ID, 666, DEFAULT_DISPLAY));
-    }
-
-    @Test
     public final void testStartFgUser_onSecondaryDisplay() throws Exception {
         AsyncUserVisibilityListener listener = addListenerForNoEvents();
 
@@ -288,7 +283,7 @@
 
         int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
                 BG_VISIBLE, DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
+        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
 
         expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
         expectNoDisplayAssignedToUser(PROFILE_USER_ID);
@@ -304,14 +299,14 @@
 
         int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
                 BG_VISIBLE, DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
+        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
 
         expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
 
         expectNoDisplayAssignedToUser(PROFILE_USER_ID);
         expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
 
-        assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+        assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
 
         listener.verify();
     }
@@ -337,41 +332,6 @@
     }
 
     @Test
-    public final void testStartBgProfile_onDefaultDisplay_whenParentIsNotStarted()
-            throws Exception {
-        AsyncUserVisibilityListener listener = addListenerForNoEvents();
-
-        int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG,
-                DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
-
-        expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
-        expectNoDisplayAssignedToUser(PROFILE_USER_ID);
-
-        listener.verify();
-    }
-
-    @Test
-    public final void testStartBgProfile_onDefaultDisplay_whenParentIsStartedOnBg()
-            throws Exception {
-        AsyncUserVisibilityListener listener = addListenerForNoEvents();
-        startBackgroundUser(PARENT_USER_ID);
-
-        int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG,
-                DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
-
-        expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
-
-        expectNoDisplayAssignedToUser(PROFILE_USER_ID);
-        expectInitialCurrentUserAssignedToDisplay(DEFAULT_DISPLAY);
-
-        assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
-
-        listener.verify();
-    }
-
-    @Test
     public final void testStartBgProfile_onSecondaryDisplay() throws Exception {
         AsyncUserVisibilityListener listener = addListenerForNoEvents();
 
@@ -525,6 +485,8 @@
      * se.
      */
     protected final void startUserInSecondaryDisplay(@UserIdInt int userId, int displayId) {
+        Preconditions.checkArgument(displayId != INVALID_DISPLAY && displayId != DEFAULT_DISPLAY,
+                "must pass a secondary display, not %d", displayId);
         Log.d(TAG, "startUserInSecondaryDisplay(" + userId + ", " + displayId + ")");
         int result = mMediator.assignUserToDisplayOnStart(userId, userId, BG_VISIBLE, displayId);
         if (result != USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java
index f084063..af85ef4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorVisibleBackgroundUserTestCase.java
@@ -20,6 +20,7 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_FAILURE;
+import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_ALREADY_VISIBLE;
 import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE;
 import static com.android.server.pm.UserManagerInternal.USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE;
 import static com.android.server.pm.UserVisibilityChangedEvent.onInvisible;
@@ -108,6 +109,34 @@
     }
 
     @Test
+    public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsCurrentUser()
+            throws Exception {
+        AsyncUserVisibilityListener listener = addListenerForEvents(
+                onInvisible(INITIAL_CURRENT_USER_ID),
+                onVisible(PARENT_USER_ID),
+                onVisible(PROFILE_USER_ID));
+        startForegroundUser(PARENT_USER_ID);
+
+        int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
+                BG_VISIBLE, DEFAULT_DISPLAY);
+        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
+        expectUserCannotBeUnassignedFromDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
+
+        expectUserIsVisible(PROFILE_USER_ID);
+        expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY);
+        expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+        expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
+        expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID);
+
+        expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY);
+        expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID);
+
+        assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
+
+        listener.verify();
+    }
+
+    @Test
     public final void testStartFgUser_onInvalidDisplay() throws Exception {
         AsyncUserVisibilityListener listener = addListenerForNoEvents();
 
@@ -206,6 +235,38 @@
     }
 
     @Test
+    public final void testStartVisibleBgUser_onSecondaryDisplay_displayAlreadyAssignedToSameUser()
+            throws Exception {
+        AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(USER_ID));
+        startUserInSecondaryDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+
+        expectUserIsVisible(USER_ID);
+        expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+        expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
+        expectUserIsNotVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
+        expectVisibleUsers(INITIAL_CURRENT_USER_ID, USER_ID);
+        expectDisplayAssignedToUser(USER_ID, SECONDARY_DISPLAY_ID);
+        expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
+        assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
+
+        int result = mMediator.assignUserToDisplayOnStart(USER_ID, USER_ID, BG_VISIBLE,
+                SECONDARY_DISPLAY_ID);
+        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_ALREADY_VISIBLE);
+
+        // Run same assertions above
+        expectUserIsVisible(USER_ID);
+        expectUserIsVisibleOnDisplay(USER_ID, SECONDARY_DISPLAY_ID);
+        expectUserIsNotVisibleOnDisplay(USER_ID, INVALID_DISPLAY);
+        expectUserIsNotVisibleOnDisplay(USER_ID, DEFAULT_DISPLAY);
+        expectVisibleUsers(INITIAL_CURRENT_USER_ID, USER_ID);
+        expectDisplayAssignedToUser(USER_ID, SECONDARY_DISPLAY_ID);
+        expectUserAssignedToDisplay(SECONDARY_DISPLAY_ID, USER_ID);
+        assertUserCanBeAssignedExtraDisplay(USER_ID, OTHER_SECONDARY_DISPLAY_ID);
+
+        listener.verify();
+    }
+
+    @Test
     public final void testStartVisibleBgUser_onSecondaryDisplay_userAlreadyAssigned()
             throws Exception {
         AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(USER_ID));
@@ -240,83 +301,14 @@
     }
 
     @Test
-    public final void testStartVisibleBgProfile_onDefaultDisplay_whenParentIsCurrentUser()
-            throws Exception {
-        AsyncUserVisibilityListener listener = addListenerForEvents(
-                onInvisible(INITIAL_CURRENT_USER_ID),
-                onVisible(PARENT_USER_ID),
-                onVisible(PROFILE_USER_ID));
-        startForegroundUser(PARENT_USER_ID);
-
-        int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
-                BG_VISIBLE, DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_VISIBLE);
-        expectUserCannotBeUnassignedFromDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
-
-        expectUserIsVisible(PROFILE_USER_ID);
-        expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, INVALID_DISPLAY);
-        expectUserIsNotVisibleOnDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
-        expectUserIsVisibleOnDisplay(PROFILE_USER_ID, DEFAULT_DISPLAY);
-        expectVisibleUsers(PARENT_USER_ID, PROFILE_USER_ID);
-
-        expectDisplayAssignedToUser(PROFILE_USER_ID, DEFAULT_DISPLAY);
-        expectUserAssignedToDisplay(DEFAULT_DISPLAY, PARENT_USER_ID);
-
-        assertUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
-
-        listener.verify();
-    }
-
-    @Test
     public final void
-            testStartVisibleBgProfile_onDefaultDisplay_whenParentIsStartedVisibleOnAnotherDisplay()
-            throws Exception {
+            testStartVisibleBgProfile_onDefaultDisplay_whenParentVisibleOnSecondaryDisplay()
+                    throws Exception {
         AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(PARENT_USER_ID));
         startUserInSecondaryDisplay(PARENT_USER_ID, OTHER_SECONDARY_DISPLAY_ID);
 
         int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
                 BG_VISIBLE, DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
-
-        expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
-        expectNoDisplayAssignedToUser(PROFILE_USER_ID);
-        expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, PARENT_USER_ID);
-
-        assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
-
-        listener.verify();
-    }
-
-    // Not supported - profiles can only be started on default display
-    @Test
-    public final void
-            testStartVisibleBgProfile_onSecondaryDisplay_whenParentIsStartedVisibleOnThatDisplay()
-            throws Exception {
-        AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(PARENT_USER_ID));
-        startUserInSecondaryDisplay(PARENT_USER_ID, OTHER_SECONDARY_DISPLAY_ID);
-
-        int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID,
-                BG_VISIBLE, DEFAULT_DISPLAY);
-        assertStartUserResult(result, USER_ASSIGNMENT_RESULT_FAILURE);
-
-        expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
-        expectNoDisplayAssignedToUser(PROFILE_USER_ID);
-        expectUserAssignedToDisplay(OTHER_SECONDARY_DISPLAY_ID, PARENT_USER_ID);
-
-        assertInvisibleUserCannotBeAssignedExtraDisplay(PROFILE_USER_ID, SECONDARY_DISPLAY_ID);
-
-        listener.verify();
-    }
-
-    @Test
-    public final void
-            testStartProfile_onDefaultDisplay_whenParentIsStartedVisibleOnSecondaryDisplay()
-            throws Exception {
-        AsyncUserVisibilityListener listener = addListenerForEvents(onVisible(PARENT_USER_ID));
-        startUserInSecondaryDisplay(PARENT_USER_ID, OTHER_SECONDARY_DISPLAY_ID);
-
-        int result = mMediator.assignUserToDisplayOnStart(PROFILE_USER_ID, PARENT_USER_ID, BG,
-                DEFAULT_DISPLAY);
         assertStartUserResult(result, USER_ASSIGNMENT_RESULT_SUCCESS_INVISIBLE);
 
         expectUserIsNotVisibleAtAll(PROFILE_USER_ID);
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 9b48114..f8955ed 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -200,7 +200,6 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-
         ExtendedMockito.doAnswer(invocation -> {
             int userId = (invocation.getArgument(0));
             return getWallpaperTestDir(userId);
@@ -398,7 +397,8 @@
             TypedXmlSerializer serializer = Xml.newBinarySerializer();
             serializer.setOutput(new ByteArrayOutputStream(), StandardCharsets.UTF_8.name());
             serializer.startDocument(StandardCharsets.UTF_8.name(), true);
-            mService.writeWallpaperAttributes(serializer, "wp", systemWallpaperData);
+            mService.mWallpaperDataParser.writeWallpaperAttributes(
+                    serializer, "wp", systemWallpaperData);
         } catch (IOException e) {
             fail("exception occurred while writing system wallpaper attributes");
         }
@@ -409,7 +409,7 @@
                 systemWallpaperData.cropFile.getAbsolutePath());
         try {
             TypedXmlPullParser parser = Xml.newBinaryPullParser();
-            mService.parseWallpaperAttributes(parser, shouldMatchSystem, true);
+            mService.mWallpaperDataParser.parseWallpaperAttributes(parser, shouldMatchSystem, true);
         } catch (XmlPullParserException e) {
             fail("exception occurred while parsing wallpaper");
         }
diff --git a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
index 245db46..ae78dfe 100644
--- a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java
@@ -40,7 +40,6 @@
 import android.hardware.fingerprint.FingerprintSensorProperties;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.SystemProperties;
@@ -166,36 +165,6 @@
     }
 
     @Test
-    public void getApexInfo_postInitialize_returnsValidEntries() throws RemoteException {
-        prepApexInfo();
-        List result = mTestInterface.getApexInfo();
-        Assert.assertNotNull("Apex info map should not be null", result);
-        // TODO(265244016): When PackageManagerInternal is a mock, it's harder to keep the
-        // `measurePackage` working in unit test. Disable it for now. We may need more refactoring
-        // or cover this in integration tests.
-        // Assert.assertFalse("Apex info map should not be empty", result.isEmpty());
-    }
-
-    @Test
-    public void getApexInfo_postInitialize_returnsActualApexs()
-            throws RemoteException, PackageManager.NameNotFoundException {
-        prepApexInfo();
-        List resultList = mTestInterface.getApexInfo();
-
-        PackageManager pm = mContext.getPackageManager();
-        Assert.assertNotNull(pm);
-        List<Bundle> castedResult = (List<Bundle>) resultList;
-        for (Bundle resultBundle : castedResult) {
-            String packageName = resultBundle.getString(
-                    BinaryTransparencyService.BUNDLE_PACKAGE_NAME);
-            Assert.assertNotNull("Package name for APEX should not be null", packageName);
-            Assert.assertTrue(packageName + "is not an APEX!",
-                    resultBundle.getBoolean(
-                            BinaryTransparencyService.BUNDLE_PACKAGE_IS_APEX));
-        }
-    }
-
-    @Test
     public void testCollectBiometricProperties_disablesFeature() {
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS,
                 BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION,
diff --git a/services/tests/servicestests/src/com/android/server/DropBoxTest.java b/services/tests/servicestests/src/com/android/server/DropBoxTest.java
index a25f492..1c79b50 100644
--- a/services/tests/servicestests/src/com/android/server/DropBoxTest.java
+++ b/services/tests/servicestests/src/com/android/server/DropBoxTest.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
+import android.os.Bundle;
 import android.os.DropBoxManager;
 import android.os.Looper;
 import android.os.Parcel;
@@ -66,7 +67,7 @@
         mContext = new ContextWrapper(super.getContext()) {
             @Override
             public void sendBroadcastAsUser(Intent intent,
-                    UserHandle user, String receiverPermission) {
+                    UserHandle user, String receiverPermission, Bundle options) {
                 // Don't actually send broadcasts.
             }
         };
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 4d1d2b2..4249405 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -16,24 +16,19 @@
 
 package com.android.server.accessibility;
 
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
-import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT;
 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 android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
-import static android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_MENU_IN_SYSTEM;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
-import static com.android.server.accessibility.AccessibilityManagerService.MENU_SERVICE_RELATIVE_CLASS_NAME;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
@@ -99,7 +94,6 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * APCT tests for {@link AccessibilityManagerService}.
@@ -438,6 +432,40 @@
         verify(mMockMagnificationController).setMagnificationFollowTypingEnabled(false);
     }
 
+    @Test
+    public void testSettingsAlwaysOn_setEnabled_featureFlagDisabled_doNothing() {
+        when(mMockMagnificationController.isAlwaysOnMagnificationFeatureFlagEnabled())
+                .thenReturn(false);
+
+        final AccessibilityUserState userState = mA11yms.mUserStates.get(
+                mA11yms.getCurrentUserIdLocked());
+        Settings.Secure.putIntForUser(
+                mTestableContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
+                1, mA11yms.getCurrentUserIdLocked());
+
+        mA11yms.readAlwaysOnMagnificationLocked(userState);
+
+        verify(mMockMagnificationController, never()).setAlwaysOnMagnificationEnabled(anyBoolean());
+    }
+
+    @Test
+    public void testSettingsAlwaysOn_setEnabled_featureFlagEnabled_propagateToController() {
+        when(mMockMagnificationController.isAlwaysOnMagnificationFeatureFlagEnabled())
+                .thenReturn(true);
+
+        final AccessibilityUserState userState = mA11yms.mUserStates.get(
+                mA11yms.getCurrentUserIdLocked());
+        Settings.Secure.putIntForUser(
+                mTestableContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
+                1, mA11yms.getCurrentUserIdLocked());
+
+        mA11yms.readAlwaysOnMagnificationLocked(userState);
+
+        verify(mMockMagnificationController).setAlwaysOnMagnificationEnabled(eq(true));
+    }
+
     @SmallTest
     @Test
     public void testOnClientChange_magnificationEnabledAndCapabilityAll_requestConnection() {
@@ -523,113 +551,6 @@
                 ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
     }
 
-    @Test
-    public void testMigrateA11yMenu_ResetSingularComponentToDefaultState() {
-        final ComponentName componentName =
-                ComponentName.createRelative("external", MENU_SERVICE_RELATIVE_CLASS_NAME);
-        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
-                eq(mA11yms.getCurrentUserIdLocked()))).thenReturn(
-                List.of(createResolveInfo(componentName)));
-
-        mA11yms.migrateAccessibilityMenuIfNecessaryLocked(mA11yms.getCurrentUserState());
-
-        verify(mMockPackageManager).setComponentEnabledSetting(componentName,
-                PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
-                PackageManager.DONT_KILL_APP);
-    }
-
-    @Test
-    public void testMigrateA11yMenu_DoNothing_WhenNoMenuComponents() {
-        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
-                eq(mA11yms.getCurrentUserIdLocked()))).thenReturn(List.of());
-
-        mA11yms.migrateAccessibilityMenuIfNecessaryLocked(mA11yms.getCurrentUserState());
-
-        verify(mMockPackageManager, never()).setComponentEnabledSetting(any(),
-                anyInt(), anyInt());
-    }
-
-    @Test
-    public void testMigrateA11yMenu_DoNothing_WhenTooManyMenuComponents() {
-        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
-                eq(mA11yms.getCurrentUserIdLocked()))).thenReturn(List.of(
-                createResolveInfo(ComponentName.createRelative("external1",
-                        MENU_SERVICE_RELATIVE_CLASS_NAME)),
-                createResolveInfo(ComponentName.createRelative("external2",
-                        MENU_SERVICE_RELATIVE_CLASS_NAME)),
-                createResolveInfo(ComponentName.createRelative("external3",
-                        MENU_SERVICE_RELATIVE_CLASS_NAME))));
-
-        mA11yms.migrateAccessibilityMenuIfNecessaryLocked(mA11yms.getCurrentUserState());
-
-        verify(mMockPackageManager, never()).setComponentEnabledSetting(any(),
-                anyInt(), anyInt());
-    }
-
-    @Test
-    public void testMigrateA11yMenu_DoNothing_WhenNoMenuInSystem() {
-        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
-                eq(mA11yms.getCurrentUserIdLocked()))).thenReturn(List.of(
-                createResolveInfo(ComponentName.createRelative("external1",
-                        MENU_SERVICE_RELATIVE_CLASS_NAME)),
-                createResolveInfo(ComponentName.createRelative("external2",
-                        MENU_SERVICE_RELATIVE_CLASS_NAME))));
-
-        mA11yms.migrateAccessibilityMenuIfNecessaryLocked(mA11yms.getCurrentUserState());
-
-        verify(mMockPackageManager, never()).setComponentEnabledSetting(any(),
-                anyInt(), anyInt());
-    }
-
-    @Test
-    public void testMigrateA11yMenu_PerformsMigration() {
-        final ComponentName menuOutsideSystem =
-                ComponentName.createRelative("external", MENU_SERVICE_RELATIVE_CLASS_NAME);
-        final String[] migratedSettings = {
-                ACCESSIBILITY_BUTTON_TARGETS,
-                ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
-                ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                ENABLED_ACCESSIBILITY_SERVICES
-        };
-        // Start the user with Menu-outside-system enabled,
-        for (String setting : migratedSettings) {
-            Settings.Secure.putStringForUser(
-                    mTestableContext.getContentResolver(),
-                    setting,
-                    menuOutsideSystem.flattenToShortString(),
-                    mA11yms.getCurrentUserIdLocked());
-        }
-        // and both Menu versions present.
-        when(mMockPackageManager.queryIntentServicesAsUser(any(), any(),
-                eq(mA11yms.getCurrentUserIdLocked()))).thenReturn(List.of(
-                createResolveInfo(menuOutsideSystem),
-                createResolveInfo(ACCESSIBILITY_MENU_IN_SYSTEM)));
-
-        mA11yms.migrateAccessibilityMenuIfNecessaryLocked(mA11yms.getCurrentUserState());
-
-        // Menu-outside-system should be disabled,
-        verify(mMockPackageManager).setComponentEnabledSetting(menuOutsideSystem,
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
-        // and all settings should migrated to Menu-in-system.
-        for (String setting : migratedSettings) {
-            ComponentName componentName = ComponentName.unflattenFromString(
-                    Settings.Secure.getStringForUser(
-                            mTestableContext.getContentResolver(),
-                            setting,
-                            mA11yms.getCurrentUserIdLocked()));
-            assertThat(componentName).isEqualTo(ACCESSIBILITY_MENU_IN_SYSTEM);
-        }
-    }
-
-    private static ResolveInfo createResolveInfo(ComponentName componentName) {
-        ResolveInfo resolveInfo = new ResolveInfo();
-        resolveInfo.serviceInfo = new ServiceInfo();
-        resolveInfo.serviceInfo.packageName = componentName.getPackageName();
-        resolveInfo.serviceInfo.name = componentName.getClassName();
-        return resolveInfo;
-    }
-
     private void mockManageAccessibilityGranted(TestableContext context) {
         context.getTestablePermissions().setPermission(Manifest.permission.MANAGE_ACCESSIBILITY,
                 PackageManager.PERMISSION_GRANTED);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java
index df21ea3..eb6670e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java
@@ -113,6 +113,7 @@
             AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
             AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
             AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED,
+            AccessibilityEvent.TYPE_VIEW_TARGETED_BY_SCROLL,
     };
 
     private AccessibilitySecurityPolicy mA11ySecurityPolicy;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
index ed0336a..b4558b2 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
@@ -179,6 +179,7 @@
         assertEquals(mFocusStrokeWidthDefaultValue, mUserState.getFocusStrokeWidthLocked());
         assertEquals(mFocusColorDefaultValue, mUserState.getFocusColorLocked());
         assertTrue(mUserState.isMagnificationFollowTypingEnabled());
+        assertFalse(mUserState.isAlwaysOnMagnificationEnabled());
     }
 
     @Test
@@ -390,6 +391,15 @@
     }
 
     @Test
+    public void setAlwaysOnMagnificationEnabled_defaultFalseAndSetTrue_returnTrue() {
+        assertFalse(mUserState.isAlwaysOnMagnificationEnabled());
+
+        mUserState.setAlwaysOnMagnificationEnabled(true);
+
+        assertTrue(mUserState.isAlwaysOnMagnificationEnabled());
+    }
+
+    @Test
     public void setFocusAppearanceData_returnExpectedFocusAppearanceData() {
         final int focusStrokeWidthValue = 100;
         final int focusColorValue = Color.BLUE;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/FlashNotificationsControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FlashNotificationsControllerTest.java
new file mode 100644
index 0000000..8a057df
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/FlashNotificationsControllerTest.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.accessibility;
+
+import static android.hardware.camera2.CameraCharacteristics.FLASH_INFO_AVAILABLE;
+import static android.hardware.camera2.CameraCharacteristics.LENS_FACING;
+import static android.hardware.camera2.CameraMetadata.LENS_FACING_BACK;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.server.accessibility.FlashNotificationsController.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
+import static com.android.server.accessibility.FlashNotificationsController.ACTION_FLASH_NOTIFICATION_STOP_PREVIEW;
+import static com.android.server.accessibility.FlashNotificationsController.EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR;
+import static com.android.server.accessibility.FlashNotificationsController.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
+import static com.android.server.accessibility.FlashNotificationsController.PREVIEW_TYPE_LONG;
+import static com.android.server.accessibility.FlashNotificationsController.PREVIEW_TYPE_SHORT;
+import static com.android.server.accessibility.FlashNotificationsController.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
+import static com.android.server.accessibility.FlashNotificationsController.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
+import static com.android.server.accessibility.FlashNotificationsController.SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+import static java.lang.Integer.max;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
+import android.media.PlayerBase;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContentResolver;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.annotation.NonNull;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for {@link FlashNotificationsController}.
+ */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class FlashNotificationsControllerTest {
+    private static final String CALL_TAG = "com.android.server.telecom";
+    private static final String NOTI_TAG = "android";
+    private static final String NOTI_REASON_PKG = "noti.reason.pkg";
+    private static final int COLOR_YELLOW = 0x66FFFF00;
+    private static final int COLOR_BLUE = 0x4d0000fe;
+
+    @Rule
+    public final TestableContext mTestableContext = new TestableContext(
+            getInstrumentation().getTargetContext());
+
+    private final Map<String, CameraInfo> mCameraInfoMap = new HashMap<>();
+    private final Set<View> mViews = new HashSet<>();
+
+    @Mock
+    private IBinder mMockToken;
+    @Mock
+    private WindowManager mMockWindowManager;
+    @Mock
+    private AudioManager mMockAudioManager;
+
+    private final List<AudioPlaybackConfiguration> mAudioConfigsWithAlarm = getConfigWithAlarm();
+
+    private CameraManager mCameraManager;
+    private AudioManager.AudioPlaybackCallback mAudioPlaybackCallback;
+    private TestableContentResolver mTestableContentResolver;
+
+    private TestableLooper mTestableLooper;
+    private Handler mTestHandler;
+    private HandlerThread mFlashHandlerThread;
+    private Handler mFlashHandler;
+
+    private FlashNotificationsController mController;
+
+    private int mScreenFlashCount = 0;
+    private int mLastFlashedViewColor = Color.TRANSPARENT;
+
+    private final CameraManager.TorchCallback mTorchCallback = new CameraManager.TorchCallback() {
+        @Override
+        public void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {
+            CameraInfo info = mCameraInfoMap.getOrDefault(cameraId,
+                    new CameraInfo(false));
+            info.setEnabled(enabled);
+            mCameraInfoMap.put(cameraId, info);
+        }
+    };
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mTestableLooper = TestableLooper.get(this);
+        mTestHandler = new Handler(mTestableLooper.getLooper());
+        mFlashHandlerThread = new HandlerThread("TestFlashHandlerThread");
+        mFlashHandlerThread.start();
+        mFlashHandler = mFlashHandlerThread.getThreadHandler();
+
+        doAnswer(invocation -> {
+            final View view = invocation.getArgument(0);
+            mLastFlashedViewColor = getBackgroundColor(view);
+            mViews.add(view);
+            return null;
+        }).when(mMockWindowManager).addView(any(View.class), any(ViewGroup.LayoutParams.class));
+        doAnswer(invocation -> {
+            final View view = invocation.getArgument(0);
+            final boolean isAnyViewAdded = !mViews.isEmpty();
+            mViews.remove(view);
+            if (isAnyViewAdded && mViews.isEmpty()) mScreenFlashCount++;
+            return null;
+        }).when(mMockWindowManager).removeView(any(View.class));
+        mTestableContext.addMockSystemService(Context.WINDOW_SERVICE, mMockWindowManager);
+
+        doAnswer(invocation -> {
+            mAudioPlaybackCallback = invocation.getArgument(0);
+            return null;
+        }).when(mMockAudioManager).registerAudioPlaybackCallback(
+                any(AudioManager.AudioPlaybackCallback.class), any(Handler.class));
+        mTestableContext.addMockSystemService(Context.AUDIO_SERVICE, mMockAudioManager);
+
+        mCameraManager = mTestableContext.getSystemService(CameraManager.class);
+        if (mCameraManager != null) {
+            try {
+                for (String id : mCameraManager.getCameraIdList()) {
+                    CameraCharacteristics value = mCameraManager.getCameraCharacteristics(id);
+                    Boolean available = value.get(FLASH_INFO_AVAILABLE);
+                    Integer facing = value.get(LENS_FACING);
+                    mCameraInfoMap.put(id, new CameraInfo(
+                            available != null && available
+                                    && facing != null && facing == LENS_FACING_BACK
+                    ));
+                }
+            } catch (CameraAccessException ignored) {
+            }
+            mCameraManager.registerTorchCallback(mTorchCallback, mTestHandler);
+        }
+
+        mTestableContentResolver = mTestableContext.getContentResolver();
+        putCameraFlash(false);
+        putScreenFlash(false);
+        putScreenColor(Color.TRANSPARENT);
+    }
+
+    @After
+    public void tearDown() {
+        mCameraManager.unregisterTorchCallback(mTorchCallback);
+        mFlashHandlerThread.quit();
+        mTestableLooper.processAllMessages();
+    }
+
+    @Test
+    public void testCallSequence_putCameraFlashTrue_assertCameraFlashedScreenNotFlashed()
+            throws InterruptedException {
+        assumeCameraTorchAvailable();
+        putCameraFlash(true);
+        initController(mFlashHandler);
+
+        simulateCallSequence();
+
+        assertThat(getCameraFlashedCount()).isGreaterThan(0);
+        assertThat(mScreenFlashCount).isEqualTo(0);
+    }
+
+    @Test
+    public void testCallSequence_putScreenFlashTrue_assertScreenFlashedCameraNotFlashed()
+            throws InterruptedException {
+        putScreenFlash(true);
+        putScreenColor(COLOR_YELLOW);
+        initController(mFlashHandler);
+
+        simulateCallSequence();
+
+        assertThat(mScreenFlashCount).isGreaterThan(0);
+        assertThat(getCameraFlashedCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testAlarmSequence_putCameraFlashTrue_assertCameraFlashedScreenNotFlashed()
+            throws InterruptedException {
+        assumeCameraTorchAvailable();
+        putCameraFlash(true);
+        initController(mFlashHandler);
+
+        simulateAlarmSequence();
+
+        assertThat(getCameraFlashedCount()).isGreaterThan(0);
+        assertThat(mScreenFlashCount).isEqualTo(0);
+    }
+
+    @Test
+    public void testAlarmSequence_putScreenFlashTrue_assertScreenFlashedCameraNotFlashed()
+            throws InterruptedException {
+        putScreenFlash(true);
+        putScreenColor(COLOR_YELLOW);
+        initController(mFlashHandler);
+
+        simulateAlarmSequence();
+
+        assertThat(mScreenFlashCount).isGreaterThan(0);
+        assertThat(getCameraFlashedCount()).isEqualTo(0);
+
+    }
+
+    @Test
+    public void testEvent_putCameraFlashTrue_assertCameraFlashedScreenNotFlashed() {
+        assumeCameraTorchAvailable();
+        putCameraFlash(true);
+        initController(mTestHandler);
+
+        simulateNotificationEvent();
+
+        assertThat(getCameraFlashedCount()).isGreaterThan(0);
+        assertThat(mScreenFlashCount).isEqualTo(0);
+    }
+
+    @Test
+    public void testEvent_putScreenFlashTrue_assertScreenFlashedCameraNotFlashed() {
+        putScreenFlash(true);
+        putScreenColor(COLOR_YELLOW);
+        initController(mTestHandler);
+
+        simulateNotificationEvent();
+
+        assertThat(mScreenFlashCount).isGreaterThan(0);
+        assertThat(getCameraFlashedCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testShortPreview_putCameraFlashTrue_assertCameraFlashedScreenNotFlashed() {
+        assumeCameraTorchAvailable();
+        putCameraFlash(true);
+        initController(mTestHandler);
+
+        simulateShortPreview();
+
+        assertThat(getCameraFlashedCount()).isGreaterThan(0);
+        assertThat(mScreenFlashCount).isEqualTo(0);
+    }
+
+    @Test
+    public void testShortPreview_putScreenFlashTrue_assertScreenFlashedCameraNotFlashed() {
+        putScreenFlash(true);
+        putScreenColor(COLOR_YELLOW);
+        initController(mTestHandler);
+
+        simulateShortPreview();
+
+        assertThat(mScreenFlashCount).isGreaterThan(0);
+        assertThat(getCameraFlashedCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testLongPreview_assertScreenFlashed()
+            throws InterruptedException {
+        initController(mFlashHandler);
+
+        simulateLongPreview(COLOR_YELLOW);
+
+        assertThat(mScreenFlashCount).isGreaterThan(0);
+    }
+
+    @Test
+    public void testLongPreview_putScreenFlashColorBlue_assertScreenFlashedYellow()
+            throws InterruptedException {
+        putScreenColor(COLOR_YELLOW);
+        initController(mFlashHandler);
+
+        simulateLongPreview(COLOR_BLUE);
+
+        assertThat(mLastFlashedViewColor).isEqualTo(COLOR_BLUE);
+    }
+
+    @Test
+    public void testLongPreview_putCameraFlashTrue_assertNotCameraFlashed()
+            throws InterruptedException {
+        assumeCameraTorchAvailable();
+        putCameraFlash(true);
+        initController(mFlashHandler);
+
+        simulateLongPreview(COLOR_YELLOW);
+
+        assertThat(getCameraFlashedCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testStartFlashNotificationSequence_invalidToken() {
+        initController(mTestHandler);
+
+        assertThat(mController.startFlashNotificationSequence(CALL_TAG,
+                AccessibilityManager.FLASH_REASON_CALL, null)).isFalse();
+    }
+
+    @Test
+    public void testOpenedCameraTest() {
+        assumeCameraTorchAvailable();
+        putCameraFlash(true);
+        putScreenFlash(true);
+        putScreenColor(COLOR_YELLOW);
+        initController(mTestHandler);
+
+        simulateCameraOpened();
+        simulateNotificationEvent();
+        simulateCameraClosed();
+
+        assertThat(getCameraFlashedCount()).isEqualTo(0);
+    }
+
+    private void initController(Handler flashHandler) {
+        mController = new FlashNotificationsController(mTestableContext,
+                flashHandler, mTestHandler);
+        mController.mFlashBroadcastReceiver.onReceive(mTestableContext,
+                new Intent(Intent.ACTION_BOOT_COMPLETED));
+    }
+
+    private void assumeCameraTorchAvailable() {
+        assumeTrue(mCameraManager != null);
+        assumeTrue(!mCameraInfoMap.isEmpty());
+    }
+
+    private void simulateCallSequence() throws InterruptedException {
+        mController.startFlashNotificationSequence(CALL_TAG,
+                AccessibilityManager.FLASH_REASON_CALL, mMockToken);
+        processLooper(2500);
+        Thread.sleep(2500);
+
+        mController.stopFlashNotificationSequence(CALL_TAG);
+        processLooper(500);
+        Thread.sleep(500);
+    }
+
+    private void simulateAlarmSequence() throws InterruptedException {
+        mAudioPlaybackCallback.onPlaybackConfigChanged(mAudioConfigsWithAlarm);
+        processLooper(2500);
+        Thread.sleep(2500);
+
+        mAudioPlaybackCallback.onPlaybackConfigChanged(Collections.emptyList());
+        processLooper(500);
+        Thread.sleep(500);
+    }
+
+    private void simulateNotificationEvent() {
+        mController.startFlashNotificationEvent(NOTI_TAG,
+                AccessibilityManager.FLASH_REASON_NOTIFICATION, NOTI_REASON_PKG);
+
+        processLooper(3000);
+    }
+
+    private void simulateShortPreview() {
+        Intent intent = new Intent(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
+        intent.putExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, PREVIEW_TYPE_SHORT);
+        mController.mFlashBroadcastReceiver.onReceive(mTestableContext, intent);
+
+        processLooper(3000);
+    }
+
+    private void simulateLongPreview(int color) throws InterruptedException {
+        Intent startIntent = new Intent(ACTION_FLASH_NOTIFICATION_START_PREVIEW);
+        startIntent.putExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE, PREVIEW_TYPE_LONG);
+        startIntent.putExtra(EXTRA_FLASH_NOTIFICATION_PREVIEW_COLOR, color);
+        mController.mFlashBroadcastReceiver.onReceive(mTestableContext, startIntent);
+        processLooper(2500);
+        Thread.sleep(2500);
+
+        Intent stopIntent = new Intent(ACTION_FLASH_NOTIFICATION_STOP_PREVIEW);
+        mController.mFlashBroadcastReceiver.onReceive(mTestableContext, stopIntent);
+        processLooper(500);
+        Thread.sleep(500);
+    }
+
+    private void processLooper(long millis) {
+        mTestableLooper.moveTimeForward(millis);
+        mTestableLooper.processAllMessages();
+    }
+
+    private static List<AudioPlaybackConfiguration> getConfigWithAlarm() {
+        List<AudioPlaybackConfiguration> list = new ArrayList<>();
+
+        AudioPlaybackConfiguration config = new AudioPlaybackConfiguration(
+                mock(PlayerBase.PlayerIdCard.class), 0, 0, 0);
+        config.handleStateEvent(AudioPlaybackConfiguration.PLAYER_STATE_STARTED,
+                AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID);
+
+        AudioAttributes.Builder builder = new AudioAttributes.Builder();
+        builder.setUsage(AudioAttributes.USAGE_ALARM);
+        AudioAttributes attr = builder.build();
+
+        config.handleAudioAttributesEvent(attr);
+
+        list.add(config);
+        return list;
+    }
+
+    private int getCameraFlashedCount() {
+        int count = 0;
+        for (CameraInfo info : mCameraInfoMap.values()) {
+            count = max(count, info.mTorchFlashCount);
+        }
+        return count;
+    }
+
+    private int getBackgroundColor(View view) {
+        final Drawable background = view.getBackground();
+        if (background instanceof ColorDrawable) {
+            return ((ColorDrawable) background).getColor();
+        } else {
+            return Color.TRANSPARENT;
+        }
+    }
+
+    private void putCameraFlash(boolean value) {
+        Settings.System.putIntForUser(mTestableContentResolver,
+                SETTING_KEY_CAMERA_FLASH_NOTIFICATION,
+                value ? 1 : 0, UserHandle.USER_CURRENT);
+    }
+
+    private void putScreenFlash(boolean value) {
+        Settings.System.putIntForUser(mTestableContentResolver,
+                SETTING_KEY_SCREEN_FLASH_NOTIFICATION,
+                value ? 1 : 0, UserHandle.USER_CURRENT);
+    }
+
+    private void putScreenColor(int color) {
+        Settings.System.putIntForUser(mTestableContentResolver,
+                SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR,
+                color, UserHandle.USER_CURRENT);
+    }
+
+    private void simulateCameraOpened() {
+        for (String cameraId : mCameraInfoMap.keySet()) {
+            System.out.println("simulate open camera: " + cameraId);
+            mController.mTorchAvailabilityCallback.onCameraOpened(cameraId, "");
+        }
+        processLooper(200);
+    }
+
+    private void simulateCameraClosed() {
+        for (String cameraId : mCameraInfoMap.keySet()) {
+            System.out.println("simulate close camera: " + cameraId);
+            mController.mTorchAvailabilityCallback.onCameraClosed(cameraId);
+        }
+        processLooper(200);
+    }
+
+    private static class CameraInfo {
+        final boolean mIsValid;
+        boolean mEnabled = false;
+        int mTorchFlashCount = 0;
+
+        CameraInfo(boolean isValid) {
+            mIsValid = isValid;
+        }
+
+        void setEnabled(boolean enabled) {
+            if (mEnabled && !enabled) mTorchFlashCount++;
+            mEnabled = enabled;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index d996e37..2d036fe 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -19,6 +19,7 @@
 import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_FULLSCREEN;
 
 import static com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback;
+import static com.android.server.accessibility.magnification.MockWindowMagnificationConnection.TEST_DISPLAY;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -48,6 +49,9 @@
 import android.graphics.Region;
 import android.hardware.display.DisplayManagerInternal;
 import android.os.Looper;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
 import android.view.DisplayInfo;
 import android.view.MagnificationSpec;
 import android.view.accessibility.MagnificationAnimationCallback;
@@ -55,6 +59,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityTraceManager;
 import com.android.server.accessibility.test.MessageCapturingHandler;
@@ -71,6 +76,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.stubbing.Answer;
+import org.testng.Assert;
 
 import java.util.Locale;
 
@@ -93,6 +99,7 @@
     static final int DISPLAY_1 = 1;
     static final int DISPLAY_COUNT = 2;
     static final int INVALID_DISPLAY = 2;
+    private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM;
 
     final FullScreenMagnificationController.ControllerContext mMockControllerCtx =
             mock(FullScreenMagnificationController.ControllerContext.class);
@@ -105,8 +112,8 @@
             MagnificationInfoChangedCallback.class);
     private final MessageCapturingHandler mMessageCapturingHandler = new MessageCapturingHandler(
             null);
-    private final MagnificationScaleProvider mScaleProvider = mock(
-            MagnificationScaleProvider.class);
+    private MagnificationScaleProvider mScaleProvider;
+    private MockContentResolver mResolver;
 
     private final ArgumentCaptor<MagnificationConfig> mConfigCaptor = ArgumentCaptor.forClass(
             MagnificationConfig.class);
@@ -129,6 +136,12 @@
         when(mMockControllerCtx.getWindowManager()).thenReturn(mMockWindowManager);
         when(mMockControllerCtx.getHandler()).thenReturn(mMessageCapturingHandler);
         when(mMockControllerCtx.getAnimationDuration()).thenReturn(1000L);
+        mResolver = new MockContentResolver();
+        mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        when(mMockContext.getContentResolver()).thenReturn(mResolver);
+        Settings.Secure.putFloatForUser(mResolver,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.0f,
+                CURRENT_USER_ID);
         initMockWindowManager();
 
         final DisplayInfo displayInfo = new DisplayInfo();
@@ -137,6 +150,7 @@
         LocalServices.removeServiceForTest(DisplayManagerInternal.class);
         LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
 
+        mScaleProvider = new MagnificationScaleProvider(mMockContext);
         mFullScreenMagnificationController = new FullScreenMagnificationController(
                 mMockControllerCtx, new Object(), mRequestObserver, mScaleProvider);
     }
@@ -1168,6 +1182,41 @@
         verify(mRequestObserver).onImeWindowVisibilityChanged(eq(DISPLAY_0), eq(true));
     }
 
+    @Test
+    public void persistScale_setValueWhenScaleIsOne_nothingChanged() {
+        final float persistedScale =
+                mFullScreenMagnificationController.getPersistedScale(TEST_DISPLAY);
+
+        PointF pivotPoint = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        mFullScreenMagnificationController.setScale(DISPLAY_0, 1.0f, pivotPoint.x, pivotPoint.y,
+                false, SERVICE_ID_1);
+        mFullScreenMagnificationController.persistScale(TEST_DISPLAY);
+
+        Assert.assertEquals(mFullScreenMagnificationController.getPersistedScale(TEST_DISPLAY),
+                persistedScale);
+    }
+
+    @Test
+    public void testOnContextChanged_alwaysOnFeatureDisabled_resetMagnification() {
+        setScaleToMagnifying();
+
+        mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(false);
+        mFullScreenMagnificationController.onUserContextChanged(DISPLAY_0);
+
+        verify(mRequestObserver).onFullScreenMagnificationActivationState(eq(DISPLAY_0), eq(false));
+    }
+
+    @Test
+    public void testOnContextChanged_alwaysOnFeatureEnabled_setScaleTo1xAndStayActivated() {
+        setScaleToMagnifying();
+
+        mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true);
+        mFullScreenMagnificationController.onUserContextChanged(DISPLAY_0);
+
+        assertEquals(1.0f, mFullScreenMagnificationController.getScale(DISPLAY_0), 0);
+        assertTrue(mFullScreenMagnificationController.isActivated(DISPLAY_0));
+    }
+
     private void setScaleToMagnifying() {
         register(DISPLAY_0);
         float scale = 2.0f;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 5334e4c..a095760 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -81,23 +81,27 @@
  *          IDLE -> SHORTCUT_TRIGGERED [label="a11y\nbtn"]
  *          IDLE -> DOUBLE_TAP [label="2tap"]
  *          DOUBLE_TAP -> IDLE [label="timeout"]
- *          DOUBLE_TAP -> ZOOMED [label="tap"]
+ *          DOUBLE_TAP -> ACTIVATED [label="tap"]
  *          DOUBLE_TAP -> NON_ACTIVATED_ZOOMED_TMP [label="hold"]
  *          NON_ACTIVATED_ZOOMED_TMP -> IDLE [label="release"]
  *          SHORTCUT_TRIGGERED -> IDLE [label="a11y\nbtn"]
- *          SHORTCUT_TRIGGERED -> ZOOMED[label="tap"]
- *          SHORTCUT_TRIGGERED -> ACTIVATED_ZOOMED_TMP [label="hold"]
+ *          SHORTCUT_TRIGGERED -> ACTIVATED [label="tap"]
+ *          SHORTCUT_TRIGGERED -> SHORTCUT_TRIGGERED_ZOOMED_TMP [label="hold"]
  *          SHORTCUT_TRIGGERED -> PANNING [label="2hold]
- *          ZOOMED -> ZOOMED_DOUBLE_TAP [label="2tap"]
- *          ZOOMED -> IDLE [label="a11y\nbtn"]
- *          ZOOMED -> PANNING [label="2hold"]
- *          ZOOMED_DOUBLE_TAP -> ZOOMED [label="timeout"]
- *          ZOOMED_DOUBLE_TAP -> ACTIVATED_ZOOMED_TMP [label="hold"]
- *          ZOOMED_DOUBLE_TAP -> IDLE [label="tap"]
- *          ACTIVATED_ZOOMED_TMP -> ZOOMED [label="release"]
- *          PANNING -> ZOOMED [label="release"]
+ *          if always-on enabled:
+ *              SHORTCUT_TRIGGERED_ZOOMED_TMP -> ACTIVATED [label="release"]
+ *          else:
+ *              SHORTCUT_TRIGGERED_ZOOMED_TMP -> IDLE [label="release"]
+ *          ACTIVATED -> ACTIVATED_DOUBLE_TAP [label="2tap"]
+ *          ACTIVATED -> IDLE [label="a11y\nbtn"]
+ *          ACTIVATED -> PANNING [label="2hold"]
+ *          ACTIVATED_DOUBLE_TAP -> ACTIVATED [label="timeout"]
+ *          ACTIVATED_DOUBLE_TAP -> ACTIVATED_ZOOMED_TMP [label="hold"]
+ *          ACTIVATED_DOUBLE_TAP -> IDLE [label="tap"]
+ *          ACTIVATED_ZOOMED_TMP -> ACTIVATED [label="release"]
+ *          PANNING -> ACTIVATED [label="release"]
  *          PANNING -> PANNING_SCALING [label="pinch"]
- *          PANNING_SCALING -> ZOOMED [label="release"]
+ *          PANNING_SCALING -> ACTIVATED [label="release"]
  *      }
  * }
  */
@@ -105,14 +109,15 @@
 public class FullScreenMagnificationGestureHandlerTest {
 
     public static final int STATE_IDLE = 1;
-    public static final int STATE_ZOOMED = 2;
+    public static final int STATE_ACTIVATED = 2;
     public static final int STATE_2TAPS = 3;
-    public static final int STATE_ZOOMED_2TAPS = 4;
+    public static final int STATE_ACTIVATED_2TAPS = 4;
     public static final int STATE_SHORTCUT_TRIGGERED = 5;
     public static final int STATE_NON_ACTIVATED_ZOOMED_TMP = 6;
     public static final int STATE_ACTIVATED_ZOOMED_TMP = 7;
-    public static final int STATE_PANNING = 8;
-    public static final int STATE_SCALING_AND_PANNING = 9;
+    public static final int STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP = 8;
+    public static final int STATE_PANNING = 9;
+    public static final int STATE_SCALING_AND_PANNING = 10;
 
     public static final int FIRST_STATE = STATE_IDLE;
     public static final int LAST_STATE = STATE_SCALING_AND_PANNING;
@@ -167,6 +172,7 @@
             }
         };
         mFullScreenMagnificationController.register(DISPLAY_0);
+        mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true);
         mClock = new OffsettableClock.Stopped();
 
         boolean detectTripleTap = true;
@@ -267,22 +273,22 @@
         assertTransition(STATE_SHORTCUT_TRIGGERED, () -> {
             send(downEvent());
             fastForward1sec();
-        }, STATE_ACTIVATED_ZOOMED_TMP);
+        }, STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP);
 
-        // A11y button followed by a tap turns zoom on
-        assertTransition(STATE_SHORTCUT_TRIGGERED, () -> tap(), STATE_ZOOMED);
+        // A11y button followed by a tap turns magnifier on
+        assertTransition(STATE_SHORTCUT_TRIGGERED, () -> tap(), STATE_ACTIVATED);
 
         // A11y button pressed second time negates the 1st press
         assertTransition(STATE_SHORTCUT_TRIGGERED, () -> triggerShortcut(), STATE_IDLE);
 
-        // A11y button turns zoom off
-        assertTransition(STATE_ZOOMED, () -> triggerShortcut(), STATE_IDLE);
+        // A11y button turns magnifier off
+        assertTransition(STATE_ACTIVATED, () -> triggerShortcut(), STATE_IDLE);
 
-        // Double tap times out while zoomed
-        assertTransition(STATE_ZOOMED_2TAPS, () -> {
+        // Double tap times out while activated
+        assertTransition(STATE_ACTIVATED_2TAPS, () -> {
             allowEventDelegation();
             fastForward1sec();
-        }, STATE_ZOOMED);
+        }, STATE_ACTIVATED);
 
         // tap+tap+swipe doesn't get delegated
         assertTransition(STATE_2TAPS, () -> swipe(), STATE_IDLE);
@@ -290,8 +296,29 @@
         // tap+tap+swipe&hold initiates temporary viewport dragging zoom in immediately
         assertTransition(STATE_2TAPS, () -> swipeAndHold(), STATE_NON_ACTIVATED_ZOOMED_TMP);
 
-        // release when activated temporary zoom in back to zoomed
-        assertTransition(STATE_ACTIVATED_ZOOMED_TMP, () -> upEvent(), STATE_ZOOMED);
+        // release when activated temporary zoom in back to activated
+        assertTransition(STATE_ACTIVATED_ZOOMED_TMP, () -> send(upEvent()), STATE_ACTIVATED);
+    }
+
+    @Test
+    public void testRelease_shortcutTriggeredZoomedTmp_alwaysOnNotEnabled_shouldInIdle() {
+        mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(false);
+        goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP);
+        send(upEvent());
+
+        assertIn(STATE_IDLE);
+    }
+
+    @Test
+    public void testRelease_shortcutTriggeredZoomedTmp_alwaysOnEnabled_shouldInActivated() {
+        mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true);
+        goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP);
+        send(upEvent());
+
+        assertIn(STATE_ACTIVATED);
+        assertTrue(!isZoomed());
+
+        returnToNormalFrom(STATE_ACTIVATED);
     }
 
     @Test
@@ -310,7 +337,7 @@
             longTap();
         };
         assertStaysIn(STATE_IDLE, tapAndLongTap);
-        assertStaysIn(STATE_ZOOMED, tapAndLongTap);
+        assertStaysIn(STATE_ACTIVATED, tapAndLongTap);
 
         // Triple tap with delays in between doesn't count
         Runnable slow3tap = () -> {
@@ -321,7 +348,7 @@
             tap();
         };
         assertStaysIn(STATE_IDLE, slow3tap);
-        assertStaysIn(STATE_ZOOMED, slow3tap);
+        assertStaysIn(STATE_ACTIVATED, slow3tap);
     }
 
     @Test
@@ -337,9 +364,9 @@
     @Test
     public void testTripleTapAndHold_zoomsImmediately() {
         assertZoomsImmediatelyOnSwipeFrom(STATE_2TAPS, STATE_NON_ACTIVATED_ZOOMED_TMP);
-        assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED, STATE_ACTIVATED_ZOOMED_TMP);
-        assertZoomsImmediatelyOnSwipeFrom(STATE_ZOOMED_2TAPS, STATE_ACTIVATED_ZOOMED_TMP);
-
+        assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED,
+                STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP);
+        assertZoomsImmediatelyOnSwipeFrom(STATE_ACTIVATED_2TAPS, STATE_ACTIVATED_ZOOMED_TMP);
     }
 
     @Test
@@ -361,8 +388,8 @@
     }
 
     @Test
-    public void testTwoFingersOneTap_zoomedState_dispatchMotionEvents() {
-        goFromStateIdleTo(STATE_ZOOMED);
+    public void testTwoFingersOneTap_activatedState_dispatchMotionEvents() {
+        goFromStateIdleTo(STATE_ACTIVATED);
         final EventCaptor eventCaptor = new EventCaptor();
         mMgh.setNext(eventCaptor);
 
@@ -371,7 +398,7 @@
         send(pointerEvent(ACTION_POINTER_UP, DEFAULT_X * 2, DEFAULT_Y));
         send(upEvent());
 
-        assertIn(STATE_ZOOMED);
+        assertIn(STATE_ACTIVATED);
         final List<Integer> expectedActions = new ArrayList();
         expectedActions.add(Integer.valueOf(ACTION_DOWN));
         expectedActions.add(Integer.valueOf(ACTION_POINTER_DOWN));
@@ -379,12 +406,12 @@
         expectedActions.add(Integer.valueOf(ACTION_UP));
         assertActionsInOrder(eventCaptor.mEvents, expectedActions);
 
-        returnToNormalFrom(STATE_ZOOMED);
+        returnToNormalFrom(STATE_ACTIVATED);
     }
 
     @Test
-    public void testThreeFingersOneTap_zoomedState_dispatchMotionEvents() {
-        goFromStateIdleTo(STATE_ZOOMED);
+    public void testThreeFingersOneTap_activatedState_dispatchMotionEvents() {
+        goFromStateIdleTo(STATE_ACTIVATED);
         final EventCaptor eventCaptor = new EventCaptor();
         mMgh.setNext(eventCaptor);
         PointF pointer1 = DEFAULT_POINT;
@@ -398,7 +425,7 @@
         send(pointerEvent(ACTION_POINTER_UP, new PointF[] {pointer1, pointer2, pointer3}, 2));
         send(upEvent());
 
-        assertIn(STATE_ZOOMED);
+        assertIn(STATE_ACTIVATED);
         final List<Integer> expectedActions = new ArrayList();
         expectedActions.add(Integer.valueOf(ACTION_DOWN));
         expectedActions.add(Integer.valueOf(ACTION_POINTER_DOWN));
@@ -408,12 +435,12 @@
         expectedActions.add(Integer.valueOf(ACTION_UP));
         assertActionsInOrder(eventCaptor.mEvents, expectedActions);
 
-        returnToNormalFrom(STATE_ZOOMED);
+        returnToNormalFrom(STATE_ACTIVATED);
     }
 
     @Test
-    public void testFirstFingerSwipe_twoPointerDownAndZoomedState_panningState() {
-        goFromStateIdleTo(STATE_ZOOMED);
+    public void testFirstFingerSwipe_twoPointerDownAndActivatedState_panningState() {
+        goFromStateIdleTo(STATE_ACTIVATED);
         PointF pointer1 = DEFAULT_POINT;
         PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
 
@@ -429,8 +456,8 @@
     }
 
     @Test
-    public void testSecondFingerSwipe_twoPointerDownAndZoomedState_panningState() {
-        goFromStateIdleTo(STATE_ZOOMED);
+    public void testSecondFingerSwipe_twoPointerDownAndActivatedState_panningState() {
+        goFromStateIdleTo(STATE_ACTIVATED);
         PointF pointer1 = DEFAULT_POINT;
         PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
 
@@ -463,8 +490,8 @@
     }
 
     @Test
-    public void testZoomedWithTripleTap_invokeShowWindowPromptAction() {
-        goFromStateIdleTo(STATE_ZOOMED);
+    public void testActivatedWithTripleTap_invokeShowWindowPromptAction() {
+        goFromStateIdleTo(STATE_ACTIVATED);
 
         verify(mWindowMagnificationPromptController).showNotificationIfNeeded();
     }
@@ -541,9 +568,8 @@
                 check(!isActivated(), state);
                 check(!isZoomed(), state);
             } break;
-            case STATE_ZOOMED: {
+            case STATE_ACTIVATED: {
                 check(isActivated(), state);
-                check(isZoomed(), state);
                 check(tapCount() < 2, state);
             } break;
             case STATE_2TAPS: {
@@ -551,7 +577,7 @@
                 check(!isZoomed(), state);
                 check(tapCount() == 2, state);
             } break;
-            case STATE_ZOOMED_2TAPS: {
+            case STATE_ACTIVATED_2TAPS: {
                 check(isActivated(), state);
                 check(isZoomed(), state);
                 check(tapCount() == 2, state);
@@ -561,14 +587,29 @@
                 check(isZoomed(), state);
                 check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
                         state);
-                check(!mMgh.mViewportDraggingState.mActivatedBeforeDrag, state);
+                check(Float.isNaN(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd),
+                        state);
             } break;
             case STATE_ACTIVATED_ZOOMED_TMP: {
                 check(isActivated(), state);
                 check(isZoomed(), state);
                 check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
                         state);
-                check(mMgh.mViewportDraggingState.mActivatedBeforeDrag, state);
+                check(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd >= 1.0f,
+                        state);
+            } break;
+            case STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP: {
+                check(isActivated(), state);
+                check(isZoomed(), state);
+                check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
+                        state);
+                if (mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled()) {
+                    check(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd >= 1.0f,
+                            state);
+                } else {
+                    check(Float.isNaN(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd),
+                            state);
+                }
             } break;
             case STATE_SHORTCUT_TRIGGERED: {
                 check(mMgh.mDetectingState.mShortcutTriggered, state);
@@ -605,7 +646,7 @@
                     tap();
                     tap();
                 } break;
-                case STATE_ZOOMED: {
+                case STATE_ACTIVATED: {
                     if (mMgh.mDetectTripleTap) {
                         goFromStateIdleTo(STATE_2TAPS);
                         tap();
@@ -614,8 +655,8 @@
                         tap();
                     }
                 } break;
-                case STATE_ZOOMED_2TAPS: {
-                    goFromStateIdleTo(STATE_ZOOMED);
+                case STATE_ACTIVATED_2TAPS: {
+                    goFromStateIdleTo(STATE_ACTIVATED);
                     tap();
                     tap();
                 } break;
@@ -625,7 +666,12 @@
                     fastForward1sec();
                 } break;
                 case STATE_ACTIVATED_ZOOMED_TMP: {
-                    goFromStateIdleTo(STATE_ZOOMED_2TAPS);
+                    goFromStateIdleTo(STATE_ACTIVATED_2TAPS);
+                    send(downEvent());
+                    fastForward1sec();
+                } break;
+                case STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP: {
+                    goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED);
                     send(downEvent());
                     fastForward1sec();
                 } break;
@@ -634,7 +680,7 @@
                     triggerShortcut();
                 } break;
                 case STATE_PANNING: {
-                    goFromStateIdleTo(STATE_ZOOMED);
+                    goFromStateIdleTo(STATE_ACTIVATED);
                     send(downEvent());
                     send(pointerEvent(ACTION_POINTER_DOWN, DEFAULT_X * 2, DEFAULT_Y));
                     fastForward(ViewConfiguration.getTapTimeout());
@@ -665,16 +711,16 @@
                 allowEventDelegation();
                 fastForward1sec();
             } break;
-            case STATE_ZOOMED: {
+            case STATE_ACTIVATED: {
                 if (mMgh.mDetectTripleTap) {
                     tap();
                     tap();
-                    returnToNormalFrom(STATE_ZOOMED_2TAPS);
+                    returnToNormalFrom(STATE_ACTIVATED_2TAPS);
                 } else {
                     triggerShortcut();
                 }
             } break;
-            case STATE_ZOOMED_2TAPS: {
+            case STATE_ACTIVATED_2TAPS: {
                 tap();
             } break;
             case STATE_NON_ACTIVATED_ZOOMED_TMP: {
@@ -682,7 +728,13 @@
             } break;
             case STATE_ACTIVATED_ZOOMED_TMP: {
                 send(upEvent());
-                returnToNormalFrom(STATE_ZOOMED);
+                returnToNormalFrom(STATE_ACTIVATED);
+            } break;
+            case STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP: {
+                send(upEvent());
+                if (mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled()) {
+                    returnToNormalFrom(STATE_ACTIVATED);
+                }
             } break;
             case STATE_SHORTCUT_TRIGGERED: {
                 triggerShortcut();
@@ -690,7 +742,7 @@
             case STATE_PANNING: {
                 send(pointerEvent(ACTION_POINTER_UP, DEFAULT_X * 2, DEFAULT_Y));
                 send(upEvent());
-                returnToNormalFrom(STATE_ZOOMED);
+                returnToNormalFrom(STATE_ACTIVATED);
             } break;
             case STATE_SCALING_AND_PANNING: {
                 returnToNormalFrom(STATE_PANNING);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index 407c575..b4a16c2 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -739,6 +739,13 @@
     }
 
     @Test
+    public void setPreferenceAlwaysOnMagnificationEnabled_setPrefEnabled_enableOnFullScreen() {
+        mMagnificationController.setAlwaysOnMagnificationEnabled(true);
+
+        verify(mScreenMagnificationController).setAlwaysOnMagnificationEnabled(eq(true));
+    }
+
+    @Test
     public void onRectangleOnScreenRequested_fullScreenIsActivated_fullScreenDispatchEvent() {
         mMagnificationController.onFullScreenMagnificationActivationState(TEST_DISPLAY,
                 true);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index 25ad2be..d841dfc 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -274,6 +274,19 @@
     }
 
     @Test
+    public void persistScale_setValueWhenScaleIsOne_nothingChanged() {
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        final float persistedScale = mWindowMagnificationManager.getPersistedScale(TEST_DISPLAY);
+
+        mWindowMagnificationManager.setScale(TEST_DISPLAY, 1.0f);
+        mWindowMagnificationManager.persistScale(TEST_DISPLAY);
+
+        assertEquals(Settings.Secure.getFloatForUser(mResolver,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 0f,
+                CURRENT_USER_ID), persistedScale);
+    }
+
+    @Test
     public void scaleSetterGetter_enabledOnTestDisplay_expectedValue() {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2.0f, NaN, NaN);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index e9dc082..93dfee6 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -69,6 +69,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.IProgressListener;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
@@ -848,7 +849,8 @@
         mInjector.secondaryDisplayIdsForStartingBackgroundUsers = new int[]{4, 8, 15, 16, 23, 42};
 
         assertThrows(IllegalArgumentException.class,
-                () -> mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 666));
+                () -> mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 666,
+                        /* unlockProgressListener= */ null));
 
         assertWithMessage("UserController.startUserOnSecondaryDisplay() calls")
                 .that(mInjector.usersStartedOnSecondaryDisplays).isEmpty();
@@ -859,7 +861,8 @@
         mInjector.secondaryDisplayIdsForStartingBackgroundUsers = new int[]{ 4, 8, 15, 16, 23, 42 };
         mInjector.returnValueForstartUserOnSecondaryDisplay = false;
 
-        boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42);
+        boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42,
+                /* unlockProgressListener= */ null);
         Log.v(TAG, "Started: " + started);
 
         assertWithMessage("mAms.startUserInBackgroundOnDisplay(%s, 42)", USER_ID)
@@ -874,7 +877,8 @@
         mInjector.secondaryDisplayIdsForStartingBackgroundUsers = new int[]{ 4, 8, 15, 16, 23, 42 };
         mInjector.returnValueForstartUserOnSecondaryDisplay = true;
 
-        boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42);
+        boolean started = mAms.startUserInBackgroundVisibleOnDisplay(USER_ID, 42,
+                /* unlockProgressListener= */ null);
         Log.v(TAG, "Started: " + started);
 
         assertWithMessage("mAms.startUserInBackgroundOnDisplay(%s, 42)", USER_ID)
@@ -989,7 +993,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return mAppOpsService;
         }
 
@@ -1009,7 +1014,8 @@
         }
 
         @Override
-        public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId) {
+        public boolean startUserInBackgroundVisibleOnDisplay(int userId, int displayId,
+                IProgressListener unlockProgressListener) {
             usersStartedOnSecondaryDisplays.add(new Pair<>(userId, displayId));
             return returnValueForstartUserOnSecondaryDisplay;
         }
diff --git a/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java b/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
index 162855a..9578993 100644
--- a/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
@@ -81,7 +81,8 @@
             final ActivityManagerService service = new ActivityManagerService(
                     new ActivityManagerService.Injector(context) {
                     @Override
-                    public AppOpsService getAppOpsService(File file, Handler handler) {
+                    public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                            Handler handler) {
                         return null;
                     }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
index 24f8eab..19bc1c2 100644
--- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -73,7 +73,8 @@
         mContext = getInstrumentation().getTargetContext();
         mService = new ActivityManagerService(new ActivityManagerService.Injector(mContext) {
             @Override
-            public AppOpsService getAppOpsService(File file, Handler handler) {
+            public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                    Handler handler) {
                 return null;
             }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index 5f55f09..fd0b679 100644
--- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -179,7 +179,8 @@
         }
 
         @Override
-        public AppOpsService getAppOpsService(File file, Handler handler) {
+        public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
+                Handler handler) {
             return null;
         }
 
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 b146c27..76dfe02 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -244,7 +244,8 @@
 
     @Test
     public void testStartUserVisibleOnDisplay() {
-        boolean started = mUserController.startUserVisibleOnDisplay(TEST_USER_ID, 42);
+        boolean started = mUserController.startUserVisibleOnDisplay(TEST_USER_ID, 42,
+                /* unlockProgressListener= */ null);
 
         assertWithMessage("startUserOnDisplay(%s, %s)", TEST_USER_ID, 42).that(started).isTrue();
         verifyUserAssignedToDisplay(TEST_USER_ID, 42);
@@ -412,7 +413,7 @@
         mInjector.mHandler.clearAllRecordedMessages();
         // Verify that continueUserSwitch worked as expected
         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
-        verify(mInjector, times(0)).dismissKeyguard(any(), anyString());
+        verify(mInjector, times(0)).dismissKeyguard(any());
         verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
         continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false);
         verifySystemUserVisibilityChangesNeverNotified();
@@ -433,7 +434,7 @@
         mInjector.mHandler.clearAllRecordedMessages();
         // Verify that continueUserSwitch worked as expected
         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
-        verify(mInjector, times(1)).dismissKeyguard(any(), anyString());
+        verify(mInjector, times(1)).dismissKeyguard(any());
         verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
         continueUserSwitchAssertions(oldUserId, TEST_USER_ID, false);
         verifySystemUserVisibilityChangesNeverNotified();
@@ -1148,7 +1149,7 @@
         }
 
         @Override
-        protected void dismissKeyguard(Runnable runnable, String reason) {
+        protected void dismissKeyguard(Runnable runnable) {
             runnable.run();
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java b/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java
index 38093de..7c736c7 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java
@@ -40,13 +40,20 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import libcore.junit.util.compat.CoreCompatChangeRule;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 
 import java.util.Collections;
 import java.util.List;
 
 public class AbsoluteVolumeBehaviorTest {
+    @Rule
+    public TestRule compatChangeRule = new CoreCompatChangeRule();
+
     private static final String TAG = "AbsoluteVolumeBehaviorTest";
 
     private static final AudioDeviceAttributes DEVICE_SPEAKER_OUT = new AudioDeviceAttributes(
@@ -92,7 +99,30 @@
                 new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
-                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        mTestLooper.dispatchAll();
+
+        assertThat(mAudioService.getDeviceVolumeBehavior(DEVICE_SPEAKER_OUT))
+                .isEqualTo(AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+    }
+
+    /**
+     * Tests that getDeviceVolumeBehavior returns the correct volume behavior, even if
+     * a different volume behavior was previously persisted via setDeviceVolumeBehavior
+     */
+    @Test
+    public void registerDispatcherAfterSetDeviceVolumeBehavior_setsVolumeBehaviorToAbsolute() {
+        List<VolumeInfo> volumes = Collections.singletonList(
+                new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
+
+        mAudioService.setDeviceVolumeBehavior(DEVICE_SPEAKER_OUT,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL, mPackageName);
+        mTestLooper.dispatchAll();
+
+        mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         assertThat(mAudioService.getDeviceVolumeBehavior(DEVICE_SPEAKER_OUT))
@@ -109,7 +139,8 @@
                         .build());
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
-                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         assertThat(mAudioService.getStreamVolume(AudioManager.STREAM_MUSIC))
@@ -124,11 +155,13 @@
                 new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
-                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(false,
-                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         assertThat(mAudioService.getDeviceVolumeBehavior(DEVICE_SPEAKER_OUT))
@@ -147,7 +180,8 @@
                 new VolumeInfo.Builder(AudioManager.STREAM_MUSIC).build());
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
-                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true);
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT, volumes, true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         mAudioService.setDeviceVolumeBehavior(DEVICE_SPEAKER_OUT,
@@ -171,7 +205,8 @@
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
                 mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
-                Collections.singletonList(volumeInfo), true);
+                Collections.singletonList(volumeInfo), true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         // Set stream volume without FLAG_ABSOLUTE_VOLUME
@@ -194,7 +229,8 @@
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
                 mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
-                Collections.singletonList(volumeInfo), true);
+                Collections.singletonList(volumeInfo), true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         // Set stream volume with FLAG_ABSOLUTE_VOLUME
@@ -218,7 +254,8 @@
         // Register dispatcher with handlesVolumeAdjustment = true
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
                 mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
-                Collections.singletonList(volumeInfo), true);
+                Collections.singletonList(volumeInfo), true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         // Adjust stream volume without FLAG_ABSOLUTE_VOLUME
@@ -247,7 +284,8 @@
         // Register dispatcher with handlesVolumeAdjustment = false
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
                 mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
-                Collections.singletonList(volumeInfo), false);
+                Collections.singletonList(volumeInfo), false,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         // Adjust stream volume without FLAG_ABSOLUTE_VOLUME
@@ -274,7 +312,8 @@
 
         mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
                 mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
-                Collections.singletonList(volumeInfo), true);
+                Collections.singletonList(volumeInfo), true,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         mTestLooper.dispatchAll();
 
         // Adjust stream volume with FLAG_ABSOLUTE_VOLUME set
@@ -289,4 +328,38 @@
         verify(mMockDispatcher, never()).dispatchDeviceVolumeAdjusted(eq(DEVICE_SPEAKER_OUT), any(),
                 anyInt(), anyInt());
     }
+
+    @Test
+    public void switchAbsoluteVolumeBehaviorToAdjustOnly_onlyDispatchesVolumeChangeForNewListener()
+            throws RemoteException {
+        VolumeInfo volumeInfo = new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
+                .setMinVolumeIndex(0)
+                .setMaxVolumeIndex(250)
+                .setVolumeIndex(0)
+                .build();
+
+        mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+                mMockDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+                Collections.singletonList(volumeInfo), false,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        mTestLooper.dispatchAll();
+
+        IAudioDeviceVolumeDispatcher.Stub mMockAdjustOnlyAbsoluteVolumeDispatcher =
+                mock(IAudioDeviceVolumeDispatcher.Stub.class);
+        mAudioService.registerDeviceVolumeDispatcherForAbsoluteVolume(true,
+                mMockAdjustOnlyAbsoluteVolumeDispatcher, mPackageName, DEVICE_SPEAKER_OUT,
+                Collections.singletonList(volumeInfo), false,
+                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        mTestLooper.dispatchAll();
+
+        // Set stream volume without FLAG_ABSOLUTE_VOLUME
+        mAudioService.setStreamVolume(AudioManager.STREAM_MUSIC, 15, 0, mPackageName);
+        mTestLooper.dispatchAll();
+
+        // Volume change not dispatched for absolute volume listener
+        verify(mMockDispatcher, never()).dispatchDeviceVolumeChanged(eq(DEVICE_SPEAKER_OUT), any());
+        // Volume changed dispatched for adjust-only absolute volume listener
+        verify(mMockAdjustOnlyAbsoluteVolumeDispatcher).dispatchDeviceVolumeChanged(
+                DEVICE_SPEAKER_OUT, new VolumeInfo.Builder(volumeInfo).setVolumeIndex(150).build());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 99f7905..e605a31 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -35,6 +35,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.content.ComponentName;
+import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.common.ICancellationSignal;
 import android.hardware.biometrics.common.OperationContext;
@@ -364,6 +365,16 @@
         showHideOverlay(c -> c.onLockoutPermanent());
     }
 
+    @Test
+    public void testPowerPressForwardsErrorMessage() throws RemoteException {
+        final FingerprintAuthenticationClient client = createClient();
+
+        client.onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_VENDOR,
+                BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED);
+
+        verify(mClientMonitorCallbackConverter).onError(anyInt(), anyInt(),
+                eq(BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED), eq(0));
+    }
     private void showHideOverlay(Consumer<FingerprintAuthenticationClient> block)
             throws RemoteException {
         final FingerprintAuthenticationClient client = createClient();
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java
index 26524d7..a40d3fe 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClientTest.java
@@ -16,8 +16,6 @@
 
 package com.android.server.biometrics.sensors.fingerprint.aidl;
 
-import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED;
-
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -29,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.fingerprint.ISession;
 import android.hardware.biometrics.fingerprint.PointerContext;
@@ -276,11 +275,12 @@
     @Test
     public void testPowerPressForwardsAcquireMessage() throws RemoteException {
         final FingerprintEnrollClient client = createClient();
-        client.start(mCallback);
-        client.onPowerPressed();
+
+        client.onAcquired(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR,
+                BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED);
 
         verify(mClientMonitorCallbackConverter).onAcquired(anyInt(),
-                eq(FINGERPRINT_ACQUIRED_POWER_PRESSED), anyInt());
+                eq(BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_POWER_PRESSED), eq(0));
     }
 
     private void showHideOverlay(Consumer<FingerprintEnrollClient> block)
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 c952609..4d06855 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -28,6 +28,7 @@
 import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertThrows;
 
+import android.app.ActivityManager;
 import android.hardware.devicestate.DeviceStateInfo;
 import android.hardware.devicestate.DeviceStateRequest;
 import android.hardware.devicestate.IDeviceStateManagerCallback;
@@ -541,7 +542,7 @@
     }
 
     @Test
-    public void requestState_flagCancelWhenRequesterNotOnTop_onTaskStackChanged()
+    public void requestState_flagCancelWhenRequesterNotOnTop_onTaskMovedToFront()
             throws RemoteException {
         requestState_flagCancelWhenRequesterNotOnTop_common(
                 // When the app is foreground, the state should not change
@@ -549,7 +550,8 @@
                     int pid = Binder.getCallingPid();
                     when(mWindowProcessController.getPid()).thenReturn(pid);
                     try {
-                        mService.mOverrideRequestTaskStackListener.onTaskStackChanged();
+                        mService.mOverrideRequestTaskStackListener.onTaskMovedToFront(
+                                new ActivityManager.RunningTaskInfo());
                     } catch (RemoteException e) {
                         throw new RuntimeException(e);
                     }
@@ -558,7 +560,8 @@
                 () -> {
                     when(mWindowProcessController.getPid()).thenReturn(FAKE_PROCESS_ID);
                     try {
-                        mService.mOverrideRequestTaskStackListener.onTaskStackChanged();
+                        mService.mOverrideRequestTaskStackListener.onTaskMovedToFront(
+                                new ActivityManager.RunningTaskInfo());
                     } catch (RemoteException e) {
                         throw new RuntimeException(e);
                     }
diff --git a/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java b/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java
index a192913..a380eff 100644
--- a/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DeviceStateToLayoutMapTest.java
@@ -19,6 +19,7 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.view.Display;
 import android.view.DisplayAddress;
 
 import androidx.test.filters.SmallTest;
@@ -64,12 +65,25 @@
         Layout testLayout = new Layout();
         testLayout.createDisplayLocked(
                 DisplayAddress.fromPhysicalDisplayId(123456L), /* isDefault= */ true,
-                /* isEnabled= */ true, mDisplayIdProducerMock,
-                /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         testLayout.createDisplayLocked(
                 DisplayAddress.fromPhysicalDisplayId(78910L), /* isDefault= */ false,
-                /* isEnabled= */ false, mDisplayIdProducerMock,
-                /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ false, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        testLayout.createDisplayLocked(
+                DisplayAddress.fromPhysicalDisplayId(98765L), /* isDefault= */ false,
+                /* isEnabled= */ true, "group1", mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        testLayout.createDisplayLocked(
+                DisplayAddress.fromPhysicalDisplayId(786L), /* isDefault= */ false,
+                /* isEnabled= */ false, "group2", mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+
         assertEquals(testLayout, configLayout);
     }
 
@@ -80,12 +94,14 @@
         Layout testLayout = new Layout();
         testLayout.createDisplayLocked(
                 DisplayAddress.fromPhysicalDisplayId(78910L), /* isDefault= */ true,
-                /* isEnabled= */ true, mDisplayIdProducerMock,
-                /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         testLayout.createDisplayLocked(
                 DisplayAddress.fromPhysicalDisplayId(123456L), /* isDefault= */ false,
-                /* isEnabled= */ false, mDisplayIdProducerMock,
-                /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ false, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
 
         assertEquals(testLayout, configLayout);
     }
@@ -98,14 +114,16 @@
 
         Layout.Display display1 = testLayout.createDisplayLocked(
                 DisplayAddress.fromPhysicalDisplayId(345L), /* isDefault= */ true,
-                /* isEnabled= */ true, mDisplayIdProducerMock,
-                /* brightnessThrottlingMapId= */ "concurrent");
+                /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ "concurrent",
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         display1.setPosition(Layout.Display.POSITION_FRONT);
 
         Layout.Display display2 = testLayout.createDisplayLocked(
                 DisplayAddress.fromPhysicalDisplayId(678L), /* isDefault= */ false,
-                /* isEnabled= */ true, mDisplayIdProducerMock,
-                /* brightnessThrottlingMapId= */ "concurrent");
+                /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ "concurrent",
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         display2.setPosition(Layout.Display.POSITION_REAR);
 
         assertEquals(testLayout, configLayout);
@@ -119,6 +137,26 @@
         assertEquals(Layout.Display.POSITION_REAR, configLayout.getAt(1).getPosition());
     }
 
+    @Test
+    public void testRefreshRateZoneId() {
+        Layout configLayout = mDeviceStateToLayoutMap.get(3);
+
+        Layout testLayout = new Layout();
+        Layout.Display display1 = testLayout.createDisplayLocked(
+                DisplayAddress.fromPhysicalDisplayId(345L), /* isDefault= */ true,
+                /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        display1.setRefreshRateZoneId("test1");
+        testLayout.createDisplayLocked(
+                DisplayAddress.fromPhysicalDisplayId(678L), /* isDefault= */ false,
+                /* isEnabled= */ true, /* displayGroup= */ null, mDisplayIdProducerMock,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+
+        assertEquals(testLayout, configLayout);
+    }
+
     ////////////////////
     // Helper Methods //
     ////////////////////
@@ -141,6 +179,12 @@
                 +      "<display enabled=\"false\">\n"
                 +        "<address>78910</address>\n"
                 +      "</display>\n"
+                +      "<display enabled=\"true\" displayGroup=\"group1\">\n"
+                +        "<address>98765</address>\n"
+                +      "</display>\n"
+                +      "<display enabled=\"false\" displayGroup=\"group2\">\n"
+                +        "<address>786</address>\n"
+                +      "</display>\n"
                 +    "</layout>\n"
 
                 +    "<layout>\n"
@@ -166,7 +210,17 @@
                 +        "<brightnessThrottlingMapId>concurrent</brightnessThrottlingMapId>\n"
                 +      "</display>\n"
                 +    "</layout>\n"
+
+                +    "<layout>\n"
+                +      "<state>3</state> \n"
+                +      "<display enabled=\"true\" defaultDisplay=\"true\" "
+                +                                               "refreshRateZoneId=\"test1\">\n"
+                +        "<address>345</address>\n"
+                +      "</display>\n"
+                +      "<display enabled=\"true\">\n"
+                +        "<address>678</address>\n"
+                +      "</display>\n"
+                +    "</layout>\n"
                 +  "</layouts>\n";
     }
 }
-
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 42bdbec..5ebc901 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -55,6 +55,8 @@
     private static final int DEFAULT_REFRESH_RATE = 120;
     private static final int DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE = 55;
     private static final int DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE = 95;
+    private static final int DEFAULT_REFRESH_RATE_IN_HBM_HDR = 90;
+    private static final int DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT = 100;
     private static final int[] LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{10, 30};
     private static final int[] LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{1, 21};
     private static final int[] HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{160};
@@ -155,6 +157,13 @@
         assertEquals(90, mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate());
         assertEquals(85, mDisplayDeviceConfig.getDefaultPeakRefreshRate());
         assertEquals(45, mDisplayDeviceConfig.getDefaultRefreshRate());
+
+        assertEquals(2, mDisplayDeviceConfig.getRefreshRangeProfiles().size());
+        assertEquals(60, mDisplayDeviceConfig.getRefreshRange("test1").min, SMALL_DELTA);
+        assertEquals(60, mDisplayDeviceConfig.getRefreshRange("test1").max, SMALL_DELTA);
+        assertEquals(80, mDisplayDeviceConfig.getRefreshRange("test2").min, SMALL_DELTA);
+        assertEquals(90, mDisplayDeviceConfig.getRefreshRange("test2").max, SMALL_DELTA);
+
         assertArrayEquals(new int[]{45, 55},
                 mDisplayDeviceConfig.getLowDisplayBrightnessThresholds());
         assertArrayEquals(new int[]{50, 60},
@@ -288,6 +297,11 @@
                 DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
         assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
         assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE);
+        assertEquals(0, mDisplayDeviceConfig.getRefreshRangeProfiles().size());
+        assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmSunlight(),
+                DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);
+        assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmHdr(),
+                DEFAULT_REFRESH_RATE_IN_HBM_HDR);
         assertArrayEquals(mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(),
                 LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
         assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(),
@@ -547,6 +561,20 @@
                 +   "<refreshRate>\n"
                 +       "<defaultRefreshRate>45</defaultRefreshRate>\n"
                 +       "<defaultPeakRefreshRate>85</defaultPeakRefreshRate>\n"
+                +       "<refreshRateZoneProfiles>"
+                +           "<refreshRateZoneProfile id=\"test1\">"
+                +               "<refreshRateRange>\n"
+                +                   "<minimum>60</minimum>\n"
+                +                   "<maximum>60</maximum>\n"
+                +               "</refreshRateRange>\n"
+                +           "</refreshRateZoneProfile>\n"
+                +           "<refreshRateZoneProfile id=\"test2\">"
+                +               "<refreshRateRange>\n"
+                +                   "<minimum>80</minimum>\n"
+                +                   "<maximum>90</maximum>\n"
+                +               "</refreshRateRange>\n"
+                +           "</refreshRateZoneProfile>\n"
+                +       "</refreshRateZoneProfiles>"
                 +       "<lowerBlockingZoneConfigs>\n"
                 +           "<defaultRefreshRate>75</defaultRefreshRate>\n"
                 +           "<blockingZoneThreshold>\n"
@@ -670,6 +698,12 @@
         when(mResources.getIntArray(
                 R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
                 .thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
+        when(mResources.getInteger(
+            R.integer.config_defaultRefreshRateInHbmHdr))
+            .thenReturn(DEFAULT_REFRESH_RATE_IN_HBM_HDR);
+        when(mResources.getInteger(
+            R.integer.config_defaultRefreshRateInHbmSunlight))
+            .thenReturn(DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);
 
         mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
     }
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 9a43762..1904671 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -56,6 +56,7 @@
 import android.hardware.display.DisplayViewport;
 import android.hardware.display.DisplayedContentSample;
 import android.hardware.display.DisplayedContentSamplingAttributes;
+import android.hardware.display.HdrConversionMode;
 import android.hardware.display.IDisplayManagerCallback;
 import android.hardware.display.IVirtualDisplayCallback;
 import android.hardware.display.VirtualDisplayConfig;
@@ -171,6 +172,17 @@
                }
            });
        }
+
+        @Override
+        void setHdrConversionMode(int conversionMode, int preferredHdrOutputType,
+                int[] autoHdrTypes) {
+            return;
+        }
+
+        @Override
+        int[] getSupportedHdrOutputTypes() {
+            return new int[]{};
+        }
    }
 
     private final DisplayManagerService.Injector mBasicInjector = new BasicInjector();
@@ -240,8 +252,7 @@
         // the usage of SensorManager, which is available only after the PowerManagerService
         // is ready.
         resetConfigToIgnoreSensorManager(mContext);
-        DisplayManagerService displayManager =
-                new DisplayManagerService(mContext, mBasicInjector);
+        DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
         registerDefaultDisplays(displayManager);
         displayManager.systemReady(false /* safeMode */);
         displayManager.windowManagerAndInputReady();
@@ -316,8 +327,7 @@
         // the usage of SensorManager, which is available only after the PowerManagerService
         // is ready.
         resetConfigToIgnoreSensorManager(mContext);
-        DisplayManagerService displayManager =
-                new DisplayManagerService(mContext, mBasicInjector);
+        DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
         registerDefaultDisplays(displayManager);
         displayManager.systemReady(false /* safeMode */);
         displayManager.windowManagerAndInputReady();
@@ -1511,6 +1521,22 @@
 
     }
 
+    @Test
+    public void testHdrConversionModeEquals() {
+        assertEquals(
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2),
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2));
+        assertNotEquals(
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2),
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 3));
+        assertEquals(
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM),
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM));
+        assertNotEquals(
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2),
+                new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM));
+    }
+
     private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
             throws Exception {
         DisplayManagerService displayManager =
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 27d912b..7e6eeee 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -2264,6 +2264,10 @@
             .thenReturn(65);
         when(resources.getInteger(R.integer.config_defaultRefreshRateInZone))
             .thenReturn(85);
+        when(resources.getInteger(R.integer.config_defaultRefreshRateInHbmHdr))
+            .thenReturn(95);
+        when(resources.getInteger(R.integer.config_defaultRefreshRateInHbmSunlight))
+            .thenReturn(100);
         when(resources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
             .thenReturn(new int[]{5});
         when(resources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
@@ -2274,8 +2278,21 @@
         when(
             resources.getIntArray(R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
             .thenReturn(new int[]{7000});
+        when(resources.getInteger(
+            com.android.internal.R.integer.config_displayWhiteBalanceBrightnessFilterHorizon))
+            .thenReturn(3);
+        ArgumentCaptor<TypedValue> valueArgumentCaptor = ArgumentCaptor.forClass(TypedValue.class);
+        doAnswer((Answer<Void>) invocation -> {
+            valueArgumentCaptor.getValue().type = 4;
+            valueArgumentCaptor.getValue().data = 13;
+            return null;
+        }).when(resources).getValue(eq(com.android.internal.R.dimen
+                .config_displayWhiteBalanceBrightnessFilterIntercept),
+                valueArgumentCaptor.capture(), eq(true));
         DisplayModeDirector director =
                 createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+        SensorManager sensorManager = createMockSensorManager(createLightSensor());
+        director.start(sensorManager);
         // We don't expect any interaction with DeviceConfig when the director is initialized
         // because we explicitly avoid doing this as this can lead to a latency spike in the
         // startup of DisplayManagerService
@@ -2285,6 +2302,8 @@
                 0.0);
         assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65);
         assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 85);
+        assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 95);
+        assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 100);
         assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
                 new int[]{250});
         assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
@@ -2294,6 +2313,7 @@
         assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
                 new int[]{10});
 
+
         // Notify that the default display is updated, such that DisplayDeviceConfig has new values
         DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
         when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
@@ -2304,6 +2324,8 @@
         when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
         when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
         when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
+        when(displayDeviceConfig.getDefaultRefreshRateInHbmHdr()).thenReturn(65);
+        when(displayDeviceConfig.getDefaultRefreshRateInHbmSunlight()).thenReturn(75);
         director.defaultDisplayDeviceUpdated(displayDeviceConfig);
 
         assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
@@ -2319,6 +2341,8 @@
                 new int[]{25});
         assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
                 new int[]{30});
+        assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 65);
+        assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 75);
 
         // Notify that the default display is updated, such that DeviceConfig has new values
         FakeDeviceConfig config = mInjector.getDeviceConfig();
@@ -2329,8 +2353,10 @@
         config.setLowDisplayBrightnessThresholds(new int[]{10});
         config.setHighDisplayBrightnessThresholds(new int[]{255});
         config.setHighAmbientBrightnessThresholds(new int[]{8000});
-
-        director.defaultDisplayDeviceUpdated(displayDeviceConfig);
+        config.setRefreshRateInHbmHdr(70);
+        config.setRefreshRateInHbmSunlight(80);
+        // Need to wait for the property change to propagate to the main thread.
+        waitForIdleSync();
 
         assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
         assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 60,
@@ -2345,6 +2371,8 @@
                 new int[]{10});
         assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
                 new int[]{20});
+        assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 70);
+        assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 80);
     }
 
     @Test
@@ -2402,6 +2430,74 @@
                 eq(lightSensorTwo), anyInt(), any(Handler.class));
     }
 
+    @Test
+    public void testAuthenticationPossibleSetsPhysicalRateRangesToMax() throws RemoteException {
+        DisplayModeDirector director =
+                createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+        // don't call director.start(createMockSensorManager());
+        // DisplayObserver will reset mSupportedModesByDisplay
+        director.onBootCompleted();
+        ArgumentCaptor<IUdfpsRefreshRateRequestCallback> captor =
+                ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class);
+        verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture());
+
+        captor.getValue().onAuthenticationPossible(DISPLAY_ID, true);
+
+        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE);
+        assertThat(vote.refreshRateRanges.physical.min).isWithin(FLOAT_TOLERANCE).of(90);
+        assertThat(vote.refreshRateRanges.physical.max).isWithin(FLOAT_TOLERANCE).of(90);
+    }
+
+    @Test
+    public void testAuthenticationPossibleUnsetsVote() throws RemoteException {
+        DisplayModeDirector director =
+                createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+        director.start(createMockSensorManager());
+        director.onBootCompleted();
+        ArgumentCaptor<IUdfpsRefreshRateRequestCallback> captor =
+                ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class);
+        verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture());
+        captor.getValue().onAuthenticationPossible(DISPLAY_ID, true);
+        captor.getValue().onAuthenticationPossible(DISPLAY_ID, false);
+
+        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_AUTH_OPTIMIZER_RENDER_FRAME_RATE);
+        assertNull(vote);
+    }
+
+    @Test
+    public void testUdfpsRequestSetsPhysicalRateRangesToMax() throws RemoteException {
+        DisplayModeDirector director =
+                createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+        // don't call director.start(createMockSensorManager());
+        // DisplayObserver will reset mSupportedModesByDisplay
+        director.onBootCompleted();
+        ArgumentCaptor<IUdfpsRefreshRateRequestCallback> captor =
+                ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class);
+        verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture());
+
+        captor.getValue().onRequestEnabled(DISPLAY_ID);
+
+        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
+        assertThat(vote.refreshRateRanges.physical.min).isWithin(FLOAT_TOLERANCE).of(90);
+        assertThat(vote.refreshRateRanges.physical.max).isWithin(FLOAT_TOLERANCE).of(90);
+    }
+
+    @Test
+    public void testUdfpsRequestUnsetsUnsetsVote() throws RemoteException {
+        DisplayModeDirector director =
+                createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
+        director.start(createMockSensorManager());
+        director.onBootCompleted();
+        ArgumentCaptor<IUdfpsRefreshRateRequestCallback> captor =
+                ArgumentCaptor.forClass(IUdfpsRefreshRateRequestCallback.class);
+        verify(mStatusBarMock).setUdfpsRefreshRateCallback(captor.capture());
+        captor.getValue().onRequestEnabled(DISPLAY_ID);
+        captor.getValue().onRequestDisabled(DISPLAY_ID);
+
+        Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_UDFPS);
+        assertNull(vote);
+    }
+
     private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) {
         return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status);
     }
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index 8a37ed9..b698cdf 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -75,6 +75,7 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
 
+import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Arrays;
@@ -86,6 +87,7 @@
     private static final int DEVICE_STATE_CLOSED = 0;
     private static final int DEVICE_STATE_OPEN = 2;
     private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1;
+    private static final File NON_EXISTING_FILE = new File("/non_existing_folder/should_not_exist");
 
     private DisplayDeviceRepository mDisplayDeviceRepo;
     private LogicalDisplayMapper mLogicalDisplayMapper;
@@ -102,7 +104,7 @@
     @Mock IPowerManager mIPowerManagerMock;
     @Mock IThermalService mIThermalServiceMock;
     @Spy DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy =
-            new DeviceStateToLayoutMap(mIdProducer);
+            new DeviceStateToLayoutMap(mIdProducer, NON_EXISTING_FILE);
 
     @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor;
 
@@ -299,9 +301,13 @@
 
         Layout layout1 = new Layout();
         layout1.createDisplayLocked(info(device1).address, /* isDefault= */ true,
-                /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         layout1.createDisplayLocked(info(device2).address, /* isDefault= */ false,
-                /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1);
         assertThat(layout1.size()).isEqualTo(2);
         final int logicalId2 = layout1.getByAddress(info(device2).address).getLogicalDisplayId();
@@ -335,16 +341,22 @@
 
         Layout layout1 = new Layout();
         layout1.createDisplayLocked(info(device1).address, /* isDefault= */ true,
-                /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout1);
 
         final int layoutState2 = 2;
         Layout layout2 = new Layout();
         layout2.createDisplayLocked(info(device2).address, /* isDefault= */ false,
-                /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         // Device3 is the default display.
         layout2.createDisplayLocked(info(device3).address, /* isDefault= */ true,
-                /* isEnabled= */ true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isEnabled= */ true, /* displayGroup= */ null, mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         when(mDeviceStateToLayoutMapSpy.get(layoutState2)).thenReturn(layout2);
         assertThat(layout2.size()).isEqualTo(2);
         final int logicalId2 = layout2.getByAddress(info(device2).address).getLogicalDisplayId();
@@ -375,6 +387,56 @@
     }
 
     @Test
+    public void testGetDisplayInfoForStateLocked_multipleDisplayGroups() {
+        DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 200, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        DisplayDevice device3 = createDisplayDevice(TYPE_INTERNAL, 700, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        DisplayDevice device4 = createDisplayDevice(TYPE_INTERNAL, 400, 600,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+
+        Layout layout = new Layout();
+        layout.createDisplayLocked(info(device1).address,
+                /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null,
+                mIdProducer, /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        layout.createDisplayLocked(info(device2).address,
+                /* isDefault= */ false, /* isEnabled= */ true, "group1", mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        layout.createDisplayLocked(info(device3).address,
+                /* isDefault= */ false, /* isEnabled= */ true, "group1", mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        layout.createDisplayLocked(info(device4).address,
+                /* isDefault= */ false, /* isEnabled= */ true, "group2", mIdProducer,
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
+        when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT)).thenReturn(layout);
+
+        LogicalDisplay display1 = add(device1);
+        LogicalDisplay display2 = add(device2);
+        LogicalDisplay display3 = add(device3);
+        LogicalDisplay display4 = add(device4);
+
+        int displayGroupId1 =
+                mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display1));
+        int displayGroupId2 =
+                mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display2));
+        int displayGroupId3 =
+                mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3));
+        int displayGroupId4 =
+                mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display4));
+        assertThat(displayGroupId1).isEqualTo(DEFAULT_DISPLAY_GROUP);
+        assertThat(displayGroupId2).isNotEqualTo(DEFAULT_DISPLAY_GROUP);
+        assertThat(displayGroupId2).isEqualTo(displayGroupId3);
+        assertThat(displayGroupId3).isNotEqualTo(DEFAULT_DISPLAY_GROUP);
+        assertThat(displayGroupId2).isNotEqualTo(displayGroupId4);
+    }
+
+    @Test
     public void testSingleDisplayGroup() {
         LogicalDisplay display1 = add(createDisplayDevice(TYPE_INTERNAL, 600, 800,
                 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY));
@@ -566,18 +628,24 @@
 
         Layout layout = new Layout();
         layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address,
-                true, true, mIdProducer,
-                /* brightnessThrottlingMapId= */ "concurrent");
+                /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null,
+                mIdProducer, /* brightnessThrottlingMapId= */ "concurrent",
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
-                false, true, mIdProducer,
-                /* brightnessThrottlingMapId= */ "concurrent");
+                /* isDefault= */ false, /* isEnabled= */ true, /* displayGroup= */ null,
+                mIdProducer, /* brightnessThrottlingMapId= */ "concurrent",
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);
 
         layout = new Layout();
         layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address,
-                false, false, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isDefault= */ false, /* isEnabled= */ false, /* displayGroup= */ null,
+                mIdProducer, /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
-                true, true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                /* isDefault= */ true, /* isEnabled= */ true, /* displayGroup= */ null,
+                mIdProducer, /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(layout);
         when(mDeviceStateToLayoutMapSpy.get(2)).thenReturn(layout);
 
@@ -604,6 +672,10 @@
         assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device1).isInTransitionLocked());
         assertFalse(mLogicalDisplayMapper.getDisplayLocked(device2).isInTransitionLocked());
+        assertEquals(-1, mLogicalDisplayMapper.getDisplayLocked(device1)
+                .getLeadDisplayIdLocked());
+        assertEquals(0, mLogicalDisplayMapper.getDisplayLocked(device2)
+                .getLeadDisplayIdLocked());
         assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device1)
                 .getBrightnessThrottlingDataIdLocked());
         assertEquals("concurrent", mLogicalDisplayMapper.getDisplayLocked(device2)
@@ -654,20 +726,26 @@
                 displayAddressOne,
                 /* isDefault= */ true,
                 /* isEnabled= */ true,
+                /* displayGroup= */ null,
                 mIdProducer,
-                /* brightnessThrottlingMapId= */ null);
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         threeDevicesEnabledLayout.createDisplayLocked(
                 displayAddressTwo,
                 /* isDefault= */ false,
                 /* isEnabled= */ true,
+                /* displayGroup= */ null,
                 mIdProducer,
-                /* brightnessThrottlingMapId= */ null);
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         threeDevicesEnabledLayout.createDisplayLocked(
                 displayAddressThree,
                 /* isDefault= */ false,
                 /* isEnabled= */ true,
+                /* displayGroup= */ null,
                 mIdProducer,
-                /* brightnessThrottlingMapId= */ null);
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
 
         when(mDeviceStateToLayoutMapSpy.get(STATE_DEFAULT))
                 .thenReturn(threeDevicesEnabledLayout);
@@ -702,20 +780,26 @@
                 displayAddressOne,
                 /* isDefault= */ true,
                 /* isEnabled= */ true,
+                /* displayGroup= */ null,
                 mIdProducer,
-                /* brightnessThrottlingMapId= */ null);
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         oneDeviceEnabledLayout.createDisplayLocked(
                 displayAddressTwo,
                 /* isDefault= */ false,
                 /* isEnabled= */ false,
+                /* displayGroup= */ null,
                 mIdProducer,
-                /* brightnessThrottlingMapId= */ null);
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         oneDeviceEnabledLayout.createDisplayLocked(
                 displayAddressThree,
                 /* isDefault= */ false,
                 /* isEnabled= */ false,
+                /* displayGroup= */ null,
                 mIdProducer,
-                /* brightnessThrottlingMapId= */ null);
+                /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
 
         when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(oneDeviceEnabledLayout);
         when(mDeviceStateToLayoutMapSpy.get(1)).thenReturn(threeDevicesEnabledLayout);
@@ -790,10 +874,11 @@
 
         Layout layout = new Layout();
         layout.createDisplayLocked(device1.getDisplayDeviceInfoLocked().address,
-                true, true, mIdProducer, /* brightnessThrottlingMapId= */ null);
+                true, true, null, mIdProducer, /* brightnessThrottlingMapId= */ null,
+                /* leadDisplayId= */ Display.DEFAULT_DISPLAY);
         layout.createDisplayLocked(device2.getDisplayDeviceInfoLocked().address,
-                false, true, mIdProducer, /* brightnessThrottlingMapId= */ null,
-                POSITION_REAR);
+                false, true, null, mIdProducer, /* brightnessThrottlingMapId= */ null,
+                POSITION_REAR, Display.DEFAULT_DISPLAY);
         when(mDeviceStateToLayoutMapSpy.get(0)).thenReturn(layout);
 
         when(mDeviceStateToLayoutMapSpy.size()).thenReturn(1);
@@ -816,9 +901,9 @@
         assertTrue(mLogicalDisplayMapper.getDisplayLocked(device2).isEnabledLocked());
 
         assertEquals(POSITION_UNKNOWN,
-                mLogicalDisplayMapper.getDisplayLocked(device1).getPositionLocked());
+                mLogicalDisplayMapper.getDisplayLocked(device1).getDevicePositionLocked());
         assertEquals(POSITION_REAR,
-                mLogicalDisplayMapper.getDisplayLocked(device2).getPositionLocked());
+                mLogicalDisplayMapper.getDisplayLocked(device2).getDevicePositionLocked());
     }
 
     /////////////////
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 1d70fc6..d28050d 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayTest.java
@@ -26,12 +26,15 @@
 
 import android.app.PropertyInvalidatedCache;
 import android.graphics.Point;
+import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.SurfaceControl;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.display.layout.Layout;
+
 import org.junit.Before;
 import org.junit.Test;
 
@@ -47,6 +50,7 @@
 
     private LogicalDisplay mLogicalDisplay;
     private DisplayDevice mDisplayDevice;
+    private DisplayDeviceRepository mDeviceRepo;
     private final DisplayDeviceInfo mDisplayDeviceInfo = new DisplayDeviceInfo();
 
     @Before
@@ -66,7 +70,7 @@
         // Disable binder caches in this process.
         PropertyInvalidatedCache.disableForTestMode();
 
-        DisplayDeviceRepository repo = new DisplayDeviceRepository(
+        mDeviceRepo = new DisplayDeviceRepository(
                 new DisplayManagerService.SyncRoot(),
                 new PersistentDataStore(new PersistentDataStore.Injector() {
                     @Override
@@ -82,8 +86,8 @@
                     @Override
                     public void finishWrite(OutputStream os, boolean success) {}
                 }));
-        repo.onDisplayDeviceEvent(mDisplayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
-        mLogicalDisplay.updateLocked(repo);
+        mDeviceRepo.onDisplayDeviceEvent(mDisplayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
+        mLogicalDisplay.updateLocked(mDeviceRepo);
     }
 
     @Test
@@ -137,4 +141,29 @@
         verify(t).setDisplayFlags(any(), eq(SurfaceControl.DISPLAY_RECEIVES_INPUT));
         reset(t);
     }
+
+    @Test
+    public void testRearDisplaysArePresentationDisplaysThatDestroyContentOnRemoval() {
+        // Assert that the display isn't a presentation display by default, with a default remove
+        // mode
+        assertEquals(0, mLogicalDisplay.getDisplayInfoLocked().flags);
+        assertEquals(Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY,
+                mLogicalDisplay.getDisplayInfoLocked().removeMode);
+
+        // Update position and test to see that it's been updated to a rear, presentation display
+        // that destroys content on removal
+        mLogicalDisplay.setDevicePositionLocked(Layout.Display.POSITION_REAR);
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        assertEquals(Display.FLAG_REAR | Display.FLAG_PRESENTATION,
+                mLogicalDisplay.getDisplayInfoLocked().flags);
+        assertEquals(Display.REMOVE_MODE_DESTROY_CONTENT,
+                mLogicalDisplay.getDisplayInfoLocked().removeMode);
+
+        // And then check the unsetting the position resets both
+        mLogicalDisplay.setDevicePositionLocked(Layout.Display.POSITION_UNKNOWN);
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        assertEquals(0, mLogicalDisplay.getDisplayInfoLocked().flags);
+        assertEquals(Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY,
+                mLogicalDisplay.getDisplayInfoLocked().removeMode);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index d4ab794..ebd63a0 100644
--- a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
@@ -47,7 +47,7 @@
 @RunWith(AndroidJUnit4.class)
 public final class DisplayBrightnessControllerTest {
     private static final int DISPLAY_ID = 1;
-    private static final float DEFAULT_BRIGHTNESS = 0.4f;
+    private static final float DEFAULT_BRIGHTNESS = 0.15f;
 
     @Mock
     private DisplayBrightnessStrategySelector mDisplayBrightnessStrategySelector;
@@ -70,11 +70,18 @@
                 return mDisplayBrightnessStrategySelector;
             }
         };
+        when(mBrightnessSetting.getBrightness()).thenReturn(Float.NaN);
         mDisplayBrightnessController = new DisplayBrightnessController(mContext, injector,
                 DISPLAY_ID, DEFAULT_BRIGHTNESS, mBrightnessSetting, mOnBrightnessChangeRunnable);
     }
 
     @Test
+    public void testIfFirstScreenBrightnessIsDefault() {
+        assertEquals(mDisplayBrightnessController.getCurrentBrightness(), DEFAULT_BRIGHTNESS,
+                0.0f);
+    }
+
+    @Test
     public void testUpdateBrightness() {
         DisplayPowerRequest displayPowerRequest = mock(DisplayPowerRequest.class);
         DisplayBrightnessStrategy displayBrightnessStrategy = mock(DisplayBrightnessStrategy.class);
diff --git a/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java b/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
index 303a370..1ef1197 100644
--- a/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
@@ -99,7 +99,24 @@
         mLooper.dispatchAll();
 
         // Verify that dream service is called to attach.
-        verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/, any());
+        verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/,
+                eq(false) /*preview*/, any());
+    }
+
+    @Test
+    public void startDream_attachOnServiceConnectedInPreviewMode() throws RemoteException {
+        // Call dream controller to start dreaming.
+        mDreamController.startDream(mToken, mDreamName, true /*isPreview*/, false /*doze*/,
+                0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
+
+        // Mock service connected.
+        final ServiceConnection serviceConnection = captureServiceConnection();
+        serviceConnection.onServiceConnected(mDreamName, mIBinder);
+        mLooper.dispatchAll();
+
+        // Verify that dream service is called to attach.
+        verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/,
+                eq(true) /*preview*/, any());
     }
 
     @Test
@@ -129,7 +146,7 @@
 
         // Mock second dream started.
         verify(newDreamService).attach(eq(newToken), eq(false) /*doze*/,
-                mRemoteCallbackCaptor.capture());
+                eq(false) /*preview*/, mRemoteCallbackCaptor.capture());
         mRemoteCallbackCaptor.getValue().sendResult(null /*data*/);
         mLooper.dispatchAll();
 
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 5ca695b..c9612cd 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -49,8 +49,8 @@
 import android.os.UserManager;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
-import android.provider.Settings;
 import android.provider.DeviceConfig;
+import android.provider.Settings;
 import android.security.KeyStore;
 
 import androidx.test.InstrumentationRegistry;
@@ -83,16 +83,15 @@
     protected static final int MANAGED_PROFILE_USER_ID = 12;
     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
     protected static final int SECONDARY_USER_ID = 20;
+    protected static final int TERTIARY_USER_ID = 21;
 
-    private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY
-                    | UserInfo.FLAG_MAIN);
-    private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
-            UserInfo.FLAG_INITIALIZED);
+    protected UserInfo mPrimaryUserInfo;
+    protected UserInfo mSecondaryUserInfo;
+    protected UserInfo mTertiaryUserInfo;
 
     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
 
-    LockSettingsService mService;
+    LockSettingsServiceTestable mService;
     LockSettingsInternal mLocalService;
 
     MockLockSettingsContext mContext;
@@ -117,6 +116,7 @@
     FingerprintManager mFingerprintManager;
     FaceManager mFaceManager;
     PackageManager mPackageManager;
+    LockSettingsServiceTestable.MockInjector mInjector;
     @Rule
     public FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
 
@@ -162,22 +162,61 @@
         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
                 mUserManager, mPasswordSlotManager);
         mAuthSecretService = mock(IAuthSecret.class);
-        mService = new LockSettingsServiceTestable(mContext, mStorage,
-                mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
-                mSpManager, mAuthSecretService, mGsiService, mRecoverableKeyStoreManager,
-                mUserManagerInternal, mDeviceStateCache);
+        mInjector =
+                new LockSettingsServiceTestable.MockInjector(
+                        mContext,
+                        mStorage,
+                        mKeyStore,
+                        mActivityManager,
+                        setUpStorageManagerMock(),
+                        mSpManager,
+                        mGsiService,
+                        mRecoverableKeyStoreManager,
+                        mUserManagerInternal,
+                        mDeviceStateCache);
+        mService =
+                new LockSettingsServiceTestable(mInjector, mGateKeeperService, mAuthSecretService);
         mService.mHasSecureLockScreen = true;
-        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
-        mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
+        mPrimaryUserInfo =
+                new UserInfo(
+                        PRIMARY_USER_ID,
+                        null,
+                        null,
+                        UserInfo.FLAG_INITIALIZED
+                                | UserInfo.FLAG_ADMIN
+                                | UserInfo.FLAG_PRIMARY
+                                | UserInfo.FLAG_MAIN
+                                | UserInfo.FLAG_FULL);
+        mSecondaryUserInfo =
+                new UserInfo(
+                        SECONDARY_USER_ID,
+                        null,
+                        null,
+                        UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
+        mTertiaryUserInfo =
+                new UserInfo(
+                        TERTIARY_USER_ID,
+                        null,
+                        null,
+                        UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
+
+        when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
+        when(mUserManagerInternal.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
+        mPrimaryUserProfiles.add(mPrimaryUserInfo);
         installChildProfile(MANAGED_PROFILE_USER_ID);
         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
         for (UserInfo profile : mPrimaryUserProfiles) {
             when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
         }
-        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
+        when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(mSecondaryUserInfo);
+        when(mUserManagerInternal.getUserInfo(eq(SECONDARY_USER_ID)))
+                .thenReturn(mSecondaryUserInfo);
+        when(mUserManager.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
+        when(mUserManagerInternal.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
 
         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
-        allUsers.add(SECONDARY_USER_INFO);
+        allUsers.add(mSecondaryUserInfo);
+        allUsers.add(mTertiaryUserInfo);
         when(mUserManager.getUsers()).thenReturn(allUsers);
 
         when(mActivityManager.unlockUser2(anyInt(), any())).thenAnswer(
@@ -227,9 +266,10 @@
         userInfo.profileGroupId = PRIMARY_USER_ID;
         mPrimaryUserProfiles.add(userInfo);
         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
-        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
+        when(mUserManager.getProfileParent(eq(profileId))).thenReturn(mPrimaryUserInfo);
         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
+        when(mUserManagerInternal.getUserInfo(eq(profileId))).thenReturn(userInfo);
         // TODO(b/258213147): Remove
         when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true);
         when(mDeviceStateCache.isUserOrganizationManaged(eq(profileId)))
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index f0f0632..9686c38 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -30,6 +30,7 @@
 import android.os.storage.IStorageManager;
 import android.security.KeyStore;
 import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.service.gatekeeper.IGateKeeperService;
 
 import com.android.internal.widget.LockscreenCredential;
 import com.android.server.ServiceThread;
@@ -40,7 +41,7 @@
 
 public class LockSettingsServiceTestable extends LockSettingsService {
 
-    private static class MockInjector extends LockSettingsService.Injector {
+    public static class MockInjector extends LockSettingsService.Injector {
 
         private LockSettingsStorage mLockSettingsStorage;
         private KeyStore mKeyStore;
@@ -52,6 +53,9 @@
         private UserManagerInternal mUserManagerInternal;
         private DeviceStateCache mDeviceStateCache;
 
+        public boolean mIsHeadlessSystemUserMode = false;
+        public boolean mIsMainUserPermanentAdmin = false;
+
         public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
                 IActivityManager activityManager,
                 IStorageManager storageManager, SyntheticPasswordManager spManager,
@@ -140,19 +144,22 @@
             return mock(ManagedProfilePasswordCache.class);
         }
 
+        @Override
+        public boolean isHeadlessSystemUserMode() {
+            return mIsHeadlessSystemUserMode;
+        }
+
+        @Override
+        public boolean isMainUserPermanentAdmin() {
+            return mIsMainUserPermanentAdmin;
+        }
     }
 
-    public MockInjector mInjector;
-
-    protected LockSettingsServiceTestable(Context context,
-            LockSettingsStorage storage, FakeGateKeeperService gatekeeper, KeyStore keystore,
-            IStorageManager storageManager, IActivityManager mActivityManager,
-            SyntheticPasswordManager spManager, IAuthSecret authSecretService,
-            FakeGsiService gsiService, RecoverableKeyStoreManager recoverableKeyStoreManager,
-            UserManagerInternal userManagerInternal, DeviceStateCache deviceStateCache) {
-        super(new MockInjector(context, storage, keystore, mActivityManager,
-                storageManager, spManager, gsiService, recoverableKeyStoreManager,
-                userManagerInternal, deviceStateCache));
+    protected LockSettingsServiceTestable(
+            LockSettingsService.Injector injector,
+            IGateKeeperService gatekeeper,
+            IAuthSecret authSecretService) {
+        super(injector);
         mGateKeeperService = gatekeeper;
         mAuthSecretService = authSecretService;
     }
@@ -199,4 +206,10 @@
         UserInfo userInfo = mUserManager.getUserInfo(userId);
         return userInfo.isCloneProfile() || userInfo.isManagedProfile();
     }
+
+    void clearAuthSecret() {
+        synchronized (mHeadlessAuthSecretLock) {
+            mAuthSecret = null;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
index a40cb06..e8ef398 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockSyntheticPasswordManager.java
@@ -119,6 +119,5 @@
 
     public void enableWeaver() {
         mWeaverService = new MockWeaverService();
-        initWeaverService();
     }
 }
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 57593cf..62d8a76 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -16,6 +16,10 @@
 
 package com.android.server.locksettings;
 
+import static android.content.pm.UserInfo.FLAG_FULL;
+import static android.content.pm.UserInfo.FLAG_MAIN;
+import static android.content.pm.UserInfo.FLAG_PRIMARY;
+
 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;
@@ -27,9 +31,9 @@
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -247,6 +251,15 @@
 
     @Test
     public void testUnlockUserKeyIfUnsecuredPassesPrimaryUserAuthSecret() throws RemoteException {
+        initSpAndSetCredential(PRIMARY_USER_ID, newPassword(null));
+        reset(mAuthSecretService);
+        mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
+        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
+    }
+
+    @Test
+    public void testUnlockUserKeyIfUnsecuredPassesPrimaryUserAuthSecretIfPasswordIsCleared()
+            throws RemoteException {
         LockscreenCredential password = newPassword("password");
         initSpAndSetCredential(PRIMARY_USER_ID, password);
         mService.setLockCredential(nonePassword(), password, PRIMARY_USER_ID);
@@ -256,6 +269,56 @@
         verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
     }
 
+    private void setupHeadlessTest() {
+        mInjector.mIsHeadlessSystemUserMode = true;
+        mInjector.mIsMainUserPermanentAdmin = true;
+        mPrimaryUserInfo.flags &= ~(FLAG_FULL | FLAG_PRIMARY);
+        mSecondaryUserInfo.flags |= FLAG_MAIN;
+        mService.initializeSyntheticPassword(PRIMARY_USER_ID);
+        mService.initializeSyntheticPassword(SECONDARY_USER_ID);
+        mService.initializeSyntheticPassword(TERTIARY_USER_ID);
+        reset(mAuthSecretService);
+    }
+
+    @Test
+    public void testHeadlessSystemUserDoesNotPassAuthSecret() throws RemoteException {
+        setupHeadlessTest();
+        mLocalService.unlockUserKeyIfUnsecured(PRIMARY_USER_ID);
+        verify(mAuthSecretService, never()).setPrimaryUserCredential(any(byte[].class));
+    }
+
+    @Test
+    public void testHeadlessSecondaryUserPassesAuthSecret() throws RemoteException {
+        setupHeadlessTest();
+        mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
+        verify(mAuthSecretService).setPrimaryUserCredential(any(byte[].class));
+    }
+
+    @Test
+    public void testHeadlessTertiaryUserPassesSameAuthSecret() throws RemoteException {
+        setupHeadlessTest();
+        mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
+        var captor = ArgumentCaptor.forClass(byte[].class);
+        verify(mAuthSecretService).setPrimaryUserCredential(captor.capture());
+        var value = captor.getValue();
+        reset(mAuthSecretService);
+        mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID);
+        verify(mAuthSecretService).setPrimaryUserCredential(eq(value));
+    }
+
+    @Test
+    public void testHeadlessTertiaryUserPassesSameAuthSecretAfterReset() throws RemoteException {
+        setupHeadlessTest();
+        mLocalService.unlockUserKeyIfUnsecured(SECONDARY_USER_ID);
+        var captor = ArgumentCaptor.forClass(byte[].class);
+        verify(mAuthSecretService).setPrimaryUserCredential(captor.capture());
+        var value = captor.getValue();
+        mService.clearAuthSecret();
+        reset(mAuthSecretService);
+        mLocalService.unlockUserKeyIfUnsecured(TERTIARY_USER_ID);
+        verify(mAuthSecretService).setPrimaryUserCredential(eq(value));
+    }
+
     @Test
     public void testTokenBasedResetPassword() throws RemoteException {
         LockscreenCredential password = newPassword("password");
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
index 966c047..50f3a88 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
@@ -8,6 +8,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.locksettings.LockSettingsStorage.PersistentData;
+
 import com.google.android.collect.Sets;
 
 import org.junit.Before;
@@ -29,7 +30,7 @@
     // sequentially, starting at slot 0.
     @Test
     public void testFrpWeaverSlotNotReused() {
-        final int userId = 10;
+        final int userId = SECONDARY_USER_ID;
         final int frpWeaverSlot = 0;
 
         setDeviceProvisioned(false);
@@ -45,7 +46,7 @@
     // it's here as a control for testFrpWeaverSlotNotReused().
     @Test
     public void testFrpWeaverSlotReused() {
-        final int userId = 10;
+        final int userId = SECONDARY_USER_ID;
         final int frpWeaverSlot = 0;
 
         setDeviceProvisioned(true);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index bb79fd8..2affe92 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -40,6 +40,8 @@
 import android.Manifest;
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
+import android.app.RemoteLockscreenValidationResult;
+import android.app.StartLockscreenValidationRequest;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Binder;
@@ -60,12 +62,16 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockscreenCredential;
+import com.android.internal.widget.VerifyCredentialResponse;
 import com.android.security.SecureBox;
+import com.android.server.locksettings.LockSettingsService;
 import com.android.server.locksettings.recoverablekeystore.storage.ApplicationKeyStorage;
 import com.android.server.locksettings.recoverablekeystore.storage.CleanupManager;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
+import com.android.server.locksettings.recoverablekeystore.storage.RemoteLockscreenValidationSessionStorage;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -81,10 +87,12 @@
 
 import java.io.File;
 import java.nio.charset.StandardCharsets;
+import java.security.PublicKey;
 import java.security.cert.CertPath;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.ScheduledExecutorService;
@@ -152,6 +160,10 @@
             .setKeyDerivationParams(KeyDerivationParams.createSha256Params(TEST_SALT))
             .setSecret(TEST_SECRET)
             .build();
+    private static final byte[] VALID_GUESS = getUtf8Bytes("password123");
+    private static final byte[] INVALID_GUESS = getUtf8Bytes("not_password");
+    private static final byte[] GUESS_LOCKOUT = getUtf8Bytes("need_to_wait");
+    private static final int TIMEOUT_MILLIS = 30 * 1000;
 
     @Mock private Context mMockContext;
     @Mock private RecoverySnapshotListenersStorage mMockListenersStorage;
@@ -160,14 +172,17 @@
     @Mock private ApplicationKeyStorage mApplicationKeyStorage;
     @Mock private CleanupManager mCleanupManager;
     @Mock private ScheduledExecutorService mExecutorService;
+    @Mock private LockSettingsService mLockSettingsService;
     @Spy private TestOnlyInsecureCertificateHelper mTestOnlyInsecureCertificateHelper;
 
+    private int mUserId;
     private RecoverableKeyStoreDb mRecoverableKeyStoreDb;
     private File mDatabaseFile;
     private RecoverableKeyStoreManager mRecoverableKeyStoreManager;
     private RecoverySessionStorage mRecoverySessionStorage;
     private RecoverySnapshotStorage mRecoverySnapshotStorage;
     private PlatformEncryptionKey mPlatformEncryptionKey;
+    private RemoteLockscreenValidationSessionStorage mRemoteLockscreenValidationSessionStorage;
 
     @Before
     public void setUp() throws Exception {
@@ -177,7 +192,9 @@
         mDatabaseFile = context.getDatabasePath(DATABASE_FILE_NAME);
         mRecoverableKeyStoreDb = RecoverableKeyStoreDb.newInstance(context);
 
+        mUserId = UserHandle.getCallingUserId();
         mRecoverySessionStorage = new RecoverySessionStorage();
+        mRemoteLockscreenValidationSessionStorage = new RemoteLockscreenValidationSessionStorage();
 
         when(mMockContext.getSystemService(anyString())).thenReturn(mKeyguardManager);
         when(mMockContext.getSystemServiceName(any())).thenReturn("test");
@@ -198,11 +215,22 @@
                 mPlatformKeyManager,
                 mApplicationKeyStorage,
                 mTestOnlyInsecureCertificateHelper,
-                mCleanupManager);
+                mCleanupManager,
+                mRemoteLockscreenValidationSessionStorage);
+        when(mLockSettingsService.verifyCredential(
+                any(LockscreenCredential.class), anyInt(), anyInt())).thenAnswer(args -> {
+                    LockscreenCredential argument = (LockscreenCredential) args.getArguments()[0];
+                    if (Arrays.equals(argument.getCredential(), VALID_GUESS)) {
+                        return VerifyCredentialResponse.OK;
+                    } else if (Arrays.equals(argument.getCredential(), INVALID_GUESS)) {
+                        return VerifyCredentialResponse.ERROR;
+                    } else return VerifyCredentialResponse.fromTimeout(TIMEOUT_MILLIS);
+                });
     }
 
     @After
     public void tearDown() {
+        mRemoteLockscreenValidationSessionStorage.finishSession(mUserId);
         mRecoverableKeyStoreDb.close();
         mDatabaseFile.delete();
     }
@@ -1269,6 +1297,175 @@
         verify(mExecutorService).schedule(any(Runnable.class), anyLong(), any());
     }
 
+    @Test
+    public void startRemoteLockscreenValidation_credentialsNotSet() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_NONE);
+        try {
+            mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+            fail("should have thrown");
+        } catch (IllegalStateException e) {
+            assertThat(e.getMessage()).contains("not set");
+        }
+        verify(mLockSettingsService).getCredentialType(mUserId);
+    }
+    @Test
+    public void startRemoteLockscreenValidation_checksPermission() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PIN);
+
+        mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        verify(mMockContext, times(1))
+                .enforceCallingOrSelfPermission(
+                        eq(Manifest.permission.CHECK_REMOTE_LOCKSCREEN), any());
+        mRemoteLockscreenValidationSessionStorage.finishSession(mUserId);
+    }
+    @Test
+    public void startRemoteLockscreenValidation_returnsCredentailsType() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PIN);
+
+        StartLockscreenValidationRequest request =
+                mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        int credetialsType = request.getLockscreenUiType();
+        assertThat(credetialsType).isEqualTo(KeyguardManager.PIN);
+        assertThat(request.getRemainingAttempts()).isEqualTo(5);
+        verify(mLockSettingsService).getCredentialType(anyInt());
+    }
+    @Test
+    public void startRemoteLockscreenValidation_returnsRemainingAttempts() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 3);
+
+        StartLockscreenValidationRequest request =
+                mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        int credetialsType = request.getLockscreenUiType();
+        assertThat(credetialsType).isEqualTo(KeyguardManager.PATTERN);
+        assertThat(request.getRemainingAttempts()).isEqualTo(2);
+    }
+    @Test
+    public void startRemoteLockscreenValidation_password() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 7);
+
+        StartLockscreenValidationRequest request =
+                mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        int credetialsType = request.getLockscreenUiType();
+        assertThat(request.getRemainingAttempts()).isEqualTo(0);
+        assertThat(credetialsType).isEqualTo(KeyguardManager.PASSWORD);
+    }
+    @Test
+    public void validateRemoteLockscreen_noActiveSession() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_NONE);
+        try {
+            mRecoverableKeyStoreManager.validateRemoteLockscreen(INVALID_GUESS,
+                    mLockSettingsService);
+            fail("should have thrown");
+        } catch (IllegalStateException e) {
+            assertThat(e.getMessage()).contains("session");
+        }
+    }
+    @Test
+    public void validateRemoteLockscreen_decryptionError() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 4);
+
+        mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        try {
+            mRecoverableKeyStoreManager.validateRemoteLockscreen(
+                        new byte[] {1, 2, 3},
+                        mLockSettingsService);
+            fail("should have thrown");
+        } catch (IllegalStateException e) {
+            // Decryption error
+        }
+    }
+    @Test
+    public void validateRemoteLockscreen_zeroRemainingAttempts() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 5);
+        mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        RemoteLockscreenValidationResult result =
+                    mRecoverableKeyStoreManager.validateRemoteLockscreen(
+                    encryptCredentialsForNewSession(VALID_GUESS),
+                        mLockSettingsService);
+
+        assertThat(result.getResultCode()).isEqualTo(
+                RemoteLockscreenValidationResult.RESULT_NO_REMAINING_ATTEMPTS);
+    }
+    @Test
+    public void validateRemoteLockscreen_guessValid() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 4);
+        mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        RemoteLockscreenValidationResult result =
+                mRecoverableKeyStoreManager.validateRemoteLockscreen(
+                        encryptCredentialsForNewSession(VALID_GUESS),
+                        mLockSettingsService);
+
+        assertThat(result.getResultCode()).isEqualTo(
+                RemoteLockscreenValidationResult.RESULT_GUESS_VALID);
+        // Valid guess resets counter
+        assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(mUserId)).isEqualTo(0);
+    }
+    @Test
+    public void validateRemoteLockscreen_timeout() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 4);
+
+        RemoteLockscreenValidationResult result =
+                mRecoverableKeyStoreManager.validateRemoteLockscreen(
+                        encryptCredentialsForNewSession(GUESS_LOCKOUT),
+                        mLockSettingsService);
+
+        assertThat(result.getResultCode()).isEqualTo(
+                RemoteLockscreenValidationResult.RESULT_LOCKOUT);
+        assertThat(result.getTimeoutMillis()).isEqualTo((long) TIMEOUT_MILLIS);
+        // Counter was not changed
+        assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(mUserId)).isEqualTo(4);
+    }
+    @Test
+    public void validateRemoteLockscreen_guessInvalid() throws Exception {
+        when(mLockSettingsService.getCredentialType(anyInt())).thenReturn(
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
+        mRecoverableKeyStoreDb.setBadRemoteGuessCounter(mUserId, 4);
+        mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+
+        RemoteLockscreenValidationResult result =
+                mRecoverableKeyStoreManager.validateRemoteLockscreen(
+                        encryptCredentialsForNewSession(INVALID_GUESS),
+                        mLockSettingsService);
+
+        assertThat(result.getResultCode()).isEqualTo(
+                RemoteLockscreenValidationResult.RESULT_GUESS_INVALID);
+        assertThat(mRecoverableKeyStoreDb.getBadRemoteGuessCounter(mUserId)).isEqualTo(5);
+    }
+
+    private byte[] encryptCredentialsForNewSession(byte[] credentials) throws Exception {
+        StartLockscreenValidationRequest request =
+                mRecoverableKeyStoreManager.startRemoteLockscreenValidation(mLockSettingsService);
+        PublicKey publicKey = SecureBox.decodePublicKey(request.getSourcePublicKey());
+        return SecureBox.encrypt(
+              publicKey,
+              /* sharedSecret= */ null,
+              LockPatternUtils.ENCRYPTED_REMOTE_CREDENTIALS_HEADER,
+              credentials);
+    }
+
     private static byte[] encryptedApplicationKey(
             SecretKey recoveryKey, byte[] applicationKey) throws Exception {
         return KeySyncUtils.encryptKeysWithRecoveryKey(recoveryKey, ImmutableMap.of(
diff --git a/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
index 9902446..5a46f8c4 100644
--- a/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
@@ -1,7 +1,7 @@
 {
   "presubmit": [
     {
-      "name": "BugreportManagerServiceImplTests",
+      "name": "FrameworksServicesTests",
       "options": [
         {
           "include-filter": "com.android.server.os."
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index 93f6db7..9fc46c5 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -1737,15 +1737,33 @@
             NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
                     invocationOnMock.getArguments()[1];
             ranking.populate(
-                    (String) invocationOnMock.getArguments()[0],
-                    0,
-                    false,
-                    0,
-                    0,
+                    /* key= */ (String) invocationOnMock.getArguments()[0],
+                    /* rank= */ 0,
+                    /* matchesInterruptionFilter= */ false,
+                    /* visibilityOverride= */ 0,
+                    /* suppressedVisualEffects= */ 0,
                     mParentNotificationChannel.getImportance(),
-                    null, null,
-                    mParentNotificationChannel, null, null, true, 0, false, -1, false, null, null,
-                    false, false, false, null, 0, false, 0);
+                    /* explanation= */ null,
+                    /* overrideGroupKey= */ null,
+                    mParentNotificationChannel,
+                    /* overridePeople= */ null,
+                    /* snoozeCriteria= */ null,
+                    /* showBadge= */ true,
+                    /* userSentiment= */ 0,
+                    /* hidden= */ false,
+                    /* lastAudiblyAlertedMs= */ -1,
+                    /* noisy= */ false,
+                    /* smartActions= */ null,
+                    /* smartReplies= */ null,
+                    /* canBubble= */ false,
+                    /* isTextChanged= */ false,
+                    /* isConversation= */ false,
+                    /* shortcutInfo= */ null,
+                    /* rankingAdjustment= */ 0,
+                    /* isBubble= */ false,
+                    /* proposedImportance= */ 0,
+                    /* sensitiveContent= */ false
+            );
             return true;
         }).when(mRankingMap).getRanking(eq(key),
                 any(NotificationListenerService.Ranking.class));
@@ -1763,15 +1781,33 @@
             NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
                     invocationOnMock.getArguments()[1];
             ranking.populate(
-                    (String) invocationOnMock.getArguments()[0],
-                    0,
-                    false,
-                    0,
-                    0,
-                    mNotificationChannel.getImportance(),
-                    null, null,
-                    mNotificationChannel, null, null, true, 0, false, -1, false, null, null, false,
-                    false, false, null, 0, false, 0);
+                    /* key= */ (String) invocationOnMock.getArguments()[0],
+                    /* rank= */ 0,
+                    /* matchesInterruptionFilter= */ false,
+                    /* visibilityOverride= */ 0,
+                    /* suppressedVisualEffects= */ 0,
+                    mParentNotificationChannel.getImportance(),
+                    /* explanation= */ null,
+                    /* overrideGroupKey= */ null,
+                    mParentNotificationChannel,
+                    /* overridePeople= */ null,
+                    /* snoozeCriteria= */ null,
+                    /* showBadge= */ true,
+                    /* userSentiment= */ 0,
+                    /* hidden= */ false,
+                    /* lastAudiblyAlertedMs= */ -1,
+                    /* noisy= */ false,
+                    /* smartActions= */ null,
+                    /* smartReplies= */ null,
+                    /* canBubble= */ false,
+                    /* isTextChanged= */ false,
+                    /* isConversation= */ false,
+                    /* shortcutInfo= */ null,
+                    /* rankingAdjustment= */ 0,
+                    /* isBubble= */ false,
+                    /* proposedImportance= */ 0,
+                    /* sensitiveContent= */ false
+            );
             return true;
         }).when(mRankingMap).getRanking(eq(CUSTOM_KEY),
                 any(NotificationListenerService.Ranking.class));
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceShellCommandTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceShellCommandTest.java
new file mode 100644
index 0000000..4434a32
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceShellCommandTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.pm;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import static java.io.FileDescriptor.err;
+import static java.io.FileDescriptor.in;
+import static java.io.FileDescriptor.out;
+
+import android.app.PropertyInvalidatedCache;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.util.ArrayMap;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.LocalServices;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * Test class for {@link UserManagerServiceShellCommand}.
+ *
+ * runtest atest UserManagerServiceShellCommandTest
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class UserManagerServiceShellCommandTest {
+
+    private UserManagerServiceShellCommand mCommand;
+    private UserManagerService mUserManagerService;
+    private @Mock LockPatternUtils mLockPatternUtils;
+    private final Binder mBinder = new Binder();
+    private final ShellCallback mShellCallback = new ShellCallback();
+    private final ResultReceiver mResultReceiver = new ResultReceiver(
+            new Handler(Looper.getMainLooper()));
+    private ByteArrayOutputStream mOutStream;
+    private PrintWriter mWriter;
+
+    @Before
+    public void setUp() throws Exception {
+        mOutStream = new ByteArrayOutputStream();
+        mWriter = new PrintWriter(new PrintStream(mOutStream));
+        MockitoAnnotations.initMocks(this);
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        // Disable binder caches in this process.
+        PropertyInvalidatedCache.disableForTestMode();
+
+        LocalServices.removeServiceForTest(UserManagerInternal.class);
+        final Context context = InstrumentationRegistry.getTargetContext();
+
+        UserManagerService serviceInstance = new UserManagerService(context);
+        mUserManagerService = spy(serviceInstance);
+
+        ArrayMap<String, UserTypeDetails> userTypes = UserTypeFactory.getUserTypes();
+        UserSystemPackageInstaller userSystemPackageInstaller =
+                new UserSystemPackageInstaller(mUserManagerService, userTypes);
+        UserManagerServiceShellCommand cmd = new UserManagerServiceShellCommand(mUserManagerService,
+                userSystemPackageInstaller, mLockPatternUtils, context);
+        mCommand = spy(cmd);
+    }
+
+    @Test
+    public void testMainUser() {
+        when(mUserManagerService.getMainUserId()).thenReturn(12);
+        doReturn(mWriter).when(mCommand).getOutPrintWriter();
+
+        assertEquals(0, mCommand.exec(mBinder, in, out, err,
+                new String[]{"get-main-user"}, mShellCallback, mResultReceiver));
+
+        mWriter.flush();
+        assertEquals("Main user id: 12", mOutStream.toString().trim());
+    }
+
+    @Test
+    public void testMainUserNull() {
+        when(mUserManagerService.getMainUserId()).thenReturn(UserHandle.USER_NULL);
+        doReturn(mWriter).when(mCommand).getOutPrintWriter();
+
+        assertEquals(1, mCommand.exec(mBinder, in, out, err,
+                new String[]{"get-main-user"}, mShellCallback, mResultReceiver));
+        mWriter.flush();
+        assertEquals("Couldn't get main user.", mOutStream.toString().trim());
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 00aa520..4af0323 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -16,7 +16,6 @@
 
 package com.android.server.pm;
 
-import static android.os.UserManager.DISALLOW_BLUETOOTH;
 import static android.os.UserManager.DISALLOW_USER_SWITCH;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -41,7 +40,6 @@
 import com.android.server.LocalServices;
 
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -188,13 +186,11 @@
         while (mUserManagerService.userExists(incorrectId)) {
             incorrectId++;
         }
-        try {
-            mUserManagerService.setUserRestriction(DISALLOW_BLUETOOTH, true, incorrectId);
-            Assert.fail();
-        } catch (IllegalArgumentException e) {
-            //Exception is expected to be thrown if user ID does not exist.
-            // IllegalArgumentException thrown means this test is successful.
-        }
+        assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, incorrectId))
+                .isFalse();
+        mUserManagerService.setUserRestriction(DISALLOW_USER_SWITCH, true, incorrectId);
+        assertThat(mUserManagerService.hasUserRestriction(DISALLOW_USER_SWITCH, incorrectId))
+                .isFalse();
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index 92fddc7..d999aa3 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -22,6 +22,7 @@
 import static android.content.pm.UserInfo.FLAG_FULL;
 import static android.content.pm.UserInfo.FLAG_GUEST;
 import static android.content.pm.UserInfo.FLAG_INITIALIZED;
+import static android.content.pm.UserInfo.FLAG_MAIN;
 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
 import static android.content.pm.UserInfo.FLAG_PROFILE;
 import static android.content.pm.UserInfo.FLAG_RESTRICTED;
@@ -206,6 +207,13 @@
         assertFalse("Switching to a profiles should be disabled", userInfo.supportsSwitchTo());
     }
 
+    /** Test UserInfo.canHaveProfile for main user */
+    @Test
+    public void testCanHaveProfile() throws Exception {
+        UserInfo userInfo = createUser(100, FLAG_MAIN, null);
+        assertTrue("Main users can have profile", userInfo.canHaveProfile());
+    }
+
     /** Tests upgradeIfNecessaryLP (but without locking) for upgrading from version 8 to 9+. */
     @Test
     public void testUpgradeIfNecessaryLP_9() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index c760efd..95009e6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -26,7 +26,6 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.content.pm.UserProperties;
@@ -46,8 +45,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.compatibility.common.util.BlockingBroadcastReceiver;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Range;
 
@@ -61,17 +58,21 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
-/** Test {@link UserManager} functionality. */
+/**
+ * Test {@link UserManager} functionality.
+ *
+ *  atest com.android.server.pm.UserManagerTest
+ */
 @Postsubmit
 @RunWith(AndroidJUnit4.class)
 public final class UserManagerTest {
     // Taken from UserManagerService
     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // 30 years
 
-    private static final int SWITCH_USER_TIMEOUT_SECONDS = 40; // 40 seconds
+    private static final int SWITCH_USER_TIMEOUT_SECONDS = 180; // 180 seconds
+    private static final int REMOVE_USER_TIMEOUT_SECONDS = 180; // 180 seconds
 
     // Packages which are used during tests.
     private static final String[] PACKAGES = new String[] {
@@ -87,13 +88,17 @@
     private PackageManager mPackageManager;
     private ArraySet<Integer> mUsersToRemove;
     private UserSwitchWaiter mUserSwitchWaiter;
+    private UserRemovalWaiter mUserRemovalWaiter;
+    private int mOriginalCurrentUserId;
 
     @Before
     public void setUp() throws Exception {
+        mOriginalCurrentUserId = ActivityManager.getCurrentUser();
         mUserManager = UserManager.get(mContext);
         mActivityManager = mContext.getSystemService(ActivityManager.class);
         mPackageManager = mContext.getPackageManager();
         mUserSwitchWaiter = new UserSwitchWaiter(TAG, SWITCH_USER_TIMEOUT_SECONDS);
+        mUserRemovalWaiter = new UserRemovalWaiter(mContext, TAG, REMOVE_USER_TIMEOUT_SECONDS);
 
         mUsersToRemove = new ArraySet<>();
         removeExistingUsers();
@@ -101,10 +106,14 @@
 
     @After
     public void tearDown() throws Exception {
+        if (mOriginalCurrentUserId != ActivityManager.getCurrentUser()) {
+            switchUser(mOriginalCurrentUserId);
+        }
         mUserSwitchWaiter.close();
 
         // Making a copy of mUsersToRemove to avoid ConcurrentModificationException
         mUsersToRemove.stream().toList().forEach(this::removeUser);
+        mUserRemovalWaiter.close();
     }
 
     private void removeExistingUsers() {
@@ -302,7 +311,7 @@
     @MediumTest
     @Test
     public void testRemoveUserByHandle_ThrowsException() {
-        assertThrows(IllegalArgumentException.class, () -> removeUser(null));
+        assertThrows(IllegalArgumentException.class, () -> mUserManager.removeUser(null));
     }
 
     @MediumTest
@@ -393,11 +402,10 @@
         mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ true,
                 asHandle(currentUser));
         try {
-            runThenWaitForUserRemoval(() -> {
-                assertThat(mUserManager.removeUserWhenPossible(user1.getUserHandle(),
-                        /* overrideDevicePolicy= */ true))
-                        .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
-            }, user1.id); // wait for user removal
+            assertThat(mUserManager.removeUserWhenPossible(user1.getUserHandle(),
+                    /* overrideDevicePolicy= */ true))
+                    .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
+            waitForUserRemoval(user1.id);
         } finally {
             mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_USER, /* value= */ false,
                     asHandle(currentUser));
@@ -462,11 +470,10 @@
         assertThat(hasUser(user1.id)).isTrue();
         assertThat(getUser(user1.id).isEphemeral()).isTrue();
 
-        runThenWaitForUserRemoval(() -> {
-            // Switch back to the starting user.
-            switchUser(startUser);
-            // User will be removed once switch is complete
-        }, user1.id); // wait for user removal
+        // Switch back to the starting user.
+        switchUser(startUser);
+        // User will be removed once switch is complete
+        waitForUserRemoval(user1.id);
 
         assertThat(hasUser(user1.id)).isFalse();
     }
@@ -479,18 +486,17 @@
         // Switch to the user just created.
         switchUser(testUser.id);
 
-        runThenWaitForUserRemoval(() -> {
-            switchUserThenRun(startUser, () -> {
-                // While the switch is happening, call removeUserWhenPossible for the current user.
-                assertThat(mUserManager.removeUserWhenPossible(testUser.getUserHandle(),
-                        /* overrideDevicePolicy= */ false))
-                        .isEqualTo(UserManager.REMOVE_RESULT_DEFERRED);
+        switchUserThenRun(startUser, () -> {
+            // While the switch is happening, call removeUserWhenPossible for the current user.
+            assertThat(mUserManager.removeUserWhenPossible(testUser.getUserHandle(),
+                    /* overrideDevicePolicy= */ false))
+                    .isEqualTo(UserManager.REMOVE_RESULT_DEFERRED);
 
-                assertThat(hasUser(testUser.id)).isTrue();
-                assertThat(getUser(testUser.id).isEphemeral()).isTrue();
-            }); // wait for user switch - startUser
-            // User will be removed once switch is complete
-        }, testUser.id); // wait for user removal
+            assertThat(hasUser(testUser.id)).isTrue();
+            assertThat(getUser(testUser.id).isEphemeral()).isTrue();
+        }); // wait for user switch - startUser
+        // User will be removed once switch is complete
+        waitForUserRemoval(testUser.id);
 
         assertThat(hasUser(testUser.id)).isFalse();
     }
@@ -511,11 +517,10 @@
             assertThat(getUser(testUser.id).isEphemeral()).isTrue();
         }); // wait for user switch - testUser
 
-        runThenWaitForUserRemoval(() -> {
-            // Switch back to the starting user.
-            switchUser(startUser);
-            // User will be removed once switch is complete
-        }, testUser.id); // wait for user removal
+        // Switch back to the starting user.
+        switchUser(startUser);
+        // User will be removed once switch is complete
+        waitForUserRemoval(testUser.id);
 
         assertThat(hasUser(testUser.id)).isFalse();
     }
@@ -525,11 +530,10 @@
     public void testRemoveUserWhenPossible_nonCurrentUserRemoved() throws Exception {
         final UserInfo user1 = createUser("User 1", /* flags= */ 0);
 
-        runThenWaitForUserRemoval(() -> {
-            assertThat(mUserManager.removeUserWhenPossible(user1.getUserHandle(),
-                    /* overrideDevicePolicy= */ false))
-                    .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
-        }, user1.id); // wait for user removal
+        assertThat(mUserManager.removeUserWhenPossible(user1.getUserHandle(),
+                /* overrideDevicePolicy= */ false))
+                .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
+        waitForUserRemoval(user1.id);
 
         assertThat(hasUser(user1.id)).isFalse();
     }
@@ -548,11 +552,10 @@
                 UserManager.USER_TYPE_PROFILE_MANAGED,
                 parentUser.id);
 
-        runThenWaitForUserRemoval(() -> {
-            assertThat(mUserManager.removeUserWhenPossible(parentUser.getUserHandle(),
-                    /* overrideDevicePolicy= */ false))
-                    .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
-        }, parentUser.id); // wait for user removal
+        assertThat(mUserManager.removeUserWhenPossible(parentUser.getUserHandle(),
+                /* overrideDevicePolicy= */ false))
+                .isEqualTo(UserManager.REMOVE_RESULT_REMOVED);
+        waitForUserRemoval(parentUser.id);
 
         assertThat(hasUser(parentUser.id)).isFalse();
         assertThat(hasUser(cloneProfileUser.id)).isFalse();
@@ -1119,7 +1122,7 @@
 
     @Nullable
     private UserInfo getUser(int id) {
-        List<UserInfo> list = mUserManager.getUsers();
+        List<UserInfo> list = mUserManager.getAliveUsers();
 
         for (UserInfo user : list) {
             if (user.id == id) {
@@ -1274,7 +1277,7 @@
     @MediumTest
     @Test
     public void testConcurrentUserCreate() throws Exception {
-        int userCount = mUserManager.getUserCount();
+        int userCount = mUserManager.getAliveUsers().size();
         int maxSupportedUsers = UserManager.getMaxSupportedUsers();
         int canBeCreatedCount = maxSupportedUsers - userCount;
         // Test exceeding the limit while running in parallel
@@ -1292,8 +1295,12 @@
             });
         }
         es.shutdown();
-        es.awaitTermination(20, TimeUnit.SECONDS);
-        assertThat(mUserManager.getUserCount()).isEqualTo(maxSupportedUsers);
+        int timeout = createUsersCount * 20;
+        assertWithMessage(
+                "Could not create " + createUsersCount + " users in " + timeout + " seconds")
+                .that(es.awaitTermination(timeout, TimeUnit.SECONDS))
+                .isTrue();
+        assertThat(mUserManager.getAliveUsers().size()).isEqualTo(maxSupportedUsers);
         assertThat(created.get()).isEqualTo(canBeCreatedCount);
     }
 
@@ -1450,34 +1457,18 @@
     }
 
     private void removeUser(UserHandle userHandle) {
-        runThenWaitForUserRemoval(
-                () -> mUserManager.removeUser(userHandle),
-                userHandle == null ? UserHandle.USER_NULL : userHandle.getIdentifier()
-        );
+        mUserManager.removeUser(userHandle);
+        waitForUserRemoval(userHandle.getIdentifier());
     }
 
     private void removeUser(int userId) {
-        runThenWaitForUserRemoval(
-                () -> mUserManager.removeUser(userId),
-                userId
-        );
+        mUserManager.removeUser(userId);
+        waitForUserRemoval(userId);
     }
 
-    private void runThenWaitForUserRemoval(Runnable runnable, int userIdToWaitUntilDeleted) {
-        Function<Intent, Boolean> checker = intent -> {
-            UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class);
-            return userHandle != null && userHandle.getIdentifier() == userIdToWaitUntilDeleted;
-        };
-
-        BlockingBroadcastReceiver blockingBroadcastReceiver = BlockingBroadcastReceiver.create(
-                mContext, Intent.ACTION_USER_REMOVED, checker);
-
-        blockingBroadcastReceiver.register();
-
-        try (blockingBroadcastReceiver) {
-            runnable.run();
-        }
-        mUsersToRemove.remove(userIdToWaitUntilDeleted);
+    private void waitForUserRemoval(int userId) {
+        mUserRemovalWaiter.waitFor(userId);
+        mUsersToRemove.remove(userId);
     }
 
     private UserInfo createUser(String name, int flags) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRemovalWaiter.java b/services/tests/servicestests/src/com/android/server/pm/UserRemovalWaiter.java
new file mode 100644
index 0000000..9e1af0c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRemovalWaiter.java
@@ -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.server.pm;
+
+import static org.junit.Assert.fail;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class UserRemovalWaiter extends BroadcastReceiver implements Closeable {
+
+    private final Context mContext;
+    private final UserManager mUserManager;
+    private final String mTag;
+    private final long mTimeoutMillis;
+    private final Map<Integer, CountDownLatch> mMap = new ConcurrentHashMap<>();
+
+    private CountDownLatch getLatch(final int userId) {
+        return mMap.computeIfAbsent(userId, absentKey -> new CountDownLatch(1));
+    }
+
+    public UserRemovalWaiter(Context context, String tag, int timeoutInSeconds) {
+        mContext = context;
+        mUserManager = UserManager.get(mContext);
+        mTag = tag;
+        mTimeoutMillis = timeoutInSeconds * 1000L;
+
+        mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_USER_REMOVED));
+    }
+
+    @Override
+    public void close() throws IOException {
+        mContext.unregisterReceiver(this);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+            Log.i(mTag, "ACTION_USER_REMOVED received for user " + userId);
+            getLatch(userId).countDown();
+        }
+    }
+
+    /**
+     * Waits for the removal of the given user, or fails if it times out.
+     */
+    public void waitFor(int userId) {
+        Log.i(mTag, "Waiting for user " + userId + " to be removed");
+        CountDownLatch latch = getLatch(userId);
+        long startTime = System.currentTimeMillis();
+        while (System.currentTimeMillis() - startTime < mTimeoutMillis) {
+            if (hasUserGone(userId) || waitLatchForOneSecond(latch)) {
+                Log.i(mTag, "User " + userId + " is removed in "
+                        + (System.currentTimeMillis() - startTime) + " ms");
+                return;
+            }
+        }
+        fail("Timeout waiting for user removal. userId = " + userId);
+    }
+
+    private boolean hasUserGone(int userId) {
+        return mUserManager.getAliveUsers().stream().noneMatch(x -> x.id == userId);
+    }
+
+    private boolean waitLatchForOneSecond(CountDownLatch latch) {
+        try {
+            return latch.await(1, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            Log.e(mTag, "Thread interrupted unexpectedly.", e);
+            return false;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java b/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java
index 00a7944..6553ea9 100644
--- a/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/LowPowerStandbyControllerTest.java
@@ -16,8 +16,14 @@
 
 package com.android.server.power;
 
+import static android.os.PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION;
+import static android.os.PowerManager.LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -27,20 +33,29 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.net.Uri;
 import android.os.IPowerManager;
 import android.os.PowerManager;
+import android.os.PowerManager.LowPowerStandbyPolicy;
 import android.os.PowerManagerInternal;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.test.mock.MockContentResolver;
+import android.util.ArraySet;
 
 import androidx.test.InstrumentationRegistry;
 
@@ -48,6 +63,7 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.power.LowPowerStandbyController.DeviceConfigWrapper;
 import com.android.server.testutils.OffsettableClock;
 
 import org.junit.After;
@@ -58,6 +74,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -68,35 +87,53 @@
  */
 public class LowPowerStandbyControllerTest {
     private static final int STANDBY_TIMEOUT = 5000;
+    private static final String TEST_PKG1 = "PKG1";
+    private static final String TEST_PKG2 = "PKG2";
+    private static final int TEST_PKG1_APP_ID = 123;
+    private static final int TEST_PKG2_APP_ID = 456;
+    private static final int USER_ID_1 = 0;
+    private static final int USER_ID_2 = 10;
+    private static final LowPowerStandbyPolicy EMPTY_POLICY = new LowPowerStandbyPolicy(
+            "Test policy", Collections.emptySet(), 0, Collections.emptySet());
 
     private LowPowerStandbyController mController;
     private BroadcastInterceptingContext mContextSpy;
     private Resources mResourcesSpy;
     private OffsettableClock mClock;
     private TestLooper mTestLooper;
+    private File mTestPolicyFile;
 
     @Mock
+    private DeviceConfigWrapper mDeviceConfigWrapperMock;
+    @Mock
     private AlarmManager mAlarmManagerMock;
     @Mock
+    private PackageManager mPackageManagerMock;
+    @Mock
+    private UserManager mUserManagerMock;
+    @Mock
     private IPowerManager mIPowerManagerMock;
     @Mock
     private PowerManagerInternal mPowerManagerInternalMock;
     @Mock
-    private NetworkPolicyManagerInternal mNetworkPolicyManagerInternal;
+    private NetworkPolicyManagerInternal mNetworkPolicyManagerInternalMock;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
         mContextSpy = spy(new BroadcastInterceptingContext(InstrumentationRegistry.getContext()));
+        when(mContextSpy.getPackageManager()).thenReturn(mPackageManagerMock);
         when(mContextSpy.getSystemService(AlarmManager.class)).thenReturn(mAlarmManagerMock);
+        when(mContextSpy.getSystemService(UserManager.class)).thenReturn(mUserManagerMock);
         PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock, null, null);
         when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
         addLocalServiceMock(PowerManagerInternal.class, mPowerManagerInternalMock);
-        addLocalServiceMock(NetworkPolicyManagerInternal.class, mNetworkPolicyManagerInternal);
+        addLocalServiceMock(NetworkPolicyManagerInternal.class, mNetworkPolicyManagerInternalMock);
 
         when(mIPowerManagerMock.isInteractive()).thenReturn(true);
 
+        when(mDeviceConfigWrapperMock.enableCustomPolicy()).thenReturn(true);
         mResourcesSpy = spy(mContextSpy.getResources());
         when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
         when(mResourcesSpy.getBoolean(
@@ -114,11 +151,17 @@
         cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContextSpy.getContentResolver()).thenReturn(cr);
 
+        when(mUserManagerMock.getUserHandles(true)).thenReturn(List.of(
+                UserHandle.of(USER_ID_1), UserHandle.of(USER_ID_2)));
+        when(mPackageManagerMock.getPackageUid(eq(TEST_PKG1), any())).thenReturn(TEST_PKG1_APP_ID);
+        when(mPackageManagerMock.getPackageUid(eq(TEST_PKG2), any())).thenReturn(TEST_PKG2_APP_ID);
+
         mClock = new OffsettableClock.Stopped();
         mTestLooper = new TestLooper(mClock::now);
 
+        mTestPolicyFile = new File(mContextSpy.getCacheDir(), "lps_policy.xml");
         mController = new LowPowerStandbyController(mContextSpy, mTestLooper.getLooper(),
-                () -> mClock.now());
+                () -> mClock.now(), mDeviceConfigWrapperMock, mTestPolicyFile);
     }
 
     @After
@@ -126,6 +169,7 @@
         LocalServices.removeServiceForTest(PowerManagerInternal.class);
         LocalServices.removeServiceForTest(LowPowerStandbyControllerInternal.class);
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
+        mTestPolicyFile.delete();
     }
 
     @Test
@@ -135,7 +179,7 @@
 
         assertThat(mController.isActive()).isFalse();
         verify(mPowerManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
-        verify(mNetworkPolicyManagerInternal, never()).setLowPowerStandbyActive(anyBoolean());
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
     }
 
     @Test
@@ -148,7 +192,7 @@
         awaitStandbyTimeoutAlarm();
         assertThat(mController.isActive()).isTrue();
         verify(mPowerManagerInternalMock, times(1)).setLowPowerStandbyActive(true);
-        verify(mNetworkPolicyManagerInternal, times(1)).setLowPowerStandbyActive(true);
+        verify(mNetworkPolicyManagerInternalMock, times(1)).setLowPowerStandbyActive(true);
     }
 
     private void awaitStandbyTimeoutAlarm() {
@@ -176,7 +220,7 @@
 
         assertThat(mController.isActive()).isFalse();
         verify(mPowerManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
-        verify(mNetworkPolicyManagerInternal, never()).setLowPowerStandbyActive(anyBoolean());
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
     }
 
     @Test
@@ -190,7 +234,7 @@
 
         assertThat(mController.isActive()).isTrue();
         verify(mPowerManagerInternalMock, times(1)).setLowPowerStandbyActive(true);
-        verify(mNetworkPolicyManagerInternal, times(1)).setLowPowerStandbyActive(true);
+        verify(mNetworkPolicyManagerInternalMock, times(1)).setLowPowerStandbyActive(true);
     }
 
     @Test
@@ -206,7 +250,7 @@
 
         assertThat(mController.isActive()).isFalse();
         verify(mPowerManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
-        verify(mNetworkPolicyManagerInternal, never()).setLowPowerStandbyActive(anyBoolean());
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
     }
 
     private void verifyStandbyAlarmCancelled() {
@@ -231,7 +275,7 @@
 
         assertThat(mController.isActive()).isFalse();
         verify(mPowerManagerInternalMock, times(1)).setLowPowerStandbyActive(false);
-        verify(mNetworkPolicyManagerInternal, times(1)).setLowPowerStandbyActive(false);
+        verify(mNetworkPolicyManagerInternalMock, times(1)).setLowPowerStandbyActive(false);
     }
 
     @Test
@@ -249,7 +293,7 @@
 
         assertThat(mController.isActive()).isFalse();
         verify(mPowerManagerInternalMock, times(1)).setLowPowerStandbyActive(false);
-        verify(mNetworkPolicyManagerInternal, times(1)).setLowPowerStandbyActive(false);
+        verify(mNetworkPolicyManagerInternalMock, times(1)).setLowPowerStandbyActive(false);
     }
 
     @Test
@@ -267,7 +311,7 @@
 
         assertThat(mController.isActive()).isTrue();
         verify(mPowerManagerInternalMock, never()).setLowPowerStandbyActive(false);
-        verify(mNetworkPolicyManagerInternal, never()).setLowPowerStandbyActive(false);
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyActive(false);
     }
 
     @Test
@@ -286,7 +330,7 @@
 
         assertThat(mController.isActive()).isTrue();
         verify(mPowerManagerInternalMock, times(2)).setLowPowerStandbyActive(true);
-        verify(mNetworkPolicyManagerInternal, times(2)).setLowPowerStandbyActive(true);
+        verify(mNetworkPolicyManagerInternalMock, times(2)).setLowPowerStandbyActive(true);
     }
 
     @Test
@@ -299,7 +343,7 @@
         assertThat(mController.isActive()).isFalse();
         verify(mAlarmManagerMock, never()).setExact(anyInt(), anyLong(), anyString(), any(), any());
         verify(mPowerManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
-        verify(mNetworkPolicyManagerInternal, never()).setLowPowerStandbyActive(anyBoolean());
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyActive(anyBoolean());
     }
 
     @Test
@@ -356,24 +400,6 @@
     }
 
     @Test
-    public void testAllowlistChange_servicesAreNotified() throws Exception {
-        setLowPowerStandbySupportedConfig(true);
-        mController.systemReady();
-
-        LowPowerStandbyControllerInternal service = LocalServices.getService(
-                LowPowerStandbyControllerInternal.class);
-        service.addToAllowlist(10);
-        mTestLooper.dispatchAll();
-        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[] {10});
-        verify(mNetworkPolicyManagerInternal).setLowPowerStandbyAllowlist(new int[] {10});
-
-        service.removeFromAllowlist(10);
-        mTestLooper.dispatchAll();
-        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[] {});
-        verify(mNetworkPolicyManagerInternal).setLowPowerStandbyAllowlist(new int[] {});
-    }
-
-    @Test
     public void testForceActive() throws Exception {
         setLowPowerStandbySupportedConfig(false);
         mController.systemReady();
@@ -383,14 +409,14 @@
 
         assertThat(mController.isActive()).isTrue();
         verify(mPowerManagerInternalMock).setLowPowerStandbyActive(true);
-        verify(mNetworkPolicyManagerInternal).setLowPowerStandbyActive(true);
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyActive(true);
 
         mController.forceActive(false);
         mTestLooper.dispatchAll();
 
         assertThat(mController.isActive()).isFalse();
         verify(mPowerManagerInternalMock).setLowPowerStandbyActive(false);
-        verify(mNetworkPolicyManagerInternal).setLowPowerStandbyActive(false);
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyActive(false);
     }
 
     private void setLowPowerStandbySupportedConfig(boolean supported) {
@@ -399,6 +425,244 @@
                 .thenReturn(supported);
     }
 
+    @Test
+    public void testSetPolicy() throws Exception {
+        mController.systemReady();
+        mController.setPolicy(EMPTY_POLICY);
+        assertThat(mController.getPolicy()).isEqualTo(EMPTY_POLICY);
+    }
+
+    @Test
+    public void testSetDefaultPolicy() throws Exception {
+        mController.systemReady();
+        mController.setPolicy(EMPTY_POLICY);
+        mController.setPolicy(null);
+        assertThat(mController.getPolicy()).isNotNull();
+        assertThat(mController.getPolicy()).isEqualTo(LowPowerStandbyController.DEFAULT_POLICY);
+    }
+
+    @Test
+    public void testAddToAllowlist_ReasonIsAllowed_servicesAreNotified() throws Exception {
+        mController.systemReady();
+        mController.setPolicy(
+                policyWithAllowedReasons(LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION));
+
+        LowPowerStandbyControllerInternal service = LocalServices.getService(
+                LowPowerStandbyControllerInternal.class);
+        service.addToAllowlist(10, LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{10});
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{10});
+
+        service.removeFromAllowlist(10, LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{});
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{});
+    }
+
+    @Test
+    public void testRemoveFromAllowlist_ReasonIsAllowed_servicesAreNotified() throws Exception {
+        mController.systemReady();
+        mController.setPolicy(
+                policyWithAllowedReasons(LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION));
+
+        LowPowerStandbyControllerInternal service = LocalServices.getService(
+                LowPowerStandbyControllerInternal.class);
+        service.addToAllowlist(10, LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
+        mTestLooper.dispatchAll();
+
+        service.removeFromAllowlist(10, LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
+        mTestLooper.dispatchAll();
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{});
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{});
+    }
+
+    @Test
+    public void testSetAllowReasons_ActiveExemptionsNoLongerAllowed_servicesAreNotified() {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(
+                policyWithAllowedReasons(LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION));
+
+        LowPowerStandbyControllerInternal service = LocalServices.getService(
+                LowPowerStandbyControllerInternal.class);
+        service.addToAllowlist(10, LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
+        mTestLooper.dispatchAll();
+
+        mController.setPolicy(EMPTY_POLICY);
+        mTestLooper.dispatchAll();
+
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{});
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{});
+    }
+
+    @Test
+    public void testSetAllowReasons_ReasonBecomesAllowed_servicesAreNotified() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(EMPTY_POLICY);
+
+        LowPowerStandbyControllerInternal service = LocalServices.getService(
+                LowPowerStandbyControllerInternal.class);
+        service.addToAllowlist(10, LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
+        mTestLooper.dispatchAll();
+
+        verify(mPowerManagerInternalMock, never()).setLowPowerStandbyAllowlist(any());
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyAllowlist(any());
+
+        mController.setPolicy(
+                policyWithAllowedReasons(LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION));
+        mTestLooper.dispatchAll();
+
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{10});
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{10});
+    }
+
+    @Test
+    public void testSetAllowReasons_NoActiveExemptions_servicesAreNotNotified() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(
+                policyWithAllowedReasons(LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION));
+        mController.setPolicy(EMPTY_POLICY);
+        mTestLooper.dispatchAll();
+
+        verify(mPowerManagerInternalMock, never()).setLowPowerStandbyAllowlist(any());
+        verify(mNetworkPolicyManagerInternalMock, never()).setLowPowerStandbyAllowlist(any());
+    }
+
+    @Test
+    public void testSetAllowedFeatures_isAllowedIfDisabled() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(false);
+        mTestLooper.dispatchAll();
+
+        assertTrue(mController.isAllowed(LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN));
+    }
+
+    @Test
+    public void testSetAllowedFeatures_isAllowedWhenEnabled() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(policyWithAllowedFeatures(LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN));
+        mTestLooper.dispatchAll();
+
+        assertTrue(mController.isAllowed(LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN));
+    }
+
+    @Test
+    public void testSetAllowedFeatures_isNotAllowed() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mTestLooper.dispatchAll();
+
+        assertFalse(mController.isAllowed(LOW_POWER_STANDBY_FEATURE_WAKE_ON_LAN));
+    }
+
+    @Test
+    public void testSetExemptPackages_uidPerUserIsExempt() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(policyWithExemptPackages(TEST_PKG1, TEST_PKG2));
+        mTestLooper.dispatchAll();
+
+        int[] expectedUidAllowlist = {
+                UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID),
+                UserHandle.getUid(USER_ID_1, TEST_PKG2_APP_ID),
+                UserHandle.getUid(USER_ID_2, TEST_PKG1_APP_ID),
+                UserHandle.getUid(USER_ID_2, TEST_PKG2_APP_ID)
+        };
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(expectedUidAllowlist);
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(expectedUidAllowlist);
+    }
+
+    @Test
+    public void testExemptPackageIsRemoved_servicesAreNotified() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(policyWithExemptPackages(TEST_PKG1));
+        mTestLooper.dispatchAll();
+
+        int[] expectedUidAllowlist = {
+                UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID),
+                UserHandle.getUid(USER_ID_2, TEST_PKG1_APP_ID),
+        };
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(expectedUidAllowlist);
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(expectedUidAllowlist);
+        verifyNoMoreInteractions(mPowerManagerInternalMock, mNetworkPolicyManagerInternalMock);
+
+        reset(mPackageManagerMock);
+        when(mPackageManagerMock.getPackageUid(eq(TEST_PKG1), any()))
+                .thenThrow(PackageManager.NameNotFoundException.class);
+
+        Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+        intent.setData(Uri.fromParts(IntentFilter.SCHEME_PACKAGE, TEST_PKG1, null));
+        intent.putExtra(Intent.EXTRA_REPLACING, false);
+        mContextSpy.sendBroadcast(intent);
+        mTestLooper.dispatchAll();
+
+        verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[0]);
+        verify(mNetworkPolicyManagerInternalMock).setLowPowerStandbyAllowlist(new int[0]);
+    }
+
+    @Test
+    public void testUsersChanged_packagesExemptForNewUser() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mController.setPolicy(policyWithExemptPackages(TEST_PKG1));
+        mTestLooper.dispatchAll();
+
+        InOrder inOrder = inOrder(mPowerManagerInternalMock);
+
+        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[] {
+                UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID),
+                UserHandle.getUid(USER_ID_2, TEST_PKG1_APP_ID),
+        });
+        inOrder.verifyNoMoreInteractions();
+
+        when(mUserManagerMock.getUserHandles(true)).thenReturn(List.of(UserHandle.of(USER_ID_1)));
+        Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
+        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(USER_ID_2));
+        mContextSpy.sendBroadcast(intent);
+        mTestLooper.dispatchAll();
+
+        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[] {
+                UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID)
+        });
+        inOrder.verifyNoMoreInteractions();
+
+        when(mUserManagerMock.getUserHandles(true)).thenReturn(
+                List.of(UserHandle.of(USER_ID_1), UserHandle.of(USER_ID_2)));
+        intent = new Intent(Intent.ACTION_USER_ADDED);
+        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(USER_ID_2));
+        mContextSpy.sendBroadcast(intent);
+        mTestLooper.dispatchAll();
+
+        inOrder.verify(mPowerManagerInternalMock).setLowPowerStandbyAllowlist(new int[]{
+                UserHandle.getUid(USER_ID_1, TEST_PKG1_APP_ID),
+                UserHandle.getUid(USER_ID_2, TEST_PKG1_APP_ID)
+        });
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void testIsExempt_exemptIfDisabled() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(false);
+        mTestLooper.dispatchAll();
+
+        assertTrue(mController.isPackageExempt(TEST_PKG1_APP_ID));
+    }
+
+    @Test
+    public void testIsExempt_notExemptIfEnabled() throws Exception {
+        mController.systemReady();
+        mController.setEnabled(true);
+        mTestLooper.dispatchAll();
+
+        assertFalse(mController.isPackageExempt(TEST_PKG1_APP_ID));
+    }
+
     private void setInteractive() throws Exception {
         when(mIPowerManagerMock.isInteractive()).thenReturn(true);
         mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON));
@@ -414,6 +678,33 @@
         mContextSpy.sendBroadcast(new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
     }
 
+    private LowPowerStandbyPolicy policyWithAllowedReasons(int allowedReasons) {
+        return new LowPowerStandbyPolicy(
+                "Test policy",
+                Collections.emptySet(),
+                allowedReasons,
+                Collections.emptySet()
+        );
+    }
+
+    private LowPowerStandbyPolicy policyWithAllowedFeatures(String... allowedFeatures) {
+        return new LowPowerStandbyPolicy(
+                "Test policy",
+                Collections.emptySet(),
+                0,
+                new ArraySet<>(allowedFeatures)
+        );
+    }
+
+    private LowPowerStandbyPolicy policyWithExemptPackages(String... exemptPackages) {
+        return new LowPowerStandbyPolicy(
+                "Test policy",
+                new ArraySet<>(exemptPackages),
+                0,
+                Collections.emptySet()
+        );
+    }
+
     private void advanceTime(long timeMs) {
         mClock.fastForward(timeMs);
         mTestLooper.dispatchAll();
diff --git a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java
index cff3bf8..b27ba88 100644
--- a/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java
+++ b/services/tests/servicestests/src/com/android/server/power/stats/BatteryStatsUserLifecycleTests.java
@@ -38,7 +38,6 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -51,8 +50,8 @@
 
     private static final long POLL_INTERVAL_MS = 500;
     private static final long USER_REMOVE_TIMEOUT_MS = 5_000;
-    private static final long STOP_USER_TIMEOUT_MS = 10_000;
-    private static final long USER_UIDS_REMOVE_TIMEOUT_MS = 15_000;
+    private static final long STOP_USER_TIMEOUT_MS = 20_000;
+    private static final long USER_UIDS_REMOVE_TIMEOUT_MS = 20_000;
     private static final long BATTERYSTATS_POLLING_TIMEOUT_MS = 5_000;
 
     private static final String CPU_DATA_TAG = "cpu";
@@ -79,26 +78,29 @@
         batteryOnScreenOff();
     }
 
-    @Ignore("b/244349060")
     @Test
     public void testNoCpuDataForRemovedUser() throws Exception {
         mIam.startUserInBackground(mTestUserId);
         waitUntilTrue("No uids for started user " + mTestUserId,
                 () -> getNumberOfUidsInBatteryStats() > 0, BATTERYSTATS_POLLING_TIMEOUT_MS);
 
+        final boolean[] userStopped = new boolean[1];
         CountDownLatch stopUserLatch = new CountDownLatch(1);
         mIam.stopUser(mTestUserId, true, new IStopUserCallback.Stub() {
             @Override
             public void userStopped(int userId) throws RemoteException {
+                userStopped[0] = true;
                 stopUserLatch.countDown();
             }
 
             @Override
             public void userStopAborted(int userId) throws RemoteException {
+                stopUserLatch.countDown();
             }
         });
-        assertTrue("User " + mTestUserId + " could not be stopped",
+        assertTrue("User " + mTestUserId + " could not be stopped in " + STOP_USER_TIMEOUT_MS,
                 stopUserLatch.await(STOP_USER_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        assertTrue("User " + mTestUserId + " could not be stopped", userStopped[0]);
 
         mUm.removeUser(mTestUserId);
         waitUntilTrue("Unable to remove user " + mTestUserId, () -> {
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
index 2ac8b37..6edef75 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -263,7 +263,8 @@
     public void vibrateIfAvailable_withNoInputDevice_returnsFalse() {
         assertFalse(mInputDeviceDelegate.isAvailable());
         assertFalse(mInputDeviceDelegate.vibrateIfAvailable(
-                UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
+                new Vibration.CallerInfo(VIBRATION_ATTRIBUTES, UID, -1, PACKAGE_NAME, REASON),
+                SYNCED_EFFECT));
     }
 
     @Test
@@ -277,7 +278,8 @@
         mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
 
         assertTrue(mInputDeviceDelegate.vibrateIfAvailable(
-                UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
+                new Vibration.CallerInfo(VIBRATION_ATTRIBUTES, UID, -1, PACKAGE_NAME, REASON),
+                SYNCED_EFFECT));
         verify(mIInputManagerMock).vibrateCombined(eq(1), same(SYNCED_EFFECT), any());
         verify(mIInputManagerMock).vibrateCombined(eq(2), same(SYNCED_EFFECT), any());
     }
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index 508e7b0f..d50aca9 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -564,17 +564,17 @@
 
         for (int usage : ALL_USAGES) {
             // Non-system vibration
-            assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                    UID, "some.app", usage, vibrateStartTime));
+            assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(createCallerInfo(
+                    UID, "some.app", usage), vibrateStartTime));
             // Vibration with UID zero
             assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                    /* uid= */ 0, "", usage, vibrateStartTime));
+                    createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
             // System vibration
             assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                    Process.SYSTEM_UID, "", usage, vibrateStartTime));
+                    createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
             // SysUI vibration
             assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                    UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
+                    createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
         }
     }
 
@@ -592,16 +592,16 @@
             for (int usage : ALL_USAGES) {
                 // Non-system vibration
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        UID, "some.app", usage, vibrateStartTime));
+                        createCallerInfo(UID, "some.app", usage), vibrateStartTime));
                 // Vibration with UID zero
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        /* uid= */ 0, "", usage, vibrateStartTime));
+                        createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
                 // System vibration
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        Process.SYSTEM_UID, "", usage, vibrateStartTime));
+                        createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
                 // SysUI vibration
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
+                        createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
             }
         }
     }
@@ -613,7 +613,7 @@
 
         for (int usage : ALL_USAGES) {
             assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                    UID, "some.app", usage, vibrateStartTime));
+                    createCallerInfo(UID, "some.app", usage), vibrateStartTime));
         }
     }
 
@@ -626,10 +626,10 @@
             if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
                     || usage == USAGE_PHYSICAL_EMULATION) {
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        /* uid= */ 0, "", usage, vibrateStartTime));
+                        createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
             } else {
                 assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        /* uid= */ 0, "", usage, vibrateStartTime));
+                        createCallerInfo(/* uid= */ 0, "", usage), vibrateStartTime));
             }
         }
     }
@@ -643,10 +643,10 @@
             if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
                     || usage == USAGE_PHYSICAL_EMULATION) {
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        Process.SYSTEM_UID, "", usage, vibrateStartTime));
+                        createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
             } else {
                 assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        Process.SYSTEM_UID, "", usage, vibrateStartTime));
+                        createCallerInfo(Process.SYSTEM_UID, "", usage), vibrateStartTime));
             }
         }
     }
@@ -660,10 +660,10 @@
             if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
                     || usage == USAGE_PHYSICAL_EMULATION) {
                 assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
+                        createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
             } else {
                 assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
-                        UID, SYSUI_PACKAGE_NAME, usage, vibrateStartTime));
+                        createCallerInfo(UID, SYSUI_PACKAGE_NAME, usage), vibrateStartTime));
             }
         }
     }
@@ -755,10 +755,10 @@
 
     private void assertVibrationIgnoredForUsageAndDisplay(@VibrationAttributes.Usage int usage,
             int displayId, Vibration.Status expectedStatus) {
-        assertEquals(errorMessageForUsage(usage),
-                expectedStatus,
-                mVibrationSettings.shouldIgnoreVibration(UID, displayId,
-                        VibrationAttributes.createForUsage(usage)));
+        Vibration.CallerInfo callerInfo = new Vibration.CallerInfo(
+                VibrationAttributes.createForUsage(usage), UID, displayId, null, null);
+        assertEquals(errorMessageForUsage(usage), expectedStatus,
+                mVibrationSettings.shouldIgnoreVibration(callerInfo));
     }
 
     private void assertVibrationNotIgnoredForUsage(@VibrationAttributes.Usage int usage) {
@@ -767,24 +767,22 @@
 
     private void assertVibrationNotIgnoredForUsageAndFlags(@VibrationAttributes.Usage int usage,
             @VibrationAttributes.Flag int flags) {
-        assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(usage, Display.DEFAULT_DISPLAY, flags);
+        assertVibrationNotIgnoredForUsageAndFlagsAndDisplay(usage, Display.DEFAULT_DISPLAY, flags);
     }
 
     private void assertVibrationNotIgnoredForUsageAndDisplay(@VibrationAttributes.Usage int usage,
             int displayId) {
-        assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(usage, displayId, /* flags= */ 0);
+        assertVibrationNotIgnoredForUsageAndFlagsAndDisplay(usage, displayId, /* flags= */ 0);
     }
 
-    private void assertVibrationNotIgnoredForUsageAndFlagsAndDidsplay(
+    private void assertVibrationNotIgnoredForUsageAndFlagsAndDisplay(
             @VibrationAttributes.Usage int usage, int displayId,
             @VibrationAttributes.Flag int flags) {
+        Vibration.CallerInfo callerInfo = new Vibration.CallerInfo(
+                new VibrationAttributes.Builder().setUsage(usage).setFlags(flags).build(), UID,
+                displayId, null, null);
         assertNull(errorMessageForUsage(usage),
-                mVibrationSettings.shouldIgnoreVibration(UID,
-                        displayId,
-                        new VibrationAttributes.Builder()
-                                .setUsage(usage)
-                                .setFlags(flags)
-                                .build()));
+                mVibrationSettings.shouldIgnoreVibration(callerInfo));
     }
 
 
@@ -826,4 +824,10 @@
         when(mPowerManagerInternalMock.getLastGoToSleep()).thenReturn(
                 new PowerManager.SleepData(sleepTime, reason));
     }
+
+    private Vibration.CallerInfo createCallerInfo(int uid, String opPkg,
+            @VibrationAttributes.Usage int usage) {
+        VibrationAttributes attrs = VibrationAttributes.createForUsage(usage);
+        return new Vibration.CallerInfo(attrs, uid, VIRTUAL_DISPLAY_ID, opPkg, null);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index 9facb4b..12810bb 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -154,10 +154,10 @@
     @Test
     public void vibrate_noVibrator_ignoresVibration() {
         mVibratorProviders.clear();
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
@@ -166,12 +166,12 @@
 
     @Test
     public void vibrate_missingVibrators_ignoresVibration() {
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startSequential()
                 .addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
@@ -182,9 +182,9 @@
     public void vibrate_singleVibratorOneShot_runsVibrationAndSetsAmplitude() throws Exception {
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
@@ -201,9 +201,9 @@
     @Test
     public void vibrate_oneShotWithoutAmplitudeControl_runsVibrationWithDefaultAmplitude()
             throws Exception {
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
@@ -222,10 +222,10 @@
             throws Exception {
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{5, 5, 5}, new int[]{1, 2, 3}, -1);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(15L));
@@ -246,10 +246,10 @@
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
         fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         int[] amplitudes = new int[]{1, 2, 3};
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5, 5, 5}, amplitudes, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(
                 waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
@@ -259,8 +259,9 @@
         assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
 
         Vibration.EndInfo cancelVibrationInfo = new Vibration.EndInfo(
-                Vibration.Status.CANCELLED_SUPERSEDED, /* endedByUid= */ 1,
-                /* endedByUsage= */ VibrationAttributes.USAGE_ALARM);
+                Vibration.Status.CANCELLED_SUPERSEDED, new Vibration.CallerInfo(
+                VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ALARM), /* uid= */
+                1, /* displayId= */ -1, /* opPkg= */ null, /* reason= */ null));
         conductor.notifyCancelled(
                 cancelVibrationInfo,
                 /* immediate= */ false);
@@ -287,11 +288,11 @@
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
         fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         int[] amplitudes = new int[]{1, 2, 3};
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{1, 10, 100}, amplitudes, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
         conductor.notifyCancelled(
@@ -315,7 +316,6 @@
         fakeVibrator.setMaxAmplitudes(1, 1, 1);
         fakeVibrator.setPwleSizeMax(10);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
                 // Very long segment so thread will be cancelled after first PWLE is triggered.
                 .addTransition(Duration.ofMillis(100), targetFrequency(100))
@@ -323,7 +323,8 @@
         VibrationEffect repeatingEffect = VibrationEffect.startComposition()
                 .repeatEffectIndefinitely(effect)
                 .compose();
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, repeatingEffect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(repeatingEffect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
                 TEST_TIMEOUT_MILLIS));
@@ -346,7 +347,6 @@
         fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK);
         fakeVibrator.setCompositionSizeMax(10);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 // Very long delay so thread will be cancelled after first PWLE is triggered.
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
@@ -354,7 +354,8 @@
         VibrationEffect repeatingEffect = VibrationEffect.startComposition()
                 .repeatEffectIndefinitely(effect)
                 .compose();
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, repeatingEffect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(repeatingEffect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
                 TEST_TIMEOUT_MILLIS));
@@ -375,11 +376,11 @@
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
         fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         int[] amplitudes = new int[]{1, 2, 3};
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{5000, 500, 50}, amplitudes, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
         conductor.notifyCancelled(
@@ -400,11 +401,11 @@
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
         fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         int[] amplitudes = new int[]{1, 2};
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{4900, 50}, amplitudes, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibrationId).size() > 1,
                 5000 + TEST_TIMEOUT_MILLIS));
@@ -433,13 +434,13 @@
         mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
                 VibrationEffect.Composition.PRIMITIVE_CLICK);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                 .compose();
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
@@ -466,9 +467,9 @@
             throws Exception {
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{100}, new int[]{100}, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
@@ -494,9 +495,9 @@
     public void vibrate_singleVibratorPrebaked_runsVibration() throws Exception {
         mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_THUD);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_THUD);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
@@ -514,12 +515,12 @@
             throws Exception {
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
-        HalVibration vibration = createVibration(vibrationId, CombinedVibration.createParallel(
+        HalVibration vibration = createVibration(CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
         vibration.addFallback(VibrationEffect.EFFECT_CLICK, fallback);
-        startThreadAndDispatcher(vibration);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibration);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
@@ -536,9 +537,9 @@
     @Test
     public void vibrate_singleVibratorPrebakedAndUnsupportedEffect_ignoresVibration()
             throws Exception {
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L));
@@ -555,12 +556,12 @@
         fakeVibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK,
                 VibrationEffect.Composition.PRIMITIVE_TICK);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(40L));
@@ -576,11 +577,11 @@
 
     @Test
     public void vibrate_singleVibratorComposedAndNoCapability_ignoresVibration() {
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .compose();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L));
@@ -600,13 +601,13 @@
                 VibrationEffect.Composition.PRIMITIVE_SPIN);
         fakeVibrator.setCompositionSizeMax(2);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.8f)
                 .compose();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
@@ -630,7 +631,6 @@
         fakeVibrator.setMaxAmplitudes(
                 0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addEffect(VibrationEffect.createOneShot(10, 100))
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
@@ -643,7 +643,8 @@
                         .build())
                 .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .compose();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         // Use first duration the vibrator is turned on since we cannot estimate the clicks.
@@ -675,7 +676,6 @@
                 VibrationEffect.Composition.PRIMITIVE_TICK);
         fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
 
-        long vibrationId = 1;
         VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
@@ -683,9 +683,10 @@
                 .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose();
-        HalVibration vib = createVibration(vibrationId, CombinedVibration.createParallel(effect));
+        HalVibration vib = createVibration(CombinedVibration.createParallel(effect));
         vib.addFallback(VibrationEffect.EFFECT_TICK, fallback);
-        startThreadAndDispatcher(vib);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vib);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         // Use first duration the vibrator is turned on since we cannot estimate the clicks.
@@ -718,7 +719,6 @@
         fakeVibrator.setMaxAmplitudes(
                 0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
                 .addSustain(Duration.ofMillis(10))
                 .addTransition(Duration.ofMillis(20), targetAmplitude(0))
@@ -726,7 +726,8 @@
                 .addSustain(Duration.ofMillis(30))
                 .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
                 .build();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(100L));
@@ -756,7 +757,6 @@
         fakeVibrator.setMaxAmplitudes(1, 1, 1);
         fakeVibrator.setPwleSizeMax(3);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
                 .addSustain(Duration.ofMillis(10))
                 .addTransition(Duration.ofMillis(20), targetAmplitude(0))
@@ -768,7 +768,8 @@
                 .addTransition(Duration.ofMillis(40), targetAmplitude(0.7f), targetFrequency(200))
                 .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
                 .build();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
@@ -784,9 +785,9 @@
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
         fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2, TEST_TIMEOUT_MILLIS));
         // Vibration still running after 2 cycles.
@@ -804,9 +805,9 @@
     public void vibrate_singleVibrator_skipsSyncedCallbacks() {
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
-        startThreadAndDispatcher(vibrationId,
+        VibrationStepConductor conductor = startThreadAndDispatcher(
                 VibrationEffect.createOneShot(10, 100));
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
@@ -820,12 +821,12 @@
             throws Exception {
         mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_TICK);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startParallel()
                 .addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
@@ -846,10 +847,10 @@
         mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
         mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
@@ -881,7 +882,6 @@
         mVibratorProviders.get(4).setSupportedPrimitives(
                 VibrationEffect.Composition.PRIMITIVE_CLICK);
 
-        long vibrationId = 1;
         VibrationEffect composed = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
                 .compose();
@@ -892,7 +892,8 @@
                         new long[]{10, 10}, new int[]{1, 2}, -1))
                 .addVibrator(4, composed)
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
@@ -929,7 +930,6 @@
                 VibrationEffect.Composition.PRIMITIVE_CLICK);
         mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
 
-        long vibrationId = 1;
         VibrationEffect composed = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
                 .compose();
@@ -938,7 +938,8 @@
                 .addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
                 .addNext(2, composed, /* delay= */ 50)
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         waitForCompletion();
         InOrder controllerVerifier = inOrder(mControllerCallbacks);
@@ -972,7 +973,6 @@
     @Test
     public void vibrate_multipleSyncedCallbackTriggered_finishSteps() throws Exception {
         int[] vibratorIds = new int[]{1, 2};
-        long vibrationId = 1;
         mockVibrators(vibratorIds);
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
         mVibratorProviders.get(1).setSupportedPrimitives(
@@ -981,13 +981,15 @@
         mVibratorProviders.get(2).setSupportedPrimitives(
                 VibrationEffect.Composition.PRIMITIVE_CLICK);
         when(mManagerHooks.prepareSyncedVibration(anyLong(), eq(vibratorIds))).thenReturn(true);
-        when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
 
         VibrationEffect composed = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
                 .compose();
         CombinedVibration effect = CombinedVibration.createParallel(composed);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
+
+        when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
 
         assertTrue(waitUntil(
                 () -> !mVibratorProviders.get(1).getEffectSegments(vibrationId).isEmpty()
@@ -1021,7 +1023,6 @@
         when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
         when(mManagerHooks.triggerSyncedVibration(anyLong())).thenReturn(true);
 
-        long vibrationId = 1;
         VibrationEffect composed = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
                 .compose();
@@ -1031,7 +1032,8 @@
                 .addVibrator(3, VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1))
                 .addVibrator(4, composed)
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC
@@ -1055,12 +1057,12 @@
         mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(false);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startParallel()
                 .addVibrator(1, VibrationEffect.createOneShot(10, 100))
                 .addVibrator(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{200}, -1))
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_ON;
@@ -1084,12 +1086,12 @@
         when(mManagerHooks.prepareSyncedVibration(anyLong(), any())).thenReturn(true);
         when(mManagerHooks.triggerSyncedVibration(anyLong())).thenReturn(false);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startParallel()
                 .addVibrator(1, VibrationEffect.createOneShot(10, 100))
                 .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC
@@ -1110,7 +1112,6 @@
         mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startParallel()
                 .addVibrator(1, VibrationEffect.createWaveform(
                         new long[]{5, 10, 10}, new int[]{1, 2, 3}, -1))
@@ -1119,7 +1120,8 @@
                 .addVibrator(3, VibrationEffect.createWaveform(
                         new long[]{60}, new int[]{6}, -1))
                 .combine();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         // All vibrators are turned on in parallel.
         assertTrue(waitUntil(
@@ -1169,8 +1171,7 @@
         Arrays.fill(amplitudes, VibrationEffect.DEFAULT_AMPLITUDE);
         VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, -1);
 
-        long vibrationId = 1;
-        startThreadAndDispatcher(vibrationId, effect);
+        startThreadAndDispatcher(effect);
         long startTime = SystemClock.elapsedRealtime();
 
         waitForCompletion(totalDuration + TEST_TIMEOUT_MILLIS);
@@ -1192,9 +1193,9 @@
         long latency = 5_000; // 5s
         fakeVibrator.setOnLatency(latency);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
                 TEST_TIMEOUT_MILLIS));
@@ -1226,7 +1227,6 @@
         mVibratorProviders.get(2).setSupportedPrimitives(
                 VibrationEffect.Composition.PRIMITIVE_CLICK);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startParallel()
                 .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .addVibrator(2, VibrationEffect.startComposition()
@@ -1235,7 +1235,8 @@
                         .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                         .compose())
                 .combine();
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
@@ -1264,13 +1265,13 @@
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.startParallel()
                 .addVibrator(1, VibrationEffect.createWaveform(
                         new long[]{100, 100}, new int[]{1, 2}, 0))
                 .addVibrator(2, VibrationEffect.createOneShot(100, 100))
                 .combine();
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> mControllers.get(1).isVibrating()
                         && mControllers.get(2).isVibrating(),
@@ -1296,9 +1297,9 @@
 
     @Test
     public void vibrate_binderDied_cancelsVibration() throws Exception {
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
@@ -1320,10 +1321,10 @@
         mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{5, 5, 5}, new int[]{60, 120, 240}, -1);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
@@ -1346,9 +1347,9 @@
         mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10, 200);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
 
         // Vibration completed but vibrator not yet released.
         verify(mManagerHooks, timeout(TEST_TIMEOUT_MILLIS)).onVibrationCompleted(eq(vibrationId),
@@ -1381,9 +1382,9 @@
         mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10_000, 240);
-        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
         conductor.notifyCancelled(
@@ -1410,9 +1411,9 @@
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
@@ -1432,11 +1433,11 @@
         mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
                 VibrationEffect.Composition.PRIMITIVE_CLICK);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
                 .compose();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
@@ -1461,11 +1462,11 @@
         fakeVibrator.setMaxAmplitudes(1, 1, 1);
         fakeVibrator.setPwleSizeMax(2);
 
-        long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.startWaveform()
                 .addTransition(Duration.ofMillis(1), targetAmplitude(1))
                 .build();
-        startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(effect);
+        long vibrationId = conductor.getVibration().id;
         waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
@@ -1485,12 +1486,6 @@
         mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL,
                 IVibrator.CAP_COMPOSE_EFFECTS);
 
-        long vibrationId1 = 1;
-        long vibrationId2 = 2;
-        long vibrationId3 = 3;
-        long vibrationId4 = 4;
-        long vibrationId5 = 5;
-
         // A simple effect, followed by a repeating effect that gets cancelled, followed by another
         // simple effect.
         VibrationEffect effect1 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
@@ -1503,12 +1498,14 @@
         VibrationEffect effect4 = VibrationEffect.createOneShot(8000, 100);
         VibrationEffect effect5 = VibrationEffect.createOneShot(20, 222);
 
-        startThreadAndDispatcher(vibrationId1, effect1);
+        VibrationStepConductor conductor1 = startThreadAndDispatcher(effect1);
+        long vibrationId1 = conductor1.getVibration().id;
         waitForCompletion();
         verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibrationId1);
         verifyCallbacksTriggered(vibrationId1, Vibration.Status.FINISHED);
 
-        VibrationStepConductor conductor2 = startThreadAndDispatcher(vibrationId2, effect2);
+        VibrationStepConductor conductor2 = startThreadAndDispatcher(effect2);
+        long vibrationId2 = conductor2.getVibration().id;
         // Effect2 won't complete on its own. Cancel it after a couple of repeats.
         Thread.sleep(150);  // More than two TICKs.
         conductor2.notifyCancelled(
@@ -1516,12 +1513,14 @@
                 /* immediate= */ false);
         waitForCompletion();
 
-        startThreadAndDispatcher(vibrationId3, effect3);
+        VibrationStepConductor conductor3 = startThreadAndDispatcher(effect3);
+        long vibrationId3 = conductor3.getVibration().id;
         waitForCompletion();
 
         // Effect4 is a long oneshot, but it gets cancelled as fast as possible.
         long start4 = System.currentTimeMillis();
-        VibrationStepConductor conductor4 = startThreadAndDispatcher(vibrationId4, effect4);
+        VibrationStepConductor conductor4 = startThreadAndDispatcher(effect4);
+        long vibrationId4 = conductor4.getVibration().id;
         conductor4.notifyCancelled(
                 new Vibration.EndInfo(Vibration.Status.CANCELLED_BY_SCREEN_OFF),
                 /* immediate= */ true);
@@ -1529,7 +1528,8 @@
         long duration4 = System.currentTimeMillis() - start4;
 
         // Effect5 is to show that things keep going after the immediate cancel.
-        startThreadAndDispatcher(vibrationId5, effect5);
+        VibrationStepConductor conductor5 = startThreadAndDispatcher(effect5);
+        long vibrationId5 = conductor5.getVibration().id;
         waitForCompletion();
 
         FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
@@ -1582,14 +1582,12 @@
         }
     }
 
-    private VibrationStepConductor startThreadAndDispatcher(
-            long vibrationId, VibrationEffect effect) {
-        return startThreadAndDispatcher(vibrationId, CombinedVibration.createParallel(effect));
+    private VibrationStepConductor startThreadAndDispatcher(VibrationEffect effect) {
+        return startThreadAndDispatcher(CombinedVibration.createParallel(effect));
     }
 
-    private VibrationStepConductor startThreadAndDispatcher(long vibrationId,
-            CombinedVibration effect) {
-        return startThreadAndDispatcher(createVibration(vibrationId, effect));
+    private VibrationStepConductor startThreadAndDispatcher(CombinedVibration effect) {
+        return startThreadAndDispatcher(createVibration(effect));
     }
 
     private VibrationStepConductor startThreadAndDispatcher(HalVibration vib) {
@@ -1624,9 +1622,9 @@
         mTestLooper.dispatchAll();  // Flush callbacks
     }
 
-    private HalVibration createVibration(long id, CombinedVibration effect) {
-        return new HalVibration(mVibrationToken, (int) id, effect, ATTRS, UID, DISPLAY_ID,
-                PACKAGE_NAME, "reason");
+    private HalVibration createVibration(CombinedVibration effect) {
+        return new HalVibration(mVibrationToken, effect,
+                new Vibration.CallerInfo(ATTRS, UID, DISPLAY_ID, PACKAGE_NAME, "reason"));
     }
 
     private SparseArray<VibratorController> createVibratorControllers() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 08c2c6e..9742384 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -1870,6 +1870,65 @@
         verifyVibrate(1);
     }
 
+    @Test
+    public void testStartFlashNotificationEvent_receiveBeepyNotification() throws Exception {
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyBeepUnlooped();
+        verifyNeverVibrate();
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+                eq(r.getSbn().getPackageName()));
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBuzzyNotification() throws Exception {
+        NotificationRecord r = getBuzzyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        verifyVibrate();
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+                eq(r.getSbn().getPackageName()));
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBuzzyBeepyNotification() throws Exception {
+        NotificationRecord r = getBuzzyBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyBeepUnlooped();
+        verifyDelayedVibrate(r.getVibration());
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+                eq(r.getSbn().getPackageName()));
+        assertTrue(r.isInterruptive());
+        assertNotEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
+    @Test
+    public void testStartFlashNotificationEvent_receiveBuzzyBeepyNotification_ringerModeSilent()
+            throws Exception {
+        NotificationRecord r = getBuzzyBeepyNotification();
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        verifyNeverVibrate();
+        verify(mAccessibilityService).startFlashNotificationEvent(any(), anyInt(),
+                eq(r.getSbn().getPackageName()));
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 8a99c2c..2f7a5f4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -194,7 +194,8 @@
                 tweak.getConversationShortcutInfo(),
                 tweak.getRankingAdjustment(),
                 tweak.isBubble(),
-                tweak.getProposedImportance()
+                tweak.getProposedImportance(),
+                tweak.hasSensitiveContent()
         );
         assertNotEquals(nru, nru2);
     }
@@ -276,7 +277,8 @@
                     getShortcutInfo(i),
                     getRankingAdjustment(i),
                     isBubble(i),
-                    getProposedImportance(i)
+                    getProposedImportance(i),
+                    hasSensitiveContent(i)
             );
             rankings[i] = ranking;
         }
@@ -408,6 +410,10 @@
         return index % 5 - 1;
     }
 
+    private boolean hasSensitiveContent(int index) {
+        return index % 3 == 0;
+    }
+
     private boolean isBubble(int index) {
         return index % 4 == 0;
     }
@@ -450,6 +456,7 @@
                 b.getConversationShortcutInfo().getId());
         assertActionsEqual(a.getSmartActions(), b.getSmartActions());
         assertEquals(a.getProposedImportance(), b.getProposedImportance());
+        assertEquals(a.hasSensitiveContent(), b.hasSensitiveContent());
     }
 
     private void detailedAssertEquals(RankingMap a, RankingMap b) {
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 23587c9..69fccf2 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.app.Notification.EXTRA_ALLOW_DURING_SETUP;
 import static android.app.Notification.FLAG_AUTO_CANCEL;
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_CAN_COLORIZE;
@@ -71,6 +72,7 @@
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.ALLOW_DISMISS_ONGOING;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -78,6 +80,7 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
@@ -200,6 +203,7 @@
 
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
 import com.android.internal.logging.InstanceIdSequence;
 import com.android.internal.logging.InstanceIdSequenceFake;
 import com.android.internal.messages.nano.SystemMessageProto;
@@ -315,6 +319,8 @@
     private Looper mMainLooper;
     @Mock
     private NotificationManager mMockNm;
+    @Mock
+    private DevicePolicyManagerInternal mDevicePolicyManager;
 
     @Mock
     IIntentSender pi1;
@@ -370,6 +376,9 @@
     BroadcastReceiver mPackageIntentReceiver;
     NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
     TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker;
+
+    TestFlagResolver mTestFlagResolver = new TestFlagResolver();
+
     private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
             1 << 30);
     @Mock
@@ -514,11 +523,11 @@
         mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient,
                 mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
                 mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
-                mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
+                mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal,
                 mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager,
                 mock(TelephonyManager.class),
                 mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class),
-                mTelecomManager, mLogger);
+                mTelecomManager, mLogger, mTestFlagResolver);
         // Return first true for RoleObserver main-thread check
         when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
@@ -1591,6 +1600,8 @@
 
     @Test
     public void testEnqueueNotificationWithTag_FgsAddsFlags_dismissalAllowed() throws Exception {
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
                 SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED,
@@ -1619,6 +1630,8 @@
 
     @Test
     public void testEnqueueNotificationWithTag_FGSaddsFlags_dismissalNotAllowed() throws Exception {
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_GRANTED);
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_SYSTEMUI,
                 SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED,
@@ -4208,8 +4221,35 @@
     }
 
     @Test
+    public void testNoNotificationDuringSetupPermission() throws Exception {
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.NOTIFICATION_DURING_SETUP, PERMISSION_GRANTED);
+        Bundle extras = new Bundle();
+        extras.putBoolean(EXTRA_ALLOW_DURING_SETUP, true);
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .addExtras(extras)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+                "testNoNotificationDuringSetupPermission", mUid, 0,
+                nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+        waitForIdle();
+
+        NotificationRecord posted = mService.findNotificationLocked(
+                PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+
+        assertTrue(posted.getNotification().extras.containsKey(EXTRA_ALLOW_DURING_SETUP));
+    }
+
+    @Test
     public void testNoFakeColorizedPermission() throws Exception {
-        when(mPackageManagerClient.checkPermission(any(), any())).thenReturn(PERMISSION_DENIED);
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS, PERMISSION_DENIED);
         Notification.Builder nb = new Notification.Builder(mContext,
                 mTestNotificationChannel.getId())
                 .setContentTitle("foo")
@@ -4234,9 +4274,8 @@
     @Test
     public void testMediaStyleRemote_hasPermission() throws RemoteException {
         String deviceName = "device";
-        when(mPackageManager.checkPermission(
-                eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt()))
-                .thenReturn(PERMISSION_GRANTED);
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.MEDIA_CONTENT_CONTROL, PERMISSION_GRANTED);
         Notification.MediaStyle style = new Notification.MediaStyle();
         style.setRemotePlaybackInfo(deviceName, 0, null);
         Notification.Builder nb = new Notification.Builder(mContext,
@@ -4263,9 +4302,8 @@
     @Test
     public void testMediaStyleRemote_noPermission() throws RemoteException {
         String deviceName = "device";
-        when(mPackageManager.checkPermission(
-                eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt()))
-                .thenReturn(PERMISSION_DENIED);
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.MEDIA_CONTENT_CONTROL, PERMISSION_DENIED);
         Notification.MediaStyle style = new Notification.MediaStyle();
         style.setRemotePlaybackInfo(deviceName, 0, null);
         Notification.Builder nb = new Notification.Builder(mContext,
@@ -4291,9 +4329,8 @@
     @Test
     public void testSubstituteAppName_hasPermission() throws RemoteException {
         String subName = "Substitute Name";
-        when(mPackageManager.checkPermission(
-                eq(android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME), any(), anyInt()))
-                .thenReturn(PERMISSION_GRANTED);
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME, PERMISSION_GRANTED);
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, subName);
         Notification.Builder nb = new Notification.Builder(mContext,
@@ -4318,9 +4355,8 @@
 
     @Test
     public void testSubstituteAppName_noPermission() throws RemoteException {
-        when(mPackageManager.checkPermission(
-                eq(android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME), any(), anyInt()))
-                .thenReturn(PERMISSION_DENIED);
+        mContext.getTestablePermissions().setPermission(
+                android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME, PERMISSION_DENIED);
         Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, "Substitute Name");
         Notification.Builder nb = new Notification.Builder(mContext,
@@ -8287,7 +8323,7 @@
         assertNotNull(n.publicVersion.bigContentView);
         assertNotNull(n.publicVersion.headsUpContentView);
 
-        mService.fixNotification(n, PKG, "tag", 9, 0);
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
 
         assertNull(n.contentView);
         assertNull(n.bigContentView);
@@ -10083,4 +10119,253 @@
         mInternalService.sendReviewPermissionsNotification();
         verify(mMockNm, never()).notify(anyString(), anyInt(), any(Notification.class));
     }
+
+    @Test
+    public void fixSystemNotification_withOnGoingFlag_shouldBeNonDismissible()
+            throws Exception {
+        // Given: a notification from an app on the system partition has the flag
+        // FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(true)
+                .build();
+
+        final ApplicationInfo systemAppInfo = new ApplicationInfo();
+        systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+                .thenReturn(systemAppInfo);
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be set
+        assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixMediaNotification_withOnGoingFlag_shouldBeNonDismissible()
+            throws Exception {
+        // Given: a media notification has the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(true)
+                .setStyle(new Notification.MediaStyle()
+                        .setMediaSession(mock(MediaSession.Token.class)))
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be set
+        assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixNonExemptNotification_withOnGoingFlag_shouldBeDismissible() throws Exception {
+        // Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(true)
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should not be set
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixNonExemptNotification_withNoDismissFlag_shouldBeDismissible()
+            throws Exception {
+        // Given: a non-exempt notification has the flag FLAG_NO_DISMISS set (even though this is
+        // not allowed)
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .build();
+        n.flags |= Notification.FLAG_NO_DISMISS;
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be cleared
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixSystemNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception {
+        // Given: a notification from an app on the system partition doesn't have the flag
+        // FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(false)
+                .build();
+
+        final ApplicationInfo systemAppInfo = new ApplicationInfo();
+        systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+                .thenReturn(systemAppInfo);
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should not be set
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixSystemNotification_withoutOnGoingFlag_withNoDismissFlag_shouldBeDismissible()
+            throws Exception {
+        // Given: a notification from an app on the system partition doesn't have the flag
+        // FLAG_ONGOING_EVENT set, but has the flag FLAG_NO_DISMISS set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(false)
+                .build();
+        n.flags |= Notification.FLAG_NO_DISMISS;
+
+        final ApplicationInfo systemAppInfo = new ApplicationInfo();
+        systemAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+                .thenReturn(systemAppInfo);
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be cleared
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixMediaNotification_withoutOnGoingFlag_shouldBeDismissible() throws Exception {
+        // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(false)
+                .setStyle(new Notification.MediaStyle()
+                        .setMediaSession(mock(MediaSession.Token.class)))
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should not be set
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixMediaNotification_withoutOnGoingFlag_withNoDismissFlag_shouldBeDismissible()
+            throws Exception {
+        // Given: a media notification doesn't have the flag FLAG_ONGOING_EVENT set,
+        // but has the flag FLAG_NO_DISMISS set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(false)
+                .setStyle(new Notification.MediaStyle()
+                        .setMediaSession(mock(MediaSession.Token.class)))
+                .build();
+        n.flags |= Notification.FLAG_NO_DISMISS;
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be cleared
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixNonExempt_Notification_withoutOnGoingFlag_shouldBeDismissible()
+            throws Exception {
+        // Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(false)
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should not be set
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixOrganizationAdminNotification_withOnGoingFlag_shouldBeNonDismissible()
+            throws Exception {
+        when(mDevicePolicyManager.isActiveDeviceOwner(mUid)).thenReturn(true);
+        // Given: a notification has the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        setSystemExemptFromDismissal(false);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(true)
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be set
+        assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    @Test
+    public void fixSystemExemptAppOpNotification_withFlag_shouldBeNonDismissible()
+            throws Exception {
+        when(mAppOpsManager.checkOpNoThrow(
+                AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid,
+                PKG)).thenReturn(AppOpsManager.MODE_ALLOWED);
+        // Given: a notification has the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        setSystemExemptFromDismissal(true);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(true)
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should be set
+        assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
+
+        setSystemExemptFromDismissal(false);
+    }
+
+    @Test
+    public void fixSystemExemptAppOpNotification_withoutFlag_shouldBeNonDismissible()
+            throws Exception {
+        when(mAppOpsManager.checkOpNoThrow(
+                AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid,
+                PKG)).thenReturn(AppOpsManager.MODE_ALLOWED);
+        // Given: a notification has the flag FLAG_ONGOING_EVENT set
+        // feature flag: ALLOW_DISMISS_ONGOING is on
+        mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+        setSystemExemptFromDismissal(false);
+        Notification n = new Notification.Builder(mContext, "test")
+                .setOngoing(true)
+                .build();
+
+        // When: fix the notification with NotificationManagerService
+        mService.fixNotification(n, PKG, "tag", 9, 0, mUid);
+
+        // Then: the notification's flag FLAG_NO_DISMISS should not be set
+        assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
+    }
+
+    private void setSystemExemptFromDismissal(boolean isOn) {
+        DeviceConfig.setProperty(
+                DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
+                /* name= */ "application_exemptions",
+                String.valueOf(isOn),
+                /* makeDefault= */ false);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java
index 87e86cb..e6569f7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordExtractorDataTest.java
@@ -19,29 +19,20 @@
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 
-import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
 import android.app.Notification;
 import android.app.NotificationChannel;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.service.notification.Adjustment;
-import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 
 import com.android.server.UiServiceTestCase;
 
 import org.junit.Test;
 
-import java.util.ArrayList;
-import java.util.Objects;
-
 public class NotificationRecordExtractorDataTest extends UiServiceTestCase {
 
     @Test
@@ -65,7 +56,8 @@
                 r.getImportance(),
                 r.getRankingScore(),
                 r.isConversation(),
-                r.getProposedImportance());
+                r.getProposedImportance(),
+                r.hasSensitiveContent());
 
         assertFalse(extractorData.hasDiffForRankingLocked(r, 1));
         assertFalse(extractorData.hasDiffForLoggingLocked(r, 1));
@@ -92,7 +84,8 @@
                 r.getImportance(),
                 r.getRankingScore(),
                 r.isConversation(),
-                r.getProposedImportance());
+                r.getProposedImportance(),
+                r.hasSensitiveContent());
 
         Bundle signals = new Bundle();
         signals.putInt(Adjustment.KEY_IMPORTANCE_PROPOSAL, IMPORTANCE_HIGH);
@@ -104,6 +97,40 @@
         assertTrue(extractorData.hasDiffForLoggingLocked(r, 1));
     }
 
+    @Test
+    public void testHasDiffs_sensitiveContentChange() {
+        NotificationRecord r = generateRecord();
+
+        NotificationRecordExtractorData extractorData = new NotificationRecordExtractorData(
+                1,
+                r.getPackageVisibilityOverride(),
+                r.canShowBadge(),
+                r.canBubble(),
+                r.getNotification().isBubbleNotification(),
+                r.getChannel(),
+                r.getGroupKey(),
+                r.getPeopleOverride(),
+                r.getSnoozeCriteria(),
+                r.getUserSentiment(),
+                r.getSuppressedVisualEffects(),
+                r.getSystemGeneratedSmartActions(),
+                r.getSmartReplies(),
+                r.getImportance(),
+                r.getRankingScore(),
+                r.isConversation(),
+                r.getProposedImportance(),
+                r.hasSensitiveContent());
+
+        Bundle signals = new Bundle();
+        signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, true);
+        Adjustment adjustment = new Adjustment("pkg", r.getKey(), signals, "", 0);
+        r.addAdjustment(adjustment);
+        r.applyAdjustments();
+
+        assertTrue(extractorData.hasDiffForRankingLocked(r, 1));
+        assertTrue(extractorData.hasDiffForLoggingLocked(r, 1));
+    }
+
     private NotificationRecord generateRecord() {
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
         final Notification.Builder builder = new Notification.Builder(getContext())
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java
index 0169a7d..beab107 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerTest.java
@@ -130,4 +130,29 @@
         p.r.getSbn().getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         assertTrue(NotificationRecordLogger.isForegroundService(p.r));
     }
+
+
+    @Test
+    public void testIsNonDismissible_hasFlagNoDismiss_shouldReturnTrue() {
+        // Given: a notification pair's notification has flag FLAG_NO_DISMISS
+        NotificationRecordLogger.NotificationRecordPair p = getNotificationRecordPair(
+                0, null);
+        p.r.getNotification().flags |= Notification.FLAG_NO_DISMISS;
+
+        // When: check the value of isNonDismissible()
+        // Then: should return true
+        assertTrue(NotificationRecordLogger.isNonDismissible(p.r));
+    }
+
+    @Test
+    public void testIsNonDismissible_noFlagNoDismiss_shouldReturnFalse() {
+        // Given: a notification pair's notification doesn't have flag FLAG_NO_DISMISS
+        NotificationRecordLogger.NotificationRecordPair p = getNotificationRecordPair(
+                0, null);
+        p.r.getNotification().flags &= ~Notification.FLAG_NO_DISMISS;
+
+        // When: check the value of isNonDismissible()
+        // Then: should return false
+        assertFalse(NotificationRecordLogger.isNonDismissible(p.r));
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index 14b0048..25e74bf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -788,6 +788,24 @@
     }
 
     @Test
+    public void testSensitiveContent() {
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, groupId /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertFalse(record.hasSensitiveContent());
+
+        Bundle signals = new Bundle();
+        signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, true);
+        record.addAdjustment(new Adjustment(mPkg, record.getKey(), signals, null, sbn.getUserId()));
+
+        record.applyAdjustments();
+
+        assertTrue(record.hasSensitiveContent());
+    }
+
+    @Test
     public void testIsInterruptive_textChanged_notSeen() {
         StatusBarNotification sbn = getNotification(PKG_O, false /* noisy */,
                 false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index 98c156e..6f2627a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -48,7 +48,6 @@
 import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -169,7 +168,7 @@
                     mock(ActivityManagerInternal.class),
                     mock(MultiRateLimiter.class), mock(PermissionHelper.class),
                     mock(UsageStatsManagerInternal.class), mock (TelecomManager.class),
-                    mock(NotificationChannelLogger.class));
+                    mock(NotificationChannelLogger.class), new TestFlagResolver());
         } catch (SecurityException e) {
             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
                 throw e;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/TestFlagResolver.java b/services/tests/uiservicestests/src/com/android/server/notification/TestFlagResolver.java
new file mode 100644
index 0000000..3b9726e
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/TestFlagResolver.java
@@ -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.server.notification;
+
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TestFlagResolver implements SystemUiSystemPropertiesFlags.FlagResolver {
+    private Map<SystemUiSystemPropertiesFlags.Flag, Boolean> mOverrides = new HashMap<>();
+
+    @Override
+    public boolean isEnabled(SystemUiSystemPropertiesFlags.Flag flag) {
+        return mOverrides.getOrDefault(flag, flag.mDefaultValue);
+    }
+
+    public void setFlagOverride(SystemUiSystemPropertiesFlags.Flag flag, boolean isEnabled) {
+        mOverrides.put(flag, isEnabled);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index e663245..e5fe32a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -48,7 +48,7 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 import static android.os.Process.NOBODY_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -3177,18 +3177,18 @@
     public void testImeInsetsFrozenFlag_resetWhenReportedToBeImeInputTarget() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
 
-        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindowContainer(
+        mDisplayContent.getInsetsStateController().getImeSourceProvider().setWindowContainer(
                 mImeWindow, null, null);
         mImeWindow.getControllableInsetProvider().setServerVisible(true);
 
-        InsetsSource imeSource = new InsetsSource(ITYPE_IME, ime());
+        InsetsSource imeSource = new InsetsSource(ID_IME, ime());
         app.mAboveInsetsState.addSource(imeSource);
         mDisplayContent.setImeLayeringTarget(app);
         mDisplayContent.updateImeInputAndControlTarget(app);
 
         InsetsState state = app.getInsetsState();
-        assertFalse(state.getSource(imeSource.getId()).isVisible());
-        assertTrue(state.getSource(imeSource.getId()).getFrame().isEmpty());
+        assertFalse(state.getOrCreateSource(imeSource.getId(), ime()).isVisible());
+        assertTrue(state.getOrCreateSource(imeSource.getId(), ime()).getFrame().isEmpty());
 
         // Simulate app is closing and expect IME insets is frozen.
         mDisplayContent.mOpeningApps.clear();
@@ -3211,8 +3211,8 @@
         // Verify when IME is visible and the app can receive the right IME insets from policy.
         makeWindowVisibleAndDrawn(app, mImeWindow);
         state = app.getInsetsState();
-        assertTrue(state.getSource(ITYPE_IME).isVisible());
-        assertEquals(state.getSource(ITYPE_IME).getFrame(), imeSource.getFrame());
+        assertTrue(state.peekSource(ID_IME).isVisible());
+        assertEquals(state.peekSource(ID_IME).getFrame(), imeSource.getFrame());
     }
 
     @SetupWindows(addWindows = { W_ACTIVITY, W_INPUT_METHOD })
@@ -3222,7 +3222,7 @@
         final WindowState app1 = createWindow(null, TYPE_APPLICATION, "app1");
         final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2");
 
-        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindowContainer(
+        mDisplayContent.getInsetsStateController().getImeSourceProvider().setWindowContainer(
                 mImeWindow, null, null);
         mImeWindow.getControllableInsetProvider().setServerVisible(true);
 
@@ -3237,7 +3237,7 @@
         mDisplayContent.getInsetsStateController().onInsetsModified(app1);
 
         // Verify app1's IME insets is visible and app2's IME insets frozen flag set.
-        assertTrue(app1.getInsetsState().peekSource(ITYPE_IME).isVisible());
+        assertTrue(app1.getInsetsState().peekSource(ID_IME).isVisible());
         assertTrue(app2.mActivityRecord.mImeInsetsFrozenUntilStartInput);
 
         // Simulate switching to app2 to make it visible to be IME targets.
@@ -3256,7 +3256,7 @@
         verify(app2.mClient, atLeastOnce()).resized(any(), anyBoolean(), any(),
                 insetsStateCaptor.capture(), anyBoolean(), anyBoolean(), anyInt(), anyInt(),
                 anyBoolean());
-        assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @Test
@@ -3288,7 +3288,7 @@
         makeWindowVisibleAndDrawn(app1, app2);
 
         final InsetsStateController controller = mDisplayContent.getInsetsStateController();
-        controller.getSourceProvider(ITYPE_IME).setWindowContainer(
+        controller.getImeSourceProvider().setWindowContainer(
                 ime, null, null);
         ime.getControllableInsetProvider().setServerVisible(true);
 
@@ -3306,8 +3306,8 @@
         controller.onInsetsModified(app1);
 
         // Expect all activities in split-screen will get IME insets visible state
-        assertTrue(app1.getInsetsState().peekSource(ITYPE_IME).isVisible());
-        assertTrue(app2.getInsetsState().peekSource(ITYPE_IME).isVisible());
+        assertTrue(app1.getInsetsState().peekSource(ID_IME).isVisible());
+        assertTrue(app2.getInsetsState().peekSource(ID_IME).isVisible());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index ee8a988..ff5ede7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -34,7 +34,6 @@
 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.annotation.NonNull;
@@ -96,9 +95,7 @@
                 .isEqualTo(typeToString(BackNavigationInfo.TYPE_RETURN_TO_HOME));
 
         // verify if back animation would start.
-        verify(mBackNavigationController).scheduleAnimationLocked(
-                eq(BackNavigationInfo.TYPE_RETURN_TO_HOME), any(), eq(mBackAnimationAdapter),
-                any());
+        assertTrue("Animation scheduled", backNavigationInfo.isPrepareRemoteAnimation());
     }
 
     @Test
@@ -115,9 +112,7 @@
                 .isEqualTo(typeToString(BackNavigationInfo.TYPE_CROSS_TASK));
 
         // verify if back animation would start.
-        verify(mBackNavigationController).scheduleAnimationLocked(
-                eq(BackNavigationInfo.TYPE_CROSS_TASK), any(), eq(mBackAnimationAdapter),
-                any());
+        assertTrue("Animation scheduled", backNavigationInfo.isPrepareRemoteAnimation());
 
         // reset drawning status
         topTask.forAllWindows(w -> {
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 2a28ae2..2723289 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
@@ -107,12 +107,15 @@
         assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
         mTarget.onStateChanged(mHalfFoldedStates[0]);
         assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
+        mTarget.onStateChanged(mConcurrentDisplayState);
+        assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
     }
 
     private final int[] mFoldedStates = {0};
     private final int[] mOpenDeviceStates = {1};
     private final int[] mHalfFoldedStates = {2};
     private final int[] mRearDisplayStates = {3};
+    private final int mConcurrentDisplayState = 4;
 
     private class DeviceStateControllerBuilder {
         private boolean mSupportFold = false;
@@ -140,6 +143,14 @@
                 when(mMockContext.getResources()
                         .getIntArray(R.array.config_rearDisplayDeviceStates))
                         .thenReturn(mRearDisplayStates);
+                when(mMockContext.getResources()
+                        .getInteger(R.integer.config_deviceStateConcurrentRearDisplay))
+                        .thenReturn(mConcurrentDisplayState);
+            } else {
+                // Match the default value in framework resources
+                when(mMockContext.getResources()
+                        .getInteger(R.integer.config_deviceStateConcurrentRearDisplay))
+                        .thenReturn(-1);
             }
 
             if (enableFold) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 3b34ba4..bfd99fd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -105,6 +105,7 @@
 import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.when;
 
+import android.annotation.NonNull;
 import android.app.ActivityTaskManager;
 import android.app.WindowConfiguration;
 import android.content.res.Configuration;
@@ -123,6 +124,7 @@
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.view.ContentRecordingSession;
+import android.view.Display;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -1557,13 +1559,13 @@
         // If the visibility of insets state is changed, the rotated state should be updated too.
         final InsetsState rotatedState = app.getFixedRotationTransformInsetsState();
         final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState();
-        assertEquals(state.getSource(ITYPE_STATUS_BAR).isVisible(),
-                rotatedState.getSource(ITYPE_STATUS_BAR).isVisible());
-        state.getSource(ITYPE_STATUS_BAR).setVisible(
-                !rotatedState.getSource(ITYPE_STATUS_BAR).isVisible());
+        assertEquals(state.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()),
+                rotatedState.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
+        state.setSourceVisible(ITYPE_STATUS_BAR,
+                !rotatedState.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
         mDisplayContent.getInsetsStateController().notifyInsetsChanged();
-        assertEquals(state.getSource(ITYPE_STATUS_BAR).isVisible(),
-                rotatedState.getSource(ITYPE_STATUS_BAR).isVisible());
+        assertEquals(state.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()),
+                rotatedState.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
 
         final Rect outFrame = new Rect();
         final Rect outInsets = new Rect();
@@ -1831,6 +1833,111 @@
     }
 
     @Test
+    public void testSecondaryInternalDisplayRotationFollowsDefaultDisplay() {
+        // Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
+        doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
+
+        final DisplayRotationCoordinator coordinator =
+                mRootWindowContainer.getDisplayRotationCoordinator();
+        final DisplayContent defaultDisplayContent = mDisplayContent;
+        final DisplayRotation defaultDisplayRotation = defaultDisplayContent.getDisplayRotation();
+        coordinator.removeDefaultDisplayRotationChangedCallback();
+
+        DeviceStateController deviceStateController = mock(DeviceStateController.class);
+        when(deviceStateController.shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay())
+                .thenReturn(true);
+
+        // Create secondary display
+        final DisplayContent secondaryDisplayContent =
+                createSecondaryDisplayContent(Display.TYPE_INTERNAL, deviceStateController);
+        final DisplayRotation secondaryDisplayRotation =
+                secondaryDisplayContent.getDisplayRotation();
+        try {
+            // TestDisplayContent bypasses this method but we need it for this test
+            doCallRealMethod().when(secondaryDisplayRotation).updateRotationUnchecked(anyBoolean());
+
+            // TestDisplayContent creates this as a mock. Lets set it up to test our use case.
+            when(secondaryDisplayContent.mDeviceStateController
+                    .shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay()).thenReturn(
+                    true);
+
+            // Check that secondary display registered callback
+            assertEquals(secondaryDisplayRotation.mDefaultDisplayRotationChangedCallback,
+                    coordinator.mDefaultDisplayRotationChangedCallback);
+
+            // Set the default display to a known orientation. This may be a zero or non-zero
+            // rotation since mDisplayInfo.logicalWidth/Height depends on the DUT's default display
+            defaultDisplayRotation.updateOrientation(SCREEN_ORIENTATION_PORTRAIT, false);
+            assertEquals(defaultDisplayRotation.mPortraitRotation,
+                    defaultDisplayRotation.getRotation());
+            assertEquals(defaultDisplayRotation.mPortraitRotation,
+                    coordinator.getDefaultDisplayCurrentRotation());
+
+            // Check that in the initial state, the secondary display is in the right rotation
+            assertRotationsAreCorrectlyReversed(defaultDisplayRotation.getRotation(),
+                    secondaryDisplayRotation.getRotation());
+
+            // Update primary display rotation, check display coordinator rotation is the default
+            // display's landscape rotation, and that the secondary display rotation is correct.
+            defaultDisplayRotation.updateOrientation(SCREEN_ORIENTATION_LANDSCAPE, false);
+            assertEquals(defaultDisplayRotation.mLandscapeRotation,
+                    defaultDisplayRotation.getRotation());
+            assertEquals(defaultDisplayRotation.mLandscapeRotation,
+                    coordinator.getDefaultDisplayCurrentRotation());
+            assertRotationsAreCorrectlyReversed(defaultDisplayRotation.getRotation(),
+                    secondaryDisplayRotation.getRotation());
+        } finally {
+            secondaryDisplayRotation.removeDefaultDisplayRotationChangedCallback();
+        }
+    }
+
+    @Test
+    public void testSecondaryNonInternalDisplayDoesNotFollowDefaultDisplay() {
+        // Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
+        doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
+
+        final DisplayRotationCoordinator coordinator =
+                mRootWindowContainer.getDisplayRotationCoordinator();
+        coordinator.removeDefaultDisplayRotationChangedCallback();
+
+        DeviceStateController deviceStateController = mock(DeviceStateController.class);
+        when(deviceStateController.shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay())
+                .thenReturn(true);
+
+        // Create secondary non-internal displays
+        createSecondaryDisplayContent(Display.TYPE_EXTERNAL, deviceStateController);
+        assertNull(coordinator.mDefaultDisplayRotationChangedCallback);
+        createSecondaryDisplayContent(Display.TYPE_VIRTUAL, deviceStateController);
+        assertNull(coordinator.mDefaultDisplayRotationChangedCallback);
+    }
+
+    private DisplayContent createSecondaryDisplayContent(int displayType,
+            @NonNull DeviceStateController deviceStateController) {
+        final DisplayInfo secondaryDisplayInfo = new DisplayInfo();
+        secondaryDisplayInfo.copyFrom(mDisplayInfo);
+        secondaryDisplayInfo.type = displayType;
+
+        return new TestDisplayContent.Builder(mAtm, secondaryDisplayInfo)
+                .setDeviceStateController(deviceStateController)
+                .build();
+    }
+
+    private static void assertRotationsAreCorrectlyReversed(@Surface.Rotation int rotation1,
+            @Surface.Rotation int rotation2) {
+        if (rotation1 == ROTATION_0) {
+            assertEquals(rotation1, rotation2);
+        } else if (rotation1 == ROTATION_180) {
+            assertEquals(rotation1, rotation2);
+        } else if (rotation1 == ROTATION_90) {
+            assertEquals(ROTATION_270, rotation2);
+        } else if (rotation1 == ROTATION_270) {
+            assertEquals(ROTATION_90, rotation2);
+        } else {
+            throw new IllegalArgumentException("Unknown rotation: " + rotation1 + ", " + rotation2);
+        }
+    }
+
+    @Test
     public void testRemoteRotation() {
         final DisplayContent dc = mDisplayContent;
         final DisplayRotation dr = dc.getDisplayRotation();
@@ -1913,13 +2020,13 @@
         assertEquals(origRot, dc.getConfiguration().windowConfiguration.getRotation());
 
         // Once transition starts, rotation is applied and transition shows DC rotating.
-        testPlayer.start();
+        testPlayer.startTransition();
         assertNotEquals(origRot, dc.getConfiguration().windowConfiguration.getRotation());
         assertNotNull(testPlayer.mLastReady);
+        assertTrue(testPlayer.mController.isPlaying());
         WindowContainerToken dcToken = dc.mRemoteToken.toWindowContainerToken();
         assertNotEquals(testPlayer.mLastReady.getChange(dcToken).getEndRotation(),
                 testPlayer.mLastReady.getChange(dcToken).getStartRotation());
-        assertTrue(testPlayer.mLastTransit.applyDisplayChangeIfNeeded());
         testPlayer.finish();
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 6733470..6656f4c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -43,6 +43,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.DisplayInfo;
 import android.view.InsetsFrameProvider;
+import android.view.InsetsSource;
 import android.view.InsetsState;
 import android.view.PrivacyIndicatorBounds;
 import android.view.RoundedCorners;
@@ -162,19 +163,20 @@
         InsetsStateController controller = mDisplayContent.getInsetsStateController();
         controller.onPostLayout();
 
-        InsetsSourceProvider statusBarProvider = controller.getSourceProvider(ITYPE_STATUS_BAR);
+        InsetsSourceProvider statusBarProvider = controller.peekSourceProvider(ITYPE_STATUS_BAR);
         assertEquals(new Rect(0, 0, 500, 100), statusBarProvider.getSource().getFrame());
         assertEquals(Insets.of(0, 100, 0, 0),
                 statusBarProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
                         false /* ignoreVisibility */));
 
-        InsetsSourceProvider topGesturesProvider = controller.getSourceProvider(ITYPE_TOP_GESTURES);
+        InsetsSourceProvider topGesturesProvider = controller.peekSourceProvider(
+                ITYPE_TOP_GESTURES);
         assertEquals(new Rect(0, 0, 500, 100), topGesturesProvider.getSource().getFrame());
         assertEquals(Insets.of(0, 100, 0, 0),
                 topGesturesProvider.getSource().calculateInsets(new Rect(0, 0, 500, 500),
                         false /* ignoreVisibility */));
 
-        InsetsSourceProvider navigationBarProvider = controller.getSourceProvider(
+        InsetsSourceProvider navigationBarProvider = controller.peekSourceProvider(
                 ITYPE_NAVIGATION_BAR);
         assertNotEquals(new Rect(0, 0, 500, 100), navigationBarProvider.getSource().getFrame());
     }
@@ -193,7 +195,7 @@
         mDisplayContent.getInsetsStateController().onPostLayout();
 
         InsetsSourceProvider provider =
-                mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR);
+                mDisplayContent.getInsetsStateController().peekSourceProvider(ITYPE_STATUS_BAR);
         // In the new flexible insets setup, the insets frame should always respect the window
         // layout result.
         assertEquals(new Rect(0, 0, 500, 100), provider.getSource().getFrame());
@@ -255,7 +257,7 @@
                 mDisplayContent.getInsetsStateController().getRawInsetsState());
         // Exclude comparing IME insets because currently the simulated layout only focuses on the
         // insets from status bar and navigation bar.
-        realInsetsState.removeSource(InsetsState.ITYPE_IME);
+        realInsetsState.removeSource(InsetsSource.ID_IME);
         realInsetsState.removeSource(InsetsState.ITYPE_CAPTION_BAR);
 
         assertEquals(new ToStringComparatorWrapper<>(realInsetsState),
@@ -270,9 +272,9 @@
                 .rotationForActivityInDifferentOrientation(eq(mWindow.mActivityRecord));
         mWindow.mAboveInsetsState.set(
                 mDisplayContent.getInsetsStateController().getRawInsetsState());
-        final Rect frame = mWindow.getInsetsState().getSource(ITYPE_STATUS_BAR).getFrame();
+        final Rect frame = mWindow.getInsetsState().peekSource(ITYPE_STATUS_BAR).getFrame();
         mDisplayContent.rotateInDifferentOrientationIfNeeded(mWindow.mActivityRecord);
-        final Rect rotatedFrame = mWindow.getInsetsState().getSource(ITYPE_STATUS_BAR).getFrame();
+        final Rect rotatedFrame = mWindow.getInsetsState().peekSource(ITYPE_STATUS_BAR).getFrame();
 
         assertEquals(DISPLAY_WIDTH, frame.width());
         assertEquals(DISPLAY_HEIGHT, rotatedFrame.width());
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 cf9ec81..6bb7769 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -17,8 +17,8 @@
 package com.android.server.wm;
 
 import static android.view.DisplayCutout.NO_CUTOUT;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.RoundedCorners.NO_ROUNDED_CORNERS;
 import static android.view.Surface.ROTATION_0;
@@ -335,7 +335,7 @@
         displayPolicy.layoutWindowLw(mNavBarWindow, null, mDisplayContent.mDisplayFrames);
         displayPolicy.layoutWindowLw(mImeWindow, null, mDisplayContent.mDisplayFrames);
 
-        final InsetsSource imeSource = state.peekSource(ITYPE_IME);
+        final InsetsSource imeSource = state.peekSource(ID_IME);
         final InsetsSource navBarSource = state.peekSource(ITYPE_NAVIGATION_BAR);
 
         assertNotNull(imeSource);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
index 4954e89..c2b3783 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
@@ -147,6 +147,20 @@
     }
 
     @Test
+    public void testOpenedCameraInSplitScreen_orientationNotFixed_doNotShowToast() {
+        configureActivity(SCREEN_ORIENTATION_UNSPECIFIED);
+        spyOn(mTask);
+        spyOn(mDisplayRotationCompatPolicy);
+        doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mActivity).getWindowingMode();
+        doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mTask).getWindowingMode();
+
+        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+
+        verify(mDisplayRotationCompatPolicy, never()).showToast(
+                R.string.display_rotation_camera_compat_toast_in_split_screen);
+    }
+
+    @Test
     public void testOnScreenRotationAnimationFinished_treatmentNotEnabled_doNotShowToast() {
         when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
                     /* checkDeviceConfig */ anyBoolean()))
@@ -172,7 +186,7 @@
     @Test
     public void testOnScreenRotationAnimationFinished_notFullscreen_doNotShowToast() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-        doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mActivity).getWindowingMode();
+        doReturn(true).when(mActivity).inMultiWindowMode();
         spyOn(mDisplayRotationCompatPolicy);
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -184,6 +198,18 @@
     }
 
     @Test
+    public void testOnScreenRotationAnimationFinished_orientationNotFixed_doNotShowToast() {
+        configureActivity(SCREEN_ORIENTATION_UNSPECIFIED);
+        mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
+        spyOn(mDisplayRotationCompatPolicy);
+
+        mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished();
+
+        verify(mDisplayRotationCompatPolicy, never()).showToast(
+                R.string.display_rotation_camera_compat_toast_after_rotation);
+    }
+
+    @Test
     public void testOnScreenRotationAnimationFinished_showToast() {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCoordinatorTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCoordinatorTests.java
new file mode 100644
index 0000000..4557df0
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCoordinatorTests.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static org.junit.Assert.assertEquals;
+
+import android.annotation.NonNull;
+import android.platform.test.annotations.Presubmit;
+import android.view.Surface;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Test class for {@link DisplayRotationCoordinator}
+ *
+ * Build/Install/Run:
+ *  atest DisplayRotationCoordinatorTests
+ */
+@SmallTest
+@Presubmit
+public class DisplayRotationCoordinatorTests {
+
+    @NonNull
+    private final DisplayRotationCoordinator mCoordinator = new DisplayRotationCoordinator();
+
+    @Test
+    public void testDefaultDisplayRotationChangedWhenNoCallbackRegistered() {
+        // Does not cause NPE
+        mCoordinator.onDefaultDisplayRotationChanged(Surface.ROTATION_90);
+    }
+
+    @Test (expected = UnsupportedOperationException.class)
+    public void testSecondRegistrationWithoutRemovingFirst() {
+        Runnable callback1 = mock(Runnable.class);
+        Runnable callback2 = mock(Runnable.class);
+        mCoordinator.setDefaultDisplayRotationChangedCallback(callback1);
+        mCoordinator.setDefaultDisplayRotationChangedCallback(callback2);
+        assertEquals(callback1, mCoordinator.mDefaultDisplayRotationChangedCallback);
+    }
+
+    @Test
+    public void testSecondRegistrationAfterRemovingFirst() {
+        Runnable callback1 = mock(Runnable.class);
+        mCoordinator.setDefaultDisplayRotationChangedCallback(callback1);
+        mCoordinator.removeDefaultDisplayRotationChangedCallback();
+
+        Runnable callback2 = mock(Runnable.class);
+        mCoordinator.setDefaultDisplayRotationChangedCallback(callback2);
+
+        mCoordinator.onDefaultDisplayRotationChanged(Surface.ROTATION_90);
+        verify(callback2).run();
+        verify(callback1, never()).run();
+    }
+
+    @Test
+    public void testRegisterThenDefaultDisplayRotationChanged() {
+        Runnable callback = mock(Runnable.class);
+        mCoordinator.setDefaultDisplayRotationChangedCallback(callback);
+        assertEquals(Surface.ROTATION_0, mCoordinator.getDefaultDisplayCurrentRotation());
+        verify(callback, never()).run();
+
+        mCoordinator.onDefaultDisplayRotationChanged(Surface.ROTATION_90);
+        verify(callback).run();
+        assertEquals(Surface.ROTATION_90, mCoordinator.getDefaultDisplayCurrentRotation());
+    }
+
+    @Test
+    public void testDefaultDisplayRotationChangedThenRegister() {
+        mCoordinator.onDefaultDisplayRotationChanged(Surface.ROTATION_90);
+        Runnable callback = mock(Runnable.class);
+        mCoordinator.setDefaultDisplayRotationChangedCallback(callback);
+        verify(callback).run();
+        assertEquals(Surface.ROTATION_90, mCoordinator.getDefaultDisplayCurrentRotation());
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index ed2b0a3..21e8ec4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -1135,7 +1135,7 @@
             mDeviceStateController = mock(DeviceStateController.class);
             mTarget = new DisplayRotation(sMockWm, mMockDisplayContent, mMockDisplayAddress,
                     mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext, new Object(),
-                    mDeviceStateController) {
+                    mDeviceStateController, mock(DisplayRotationCoordinator.class)) {
                 @Override
                 DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy(
                         WindowManagerService service, DisplayContent displayContent) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index b2abd44..19d1d83 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -33,7 +33,7 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.os.UserHandle;
+import android.os.Process;
 import android.util.ArraySet;
 import android.view.Display;
 import android.window.DisplayWindowPolicyController;
@@ -101,7 +101,7 @@
         int uidAmount = (expectedUid0 && expectedUid1) ? 2 : (expectedUid0 || expectedUid1) ? 1 : 0;
         assertEquals(expectedTopActivity == null ? null :
                 expectedTopActivity.info.getComponentName(), mDwpc.mTopActivity);
-        assertEquals(expectedTopActivity == null ? UserHandle.USER_NULL :
+        assertEquals(expectedTopActivity == null ? Process.INVALID_UID :
                 expectedTopActivity.info.applicationInfo.uid, mDwpc.mTopActivityUid);
         assertEquals(uidAmount, mDwpc.mRunningUids.size());
         assertTrue(mDwpc.mRunningUids.contains(TEST_USER_0_ID) == expectedUid0);
@@ -224,7 +224,7 @@
                 new ComponentName("fake.package", "DisallowedActivity");
 
         ComponentName mTopActivity = null;
-        int mTopActivityUid = UserHandle.USER_NULL;
+        int mTopActivityUid = Process.INVALID_UID;
         ArraySet<Integer> mRunningUids = new ArraySet<>();
 
         @Override
@@ -254,8 +254,8 @@
         }
 
         @Override
-        public void onTopActivityChanged(ComponentName topActivity, int uid) {
-            super.onTopActivityChanged(topActivity, uid);
+        public void onTopActivityChanged(ComponentName topActivity, int uid, int userId) {
+            super.onTopActivityChanged(topActivity, uid, userId);
             mTopActivity = topActivity;
             mTopActivityUid = uid;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index 4eaae9f..d1a41ae 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -552,7 +552,7 @@
         /** Please use the {@link Builder} to create. */
         DualDisplayContent(RootWindowContainer rootWindowContainer,
                 Display display) {
-            super(rootWindowContainer, display);
+            super(rootWindowContainer, display, mock(DeviceStateController.class));
 
             mFirstRoot = getGroupRoot(FEATURE_FIRST_ROOT);
             mSecondRoot = getGroupRoot(FEATURE_SECOND_ROOT);
diff --git a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
index 0568b38..c0a90b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
@@ -182,13 +182,11 @@
     @Test
     public void testApplicationNotInFocusWithModeId() {
         final WindowState appWindow = createWindow("appWindow");
-        assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET);
-        assertEquals(appWindow.mFrameRateVote, FRAME_RATE_VOTE_NONE);
-
-        final WindowState inFocusWindow = createWindow("inFocus");
-        appWindow.mToken.mDisplayContent.mCurrentFocus = inFocusWindow;
-
+        mDisplayContent.mCurrentFocus = appWindow;
         appWindow.updateFrameRateSelectionPriorityIfNeeded();
+        mDisplayContent.mCurrentFocus = null;
+        appWindow.updateFrameRateSelectionPriorityIfNeeded();
+
         // The window is not in focus.
         assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET);
         assertEquals(appWindow.mFrameRateVote, FRAME_RATE_VOTE_NONE);
@@ -211,13 +209,11 @@
     @Test
     public void testApplicationNotInFocusWithoutModeId() {
         final WindowState appWindow = createWindow("appWindow");
-        assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET);
-        assertEquals(appWindow.mFrameRateVote, FRAME_RATE_VOTE_NONE);
-
-        final WindowState inFocusWindow = createWindow("inFocus");
-        appWindow.mToken.mDisplayContent.mCurrentFocus = inFocusWindow;
-
+        mDisplayContent.mCurrentFocus = appWindow;
         appWindow.updateFrameRateSelectionPriorityIfNeeded();
+        mDisplayContent.mCurrentFocus = null;
+        appWindow.updateFrameRateSelectionPriorityIfNeeded();
+
         // The window is not in focus.
         assertEquals(appWindow.mFrameRateSelectionPriority, RefreshRatePolicy.LAYER_PRIORITY_UNSET);
         assertEquals(appWindow.mFrameRateVote, FRAME_RATE_VOTE_NONE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
index d4e860e..20bb549 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -39,7 +39,7 @@
 @RunWith(WindowTestRunner.class)
 public class ImeInsetsSourceProviderTest extends WindowTestsBase {
 
-    private InsetsSource mImeSource = new InsetsSource(ITYPE_IME, ime());
+    private InsetsSource mImeSource = new InsetsSource(ID_IME, ime());
     private ImeInsetsSourceProvider mImeProvider;
 
     @Before
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 9887839..1a126cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -276,12 +276,11 @@
         policy.updateBarControlTarget(mAppWindow);
         waitUntilWindowAnimatorIdle();
         assertFalse(mDisplayContent.getInsetsStateController().getRawInsetsState()
-                .getSource(ITYPE_STATUS_BAR).isVisible());
+                .isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
         assertFalse(mDisplayContent.getInsetsStateController().getRawInsetsState()
-                .getSource(ITYPE_NAVIGATION_BAR).isVisible());
+                .isSourceOrDefaultVisible(ITYPE_NAVIGATION_BAR, navigationBars()));
 
-        policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR},
-                true /* isGestureOnSystemBar */);
+        policy.showTransient(navigationBars() | statusBars(), true /* isGestureOnSystemBar */);
         waitUntilWindowAnimatorIdle();
         final InsetsSourceControl[] controls =
                 mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -293,9 +292,9 @@
         }
 
         assertTrue(mDisplayContent.getInsetsStateController().getRawInsetsState()
-                .getSource(ITYPE_STATUS_BAR).isVisible());
+                .isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
         assertTrue(mDisplayContent.getInsetsStateController().getRawInsetsState()
-                .getSource(ITYPE_NAVIGATION_BAR).isVisible());
+                .isSourceOrDefaultVisible(ITYPE_NAVIGATION_BAR, navigationBars()));
     }
 
     @SetupWindows(addWindows = W_ACTIVITY)
@@ -308,11 +307,11 @@
         spyOn(policy);
         doNothing().when(policy).startAnimation(anyBoolean(), any());
         policy.updateBarControlTarget(mAppWindow);
-        policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR},
+        policy.showTransient(navigationBars() | statusBars(),
                 true /* isGestureOnSystemBar */);
         waitUntilWindowAnimatorIdle();
-        assertTrue(policy.isTransient(ITYPE_STATUS_BAR));
-        assertFalse(policy.isTransient(ITYPE_NAVIGATION_BAR));
+        assertTrue(policy.isTransient(statusBars()));
+        assertFalse(policy.isTransient(navigationBars()));
         final InsetsSourceControl[] controls =
                 mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
 
@@ -344,7 +343,7 @@
         spyOn(policy);
         doNothing().when(policy).startAnimation(anyBoolean(), any());
         policy.updateBarControlTarget(mAppWindow);
-        policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR},
+        policy.showTransient(navigationBars() | statusBars(),
                 true /* isGestureOnSystemBar */);
         waitUntilWindowAnimatorIdle();
         InsetsSourceControl[] controls =
@@ -362,11 +361,11 @@
 
         final InsetsState clientState = mAppWindow.getInsetsState();
         // The transient bar states for client should be invisible.
-        assertFalse(clientState.getSource(ITYPE_STATUS_BAR).isVisible());
-        assertFalse(clientState.getSource(ITYPE_NAVIGATION_BAR).isVisible());
+        assertFalse(clientState.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
+        assertFalse(clientState.isSourceOrDefaultVisible(ITYPE_NAVIGATION_BAR, navigationBars()));
         // The original state shouldn't be modified.
-        assertTrue(state.getSource(ITYPE_STATUS_BAR).isVisible());
-        assertTrue(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
+        assertTrue(state.isSourceOrDefaultVisible(ITYPE_STATUS_BAR, statusBars()));
+        assertTrue(state.isSourceOrDefaultVisible(ITYPE_NAVIGATION_BAR, navigationBars()));
 
         mAppWindow.setRequestedVisibleTypes(
                 navigationBars() | statusBars(), navigationBars() | statusBars());
@@ -393,13 +392,13 @@
         spyOn(policy);
         doNothing().when(policy).startAnimation(anyBoolean(), any());
         policy.updateBarControlTarget(app);
-        policy.showTransient(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR},
+        policy.showTransient(navigationBars() | statusBars(),
                 true /* isGestureOnSystemBar */);
         final InsetsSourceControl[] controls =
                 mDisplayContent.getInsetsStateController().getControlsForDispatch(app);
         policy.updateBarControlTarget(app2);
-        assertFalse(policy.isTransient(ITYPE_STATUS_BAR));
-        assertFalse(policy.isTransient(ITYPE_NAVIGATION_BAR));
+        assertFalse(policy.isTransient(statusBars()));
+        assertFalse(policy.isTransient(navigationBars()));
     }
 
     private WindowState addNavigationBar() {
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 4d69979..74fde65 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -19,12 +19,10 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.InsetsState.ITYPE_CLIMATE_BAR;
-import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_IME;
-import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.navigationBars;
+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.TYPE_APPLICATION;
@@ -48,6 +46,7 @@
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
+import android.view.InsetsSource;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
@@ -63,6 +62,15 @@
 @RunWith(WindowTestRunner.class)
 public class InsetsStateControllerTest extends WindowTestsBase {
 
+    private static final int ID_STATUS_BAR =
+            InsetsSource.createId(null /* owner */, 0 /* index */, statusBars());
+    private static final int ID_NAVIGATION_BAR =
+            InsetsSource.createId(null /* owner */, 0 /* index */, navigationBars());
+    private static final int ID_CLIMATE_BAR =
+            InsetsSource.createId(null /* owner */, 1 /* index */, statusBars());
+    private static final int ID_EXTRA_NAVIGATION_BAR =
+            InsetsSource.createId(null /* owner */, 1 /* index */, navigationBars());
+
     @Test
     public void testStripForDispatch_navBar() {
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
@@ -72,14 +80,15 @@
         // IME cannot be the IME target.
         ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(ime, null, null);
 
-        assertNull(navBar.getInsetsState().peekSource(ITYPE_IME));
-        assertNull(navBar.getInsetsState().peekSource(ITYPE_STATUS_BAR));
+        assertNull(navBar.getInsetsState().peekSource(ID_IME));
+        assertNull(navBar.getInsetsState().peekSource(ID_STATUS_BAR));
     }
 
     @Test
@@ -88,15 +97,15 @@
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
         app.setWindowingMode(WINDOWING_MODE_PINNED);
 
-        assertNull(app.getInsetsState().peekSource(ITYPE_STATUS_BAR));
-        assertNull(app.getInsetsState().peekSource(ITYPE_NAVIGATION_BAR));
-        assertNull(app.getInsetsState().peekSource(ITYPE_IME));
+        assertNull(app.getInsetsState().peekSource(ID_STATUS_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_IME));
     }
 
     @Test
@@ -105,14 +114,14 @@
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
         app.setWindowingMode(WINDOWING_MODE_FREEFORM);
 
-        assertNull(app.getInsetsState().peekSource(ITYPE_STATUS_BAR));
-        assertNull(app.getInsetsState().peekSource(ITYPE_NAVIGATION_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_STATUS_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
     }
 
     @Test
@@ -121,57 +130,58 @@
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
         app.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         app.setAlwaysOnTop(true);
 
-        assertNull(app.getInsetsState().peekSource(ITYPE_STATUS_BAR));
-        assertNull(app.getInsetsState().peekSource(ITYPE_NAVIGATION_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_STATUS_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_independentSources() {
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
 
         final WindowState app1 = createWindow(null, TYPE_APPLICATION, "app1");
         final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2");
 
-        app1.mAboveInsetsState.addSource(getController().getRawInsetsState().getSource(ITYPE_IME));
+        app1.mAboveInsetsState.addSource(getController().getRawInsetsState().peekSource(ID_IME));
 
-        getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
-        assertFalse(app2.getInsetsState().getSource(ITYPE_IME)
-                .isVisible());
-        assertTrue(app1.getInsetsState().getSource(ITYPE_IME)
-                .isVisible());
+        getController().getRawInsetsState().setSourceVisible(ID_IME, true);
+        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertTrue(app1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_belowIme() {
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
 
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        app.mAboveInsetsState.getSource(ITYPE_IME).setVisible(true);
-        app.mAboveInsetsState.getSource(ITYPE_IME).setFrame(mImeWindow.getFrame());
+        app.mAboveInsetsState.getOrCreateSource(ID_IME, ime())
+                .setVisible(true)
+                .setFrame(mImeWindow.getFrame());
 
-        getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
+        getController().getRawInsetsState().setSourceVisible(ID_IME, true);
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_aboveIme() {
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
 
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
 
-        getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
-        assertFalse(app.getInsetsState().getSource(ITYPE_IME)
-                .isVisible());
+        getController().getRawInsetsState().setSourceVisible(ID_IME, true);
+        assertFalse(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
@@ -185,7 +195,8 @@
 
         // Make IME and stay visible during the test.
         mImeWindow.setHasSurface(true);
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
         getController().onImeControlTargetChanged(
                 mDisplayContent.getImeInputTarget().getWindowState());
         mDisplayContent.getImeInputTarget().getWindowState().setRequestedVisibleTypes(ime(), ime());
@@ -205,9 +216,8 @@
         mDisplayContent.applySurfaceChangesTransaction();
 
         // app won't get visible IME insets while above IME even when IME is visible.
-        assertTrue(getController().getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
-        assertFalse(app.getInsetsState().getSource(ITYPE_IME)
-                .isVisible());
+        assertTrue(getController().getRawInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertFalse(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
 
         // Reset invocation counter.
         clearInvocations(app);
@@ -216,20 +226,22 @@
         app.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
         mDisplayContent.computeImeTarget(true);
         mDisplayContent.applySurfaceChangesTransaction();
-        app.mAboveInsetsState.getSource(ITYPE_IME).setVisible(true);
-        app.mAboveInsetsState.getSource(ITYPE_IME).setFrame(mImeWindow.getFrame());
+        app.mAboveInsetsState.getOrCreateSource(ID_IME, ime())
+                .setVisible(true)
+                .setFrame(mImeWindow.getFrame());
 
         // Make sure app got notified.
         verify(app, atLeastOnce()).notifyInsetsChanged();
 
         // app will get visible IME insets while below IME.
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_childWindow_altFocusable() {
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
 
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
@@ -241,20 +253,20 @@
         mDisplayContent.setLayoutNeeded();
         mDisplayContent.applySurfaceChangesTransaction();
 
-        getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
-        assertFalse(child.getInsetsState().getSource(ITYPE_IME)
-                .isVisible());
+        getController().getRawInsetsState().setSourceVisible(ID_IME, true);
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertFalse(child.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_childWindow_splitScreen() {
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
 
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
-        app.mAboveInsetsState.addSource(getController().getRawInsetsState().peekSource(ITYPE_IME));
+        app.mAboveInsetsState.addSource(getController().getRawInsetsState().peekSource(ID_IME));
         child.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
         child.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
 
@@ -262,10 +274,9 @@
         mDisplayContent.setLayoutNeeded();
         mDisplayContent.applySurfaceChangesTransaction();
 
-        getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
-        assertFalse(child.getInsetsState().getSource(ITYPE_IME)
-                .isVisible());
+        getController().getRawInsetsState().setSourceVisible(ID_IME, true);
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertFalse(child.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @Test
@@ -277,20 +288,21 @@
         ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
 
         WindowContainerInsetsSourceProvider statusBarProvider =
-                getController().getSourceProvider(ITYPE_STATUS_BAR);
+                getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars());
         final SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>> imeOverrideProviders =
                 new SparseArray<>();
         imeOverrideProviders.put(TYPE_INPUT_METHOD, ((displayFrames, windowState, rect) ->
                 rect.set(0, 1, 2, 3)));
         statusBarProvider.setWindowContainer(statusBar, null, imeOverrideProviders);
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(ime, null, null);
         statusBar.setControllableInsetProvider(statusBarProvider);
         statusBar.updateSourceFrame(statusBar.getFrame());
 
         statusBarProvider.onPostLayout();
 
         final InsetsState state = ime.getInsetsState();
-        assertEquals(new Rect(0, 1, 2, 3), state.getSource(ITYPE_STATUS_BAR).getFrame());
+        assertEquals(new Rect(0, 1, 2, 3), state.peekSource(ID_STATUS_BAR).getFrame());
     }
 
     @Test
@@ -300,15 +312,14 @@
         final WindowState climateBar = createWindow(null, TYPE_APPLICATION, "climateBar");
         final WindowState extraNavBar = createWindow(null, TYPE_APPLICATION, "extraNavBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_CLIMATE_BAR).setWindowContainer(climateBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_EXTRA_NAVIGATION_BAR).setWindowContainer(
-                extraNavBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
+        getController().getOrCreateSourceProvider(ID_CLIMATE_BAR, statusBars())
+                .setWindowContainer(climateBar, null, null);
+        getController().getOrCreateSourceProvider(ID_EXTRA_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(extraNavBar, null, null);
         getController().onBarControlTargetChanged(app, null, app, null);
         InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
         assertEquals(4, controls.length);
@@ -318,8 +329,8 @@
     public void testControlRevoked() {
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
         getController().onBarControlTargetChanged(app, null, null, null);
         assertNotNull(getController().getControlsForDispatch(app));
         getController().onBarControlTargetChanged(null, null, null, null);
@@ -330,8 +341,8 @@
     public void testControlRevoked_animation() {
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
         getController().onBarControlTargetChanged(app, null, null, null);
         assertNotNull(getController().getControlsForDispatch(app));
         statusBar.cancelAnimation();
@@ -343,21 +354,22 @@
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         final WindowContainerInsetsSourceProvider provider = getController()
-                .getSourceProvider(ITYPE_STATUS_BAR);
+                .getOrCreateSourceProvider(ID_STATUS_BAR, statusBars());
         provider.setWindowContainer(statusBar, null, null);
 
         final InsetsState rotatedState = new InsetsState(app.getInsetsState(),
                 true /* copySources */);
+        rotatedState.getOrCreateSource(ID_STATUS_BAR, statusBars());
         spyOn(app.mToken);
         doReturn(rotatedState).when(app.mToken).getFixedRotationTransformInsetsState();
-        assertTrue(rotatedState.getSource(ITYPE_STATUS_BAR).isVisible());
+        assertTrue(rotatedState.isSourceOrDefaultVisible(ID_STATUS_BAR, statusBars()));
 
         provider.getSource().setVisible(false);
-        mDisplayContent.getInsetsPolicy().showTransient(new int[] { ITYPE_STATUS_BAR },
+        mDisplayContent.getInsetsPolicy().showTransient(statusBars(),
                 true /* isGestureOnSystemBar */);
 
-        assertTrue(mDisplayContent.getInsetsPolicy().isTransient(ITYPE_STATUS_BAR));
-        assertFalse(app.getInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
+        assertTrue(mDisplayContent.getInsetsPolicy().isTransient(statusBars()));
+        assertFalse(app.getInsetsState().isSourceOrDefaultVisible(ID_STATUS_BAR, statusBars()));
     }
 
     @Test
@@ -366,18 +378,18 @@
         final WindowState statusBar = createTestWindow("statusBar");
         final WindowState navBar = createTestWindow("navBar");
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
 
-        assertNull(app.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNull(statusBar.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNull(navBar.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
+        assertNull(app.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNull(statusBar.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNull(navBar.mAboveInsetsState.peekSource(ID_STATUS_BAR));
 
         getController().updateAboveInsetsState(true /* notifyInsetsChange */);
 
-        assertNotNull(app.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNull(statusBar.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNull(navBar.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
+        assertNotNull(app.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNull(statusBar.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNull(navBar.mAboveInsetsState.peekSource(ID_STATUS_BAR));
 
         verify(app, atLeastOnce()).notifyInsetsChanged();
     }
@@ -388,18 +400,18 @@
         final WindowState statusBar = createTestWindow("statusBar");
         final WindowState navBar = createTestWindow("navBar");
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
 
-        assertNull(app.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNull(app.mAboveInsetsState.peekSource(ITYPE_NAVIGATION_BAR));
+        assertNull(app.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNull(app.mAboveInsetsState.peekSource(ID_NAVIGATION_BAR));
 
         getController().updateAboveInsetsState(true /* notifyInsetsChange */);
 
-        assertNotNull(app.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNotNull(app.mAboveInsetsState.peekSource(ITYPE_NAVIGATION_BAR));
+        assertNotNull(app.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNotNull(app.mAboveInsetsState.peekSource(ID_NAVIGATION_BAR));
 
         verify(app, atLeastOnce()).notifyInsetsChanged();
     }
@@ -411,38 +423,40 @@
         final WindowState statusBar = createTestWindow("statusBar");
         final WindowState navBar = createTestWindow("navBar");
 
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
+        final InsetsSourceProvider imeSourceProvider =
+                getController().getOrCreateSourceProvider(ID_IME, ime());
+        imeSourceProvider.setWindowContainer(ime, null, null);
 
         waitUntilHandlersIdle();
         clearInvocations(mDisplayContent);
-        getController().getSourceProvider(ITYPE_IME).setClientVisible(true);
+        imeSourceProvider.setClientVisible(true);
         waitUntilHandlersIdle();
         // The visibility change should trigger a traversal to notify the change.
         verify(mDisplayContent).notifyInsetsChanged(any());
 
-        getController().getSourceProvider(ITYPE_STATUS_BAR).setWindowContainer(statusBar, null,
-                null);
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
 
         getController().updateAboveInsetsState(false /* notifyInsetsChange */);
 
         // ime is below others.
-        assertNull(app.mAboveInsetsState.peekSource(ITYPE_IME));
-        assertNull(statusBar.mAboveInsetsState.peekSource(ITYPE_IME));
-        assertNull(navBar.mAboveInsetsState.peekSource(ITYPE_IME));
-        assertNotNull(ime.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNotNull(ime.mAboveInsetsState.peekSource(ITYPE_NAVIGATION_BAR));
+        assertNull(app.mAboveInsetsState.peekSource(ID_IME));
+        assertNull(statusBar.mAboveInsetsState.peekSource(ID_IME));
+        assertNull(navBar.mAboveInsetsState.peekSource(ID_IME));
+        assertNotNull(ime.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNotNull(ime.mAboveInsetsState.peekSource(ID_NAVIGATION_BAR));
 
         ime.getParent().positionChildAt(POSITION_TOP, ime, true /* includingParents */);
         getController().updateAboveInsetsState(true /* notifyInsetsChange */);
 
         // ime is above others.
-        assertNotNull(app.mAboveInsetsState.peekSource(ITYPE_IME));
-        assertNotNull(statusBar.mAboveInsetsState.peekSource(ITYPE_IME));
-        assertNotNull(navBar.mAboveInsetsState.peekSource(ITYPE_IME));
-        assertNull(ime.mAboveInsetsState.peekSource(ITYPE_STATUS_BAR));
-        assertNull(ime.mAboveInsetsState.peekSource(ITYPE_NAVIGATION_BAR));
+        assertNotNull(app.mAboveInsetsState.peekSource(ID_IME));
+        assertNotNull(statusBar.mAboveInsetsState.peekSource(ID_IME));
+        assertNotNull(navBar.mAboveInsetsState.peekSource(ID_IME));
+        assertNull(ime.mAboveInsetsState.peekSource(ID_STATUS_BAR));
+        assertNull(ime.mAboveInsetsState.peekSource(ID_NAVIGATION_BAR));
 
         verify(ime, atLeastOnce()).notifyInsetsChanged();
         verify(app, atLeastOnce()).notifyInsetsChanged();
@@ -456,7 +470,8 @@
         final WindowState ime = createWindow(null,  TYPE_INPUT_METHOD, imeToken, "ime");
         final WindowState app = createTestWindow("app");
 
-        getController().getSourceProvider(ITYPE_IME).setWindowContainer(ime, null, null);
+        getController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(ime, null, null);
         ime.getControllableInsetProvider().setServerVisible(true);
 
         app.mActivityRecord.setVisibility(true);
@@ -468,7 +483,7 @@
         assertTrue(ime.getControllableInsetProvider().getSource().isVisible());
 
         getController().updateAboveInsetsState(true /* notifyInsetsChange */);
-        assertNotNull(app.getInsetsState().peekSource(ITYPE_IME));
+        assertNotNull(app.getInsetsState().peekSource(ID_IME));
         verify(app, atLeastOnce()).notifyInsetsChanged();
 
         // Expect the app will still get IME insets even when the app was invisible.
@@ -476,7 +491,7 @@
         app.mActivityRecord.setVisible(false);
         app.setHasSurface(false);
         getController().updateAboveInsetsState(true /* notifyInsetsChange */);
-        assertNotNull(app.getInsetsState().peekSource(ITYPE_IME));
+        assertNotNull(app.getInsetsState().peekSource(ID_IME));
         verify(app, atLeastOnce()).notifyInsetsChanged();
 
         // Expect the app will get IME insets when the app is requesting visible.
@@ -484,19 +499,19 @@
         app.mActivityRecord.setVisibility(true);
         assertTrue(app.isVisibleRequested());
         getController().updateAboveInsetsState(true /* notifyInsetsChange */);
-        assertNotNull(app.getInsetsState().peekSource(ITYPE_IME));
+        assertNotNull(app.getInsetsState().peekSource(ID_IME));
         verify(app, atLeastOnce()).notifyInsetsChanged();
     }
 
     @Test
     public void testDispatchGlobalInsets() {
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
-        getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindowContainer(navBar, null,
-                null);
+        getController().getOrCreateSourceProvider(ID_NAVIGATION_BAR, navigationBars())
+                .setWindowContainer(navBar, null, null);
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        assertNull(app.getInsetsState().peekSource(ITYPE_NAVIGATION_BAR));
+        assertNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
         app.mAttrs.receiveInsetsIgnoringZOrder = true;
-        assertNotNull(app.getInsetsState().peekSource(ITYPE_NAVIGATION_BAR));
+        assertNotNull(app.getInsetsState().peekSource(ID_NAVIGATION_BAR));
     }
 
     @SetupWindows(addWindows = W_INPUT_METHOD)
@@ -506,7 +521,8 @@
         final WindowState app2 = createTestWindow("app2");
 
         makeWindowVisible(mImeWindow);
-        final InsetsSourceProvider imeInsetsProvider = getController().getSourceProvider(ITYPE_IME);
+        final InsetsSourceProvider imeInsetsProvider =
+                getController().getOrCreateSourceProvider(ID_IME, ime());
         imeInsetsProvider.setWindowContainer(mImeWindow, null, null);
         imeInsetsProvider.updateSourceFrame(mImeWindow.getFrame());
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
index 12b7c9d..e1fc0cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java
@@ -18,7 +18,6 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
-import static com.android.server.wm.LetterboxConfiguration.DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT;
@@ -26,8 +25,6 @@
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;
 import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
@@ -37,7 +34,6 @@
 
 import android.content.Context;
 import android.platform.test.annotations.Presubmit;
-import android.provider.DeviceConfig;
 
 import androidx.test.filters.SmallTest;
 
@@ -233,34 +229,6 @@
                 LetterboxConfiguration::movePositionForVerticalReachabilityToNextBottomStop);
     }
 
-    @Test
-    public void testIsCompatFakeFocusEnabledOnDevice() {
-        boolean wasFakeFocusEnabled = DeviceConfig
-                .getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, false);
-
-        // Set runtime flag to true and build time flag to false
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "true", false);
-        mLetterboxConfiguration.setIsCompatFakeFocusEnabled(false);
-        assertFalse(mLetterboxConfiguration.isCompatFakeFocusEnabled());
-
-        // Set runtime flag to false and build time flag to true
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "false", false);
-        mLetterboxConfiguration.setIsCompatFakeFocusEnabled(true);
-        assertFalse(mLetterboxConfiguration.isCompatFakeFocusEnabled());
-
-        // Set runtime flag to true so that both are enabled
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, "true", false);
-        assertTrue(mLetterboxConfiguration.isCompatFakeFocusEnabled());
-
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
-                DEVICE_CONFIG_KEY_ENABLE_COMPAT_FAKE_FOCUS, Boolean.toString(wasFakeFocusEnabled),
-                false);
-    }
-
     private void assertForHorizontalMove(int from, int expected, int expectedTime,
             boolean halfFoldPose, BiConsumer<LetterboxConfiguration, Boolean> move) {
         // We are in the current position
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index bcaf886..0db983c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -24,7 +24,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.hardware.display.DisplayManager;
@@ -32,6 +34,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.Display.Mode;
 import android.view.Surface;
+import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
 import androidx.test.filters.FlakyTest;
@@ -289,6 +292,22 @@
         assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
         assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
         assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
+
+        // Use default mode if it is animating by shell transition.
+        overrideWindow.mActivityRecord.mSurfaceAnimator.cancelAnimation();
+        registerTestTransitionPlayer();
+        final Transition transition = overrideWindow.mTransitionController.createTransition(
+                WindowManager.TRANSIT_OPEN);
+        transition.collect(overrideWindow.mActivityRecord);
+        assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
+
+        // If there will be display size change when switching from preferred mode to default mode,
+        // then keep the current preferred mode during animating.
+        mDisplayInfo = spy(mDisplayInfo);
+        final Mode defaultMode = new Mode(4321 /* width */, 1234 /* height */, LOW_REFRESH_RATE);
+        doReturn(defaultMode).when(mDisplayInfo).getDefaultMode();
+        mPolicy = new RefreshRatePolicy(mWm, mDisplayInfo, mDenylist);
+        assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
     }
 
     @Test
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 7ad5442..c1874a4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -37,6 +37,7 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -259,6 +260,51 @@
     }
 
     @Test
+    public void testCheckOpaqueIsLetterboxedWhenStrategyIsApplied() {
+        mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
+        setUpDisplaySizeWithApp(2000, 1000);
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        // Translucent Activity
+        final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+                .setLaunchedFromUid(mActivity.getUid())
+                .build();
+        doReturn(false).when(translucentActivity).fillsParent();
+        spyOn(mActivity);
+        mTask.addChild(translucentActivity);
+        verify(mActivity).isFinishing();
+    }
+
+    @Test
+    public void testTranslucentActivitiesWhenUnfolding() {
+        mWm.mLetterboxConfiguration.setTranslucentLetterboxingOverrideEnabled(true);
+        setUpDisplaySizeWithApp(2800, 1400);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mActivity.mWmService.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
+                1.0f /*letterboxVerticalPositionMultiplier*/);
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
+        // We launch a transparent activity
+        final ActivityRecord translucentActivity = new ActivityBuilder(mAtm)
+                .setLaunchedFromUid(mActivity.getUid())
+                .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+                .build();
+        doReturn(false).when(translucentActivity).fillsParent();
+        mTask.addChild(translucentActivity);
+
+        mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        spyOn(mActivity);
+
+        // Halffold
+        setFoldablePosture(translucentActivity, true /* isHalfFolded */, false /* isTabletop */);
+        verify(mActivity).recomputeConfiguration();
+        clearInvocations(mActivity);
+
+        // Unfold
+        setFoldablePosture(translucentActivity, false /* isHalfFolded */, false /* isTabletop */);
+        verify(mActivity).recomputeConfiguration();
+    }
+
+    @Test
     public void testRestartProcessIfVisible() {
         setUpDisplaySizeWithApp(1000, 2500);
         doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
@@ -1440,7 +1486,7 @@
         // The activity doesn't fill the display, so the letterbox of the rotated activity is
         // overlapped with the rotated content frame of status bar. Hence the status bar shouldn't
         // be transparent.
-        assertFalse(displayPolicy.isFullyTransparentAllowed(w, ITYPE_STATUS_BAR));
+        assertFalse(displayPolicy.isFullyTransparentAllowed(w, statusBars()));
 
         // Activity is sandboxed.
         assertActivityMaxBoundsSandboxed();
@@ -1453,7 +1499,7 @@
 
         // The letterbox should only cover the notch area, so status bar can be transparent.
         assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
-        assertTrue(displayPolicy.isFullyTransparentAllowed(w, ITYPE_STATUS_BAR));
+        assertTrue(displayPolicy.isFullyTransparentAllowed(w, statusBars()));
         assertActivityMaxBoundsSandboxed();
 
         // The insets state for metrics should be rotated (landscape).
@@ -1895,6 +1941,43 @@
     }
 
     @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION})
+    public void testOverrideRespectRequestedOrientationIsEnabled_orientationIsRespected() {
+        // Set up a display in landscape
+        setUpDisplaySizeWithApp(2800, 1400);
+
+        final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */ false,
+                RESIZE_MODE_UNRESIZEABLE, SCREEN_ORIENTATION_PORTRAIT);
+        activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+
+        // Display should be rotated.
+        assertEquals(SCREEN_ORIENTATION_PORTRAIT, activity.mDisplayContent.getOrientation());
+
+        // No size compat mode
+        assertFalse(activity.inSizeCompatMode());
+    }
+
+    @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION})
+    public void testOverrideRespectRequestedOrientationIsEnabled_multiWindow_orientationIgnored() {
+        // Set up a display in landscape
+        setUpDisplaySizeWithApp(2800, 1400);
+
+        final ActivityRecord activity = buildActivityRecord(/* supportsSizeChanges= */ false,
+                RESIZE_MODE_UNRESIZEABLE, SCREEN_ORIENTATION_PORTRAIT);
+        TaskFragment taskFragment = activity.getTaskFragment();
+        spyOn(taskFragment);
+        activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        doReturn(WINDOWING_MODE_MULTI_WINDOW).when(taskFragment).getWindowingMode();
+
+        // Display should not be rotated.
+        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, activity.mDisplayContent.getOrientation());
+
+        // No size compat mode
+        assertFalse(activity.inSizeCompatMode());
+    }
+
+    @Test
     public void testSplitAspectRatioForUnresizableLandscapeApps() {
         // Set up a display in portrait and ignoring orientation request.
         int screenWidth = 1400;
@@ -3302,14 +3385,20 @@
 
     }
 
-    private void setFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
-        final DisplayRotation r = mActivity.mDisplayContent.getDisplayRotation();
+    private void setFoldablePosture(ActivityRecord activity, boolean isHalfFolded,
+            boolean isTabletop) {
+        final DisplayRotation r = activity.mDisplayContent.getDisplayRotation();
         doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();
         doReturn(false).when(r).isDeviceInPosture(any(DeviceState.class), anyBoolean());
         if (isHalfFolded) {
-            doReturn(true).when(r).isDeviceInPosture(DeviceState.HALF_FOLDED, isTabletop);
+            doReturn(true).when(r)
+                    .isDeviceInPosture(DeviceState.HALF_FOLDED, isTabletop);
         }
-        mActivity.recomputeConfiguration();
+        activity.recomputeConfiguration();
+    }
+
+    private void setFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
+        setFoldablePosture(mActivity, isHalfFolded, isTabletop);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
new file mode 100644
index 0000000..a27a5fd
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Class for testing {@link SurfaceControl}.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:SurfaceControlTests
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class SurfaceControlTests {
+
+    @SmallTest
+    @Test
+    public void testUseValidSurface() {
+        SurfaceControl sc = buildTestSurface();
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        t.setVisibility(sc, false);
+        sc.release();
+    }
+
+    @SmallTest
+    @Test
+    public void testUseInvalidSurface() {
+        SurfaceControl sc = buildTestSurface();
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        sc.release();
+        try {
+            t.setVisibility(sc, false);
+            fail("Expected exception from updating invalid surface");
+        } catch (Exception e) {
+            // Expected exception
+        }
+    }
+
+    @SmallTest
+    @Test
+    public void testUseInvalidSurface_debugEnabled() {
+        SurfaceControl sc = buildTestSurface();
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        try {
+            SurfaceControl.setDebugUsageAfterRelease(true);
+            sc.release();
+            try {
+                t.setVisibility(sc, false);
+                fail("Expected exception from updating invalid surface");
+            } catch (IllegalStateException ise) {
+                assertNotNull(ise.getCause());
+            } catch (Exception e) {
+                fail("Expected IllegalStateException with cause");
+            }
+        } finally {
+            SurfaceControl.setDebugUsageAfterRelease(false);
+        }
+    }
+
+    @SmallTest
+    @Test
+    public void testWriteInvalidSurface_debugEnabled() {
+        SurfaceControl sc = buildTestSurface();
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        Parcel p = Parcel.obtain();
+        try {
+            SurfaceControl.setDebugUsageAfterRelease(true);
+            sc.release();
+            try {
+                sc.writeToParcel(p, 0 /* flags */);
+                fail("Expected exception from writing invalid surface to parcel");
+            } catch (IllegalStateException ise) {
+                assertNotNull(ise.getCause());
+            } catch (Exception e) {
+                fail("Expected IllegalStateException with cause");
+            }
+        } finally {
+            SurfaceControl.setDebugUsageAfterRelease(false);
+            p.recycle();
+        }
+    }
+
+    private SurfaceControl buildTestSurface() {
+        return new SurfaceControl.Builder()
+                .setContainerLayer()
+                .setName("SurfaceControlTests")
+                .setCallsite("SurfaceControlTests")
+                .build();
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
index 22d72ed..c538727 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncGroupTest.java
@@ -54,11 +54,11 @@
         final CountDownLatch finishedLatch = new CountDownLatch(1);
         SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
         syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown);
-        SyncTarget syncTarget = new SyncTarget();
+        SurfaceSyncGroup syncTarget = new SurfaceSyncGroup("FakeSyncTarget");
         syncGroup.add(syncTarget, null /* runnable */);
         syncGroup.markSyncReady();
 
-        syncTarget.onBufferReady();
+        syncTarget.markSyncReady();
 
         finishedLatch.await(5, TimeUnit.SECONDS);
         assertEquals(0, finishedLatch.getCount());
@@ -69,22 +69,22 @@
         final CountDownLatch finishedLatch = new CountDownLatch(1);
         SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
         syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown);
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
-        SyncTarget syncTarget3 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
+        SurfaceSyncGroup syncTarget3 = new SurfaceSyncGroup("FakeSyncTarget3");
 
         syncGroup.add(syncTarget1, null /* runnable */);
         syncGroup.add(syncTarget2, null /* runnable */);
         syncGroup.add(syncTarget3, null /* runnable */);
         syncGroup.markSyncReady();
 
-        syncTarget1.onBufferReady();
+        syncTarget1.markSyncReady();
         assertNotEquals(0, finishedLatch.getCount());
 
-        syncTarget3.onBufferReady();
+        syncTarget3.markSyncReady();
         assertNotEquals(0, finishedLatch.getCount());
 
-        syncTarget2.onBufferReady();
+        syncTarget2.markSyncReady();
 
         finishedLatch.await(5, TimeUnit.SECONDS);
         assertEquals(0, finishedLatch.getCount());
@@ -94,8 +94,8 @@
     public void testAddSyncWhenSyncComplete() {
         SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
 
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
 
         assertTrue(syncGroup.add(syncTarget1, null /* runnable */));
         syncGroup.markSyncReady();
@@ -114,21 +114,21 @@
         syncGroup1.addSyncCompleteCallback(mExecutor, finishedLatch1::countDown);
         syncGroup2.addSyncCompleteCallback(mExecutor, finishedLatch2::countDown);
 
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
 
         assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
         assertTrue(syncGroup2.add(syncTarget2, null /* runnable */));
         syncGroup1.markSyncReady();
         syncGroup2.markSyncReady();
 
-        syncTarget1.onBufferReady();
+        syncTarget1.markSyncReady();
 
         finishedLatch1.await(5, TimeUnit.SECONDS);
         assertEquals(0, finishedLatch1.getCount());
         assertNotEquals(0, finishedLatch2.getCount());
 
-        syncTarget2.onBufferReady();
+        syncTarget2.markSyncReady();
 
         finishedLatch2.await(5, TimeUnit.SECONDS);
         assertEquals(0, finishedLatch2.getCount());
@@ -144,8 +144,8 @@
         syncGroup1.addSyncCompleteCallback(mExecutor, finishedLatch1::countDown);
         syncGroup2.addSyncCompleteCallback(mExecutor, finishedLatch2::countDown);
 
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
 
         assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
         assertTrue(syncGroup2.add(syncTarget2, null /* runnable */));
@@ -155,12 +155,12 @@
 
         // Finish syncTarget2 first to test that the syncGroup is not complete until the merged sync
         // is also done.
-        syncTarget2.onBufferReady();
+        syncTarget2.markSyncReady();
         finishedLatch2.await(1, TimeUnit.SECONDS);
         // Sync did not complete yet
         assertNotEquals(0, finishedLatch2.getCount());
 
-        syncTarget1.onBufferReady();
+        syncTarget1.markSyncReady();
 
         // The first sync will still get a callback when it's sync requirements are done.
         finishedLatch1.await(5, TimeUnit.SECONDS);
@@ -180,13 +180,13 @@
         syncGroup1.addSyncCompleteCallback(mExecutor, finishedLatch1::countDown);
         syncGroup2.addSyncCompleteCallback(mExecutor, finishedLatch2::countDown);
 
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
 
         assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
         assertTrue(syncGroup2.add(syncTarget2, null /* runnable */));
         syncGroup1.markSyncReady();
-        syncTarget1.onBufferReady();
+        syncTarget1.markSyncReady();
 
         // The first sync will still get a callback when it's sync requirements are done.
         finishedLatch1.await(5, TimeUnit.SECONDS);
@@ -194,7 +194,7 @@
 
         syncGroup2.add(syncGroup1, null /* runnable */);
         syncGroup2.markSyncReady();
-        syncTarget2.onBufferReady();
+        syncTarget2.markSyncReady();
 
         // Verify that the second sync will receive complete since the merged sync was already
         // completed before the merge.
@@ -212,9 +212,9 @@
         syncGroup1.addSyncCompleteCallback(mExecutor, finishedLatch1::countDown);
         syncGroup2.addSyncCompleteCallback(mExecutor, finishedLatch2::countDown);
 
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
-        SyncTarget syncTarget3 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
+        SurfaceSyncGroup syncTarget3 = new SurfaceSyncGroup("FakeSyncTarget3");
 
         assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
         assertTrue(syncGroup1.add(syncTarget2, null /* runnable */));
@@ -228,8 +228,8 @@
 
         // Make target1 and target3 ready, but not target2. SyncGroup2 should not be ready since
         // SyncGroup2 also waits for all of SyncGroup1 to finish, which includes target2
-        syncTarget1.onBufferReady();
-        syncTarget3.onBufferReady();
+        syncTarget1.markSyncReady();
+        syncTarget3.markSyncReady();
 
         // Neither SyncGroup will be ready.
         finishedLatch1.await(1, TimeUnit.SECONDS);
@@ -238,7 +238,7 @@
         assertEquals(1, finishedLatch1.getCount());
         assertEquals(1, finishedLatch2.getCount());
 
-        syncTarget2.onBufferReady();
+        syncTarget2.markSyncReady();
 
         // Both sync groups should be ready after target2 completed.
         finishedLatch1.await(5, TimeUnit.SECONDS);
@@ -257,13 +257,13 @@
         syncGroup1.addSyncCompleteCallback(mExecutor, finishedLatch1::countDown);
         syncGroup2.addSyncCompleteCallback(mExecutor, finishedLatch2::countDown);
 
-        SyncTarget syncTarget1 = new SyncTarget();
-        SyncTarget syncTarget2 = new SyncTarget();
-        SyncTarget syncTarget3 = new SyncTarget();
+        SurfaceSyncGroup syncTarget1 = new SurfaceSyncGroup("FakeSyncTarget1");
+        SurfaceSyncGroup syncTarget2 = new SurfaceSyncGroup("FakeSyncTarget2");
+        SurfaceSyncGroup syncTarget3 = new SurfaceSyncGroup("FakeSyncTarget3");
 
         assertTrue(syncGroup1.add(syncTarget1, null /* runnable */));
         assertTrue(syncGroup1.add(syncTarget2, null /* runnable */));
-        syncTarget2.onBufferReady();
+        syncTarget2.markSyncReady();
 
         // Add syncTarget1 to syncGroup2 so it forces syncGroup1 into syncGroup2
         assertTrue(syncGroup2.add(syncTarget1, null /* runnable */));
@@ -272,7 +272,7 @@
         syncGroup1.markSyncReady();
         syncGroup2.markSyncReady();
 
-        syncTarget1.onBufferReady();
+        syncTarget1.markSyncReady();
 
         // Only SyncGroup1 will be ready, but SyncGroup2 still needs its own targets to be ready.
         finishedLatch1.await(1, TimeUnit.SECONDS);
@@ -281,7 +281,7 @@
         assertEquals(0, finishedLatch1.getCount());
         assertEquals(1, finishedLatch2.getCount());
 
-        syncTarget3.onBufferReady();
+        syncTarget3.markSyncReady();
 
         // SyncGroup2 is finished after target3 completed.
         finishedLatch2.await(1, TimeUnit.SECONDS);
@@ -302,7 +302,7 @@
         SurfaceControl.Transaction targetTransaction = spy(new StubTransaction());
         SurfaceSyncGroup.setTransactionFactory(() -> targetTransaction);
 
-        SyncTarget syncTarget = new SyncTarget();
+        SurfaceSyncGroup syncTarget = new SurfaceSyncGroup("FakeSyncTarget");
         assertTrue(
                 syncGroup.add(syncTarget.mISurfaceSyncGroup, true /* parentSyncGroupMerge */,
                         null /* runnable */));
@@ -329,7 +329,7 @@
         SurfaceControl.Transaction targetTransaction = spy(new StubTransaction());
         SurfaceSyncGroup.setTransactionFactory(() -> targetTransaction);
 
-        SyncTarget syncTarget = new SyncTarget();
+        SurfaceSyncGroup syncTarget = new SurfaceSyncGroup("FakeSyncTarget");
         assertTrue(syncGroup.add(syncTarget, null /* runnable */));
         syncTarget.markSyncReady();
 
@@ -344,13 +344,13 @@
         final CountDownLatch finishedLatch = new CountDownLatch(1);
         SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
         syncGroup.addSyncCompleteCallback(mExecutor, finishedLatch::countDown);
-        SyncTarget syncTarget = new SyncTarget();
+        SurfaceSyncGroup syncTarget = new SurfaceSyncGroup("FakeSyncTarget");
         syncGroup.add(syncTarget, null /* runnable */);
         // Add the syncTarget to the same syncGroup and ensure it doesn't crash.
         syncGroup.add(syncTarget, null /* runnable */);
         syncGroup.markSyncReady();
 
-        syncTarget.onBufferReady();
+        syncTarget.markSyncReady();
 
         try {
             finishedLatch.await(5, TimeUnit.SECONDS);
@@ -359,14 +359,4 @@
         }
         assertEquals(0, finishedLatch.getCount());
     }
-
-    private static class SyncTarget extends SurfaceSyncGroup {
-        SyncTarget() {
-            super("FakeSyncTarget");
-        }
-
-        void onBufferReady() {
-            markSyncReady();
-        }
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 42bbd2d..f4a266c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -352,6 +352,7 @@
         mAtmService.setWindowManager(mWmService);
         mWmService.mDisplayEnabled = true;
         mWmService.mDisplayReady = true;
+        mAtmService.getTransitionController().mIsWaitingForDisplayEnabled = false;
         // Set configuration for default display
         mWmService.getDefaultDisplayContentLocked().reconfigureDisplayLocked();
 
@@ -419,6 +420,7 @@
         LocalServices.removeServiceForTest(UsageStatsManagerInternal.class);
         LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
         LocalServices.removeServiceForTest(UserManagerInternal.class);
+        LocalServices.removeServiceForTest(ImeTargetVisibilityPolicy.class);
     }
 
     Description getDescription() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 40e8273..378e8be 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -352,6 +352,8 @@
         final int pid = Binder.getCallingPid();
         final int uid = Binder.getCallingUid();
         final ActivityRecord activity = createActivityRecord(mDisplayContent);
+        // Flush EVENT_APPEARED.
+        mController.dispatchPendingEvents();
         final Task task = activity.getTask();
         activity.info.applicationInfo.uid = uid;
         doReturn(pid).when(activity).getPid();
@@ -379,6 +381,8 @@
                 DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
         activity.reparent(taskFragment, POSITION_TOP);
         activity.mLastTaskFragmentOrganizerBeforePip = null;
+        // Flush EVENT_INFO_CHANGED.
+        mController.dispatchPendingEvents();
 
         // Clear invocations now because there will be another transaction for the TaskFragment
         // change above, triggered by the reparent. We only want to test onActivityReparentedToTask
@@ -400,6 +404,8 @@
         final Task task = createTask(mDisplayContent);
         task.addChild(mTaskFragment, POSITION_TOP);
         final ActivityRecord activity = createActivityRecord(task);
+        // Flush EVENT_APPEARED.
+        mController.dispatchPendingEvents();
 
         // Make sure the activity belongs to the same app, but it is in a different pid.
         activity.info.applicationInfo.uid = uid;
@@ -442,6 +448,8 @@
         final Task task = createTask(mDisplayContent);
         task.addChild(mTaskFragment, POSITION_TOP);
         final ActivityRecord activity = createActivityRecord(task);
+        // Flush EVENT_APPEARED.
+        mController.dispatchPendingEvents();
 
         // Make sure the activity is embedded in untrusted mode.
         activity.info.applicationInfo.uid = uid + 1;
@@ -503,7 +511,7 @@
     public void testApplyTransaction_enforceConfigurationChangeOnOrganizedTaskFragment() {
         // Throw exception if the transaction is trying to change a window that is not organized by
         // the organizer.
-        mTransaction.setBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
+        mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
 
         assertApplyTransactionDisallowed(mTransaction);
 
@@ -1146,10 +1154,12 @@
         setupTaskFragmentInPip();
         spyOn(mWindowOrganizerController);
 
-        // Set bounds is ignored on a TaskFragment that is in a PIP Task.
-        mTransaction.setBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
+        // Set relative bounds is ignored on a TaskFragment that is in a PIP Task.
+        mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
 
-        verify(mTaskFragment, never()).setBounds(any());
+        assertApplyTransactionAllowed(mTransaction);
+
+        verify(mTaskFragment, never()).setRelativeEmbeddedBounds(any());
     }
 
     @Test
@@ -1360,7 +1370,7 @@
     }
 
     /**
-     * For config change to untrusted embedded TaskFragment, we only allow bounds change within
+     * For config change to untrusted embedded TaskFragment, the bounds should be always within
      * its parent bounds.
      */
     @Test
@@ -1370,51 +1380,17 @@
         doReturn(false).when(mTaskFragment).isAllowedToBeEmbeddedInTrustedMode();
         final Task task = createTask(mDisplayContent);
         final Rect taskBounds = new Rect(task.getBounds());
-        final Rect taskAppBounds = new Rect(task.getWindowConfiguration().getAppBounds());
-        final int taskScreenWidthDp = task.getConfiguration().screenWidthDp;
-        final int taskScreenHeightDp = task.getConfiguration().screenHeightDp;
-        final int taskSmallestScreenWidthDp = task.getConfiguration().smallestScreenWidthDp;
         task.addChild(mTaskFragment, POSITION_TOP);
 
-        // Throw exception if the transaction is trying to change bounds of an untrusted outside of
-        // its parent's.
-
-        // setBounds
+        // When set a relative bounds outside of its parent's, it is allowed, but the actual
+        // TaskFragment bounds will be updated to be fit the parent's bounds.
         final Rect tfBounds = new Rect(taskBounds);
         tfBounds.right++;
-        mTransaction.setBounds(mFragmentWindowToken, tfBounds);
-        assertApplyTransactionDisallowed(mTransaction);
-
-        mTransaction.setBounds(mFragmentWindowToken, taskBounds);
+        mTransaction.setRelativeBounds(mFragmentWindowToken, tfBounds);
         assertApplyTransactionAllowed(mTransaction);
 
-        // setAppBounds
-        final Rect tfAppBounds = new Rect(taskAppBounds);
-        tfAppBounds.right++;
-        mTransaction.setAppBounds(mFragmentWindowToken, tfAppBounds);
-        assertApplyTransactionDisallowed(mTransaction);
-
-        mTransaction.setAppBounds(mFragmentWindowToken, taskAppBounds);
-        assertApplyTransactionAllowed(mTransaction);
-
-        // setScreenSizeDp
-        mTransaction.setScreenSizeDp(mFragmentWindowToken, taskScreenWidthDp + 1,
-                taskScreenHeightDp + 1);
-        assertApplyTransactionDisallowed(mTransaction);
-
-        mTransaction.setScreenSizeDp(mFragmentWindowToken, taskScreenWidthDp, taskScreenHeightDp);
-        assertApplyTransactionAllowed(mTransaction);
-
-        // setSmallestScreenWidthDp
-        mTransaction.setSmallestScreenWidthDp(mFragmentWindowToken, taskSmallestScreenWidthDp + 1);
-        assertApplyTransactionDisallowed(mTransaction);
-
-        mTransaction.setSmallestScreenWidthDp(mFragmentWindowToken, taskSmallestScreenWidthDp);
-        assertApplyTransactionAllowed(mTransaction);
-
-        // Any of the change mask is not allowed.
-        mTransaction.setFocusable(mFragmentWindowToken, false);
-        assertApplyTransactionDisallowed(mTransaction);
+        assertEquals(tfBounds, mTaskFragment.getRelativeEmbeddedBounds());
+        assertEquals(taskBounds, mTaskFragment.getBounds());
     }
 
     // TODO(b/232871351): add test for minimum dimension violation in startActivityInTaskFragment
@@ -1446,7 +1422,7 @@
     }
 
     @Test
-    public void testMinDimensionViolation_SetBounds() {
+    public void testMinDimensionViolation_setRelativeBounds() {
         final Task task = createTask(mDisplayContent);
         mTaskFragment = new TaskFragmentBuilder(mAtm)
                 .setParentTask(task)
@@ -1464,12 +1440,14 @@
 
         // Shrink the TaskFragment to mTaskFragBounds to make its bounds smaller than activity's
         // minimum dimensions.
-        mTransaction.setBounds(mTaskFragment.mRemoteToken.toWindowContainerToken(), mTaskFragBounds)
+        mTransaction.setRelativeBounds(mTaskFragment.mRemoteToken.toWindowContainerToken(),
+                        mTaskFragBounds)
                 .setErrorCallbackToken(mErrorToken);
         assertApplyTransactionAllowed(mTransaction);
 
-        assertWithMessage("setBounds must not be performed.")
-                .that(mTaskFragment.getBounds()).isEqualTo(task.getBounds());
+        // When the requested bounds do not satisfy the min dimension, it will be reset to empty.
+        assertWithMessage("setRelativeBounds must not be performed.")
+                .that(mTaskFragment.getRelativeEmbeddedBounds()).isEqualTo(new Rect());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index 5099869..dab842c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -45,11 +45,13 @@
 import static org.mockito.Mockito.clearInvocations;
 
 import android.content.res.Configuration;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
 import android.view.SurfaceControl;
 import android.window.ITaskFragmentOrganizer;
+import android.window.TaskFragmentAnimationParams;
 import android.window.TaskFragmentInfo;
 import android.window.TaskFragmentOrganizer;
 
@@ -299,35 +301,44 @@
 
     @Test
     public void testEmbeddedTaskFragmentEnterPip_singleActivity_resetOrganizerOverrideConfig() {
-        final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
-                .setOrganizer(mOrganizer)
-                .setFragmentToken(new Binder())
-                .setCreateParentTask()
-                .createActivityCount(1)
+        final Task task = createTask(mDisplayContent);
+        final TaskFragment taskFragment0 = createTaskFragmentWithEmbeddedActivity(task, mOrganizer);
+        final TaskFragment taskFragment1 = new TaskFragmentBuilder(mAtm)
+                .setParentTask(task)
                 .build();
-        final Task task = taskFragment.getTask();
-        final ActivityRecord activity = taskFragment.getTopMostActivity();
+        final ActivityRecord activity = taskFragment0.getTopMostActivity();
         final Rect taskFragmentBounds = new Rect(0, 0, 300, 1000);
         task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        taskFragment.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        taskFragment.setBounds(taskFragmentBounds);
+        taskFragment0.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        taskFragment0.setBounds(taskFragmentBounds);
+        taskFragment0.setAdjacentTaskFragment(taskFragment1);
+        taskFragment0.setCompanionTaskFragment(taskFragment1);
+        taskFragment0.setAnimationParams(new TaskFragmentAnimationParams.Builder()
+                .setAnimationBackgroundColor(Color.GREEN)
+                .build());
 
         assertEquals(taskFragmentBounds, activity.getBounds());
         assertEquals(WINDOWING_MODE_MULTI_WINDOW, activity.getWindowingMode());
+        assertEquals(taskFragment1, taskFragment0.getAdjacentTaskFragment());
+        assertEquals(taskFragment1, taskFragment0.getCompanionTaskFragment());
+        assertNotEquals(TaskFragmentAnimationParams.DEFAULT, taskFragment0.getAnimationParams());
 
         // Move activity to pinned root task.
         mRootWindowContainer.moveActivityToPinnedRootTask(activity,
                 null /* launchIntoPipHostActivity */, "test");
 
         // Ensure taskFragment requested config is reset.
-        assertEquals(taskFragment, activity.getOrganizedTaskFragment());
+        assertEquals(taskFragment0, activity.getOrganizedTaskFragment());
         assertEquals(task, activity.getTask());
         assertTrue(task.inPinnedWindowingMode());
-        assertTrue(taskFragment.inPinnedWindowingMode());
+        assertTrue(taskFragment0.inPinnedWindowingMode());
         final Rect taskBounds = task.getBounds();
-        assertEquals(taskBounds, taskFragment.getBounds());
+        assertEquals(taskBounds, taskFragment0.getBounds());
         assertEquals(taskBounds, activity.getBounds());
-        assertEquals(Configuration.EMPTY, taskFragment.getRequestedOverrideConfiguration());
+        assertEquals(Configuration.EMPTY, taskFragment0.getRequestedOverrideConfiguration());
+        assertNull(taskFragment0.getAdjacentTaskFragment());
+        assertNull(taskFragment0.getCompanionTaskFragment());
+        assertEquals(TaskFragmentAnimationParams.DEFAULT, taskFragment0.getAnimationParams());
         // Because the whole Task is entering PiP, no need to record for future reparent.
         assertNull(activity.mLastTaskFragmentOrganizerBeforePip);
     }
@@ -335,18 +346,8 @@
     @Test
     public void testEmbeddedTaskFragmentEnterPip_multiActivities_notifyOrganizer() {
         final Task task = createTask(mDisplayContent);
-        final TaskFragment taskFragment0 = new TaskFragmentBuilder(mAtm)
-                .setParentTask(task)
-                .setOrganizer(mOrganizer)
-                .setFragmentToken(new Binder())
-                .createActivityCount(1)
-                .build();
-        final TaskFragment taskFragment1 = new TaskFragmentBuilder(mAtm)
-                .setParentTask(task)
-                .setOrganizer(mOrganizer)
-                .setFragmentToken(new Binder())
-                .createActivityCount(1)
-                .build();
+        final TaskFragment taskFragment0 = createTaskFragmentWithEmbeddedActivity(task, mOrganizer);
+        final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, mOrganizer);
         final ActivityRecord activity0 = taskFragment0.getTopMostActivity();
         final ActivityRecord activity1 = taskFragment1.getTopMostActivity();
         activity0.setVisibility(true /* visible */, false /* deferHidingClient */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index e7813ff..2bfc5ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -56,6 +56,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.Gravity;
 import android.view.InsetsState;
+import android.view.WindowInsets;
 
 import androidx.test.filters.SmallTest;
 
@@ -1918,16 +1919,20 @@
 
         state.setDisplayFrame(displayFrame);
         if (sl > dl) {
-            state.getSource(ITYPE_CLIMATE_BAR).setFrame(dl, dt, sl, db);
+            state.getOrCreateSource(ITYPE_CLIMATE_BAR, WindowInsets.Type.statusBars())
+                    .setFrame(dl, dt, sl, db);
         }
         if (st > dt) {
-            state.getSource(ITYPE_STATUS_BAR).setFrame(dl, dt, dr, st);
+            state.getOrCreateSource(ITYPE_STATUS_BAR, WindowInsets.Type.statusBars())
+                    .setFrame(dl, dt, dr, st);
         }
         if (sr < dr) {
-            state.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setFrame(sr, dt, dr, db);
+            state.getOrCreateSource(ITYPE_EXTRA_NAVIGATION_BAR, WindowInsets.Type.navigationBars())
+                    .setFrame(sr, dt, dr, db);
         }
         if (sb < db) {
-            state.getSource(ITYPE_NAVIGATION_BAR).setFrame(dl, sb, dr, db);
+            state.getOrCreateSource(ITYPE_NAVIGATION_BAR, WindowInsets.Type.navigationBars())
+                    .setFrame(dl, sb, dr, db);
         }
         // Recompute config and push to children.
         display.onRequestedOverrideConfigurationChanged(display.getConfiguration());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index 83be4f0..fec079b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -27,8 +27,10 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 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 android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -51,8 +53,9 @@
     public static final int DEFAULT_LOGICAL_DISPLAY_DENSITY = 300;
 
     /** Please use the {@link Builder} to create, visible for use in test builder overrides only. */
-    TestDisplayContent(RootWindowContainer rootWindowContainer, Display display) {
-        super(display, rootWindowContainer);
+    TestDisplayContent(RootWindowContainer rootWindowContainer, Display display,
+            @NonNull DeviceStateController deviceStateController) {
+        super(display, rootWindowContainer, deviceStateController);
         // Normally this comes from display-properties as exposed by WM. Without that, just
         // hard-code to FULLSCREEN for tests.
         setWindowingMode(WINDOWING_MODE_FULLSCREEN);
@@ -97,6 +100,8 @@
         private int mStatusBarHeight = 0;
         private SettingsEntry mOverrideSettings;
         private DisplayMetrics mDisplayMetrics;
+        @NonNull
+        private DeviceStateController mDeviceStateController = mock(DeviceStateController.class);
         @Mock
         Context mMockContext;
         @Mock
@@ -198,8 +203,13 @@
                         com.android.internal.R.dimen.default_minimal_size_resizable_task);
             return this;
         }
+        Builder setDeviceStateController(@NonNull DeviceStateController deviceStateController) {
+            mDeviceStateController = deviceStateController;
+            return this;
+        }
         TestDisplayContent createInternal(Display display) {
-            return new TestDisplayContent(mService.mRootWindowContainer, display);
+            return new TestDisplayContent(mService.mRootWindowContainer, display,
+                    mDeviceStateController);
         }
         TestDisplayContent build() {
             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 9018138..f56fae9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -106,10 +106,8 @@
     private BLASTSyncEngine mSyncEngine;
 
     private Transition createTestTransition(int transitType) {
-        TransitionTracer tracer = mock(TransitionTracer.class);
-        final TransitionController controller = new TransitionController(
-                mock(ActivityTaskManagerService.class), mock(TaskSnapshotController.class),
-                mock(TransitionTracer.class));
+        final TransitionController controller = new TestTransitionController(
+                mock(ActivityTaskManagerService.class));
 
         mSyncEngine = createTestBLASTSyncEngine();
         final Transition t = new Transition(transitType, 0 /* flags */, controller, mSyncEngine);
@@ -664,6 +662,10 @@
         changeInChange.setVisibleRequested(true);
         openInOpen.setVisibleRequested(true);
         openInChange.setVisibleRequested(true);
+        // Force the change-type changes to be "dirty" so they aren't skipped
+        changes.get(changeTask).mKnownConfigChanges = 1;
+        changes.get(changeInChangeTask).mKnownConfigChanges = 1;
+        changes.get(changeInChange).mKnownConfigChanges = 1;
 
         final int transit = transition.mType;
         int flags = 0;
@@ -718,7 +720,7 @@
         changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */));
         fillChangeMap(changes, newTask);
         // End states.
-        closing.setVisibleRequested(true);
+        closing.setVisibleRequested(false);
         opening.setVisibleRequested(true);
 
         final int transit = transition.mType;
@@ -759,7 +761,7 @@
         changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */));
         fillChangeMap(changes, newTask);
         // End states.
-        closing.setVisibleRequested(true);
+        closing.setVisibleRequested(false);
         opening.setVisibleRequested(true);
 
         final int transit = transition.mType;
@@ -780,8 +782,7 @@
 
     @Test
     public void testTimeout() {
-        final TransitionController controller = new TransitionController(mAtm,
-                mock(TaskSnapshotController.class), mock(TransitionTracer.class));
+        final TransitionController controller = new TestTransitionController(mAtm);
         final BLASTSyncEngine sync = new BLASTSyncEngine(mWm);
         final CountDownLatch latch = new CountDownLatch(1);
         // When the timeout is reached, it will finish the sync-group and notify transaction ready.
@@ -1062,9 +1063,7 @@
 
     @Test
     public void testIntermediateVisibility() {
-        final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
-        final TransitionController controller = new TransitionController(mAtm, snapshotController,
-                mock(TransitionTracer.class));
+        final TransitionController controller = new TestTransitionController(mAtm);
         final ITransitionPlayer player = new ITransitionPlayer.Default();
         controller.registerTransitionPlayer(player, null /* playerProc */);
         final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -1135,10 +1134,8 @@
 
     @Test
     public void testTransientLaunch() {
-        final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
         final ArrayList<ActivityRecord> enteringAnimReports = new ArrayList<>();
-        final TransitionController controller = new TransitionController(mAtm, snapshotController,
-                mock(TransitionTracer.class)) {
+        final TransitionController controller = new TestTransitionController(mAtm) {
             @Override
             protected void dispatchLegacyAppTransitionFinished(ActivityRecord ar) {
                 if (ar.mEnteringAnimation) {
@@ -1147,6 +1144,7 @@
                 super.dispatchLegacyAppTransitionFinished(ar);
             }
         };
+        final TaskSnapshotController snapshotController = controller.mTaskSnapshotController;
         final ITransitionPlayer player = new ITransitionPlayer.Default();
         controller.registerTransitionPlayer(player, null /* playerProc */);
         final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -1211,9 +1209,7 @@
 
     @Test
     public void testNotReadyPushPop() {
-        final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
-        final TransitionController controller = new TransitionController(mAtm, snapshotController,
-                mock(TransitionTracer.class));
+        final TransitionController controller = new TestTransitionController(mAtm);
         final ITransitionPlayer player = new ITransitionPlayer.Default();
         controller.registerTransitionPlayer(player, null /* playerProc */);
         final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -1358,7 +1354,7 @@
         assertEquals(2, info.getChanges().size());
         assertFalse(info.getChanges().get(0).hasFlags(FLAG_FILLS_TASK));
         assertEquals(embeddedTf.getBounds(), info.getChanges().get(0).getEndAbsBounds());
-        assertFalse(info.getChanges().get(1).hasFlags(FLAG_FILLS_TASK));
+        assertTrue(info.getChanges().get(1).hasFlags(FLAG_FILLS_TASK));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java
index 19da718..7d13de8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerInsetsSourceProviderTest.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.statusBars;
@@ -47,7 +47,7 @@
 
     private InsetsSource mSource = new InsetsSource(ITYPE_STATUS_BAR, statusBars());
     private WindowContainerInsetsSourceProvider mProvider;
-    private InsetsSource mImeSource = new InsetsSource(ITYPE_IME, ime());
+    private InsetsSource mImeSource = new InsetsSource(ID_IME, ime());
     private WindowContainerInsetsSourceProvider mImeProvider;
 
     @Before
@@ -170,10 +170,10 @@
         final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
         statusBar.getFrame().set(0, 0, 500, 100);
         mProvider.setWindowContainer(statusBar, null, null);
-        mProvider.updateControlForFakeTarget(target);
+        mProvider.updateFakeControlTarget(target);
         assertNotNull(mProvider.getControl(target));
         assertNull(mProvider.getControl(target).getLeash());
-        mProvider.updateControlForFakeTarget(null);
+        mProvider.updateFakeControlTarget(null);
         assertNull(mProvider.getControl(target));
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index cac7745..4dd5de3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -200,7 +200,7 @@
         final WindowSurfaceController surfaceController = mock(WindowSurfaceController.class);
         doReturn(true).when(surfaceController).hasSurface();
         spyOn(win);
-        doReturn(true).when(win).isExitAnimationRunningSelfOrParent();
+        doReturn(true).when(win).isAnimationRunningSelfOrParent();
         win.mWinAnimator.mSurfaceController = surfaceController;
         win.mViewVisibility = View.VISIBLE;
         win.mHasSurface = true;
@@ -500,6 +500,51 @@
                 virtualDisplay.getDisplay().getDisplayId());
     }
 
+    @Test
+    public void testSetInTouchModeOnAllDisplays_perDisplayFocusDisabled() {
+        testSetInTouchModeOnAllDisplays(/* perDisplayFocusEnabled= */ false);
+    }
+
+    @Test
+    public void testSetInTouchModeOnAllDisplays_perDisplayFocusEnabled() {
+        testSetInTouchModeOnAllDisplays(/* perDisplayFocusEnabled= */ true);
+    }
+
+    private void testSetInTouchModeOnAllDisplays(boolean perDisplayFocusEnabled) {
+        // Create a couple of extra displays.
+        // setInTouchModeOnAllDisplays should ignore the ownFocus setting.
+        final VirtualDisplay virtualDisplay = createVirtualDisplay(/* ownFocus= */ false);
+        final VirtualDisplay virtualDisplayOwnFocus = createVirtualDisplay(/* ownFocus= */ true);
+
+        // Enable or disable global touch mode (config_perDisplayFocusEnabled setting).
+        // setInTouchModeOnAllDisplays should ignore this value.
+        Resources mockResources = mock(Resources.class);
+        spyOn(mContext);
+        when(mContext.getResources()).thenReturn(mockResources);
+        doReturn(perDisplayFocusEnabled).when(mockResources).getBoolean(
+                com.android.internal.R.bool.config_perDisplayFocusEnabled);
+
+        int callingPid = Binder.getCallingPid();
+        int callingUid = Binder.getCallingUid();
+        doReturn(false).when(mWm).checkCallingPermission(anyString(), anyString(), anyBoolean());
+        when(mWm.mAtmService.instrumentationSourceHasPermission(callingPid,
+                android.Manifest.permission.MODIFY_TOUCH_MODE_STATE)).thenReturn(true);
+
+        for (boolean inTouchMode : new boolean[]{true, false}) {
+            mWm.setInTouchModeOnAllDisplays(inTouchMode);
+            for (int i = 0; i < mWm.mRoot.mChildren.size(); ++i) {
+                DisplayContent dc = mWm.mRoot.mChildren.get(i);
+                // All displays that are not already in the desired touch mode are requested to
+                // change their touch mode.
+                if (dc.isInTouchMode() != inTouchMode) {
+                    verify(mWm.mInputManager).setInTouchMode(
+                            true, callingPid, callingUid, /* hasPermission= */ true,
+                            dc.getDisplay().getDisplayId());
+                }
+            }
+        }
+    }
+
     private VirtualDisplay createVirtualDisplay(boolean ownFocus) {
         // Create virtual display
         Point surfaceSize = new Point(
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index b2761d1..169586e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -871,6 +871,7 @@
         lastReportedTiles.clear();
         called[0] = false;
         task1.positionChildAt(POSITION_TOP, rootTask, false /* includingParents */);
+        mAtm.mTaskOrganizerController.dispatchPendingEvents();
         assertTrue(called[0]);
         assertEquals(ACTIVITY_TYPE_STANDARD, lastReportedTiles.get(0).topActivityType);
 
@@ -1124,11 +1125,11 @@
 
         final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
-        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
+        final ActivityRecord record = createActivityRecordAndDispatchPendingEvents(task);
 
         rootTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription"));
-        waitUntilHandlersIdle();
+        mAtm.mTaskOrganizerController.dispatchPendingEvents();
         assertEquals("TestDescription", o.mChangedInfo.taskDescription.getLabel());
     }
 
@@ -1288,6 +1289,8 @@
     public void testAppearDeferThenInfoChange() {
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
+        // Flush EVENT_APPEARED.
+        mAtm.mTaskOrganizerController.dispatchPendingEvents();
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
@@ -1310,6 +1313,8 @@
     public void testAppearDeferThenVanish() {
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
+        // Flush EVENT_APPEARED.
+        mAtm.mTaskOrganizerController.dispatchPendingEvents();
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
@@ -1328,7 +1333,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
-        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
+        final ActivityRecord record = createActivityRecordAndDispatchPendingEvents(task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
@@ -1358,7 +1363,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
-        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
+        final ActivityRecord record = createActivityRecordAndDispatchPendingEvents(task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
@@ -1381,7 +1386,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
-        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
+        createActivityRecordAndDispatchPendingEvents(task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
@@ -1400,7 +1405,7 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
-        final ActivityRecord record = createActivityRecord(rootTask.mDisplayContent, task);
+        final ActivityRecord record = createActivityRecordAndDispatchPendingEvents(task);
 
         // Assume layout defer
         mWm.mWindowPlacerLocked.deferLayout();
@@ -1465,13 +1470,12 @@
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
         final Task task = createTask(rootTask);
-        final ActivityRecord activity = createActivityRecord(rootTask.mDisplayContent, task);
+        final ActivityRecord activity = createActivityRecordAndDispatchPendingEvents(task);
         final ArgumentCaptor<RunningTaskInfo> infoCaptor =
                 ArgumentCaptor.forClass(RunningTaskInfo.class);
 
         assertTrue(rootTask.isOrganized());
 
-        spyOn(activity);
         doReturn(true).when(activity).inSizeCompatMode();
         doReturn(true).when(activity).isState(RESUMED);
 
@@ -1550,6 +1554,13 @@
         verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
     }
 
+    private ActivityRecord createActivityRecordAndDispatchPendingEvents(Task task) {
+        final ActivityRecord record = createActivityRecord(task);
+        // Flush EVENT_APPEARED.
+        mAtm.mTaskOrganizerController.dispatchPendingEvents();
+        return record;
+    }
+
     /**
      * Verifies that task vanished is called for a specific task.
      */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index d3e5a8a..b2d8fed 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -20,7 +20,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.Surface.ROTATION_0;
@@ -45,10 +45,8 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -103,7 +101,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -124,15 +121,6 @@
 @RunWith(WindowTestRunner.class)
 public class WindowStateTests extends WindowTestsBase {
 
-    @Before
-    public void setUp() {
-        // TODO: Let the insets source with new mode keep the visibility control, and remove this
-        // setup code. Now mTopFullscreenOpaqueWindowState will take back the control of insets
-        // visibility.
-        spyOn(mDisplayContent);
-        doNothing().when(mDisplayContent).layoutAndAssignWindowLayersIfNeeded();
-    }
-
     @Test
     public void testIsParentWindowHidden() {
         final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
@@ -437,13 +425,15 @@
         final WindowState app = mAppWindow;
         statusBar.mHasSurface = true;
         assertTrue(statusBar.isVisible());
-        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
+        mDisplayContent.getInsetsStateController()
+                .getOrCreateSourceProvider(ITYPE_STATUS_BAR, statusBars())
                 .setWindowContainer(statusBar, null /* frameProvider */,
                         null /* imeFrameProvider */);
         mDisplayContent.getInsetsStateController().onBarControlTargetChanged(
                 app, null /* fakeTopControlling */, app, null /* fakeNavControlling */);
         app.setRequestedVisibleTypes(0, statusBars());
-        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
+        mDisplayContent.getInsetsStateController()
+                .getOrCreateSourceProvider(ITYPE_STATUS_BAR, statusBars())
                 .updateClientVisibility(app);
         waitUntilHandlersIdle();
         assertFalse(statusBar.isVisible());
@@ -986,19 +976,6 @@
         assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
     }
 
-    @UseTestDisplay(addWindows = {W_ACTIVITY, W_INPUT_METHOD})
-    @Test
-    public void testNeedsRelativeLayeringToIme_systemDialog() {
-        WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY,
-                mDisplayContent,
-                "SystemDialog", true);
-        mDisplayContent.setImeLayeringTarget(mAppWindow);
-        mAppWindow.getRootTask().setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-        makeWindowVisible(mImeWindow);
-        systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
-        assertTrue(systemDialogWindow.needsRelativeLayeringToIme());
-    }
-
     @Test
     public void testSetFreezeInsetsState() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
@@ -1039,12 +1016,16 @@
         mAppWindow.mAboveInsetsState.addSource(navSource);
 
         navSource.setVisible(false);
-        assertTrue(mImeWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
-        assertFalse(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
+        assertTrue(mImeWindow.getInsetsState().isSourceOrDefaultVisible(
+                ITYPE_NAVIGATION_BAR, navigationBars()));
+        assertFalse(mAppWindow.getInsetsState().isSourceOrDefaultVisible(
+                ITYPE_NAVIGATION_BAR, navigationBars()));
 
         navSource.setVisible(true);
-        assertTrue(mImeWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
-        assertTrue(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
+        assertTrue(mImeWindow.getInsetsState().isSourceOrDefaultVisible(
+                ITYPE_NAVIGATION_BAR, navigationBars()));
+        assertTrue(mAppWindow.getInsetsState().isSourceOrDefaultVisible(
+                ITYPE_NAVIGATION_BAR, navigationBars()));
     }
 
     @Test
@@ -1069,8 +1050,8 @@
         controller.updateAboveInsetsState(false);
 
         // Expect all app windows behind IME can receive IME insets visible.
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
-        assertTrue(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertTrue(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
 
         // Simulate app plays closing transition to app2.
         app.mActivityRecord.commitVisibility(false, false);
@@ -1078,8 +1059,8 @@
         assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
 
         // Verify the IME insets is visible on app, but not for app2 during app task switching.
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
-        assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @Test
@@ -1108,8 +1089,8 @@
 
         // Expect app windows behind IME can receive IME insets visible,
         // but not for app2 in background.
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
-        assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
 
         // Simulate app plays closing transition to app2.
         // And app2 is now IME layering target but not yet to be the IME input target.
@@ -1119,8 +1100,8 @@
         assertTrue(app.mActivityRecord.mImeInsetsFrozenUntilStartInput);
 
         // Verify the IME insets is still visible on app, but not for app2 during task switching.
-        assertTrue(app.getInsetsState().getSource(ITYPE_IME).isVisible());
-        assertFalse(app2.getInsetsState().getSource(ITYPE_IME).isVisible());
+        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
+        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @SetupWindows(addWindows = W_ACTIVITY)
@@ -1165,18 +1146,18 @@
         mNotificationShadeWindow.setHasSurface(true);
         mNotificationShadeWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
         assertTrue(mNotificationShadeWindow.canBeImeTarget());
-        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindowContainer(
-                mImeWindow, null, null);
+        mDisplayContent.getInsetsStateController().getOrCreateSourceProvider(ID_IME, ime())
+                .setWindowContainer(mImeWindow, null, null);
 
         mDisplayContent.computeImeTarget(true);
         assertEquals(mNotificationShadeWindow, mDisplayContent.getImeTarget(IME_TARGET_LAYERING));
         mDisplayContent.getInsetsStateController().getRawInsetsState()
-                .setSourceVisible(ITYPE_IME, true);
+                .setSourceVisible(ID_IME, true);
 
         // Verify notificationShade can still get IME insets even windowing mode is multi-window.
         InsetsState state = mNotificationShadeWindow.getInsetsState();
-        assertNotNull(state.peekSource(ITYPE_IME));
-        assertTrue(state.getSource(ITYPE_IME).isVisible());
+        assertNotNull(state.peekSource(ID_IME));
+        assertTrue(state.isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index e5efe05..323894ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -79,6 +79,7 @@
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
 import android.hardware.display.DisplayManager;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -750,11 +751,11 @@
     }
 
     /**
-     * Creates a {@link TaskFragment} with {@link ActivityRecord} and attach it to the
+     * Creates a {@link TaskFragment} with {@link ActivityRecord}, and attaches it to the
      * {@code parentTask}.
      *
-     * @param parentTask the {@link Task} this TaskFragment is going to be attached
-     * @return the created TaskFragment
+     * @param parentTask the {@link Task} this {@link TaskFragment} is going to be attached.
+     * @return the created {@link TaskFragment}
      */
     static TaskFragment createTaskFragmentWithActivity(@NonNull Task parentTask) {
         return new TaskFragmentBuilder(parentTask.mAtmService)
@@ -763,13 +764,27 @@
                 .build();
     }
 
+    /**
+     * Creates an embedded {@link TaskFragment} organized by {@code organizer} with
+     * {@link ActivityRecord}, and attaches it to the {@code parentTask}.
+     *
+     * @param parentTask the {@link Task} this {@link TaskFragment} is going to be attached.
+     * @param organizer  the {@link TaskFragmentOrganizer} this {@link TaskFragment} is going to be
+     *                   organized by.
+     * @return the created {@link TaskFragment}
+     */
     static TaskFragment createTaskFragmentWithEmbeddedActivity(@NonNull Task parentTask,
-            TaskFragmentOrganizer organizer) {
-        return new TaskFragmentBuilder(parentTask.mAtmService)
+            @NonNull TaskFragmentOrganizer organizer) {
+        final IBinder fragmentToken = new Binder();
+        final TaskFragment taskFragment = new TaskFragmentBuilder(parentTask.mAtmService)
                 .setParentTask(parentTask)
                 .createActivityCount(1)
                 .setOrganizer(organizer)
+                .setFragmentToken(fragmentToken)
                 .build();
+        parentTask.mAtmService.mWindowOrganizerController.mLaunchTaskFragments
+                .put(fragmentToken, taskFragment);
+        return taskFragment;
     }
 
     /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */
@@ -1728,6 +1743,14 @@
         }
     }
 
+    static class TestTransitionController extends TransitionController {
+        TestTransitionController(ActivityTaskManagerService atms) {
+            super(atms);
+            mTaskSnapshotController = mock(TaskSnapshotController.class);
+            mTransitionTracer = mock(TransitionTracer.class);
+        }
+    }
+
     static class TestTransitionPlayer extends ITransitionPlayer.Stub {
         final TransitionController mController;
         final WindowOrganizerController mOrganizer;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 3ff791b..714eb4b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -16,7 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsState.ITYPE_IME;
+import static android.view.InsetsSource.ID_IME;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -39,6 +39,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
+import android.view.WindowInsets;
 import android.window.WindowContext;
 
 import androidx.test.filters.SmallTest;
@@ -262,8 +263,9 @@
     @Test
     public void testSetInsetsFrozen_notAffectImeWindowState() {
         // Pre-condition: make the IME window be controlled by IME insets provider.
-        mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_IME).setWindowContainer(
-                mDisplayContent.mInputMethodWindow, null, null);
+        mDisplayContent.getInsetsStateController()
+                .getOrCreateSourceProvider(ID_IME, WindowInsets.Type.ime())
+                .setWindowContainer(mDisplayContent.mInputMethodWindow, null, null);
 
         // Simulate an app window to be the IME layering target, assume the app window has no
         // frozen insets state by default.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 8c58158..6cf2b2d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -22,7 +22,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -32,7 +31,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
@@ -45,16 +43,21 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseBooleanArray;
 import android.view.IRecentsAnimationRunner;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
+import android.window.ScreenCapture;
 
 import androidx.test.filters.SmallTest;
 
@@ -547,26 +550,24 @@
     }
 
     @Test
-    public void testSystemDialogWindow_expectHigherThanIme_inMultiWindow() {
-        // Simulate the app window is in multi windowing mode and being IME target
-        mAppWindow.getConfiguration().windowConfiguration.setWindowingMode(
-                WINDOWING_MODE_MULTI_WINDOW);
-        mDisplayContent.setImeLayeringTarget(mAppWindow);
-        mDisplayContent.setImeInputTarget(mAppWindow);
-        makeWindowVisible(mImeWindow);
+    public void testImeScreenshotLayer() {
+        final Task task = createTask(mDisplayContent);
+        final WindowState imeAppTarget = createAppWindow(task, TYPE_APPLICATION, "imeAppTarget");
+        final Rect bounds = mImeWindow.getParentFrame();
+        final ScreenCapture.ScreenshotHardwareBuffer imeBuffer =
+                ScreenCapture.captureLayersExcluding(mImeWindow.getSurfaceControl(),
+                bounds, 1.0f, PixelFormat.RGB_565, null);
 
-        // Create a popupWindow
-        final WindowState systemDialogWindow = createWindow(null, TYPE_SECURE_SYSTEM_OVERLAY,
-                mDisplayContent, "SystemDialog", true);
-        systemDialogWindow.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
-        spyOn(systemDialogWindow);
+        spyOn(mDisplayContent.mWmService.mTaskSnapshotController);
+        doReturn(imeBuffer).when(mDisplayContent.mWmService.mTaskSnapshotController)
+                .snapshotImeFromAttachedTask(task);
 
-        mDisplayContent.assignChildLayers(mTransaction);
+        mDisplayContent.showImeScreenshot(imeAppTarget);
 
-        // Verify the surface layer of the popupWindow should higher than IME
-        verify(systemDialogWindow).needsRelativeLayeringToIme();
-        assertThat(systemDialogWindow.needsRelativeLayeringToIme()).isTrue();
-        assertZOrderGreaterThan(mTransaction, systemDialogWindow.getSurfaceControl(),
-                mDisplayContent.getImeContainer().getSurfaceControl());
+        assertEquals(imeAppTarget, mDisplayContent.mImeScreenshot.getImeTarget());
+        assertNotNull(mDisplayContent.mImeScreenshot);
+        assertZOrderGreaterThan(mTransaction,
+                mDisplayContent.mImeScreenshot.getImeScreenshotSurface(),
+                imeAppTarget.mSurfaceControl);
     }
 }
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index 133f924..9f3b52e 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -22,6 +22,10 @@
     libs: [
         "services.core",
         "android.hidl.manager-V1.0-java",
+        "android.hardware.usb.gadget-V1.0-java",
+        "android.hardware.usb.gadget-V1.1-java",
+        "android.hardware.usb.gadget-V1.2-java",
+        "android.hardware.usb.gadget-V1-java",
     ],
 
     static_libs: [
@@ -30,9 +34,5 @@
         "android.hardware.usb-V1.2-java",
         "android.hardware.usb-V1.3-java",
         "android.hardware.usb-V2-java",
-        "android.hardware.usb.gadget-V1.0-java",
-        "android.hardware.usb.gadget-V1.1-java",
-        "android.hardware.usb.gadget-V1.2-java",
-        "android.hardware.usb.gadget-V1-java",
     ],
 }
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index e1de58e..aa1d556 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -119,11 +119,11 @@
     /**
      * List of connected MIDI devices
      */
-    private final HashMap<String, UsbMidiDevice>
-            mMidiDevices = new HashMap<String, UsbMidiDevice>();
+    private final HashMap<String, UsbAlsaMidiDevice>
+            mMidiDevices = new HashMap<String, UsbAlsaMidiDevice>();
 
-    // UsbMidiDevice for USB peripheral mode (gadget) device
-    private UsbMidiDevice mPeripheralMidiDevice = null;
+    // UsbAlsaMidiDevice for USB peripheral mode (gadget) device
+    private UsbAlsaMidiDevice mPeripheralMidiDevice = null;
 
     private final HashSet<Integer> mAlsaCards = new HashSet<>();
     private final FileObserver mAlsaObserver = new FileObserver(new File(ALSA_DIRECTORY),
@@ -331,11 +331,11 @@
                 Slog.d(TAG, "numLegacyMidiOutputs:" + numLegacyMidiOutputs);
             }
 
-            UsbMidiDevice usbMidiDevice = UsbMidiDevice.create(mContext, properties,
+            UsbAlsaMidiDevice midiDevice = UsbAlsaMidiDevice.create(mContext, properties,
                     cardRec.getCardNum(), 0 /*device*/, numLegacyMidiInputs,
                     numLegacyMidiOutputs);
-            if (usbMidiDevice != null) {
-                mMidiDevices.put(deviceAddress, usbMidiDevice);
+            if (midiDevice != null) {
+                mMidiDevices.put(deviceAddress, midiDevice);
             }
         }
     }
@@ -355,10 +355,10 @@
         }
 
         // MIDI
-        UsbMidiDevice usbMidiDevice = mMidiDevices.remove(deviceAddress);
-        if (usbMidiDevice != null) {
+        UsbAlsaMidiDevice midiDevice = mMidiDevices.remove(deviceAddress);
+        if (midiDevice != null) {
             Slog.i(TAG, "USB MIDI Device Removed: " + deviceAddress);
-            IoUtils.closeQuietly(usbMidiDevice);
+            IoUtils.closeQuietly(midiDevice);
         }
 
         logDevices("usbDeviceRemoved()");
@@ -381,7 +381,7 @@
                     com.android.internal.R.string.usb_midi_peripheral_product_name));
             properties.putInt(MidiDeviceInfo.PROPERTY_ALSA_CARD, card);
             properties.putInt(MidiDeviceInfo.PROPERTY_ALSA_DEVICE, device);
-            mPeripheralMidiDevice = UsbMidiDevice.create(mContext, properties, card, device,
+            mPeripheralMidiDevice = UsbAlsaMidiDevice.create(mContext, properties, card, device,
                     1 /* numInputs */, 1 /* numOutputs */);
         } else if (!enabled && mPeripheralMidiDevice != null) {
             IoUtils.closeQuietly(mPeripheralMidiDevice);
@@ -500,9 +500,9 @@
         }
 
         for (String deviceAddr : mMidiDevices.keySet()) {
-            // A UsbMidiDevice does not have a handle to the UsbDevice anymore
-            mMidiDevices.get(deviceAddr).dump(deviceAddr, dump, "midi_devices",
-                    UsbAlsaManagerProto.MIDI_DEVICES);
+            // A UsbAlsaMidiDevice does not have a handle to the UsbDevice anymore
+            mMidiDevices.get(deviceAddr).dump(deviceAddr, dump, "alsa_midi_devices",
+                    UsbAlsaManagerProto.ALSA_MIDI_DEVICES);
         }
 
         dump.end(token);
diff --git a/services/usb/java/com/android/server/usb/UsbMidiDevice.java b/services/usb/java/com/android/server/usb/UsbAlsaMidiDevice.java
similarity index 91%
rename from services/usb/java/com/android/server/usb/UsbMidiDevice.java
rename to services/usb/java/com/android/server/usb/UsbAlsaMidiDevice.java
index d9ad703..e92c034 100644
--- a/services/usb/java/com/android/server/usb/UsbMidiDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaMidiDevice.java
@@ -10,7 +10,7 @@
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions an
+ * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
@@ -24,7 +24,7 @@
 import android.media.midi.MidiManager;
 import android.media.midi.MidiReceiver;
 import android.os.Bundle;
-import android.service.usb.UsbMidiDeviceProto;
+import android.service.usb.UsbAlsaMidiDeviceProto;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -43,8 +43,12 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
-public final class UsbMidiDevice implements Closeable {
-    private static final String TAG = "UsbMidiDevice";
+/**
+ * Opens device connections to MIDI 1.0 endpoints.
+ * These endpoints will use ALSA.
+ */
+public final class UsbAlsaMidiDevice implements Closeable {
+    private static final String TAG = "UsbAlsaMidiDevice";
 
     private final int mAlsaCard;
     private final int mAlsaDevice;
@@ -142,13 +146,13 @@
     }
 
     /**
-     * Creates an UsbMidiDevice based on the input parameters. Read/Write streams
+     * Creates an UsbAlsaMidiDevice based on the input parameters. Read/Write streams
      * will be created individually as some devices don't have the same number of
      * inputs and outputs.
      */
-    public static UsbMidiDevice create(Context context, Bundle properties, int card,
+    public static UsbAlsaMidiDevice create(Context context, Bundle properties, int card,
             int device, int numInputs, int numOutputs) {
-        UsbMidiDevice midiDevice = new UsbMidiDevice(card, device, numInputs, numOutputs);
+        UsbAlsaMidiDevice midiDevice = new UsbAlsaMidiDevice(card, device, numInputs, numOutputs);
         if (!midiDevice.register(context, properties)) {
             IoUtils.closeQuietly(midiDevice);
             Log.e(TAG, "createDeviceServer failed");
@@ -157,7 +161,7 @@
         return midiDevice;
     }
 
-    private UsbMidiDevice(int card, int device, int numInputs, int numOutputs) {
+    private UsbAlsaMidiDevice(int card, int device, int numInputs, int numOutputs) {
         mAlsaCard = card;
         mAlsaDevice = device;
         mNumInputs = numInputs;
@@ -217,7 +221,7 @@
 
         if (inputStreamCount > 0) {
             // Create input thread which will read from all output ports of the physical device
-            new Thread("UsbMidiDevice input thread") {
+            new Thread("UsbAlsaMidiDevice input thread") {
                 @Override
                 public void run() {
                     byte[] buffer = new byte[BUFFER_SIZE];
@@ -272,13 +276,13 @@
             final FileOutputStream outputStreamF = mOutputStreams[port];
             final int portF = port;
 
-            new Thread("UsbMidiDevice output thread " + port) {
+            new Thread("UsbAlsaMidiDevice output thread " + port) {
                 @Override
                 public void run() {
                     while (true) {
                         MidiEvent event;
                         try {
-                            event = (MidiEvent)eventSchedulerF.waitNextEvent();
+                            event = (MidiEvent) eventSchedulerF.waitNextEvent();
                         } catch (InterruptedException e) {
                             // try again
                             continue;
@@ -303,9 +307,9 @@
     }
 
     private boolean register(Context context, Bundle properties) {
-        MidiManager midiManager = (MidiManager)context.getSystemService(Context.MIDI_SERVICE);
+        MidiManager midiManager = context.getSystemService(MidiManager.class);
         if (midiManager == null) {
-            Log.e(TAG, "No MidiManager in UsbMidiDevice.register()");
+            Log.e(TAG, "No MidiManager in UsbAlsaMidiDevice.register()");
             return false;
         }
 
@@ -365,9 +369,9 @@
             long id) {
         long token = dump.start(idName, id);
 
-        dump.write("device_address", UsbMidiDeviceProto.DEVICE_ADDRESS, deviceAddr);
-        dump.write("card", UsbMidiDeviceProto.CARD, mAlsaCard);
-        dump.write("device", UsbMidiDeviceProto.DEVICE, mAlsaDevice);
+        dump.write("device_address", UsbAlsaMidiDeviceProto.DEVICE_ADDRESS, deviceAddr);
+        dump.write("card", UsbAlsaMidiDeviceProto.CARD, mAlsaCard);
+        dump.write("device", UsbAlsaMidiDeviceProto.DEVICE, mAlsaDevice);
 
         dump.end(token);
     }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index a480ebd..77b2638 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -44,7 +44,6 @@
 import android.debug.AdbNotifications;
 import android.debug.AdbTransportType;
 import android.debug.IAdbTransport;
-import android.hardware.usb.IUsbOperationInternal;
 import android.hardware.usb.ParcelableUsbPort;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbConfiguration;
@@ -57,7 +56,6 @@
 import android.hardware.usb.gadget.V1_0.GadgetFunction;
 import android.hardware.usb.gadget.V1_0.Status;
 import android.hardware.usb.gadget.V1_2.UsbSpeed;
-import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.BatteryManager;
 import android.os.Environment;
@@ -1351,6 +1349,9 @@
                         || (mCurrentFunctions == UsbManager.FUNCTION_NCM)) {
                     titleRes = com.android.internal.R.string.usb_tether_notification_title;
                     id = SystemMessage.NOTE_USB_TETHER;
+                } else if (mCurrentFunctions == UsbManager.FUNCTION_UVC) {
+                    titleRes = com.android.internal.R.string.usb_uvc_notification_title;
+                    id = SystemMessage.NOTE_USB_UVC;
                 } else if (mCurrentFunctions == UsbManager.FUNCTION_ACCESSORY) {
                     titleRes = com.android.internal.R.string.usb_accessory_notification_title;
                     id = SystemMessage.NOTE_USB_ACCESSORY;
@@ -1626,6 +1627,8 @@
                     int status, int mRequest, long mFunctions, boolean mChargingFunctions);
 
         public abstract void getUsbSpeedCb(int speed);
+
+        public abstract void resetCb(int status);
     }
 
     private static final class UsbHandlerLegacy extends UsbHandler {
@@ -1987,14 +1990,30 @@
             return true;
         }
 
+        /**
+         * This callback function is only applicable for USB Gadget HAL,
+         * USBHandlerLegacy does not supported it.
+         */
         @Override
         public void setCurrentUsbFunctionsCb(long functions,
                     int status, int mRequest, long mFunctions, boolean mChargingFunctions){
         }
 
+        /**
+         * This callback function is only applicable for USB Gadget HAL,
+         * USBHandlerLegacy does not supported it.
+         */
         @Override
         public void getUsbSpeedCb(int speed){
         }
+
+        /**
+         * This callback function is only applicable for USB Gadget HAL,
+         * USBHandlerLegacy does not supported it.
+         */
+        @Override
+        public void resetCb(int status){
+        }
     }
 
     private static final class UsbHandlerHal extends UsbHandler {
@@ -2146,6 +2165,7 @@
                     }
                     break;
                 case MSG_RESET_USB_GADGET:
+                    operationId = sUsbOperationCount.incrementAndGet();
                     synchronized (mGadgetProxyLock) {
                         if (mUsbGadgetHal == null) {
                             Slog.e(TAG, "reset Usb Gadget mUsbGadgetHal is null");
@@ -2159,7 +2179,7 @@
                             if (mConfigured) {
                                 mResetUsbGadgetDisableDebounce = true;
                             }
-                            mUsbGadgetHal.reset();
+                            mUsbGadgetHal.reset(operationId);
                         } catch (Exception e) {
                             Slog.e(TAG, "reset Usb Gadget failed", e);
                             mResetUsbGadgetDisableDebounce = false;
@@ -2221,6 +2241,12 @@
             mUsbSpeed = speed;
         }
 
+        @Override
+        public void resetCb(int status) {
+            if (status != Status.SUCCESS)
+                Slog.e(TAG, "resetCb fail");
+        }
+
         private void setUsbConfig(long config, boolean chargingFunctions, int operationId) {
             if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest);
             /**
@@ -2362,6 +2388,10 @@
         mHandler.getUsbSpeedCb(speed);
     }
 
+    public void resetCb(int status) {
+        mHandler.resetCb(status);
+    }
+
     /**
      * Returns a dup of the control file descriptor for the given function.
      */
@@ -2403,6 +2433,9 @@
             MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_RNDIS);
         } else if (functions == UsbManager.FUNCTION_ACCESSORY) {
             MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_ACCESSORY);
+        } else if (functions == UsbManager.FUNCTION_UVC) {
+            // MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_UVC);
+            // TODO: Add MetricsEvent for UVC?
         }
         mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, operationId);
     }
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
index bdfe60a..d47ccc7 100644
--- a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
@@ -23,6 +23,7 @@
 import android.annotation.Nullable;
 import android.hardware.usb.gadget.IUsbGadget;
 import android.hardware.usb.gadget.IUsbGadgetCallback;
+import android.hardware.usb.Status;
 import android.hardware.usb.UsbManager.UsbGadgetHalVersion;
 import android.os.ServiceManager;
 import android.os.IBinder;
@@ -139,14 +140,15 @@
     }
 
     @Override
-    public void reset() {
+    public void reset(long operationId) {
         try {
             synchronized (mGadgetProxyLock) {
-                mGadgetProxy.reset();
+                mGadgetProxy.reset(new UsbGadgetCallback(), operationId);
             }
         } catch (RemoteException e) {
             logAndPrintException(mPw,
-                    "RemoteException while calling getUsbSpeed", e);
+                    "RemoteException while calling getUsbSpeed"
+                    + ", opID:" + operationId, e);
             return;
         }
     }
@@ -155,7 +157,7 @@
     public void setCurrentUsbFunctions(int mRequest, long mFunctions,
             boolean mChargingFunctions, int timeout, long operationId) {
         try {
-            mUsbGadgetCallback = new UsbGadgetCallback(mRequest,
+            mUsbGadgetCallback = new UsbGadgetCallback(null, mRequest,
                                       mFunctions, mChargingFunctions);
             synchronized (mGadgetProxyLock) {
                 mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback,
@@ -174,6 +176,7 @@
     }
 
     private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
+        public IndentingPrintWriter mPw;
         public int mRequest;
         public long mFunctions;
         public boolean mChargingFunctions;
@@ -181,8 +184,9 @@
         UsbGadgetCallback() {
         }
 
-        UsbGadgetCallback(int request, long functions,
+        UsbGadgetCallback(IndentingPrintWriter pw, int request, long functions,
                 boolean chargingFunctions) {
+            mPw = pw;
             mRequest = request;
             mFunctions = functions;
             mChargingFunctions = chargingFunctions;
@@ -191,6 +195,15 @@
         @Override
         public void setCurrentUsbFunctionsCb(long functions,
                 int status, long transactionId) {
+            if (status == Status.SUCCESS) {
+                logAndPrint(Log.INFO, mPw, "Usb setCurrentUsbFunctionsCb"
+                + " ,functions:" + functions + " ,status:" + status
+                + " ,transactionId:" + transactionId);
+            } else {
+                logAndPrint(Log.ERROR, mPw, "Usb setCurrentUsbFunctionsCb failed"
+                + " ,functions:" + functions + " ,status:" + status
+                + " ,transactionId:" + transactionId);
+            }
             mDeviceManager.setCurrentUsbFunctionsCb(functions, status,
                     mRequest, mFunctions, mChargingFunctions);
         }
@@ -198,15 +211,38 @@
         @Override
         public void getCurrentUsbFunctionsCb(long functions,
                 int status, long transactionId) {
+            if (status == Status.SUCCESS) {
+                logAndPrint(Log.INFO, mPw, "Usb getCurrentUsbFunctionsCb"
+                + " ,functions:" + functions + " ,status:" + status
+                + " ,transactionId:" + transactionId);
+            } else {
+                logAndPrint(Log.ERROR, mPw, "Usb getCurrentUsbFunctionsCb failed"
+                + " ,functions:" + functions + " ,status:" + status
+                + " ,transactionId:" + transactionId);
+            }
             mDeviceManager.getCurrentUsbFunctionsCb(functions, status);
         }
 
         @Override
         public void getUsbSpeedCb(int speed, long transactionId) {
+            logAndPrint(Log.INFO, mPw, "getUsbSpeedCb speed:"
+                + speed + " ,transactionId:" + transactionId);
             mDeviceManager.getUsbSpeedCb(speed);
         }
 
         @Override
+        public void resetCb(int status, long transactionId) {
+            if (status == Status.SUCCESS) {
+                logAndPrint(Log.INFO, mPw, "Usb resetCb status:"
+                + status + " ,transactionId:" + transactionId);
+            } else {
+                logAndPrint(Log.ERROR, mPw, "Usb resetCb status"
+                + status + " ,transactionId:" + transactionId);
+            }
+            mDeviceManager.resetCb(status);
+        }
+
+        @Override
         public String getInterfaceHash() {
             return IUsbGadgetCallback.HASH;
         }
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
index 267247b..7b52f46 100644
--- a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
@@ -112,8 +112,11 @@
      * This function is used to reset USB gadget driver.
      * Performs USB data connection reset. The connection will disconnect and
      * reconnect.
+     *
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
      */
-    public void reset();
+    public void reset(long transactionId);
 
     /**
      * Invoked to query the version of current gadget hal implementation.
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
index 3e5ecc5..2c5fcb8 100644
--- a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
@@ -188,7 +188,7 @@
     }
 
     @Override
-    public void reset() {
+    public void reset(long transactionId) {
         try {
             synchronized(mGadgetProxyLock) {
                 if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
@@ -199,7 +199,7 @@
             }
         } catch (RemoteException e) {
             logAndPrintException(mPw,
-                    "RemoteException while calling getUsbSpeed", e);
+                    "RemoteException while calling reset", e);
             return;
         }
     }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index cc22847..b672b00 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -578,18 +578,19 @@
     public void dump(String prefix, PrintWriter pw) {
         synchronized (mLock) {
             pw.print(prefix); pw.print("mReStartPeriodSeconds="); pw.println(mReStartPeriodSeconds);
-            pw.print(prefix); pw.print("mBound=");
+            pw.print(prefix); pw.print("bound for HotwordDetectionService=");
             pw.println(mRemoteHotwordDetectionService != null
                     && mRemoteHotwordDetectionService.isBound());
+            pw.print(prefix); pw.print("bound for VisualQueryDetectionService=");
             pw.println(mRemoteVisualQueryDetectionService != null
                     && mRemoteHotwordDetectionService != null
                     && mRemoteHotwordDetectionService.isBound());
             pw.print(prefix); pw.print("mRestartCount=");
             pw.println(mRestartCount);
             pw.print(prefix); pw.print("mLastRestartInstant="); pw.println(mLastRestartInstant);
-            pw.print(prefix); pw.print("mDetectorType=");
-            pw.println(HotwordDetector.detectorTypeToString(mDetectorType));
-            pw.print(prefix); pw.println("DetectorSession(s)");
+            pw.print(prefix); pw.println("DetectorSession(s):");
+            pw.print(prefix); pw.print("Num of DetectorSession(s)=");
+            pw.println(mDetectorSessions.size());
             runForEachDetectorSessionLocked((session) -> {
                 session.dumpLocked(prefix, pw);
             });
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 0abed0b..717f4e7 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -230,7 +230,7 @@
     class LocalService extends VoiceInteractionManagerInternal {
         @Override
         public void startLocalVoiceInteraction(@NonNull IBinder callingActivity,
-                @Nullable String attributionTag, @NonNull Bundle options) {
+                @Nullable String attributionTag, @Nullable Bundle options) {
             if (DEBUG) {
                 Slog.i(TAG, "startLocalVoiceInteraction " + callingActivity);
             }
@@ -426,7 +426,7 @@
 
         // TODO: VI Make sure the caller is the current user or profile
         void startLocalVoiceInteraction(@NonNull final IBinder token,
-                @Nullable String attributionTag, @NonNull Bundle options) {
+                @Nullable String attributionTag, @Nullable Bundle options) {
             if (mImpl == null) return;
 
             final int callingUid = Binder.getCallingUid();
@@ -945,7 +945,7 @@
         }
 
         @Override
-        public void showSession(@NonNull Bundle args, int flags, @Nullable String attributionTag) {
+        public void showSession(@Nullable Bundle args, int flags, @Nullable String attributionTag) {
             synchronized (this) {
                 enforceIsCurrentVoiceInteractionService();
 
@@ -976,7 +976,7 @@
         }
 
         @Override
-        public boolean showSessionFromSession(@NonNull IBinder token, @NonNull Bundle sessionArgs,
+        public boolean showSessionFromSession(@NonNull IBinder token, @Nullable Bundle sessionArgs,
                 int flags, @Nullable String attributionTag) {
             synchronized (this) {
                 if (mImpl == null) {
@@ -1828,7 +1828,7 @@
 
         @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE)
         @Override
-        public boolean showSessionForActiveService(@NonNull Bundle args, int sourceFlags,
+        public boolean showSessionForActiveService(@Nullable Bundle args, int sourceFlags,
                 @Nullable String attributionTag,
                 @Nullable IVoiceInteractionSessionShowCallback showCallback,
                 @Nullable IBinder activityToken) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 3dbd269..ad0e921 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -986,6 +986,8 @@
         if (mHotwordDetectionConnection != null) {
             pw.println("  Hotword detection connection:");
             mHotwordDetectionConnection.dump("    ", pw);
+        } else {
+            pw.println("  No Hotword detection connection");
         }
         if (mActiveSession != null) {
             pw.println("  Active session:");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 763024f..216f45a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -51,6 +51,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -346,7 +347,8 @@
             mFgHandler.post(mSetPowerBoostRunnable);
 
             if (mLowPowerStandbyControllerInternal != null) {
-                mLowPowerStandbyControllerInternal.addToAllowlist(mCallingUid);
+                mLowPowerStandbyControllerInternal.addToAllowlist(mCallingUid,
+                        PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
                 mLowPowerStandbyAllowlisted = true;
                 mFgHandler.removeCallbacks(mRemoveFromLowPowerStandbyAllowlistRunnable);
                 mFgHandler.postDelayed(mRemoveFromLowPowerStandbyAllowlistRunnable,
@@ -861,7 +863,8 @@
         synchronized (mLock) {
             if (mLowPowerStandbyAllowlisted) {
                 mFgHandler.removeCallbacks(mRemoveFromLowPowerStandbyAllowlistRunnable);
-                mLowPowerStandbyControllerInternal.removeFromAllowlist(mCallingUid);
+                mLowPowerStandbyControllerInternal.removeFromAllowlist(mCallingUid,
+                        PowerManager.LOW_POWER_STANDBY_ALLOWED_REASON_VOICE_INTERACTION);
                 mLowPowerStandbyAllowlisted = false;
             }
         }
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 95c9061..41c70b1 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1869,8 +1869,15 @@
 
     /**
      * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
-     *
-     * Any other currently playing DTMF tone in the specified call is immediately stopped.
+     * <p>
+     * Tones are both played locally for the user to hear and sent to the network to be relayed
+     * to the remote device.
+     * <p>
+     * You must ensure that any call to {@link #playDtmfTone(char}) is followed by a matching
+     * call to {@link #stopDtmfTone()} and that each tone is stopped before a new one is started.
+     * The play and stop commands are relayed to the underlying
+     * {@link android.telecom.ConnectionService} as executed; implementations may not correctly
+     * handle out of order commands.
      *
      * @param digit A character representing the DTMF digit for which to play the tone. This
      *         value must be one of {@code '0'} through {@code '9'}, {@code '*'} or {@code '#'}.
diff --git a/telecomm/java/android/telecom/CallAttributes.java b/telecomm/java/android/telecom/CallAttributes.java
index 6d87981..1a0f192 100644
--- a/telecomm/java/android/telecom/CallAttributes.java
+++ b/telecomm/java/android/telecom/CallAttributes.java
@@ -116,13 +116,13 @@
      */
     public static final int SUPPORTS_STREAM = 1 << 2;
     /**
-     * The call can be completely transferred from one endpoint to another
+     * The call can be completely transferred from one endpoint to another.
      */
     public static final int SUPPORTS_TRANSFER = 1 << 3;
 
     /**
      * Build an instance of {@link CallAttributes}. In order to build a valid instance, a
-     * {@link PhoneAccountHandle}, call {@link Direction}, display name, and {@link Uri} address
+     * {@link PhoneAccountHandle}, call direction, display name, and {@link Uri} address
      * are required.
      *
      * <p>
@@ -165,7 +165,8 @@
         }
 
         /**
-         * @param callType see {@link CallType} for valid arguments
+         * Sets the type of call; uses to indicate if a call is a video call or audio call.
+         * @param callType The call type.
          * @return Builder
          */
         @NonNull
@@ -180,7 +181,9 @@
         }
 
         /**
-         * @param callCapabilities see {@link CallCapability} for valid arguments
+         * Sets the capabilities of this call.  Use this to indicate whether your app supports
+         * holding, streaming and call transfers.
+         * @param callCapabilities Bitmask of call capabilities.
          * @return Builder
          */
         @NonNull
diff --git a/telecomm/java/android/telecom/CallControlCallback.java b/telecomm/java/android/telecom/CallControlCallback.java
new file mode 100644
index 0000000..aadf337
--- /dev/null
+++ b/telecomm/java/android/telecom/CallControlCallback.java
@@ -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 android.telecom;
+
+import android.annotation.NonNull;
+
+import java.util.function.Consumer;
+
+/**
+ * CallControlCallback relays call updates (that require a response) from the Telecom framework out
+ * to the application.This can include operations which the app must implement on a Call due to the
+ * presence of other calls on the device, requests relayed from a Bluetooth device, or from another
+ * calling surface.
+ *
+ * <p>
+ * All CallControlCallbacks are transactional, meaning that a client must
+ * complete the {@link Consumer} via {@link Consumer#accept(Object)} in order to complete the
+ * CallControlCallbacks. If a CallControlCallbacks can be completed, the
+ * {@link Consumer#accept(Object)} should be called with {@link Boolean#TRUE}. Otherwise,
+ * {@link Consumer#accept(Object)} should be called with {@link Boolean#FALSE} to represent the
+ * CallControlCallbacks cannot be completed on the client side.
+ *
+ * <p>
+ * Note: Each CallEventCallback has a timeout of 5000 milliseconds. Failing to complete the
+ * {@link Consumer} before the timeout will result in a failed transaction.
+ */
+public interface CallControlCallback {
+    /**
+     * Telecom is informing the client to set the call active
+     *
+     * @param wasCompleted The {@link Consumer} to be completed. If the client can set the call
+     *                     active on their end, the {@link Consumer#accept(Object)} should be
+     *                     called with {@link Boolean#TRUE}. Otherwise,
+     *                     {@link Consumer#accept(Object)} should be called with
+     *                     {@link Boolean#FALSE}.
+     */
+    void onSetActive(@NonNull Consumer<Boolean> wasCompleted);
+
+    /**
+     * Telecom is informing the client to set the call inactive. This is the same as holding a call
+     * for two endpoints but can be extended to setting a meeting inactive.
+     *
+     * @param wasCompleted The {@link Consumer} to be completed. If the client can set the call
+     *                     inactive on their end, the {@link Consumer#accept(Object)} should be
+     *                     called with {@link Boolean#TRUE}. Otherwise,
+     *                     {@link Consumer#accept(Object)} should be called with
+     *                     {@link Boolean#FALSE}.
+     */
+    void onSetInactive(@NonNull Consumer<Boolean> wasCompleted);
+
+    /**
+     * Telecom is informing the client to answer an incoming call and set it to active.
+     *
+     * @param videoState   see {@link android.telecom.CallAttributes.CallType} for valid states
+     * @param wasCompleted The {@link Consumer} to be completed. If the client can answer the call
+     *                     on their end, {@link Consumer#accept(Object)} should be called with
+     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)} should
+     *                     be called with {@link Boolean#FALSE}.
+     */
+    void onAnswer(@android.telecom.CallAttributes.CallType int videoState,
+            @NonNull Consumer<Boolean> wasCompleted);
+
+    /**
+     * Telecom is informing the client to reject the incoming call
+     *
+     * @param wasCompleted The {@link Consumer} to be completed. If the client can reject the
+     *                     incoming call, {@link Consumer#accept(Object)} should be called with
+     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)}
+     *                     should  be called with {@link Boolean#FALSE}.
+     */
+    void onReject(@NonNull Consumer<Boolean> wasCompleted);
+
+    /**
+     * Telecom is informing the client to disconnect the call
+     *
+     * @param wasCompleted The {@link Consumer} to be completed. If the client can disconnect the
+     *                     call on their end, {@link Consumer#accept(Object)} should be called with
+     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)}
+     *                     should  be called with {@link Boolean#FALSE}.
+     */
+    void onDisconnect(@NonNull Consumer<Boolean> wasCompleted);
+
+    /**
+     * Telecom is informing the client to set the call in streaming.
+     *
+     * @param wasCompleted The {@link Consumer} to be completed. If the client can stream the
+     *                     call on their end, {@link Consumer#accept(Object)} should be called with
+     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)}
+     *                     should be called with {@link Boolean#FALSE}.
+     */
+    void onCallStreamingStarted(@NonNull Consumer<Boolean> wasCompleted);
+}
diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java
index 806febd..bfe3685 100644
--- a/telecomm/java/android/telecom/CallEventCallback.java
+++ b/telecomm/java/android/telecom/CallEventCallback.java
@@ -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,108 +16,22 @@
 
 package android.telecom;
 
-
 import android.annotation.NonNull;
 
 import java.util.List;
-import java.util.function.Consumer;
 
 /**
- * CallEventCallback relays updates to a call from the Telecom framework.
- * This can include operations which the app must implement on a Call due to the presence of other
- * calls on the device, requests relayed from a Bluetooth device, or from another calling surface.
- *
- * <p>
- * CallEventCallbacks with {@link Consumer}s are transactional, meaning that a client must
- * complete the {@link Consumer} via {@link Consumer#accept(Object)} in order to complete the
- * CallEventCallback. If a CallEventCallback can be completed, the
- * {@link Consumer#accept(Object)} should be called with {@link Boolean#TRUE}. Otherwise,
- * {@link Consumer#accept(Object)} should be called with {@link Boolean#FALSE} to represent the
- * CallEventCallback cannot be completed on the client side.
- *
- * <p>
- * Note: Each CallEventCallback has a timeout of 5000 milliseconds. Failing to complete the
- * {@link Consumer} before the timeout will result in a failed transaction.
+ * CallEventCallback relays call updates (that do not require any action) from the Telecom framework
+ * out to the application. This can include operations which the app must implement on a Call due to
+ * the presence of other calls on the device, requests relayed from a Bluetooth device,
+ * or from another calling surface.
  */
 public interface CallEventCallback {
     /**
-     * Telecom is informing the client to set the call active
-     *
-     * @param wasCompleted The {@link Consumer} to be completed. If the client can set the call
-     *                     active on their end, the {@link Consumer#accept(Object)} should be
-     *                     called with {@link Boolean#TRUE}. Otherwise,
-     *                     {@link Consumer#accept(Object)} should be called with
-     *                     {@link Boolean#FALSE}.
-     */
-    void onSetActive(@NonNull Consumer<Boolean> wasCompleted);
-
-    /**
-     * Telecom is informing the client to set the call inactive. This is the same as holding a call
-     * for two endpoints but can be extended to setting a meeting inactive.
-     *
-     * @param wasCompleted The {@link Consumer} to be completed. If the client can set the call
-     *                     inactive on their end, the {@link Consumer#accept(Object)} should be
-     *                     called with {@link Boolean#TRUE}. Otherwise,
-     *                     {@link Consumer#accept(Object)} should be called with
-     *                     {@link Boolean#FALSE}.
-     */
-    void onSetInactive(@NonNull Consumer<Boolean> wasCompleted);
-
-    /**
-     * Telecom is informing the client to answer an incoming call and set it to active.
-     *
-     * @param videoState   see {@link android.telecom.CallAttributes.CallType} for valid states
-     * @param wasCompleted The {@link Consumer} to be completed. If the client can answer the call
-     *                     on their end, {@link Consumer#accept(Object)} should be called with
-     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)} should
-     *                     be called with {@link Boolean#FALSE}.
-     */
-    void onAnswer(@android.telecom.CallAttributes.CallType int videoState,
-            @NonNull Consumer<Boolean> wasCompleted);
-
-    /**
-     * Telecom is informing the client to reject the incoming call
-     *
-     * @param wasCompleted The {@link Consumer} to be completed. If the client can reject the
-     *                     incoming call, {@link Consumer#accept(Object)} should be called with
-     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)}
-     *                     should  be called with {@link Boolean#FALSE}.
-     */
-    void onReject(@NonNull Consumer<Boolean> wasCompleted);
-
-    /**
-     * Telecom is informing the client to disconnect the call
-     *
-     * @param wasCompleted The {@link Consumer} to be completed. If the client can disconnect the
-     *                     call on their end, {@link Consumer#accept(Object)} should be called with
-     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)}
-     *                     should  be called with {@link Boolean#FALSE}.
-     */
-    void onDisconnect(@NonNull Consumer<Boolean> wasCompleted);
-
-    /**
-     * Telecom is informing the client to set the call in streaming.
-     *
-     * @param wasCompleted The {@link Consumer} to be completed. If the client can stream the
-     *                     call on their end, {@link Consumer#accept(Object)} should be called with
-     *                     {@link Boolean#TRUE}. Otherwise, {@link Consumer#accept(Object)}
-     *                     should be called with {@link Boolean#FALSE}.
-     */
-    void onCallStreamingStarted(@NonNull Consumer<Boolean> wasCompleted);
-
-    /**
-     * Telecom is informing the client user requested call streaming but the stream can't be
-     * started.
-     *
-     * @param reason Code to indicate the reason of this failure
-     */
-    void onCallStreamingFailed(@CallStreamingService.StreamingFailedReason int reason);
-
-    /**
      * Telecom is informing the client the current {@link CallEndpoint} changed.
      *
      * @param newCallEndpoint The new {@link CallEndpoint} through which call media flows
-     *                       (i.e. speaker, bluetooth, etc.).
+     *                        (i.e. speaker, bluetooth, etc.).
      */
     void onCallEndpointChanged(@NonNull CallEndpoint newCallEndpoint);
 
@@ -134,4 +48,12 @@
      * @param isMuted The current mute state.
      */
     void onMuteStateChanged(boolean isMuted);
+
+    /**
+     * Telecom is informing the client user requested call streaming but the stream can't be
+     * started.
+     *
+     * @param reason Code to indicate the reason of this failure
+     */
+    void onCallStreamingFailed(@CallStreamingService.StreamingFailedReason int reason);
 }
diff --git a/telecomm/java/android/telecom/CallException.java b/telecomm/java/android/telecom/CallException.java
index d191593..e554082 100644
--- a/telecomm/java/android/telecom/CallException.java
+++ b/telecomm/java/android/telecom/CallException.java
@@ -30,7 +30,7 @@
 /**
  * This class defines exceptions that can be thrown when using Telecom APIs with
  * {@link android.os.OutcomeReceiver}s.  Most of these exceptions are thrown when changing a call
- * state with {@link CallControl}s or {@link CallEventCallback}s.
+ * state with {@link CallControl}s or {@link CallControlCallback}s.
  */
 public final class CallException extends RuntimeException implements Parcelable {
     /** @hide **/
diff --git a/telecomm/java/android/telecom/CallStreamingService.java b/telecomm/java/android/telecom/CallStreamingService.java
index affa6b6..7f11128 100644
--- a/telecomm/java/android/telecom/CallStreamingService.java
+++ b/telecomm/java/android/telecom/CallStreamingService.java
@@ -79,7 +79,7 @@
                     break;
                 case MSG_CALL_STREAMING_CHANGED_CHANGED:
                     int state = (int) msg.obj;
-                    mCall.setStreamingState(state);
+                    mCall.requestStreamingState(state);
                     CallStreamingService.this.onCallStreamingStateChanged(state);
                     break;
                 default:
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 773ed70..536e458 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -81,19 +81,240 @@
  * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
  * <p>
  * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
- * before Telecom will bind to them.  Self-managed {@link ConnectionService}s must be granted the
- * appropriate permission before Telecom will bind to them.
+ * before Telecom will bind to them.  Self-managed {@link ConnectionService}s must declare the
+ * {@link android.Manifest.permission#MANAGE_OWN_CALLS} permission in their manifest before Telecom
+ * will bind to them.
  * <p>
  * Once registered and enabled by the user in the phone app settings or granted permission, telecom
  * will bind to a {@link ConnectionService} implementation when it wants that
  * {@link ConnectionService} to place a call or the service has indicated that is has an incoming
- * call through {@link TelecomManager#addNewIncomingCall}. The {@link ConnectionService} can then
- * expect a call to {@link #onCreateIncomingConnection} or {@link #onCreateOutgoingConnection}
+ * call through {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}. The
+ * {@link ConnectionService} can then expect a call to
+ * {@link #onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)} or
+ * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
  * wherein it should provide a new instance of a {@link Connection} object.  It is through this
  * {@link Connection} object that telecom receives state updates and the {@link ConnectionService}
  * receives call-commands such as answer, reject, hold and disconnect.
  * <p>
  * When there are no more live calls, telecom will unbind from the {@link ConnectionService}.
+ * <p>
+ * <h1>Self-Managed Connection Services</h1>
+ * A VoIP app can implement a {@link ConnectionService} to ensure that its calls are integrated
+ * into the Android platform.  There are numerous benefits to using the Telecom APIs for a VoIP app:
+ * <ul>
+ *     <li>Call concurrency is handled - the user is able to swap between calls in different
+ *     apps and on the mobile network.</li>
+ *     <li>Simplified audio routing - the platform provides your app with a unified list of the
+ *     audio routes which are available
+ *     (e.g. {@link android.telecom.Connection#onAvailableCallEndpointsChanged(List)}) and a
+ *     standardized way to switch audio routes
+ *     (e.g. {@link android.telecom.Connection#requestCallEndpointChange(CallEndpoint, Executor,
+ *     OutcomeReceiver)} ).</li>
+ *     <li>Bluetooth integration - your calls will be visible on and controllable via
+ *     bluetooth devices (e.g. car head units and headsets).</li>
+ *     <li>Companion device integration - wearable devices such as watches which implement an
+ *     {@link InCallService} can optionally subscribe to see self-managed calls.  Similar to a
+ *     bluetooth headunit, wearables will typically render your call using a generic call UX and
+ *     provide the user with basic call controls such as hangup, answer, reject.</li>
+ *     <li>Automotive calling experiences - Android supports automotive optimized experiences which
+ *     provides a means for calls to be controlled and viewed in an automobile; these experiences
+ *     are capable of leveraging call metadata provided by your app.</li>
+ * </ul>
+ * <h2>Registering a Phone Account</h2>
+ * Before your app can handle incoming or outgoing calls through Telecom it needs to register a
+ * {@link PhoneAccount} with Telecom indicating to the platform that your app is capable of calling.
+ * <p>
+ * Your app should create a new instance of {@link PhoneAccount} which meets the following
+ * requirements:
+ * <ul>
+ *     <li>Has {@link PhoneAccount#CAPABILITY_SELF_MANAGED} (set using
+ *     {@link PhoneAccount.Builder#setCapabilities(int)}).  This indicates to Telecom that your
+ *     app will report calls but that it provides a primary UI for the calls by itself.</li>
+ *     <li>Provide a unique identifier for the {@link PhoneAccount} via the
+ *     {@link PhoneAccountHandle#getId()} attribute.  As per the {@link PhoneAccountHandle}
+ *     documentation, you should NOT use an identifier which contains PII or other sensitive
+ *     information.  A typical choice is a UUID.</li>
+ * </ul>
+ * Your app should register the new {@link PhoneAccount} with Telecom using
+ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)}.  {@link PhoneAccount}s persist across
+ * reboot.  You can use {@link TelecomManager#getOwnSelfManagedPhoneAccounts()} to confirm the
+ * {@link PhoneAccount} you registered.  Your app should generally only register a single
+ * {@link PhoneAccount}.
+ *
+ * <h2>Implementing ConnectionService</h2>
+ * Your app uses {@link TelecomManager#placeCall(Uri, Bundle)} to start new outgoing calls and
+ * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)} to report new incoming
+ * calls.  Calling these APIs causes the Telecom stack to bind to your app's
+ * {@link ConnectionService} implementation.  Telecom will either inform your app that it cannot
+ * handle a call request at the current time (i.e. there could be an ongoing emergency call, which
+ * means your app is not allowed to handle calls at the current time), or it will ask your app to
+ * create a new instance of {@link Connection} to represent a call in your app.
+ *
+ * Your app should implement the following {@link ConnectionService} methods:
+ * <ul>
+ *     <li>{@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to ask your app to make a new {@link Connection}
+ *     to represent an outgoing call your app requested via
+ *     {@link TelecomManager#placeCall(Uri, Bundle)}.</li>
+ *     <li><{@link ConnectionService#onCreateOutgoingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to inform your app that a call it reported via
+ *     {@link TelecomManager#placeCall(Uri, Bundle)} cannot be handled at this time.  Your app
+ *     should NOT place a call at the current time.</li>
+ *     <li>{@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to ask your app to make a new {@link Connection}
+ *     to represent an incoming call your app reported via
+ *     {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}.</li>
+ *     <li>{@link ConnectionService#onCreateIncomingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - called by Telecom to inform your app that an incoming call it reported
+ *     via {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)} cannot be handled
+ *     at this time.  Your app should NOT post a new incoming call notification and should silently
+ *     reject the call.</li>
+ * </ul>
+ *
+ * <h2>Implementing a Connection</h2>
+ * Your app should extend the {@link Connection} class to represent calls in your app.  When you
+ * create new instances of your {@link Connection}, you should ensure the following properties are
+ * set on the new {@link Connection} instance returned by your {@link ConnectionService}:
+ * <ul>
+ *     <li>{@link Connection#setAddress(Uri, int)} - the identifier for the other party.  For
+ *     apps that user phone numbers the {@link Uri} can be a {@link PhoneAccount#SCHEME_TEL} URI
+ *     representing the phone number.</li>
+ *     <li>{@link Connection#setCallerDisplayName(String, int)} - the display name of the other
+ *     party.  This is what will be shown on Bluetooth devices and other calling surfaces such
+ *     as wearable devices.  This is particularly important for calls that do not use a phone
+ *     number to identify the caller or called party.</li>
+ *     <li>{@link Connection#setConnectionProperties(int)} - ensure you set
+ *     {@link Connection#PROPERTY_SELF_MANAGED} to identify to the platform that the call is
+ *     handled by your app.</li>
+ *     <li>{@link Connection#setConnectionCapabilities(int)} - if your app supports making calls
+ *     inactive (i.e. holding calls) you should get {@link Connection#CAPABILITY_SUPPORT_HOLD} and
+ *     {@link Connection#CAPABILITY_HOLD} to indicate to the platform that you calls can potentially
+ *     be held for concurrent calling scenarios.</li>
+ *     <li>{@link Connection#setAudioModeIsVoip(boolean)} - set to {@code true} to ensure that the
+ *     platform knows your call is a VoIP call.</li>
+ *     <li>For newly created {@link Connection} instances, do NOT change the state of your call
+ *     using {@link Connection#setActive()}, {@link Connection#setOnHold()} until the call is added
+ *     to Telecom (ie you have returned it via
+ *     {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
+ *     or
+ *     {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}).
+ *     </li>
+ * </ul>
+ *
+ * <h2>How to Place Outgoing Calls</h2>
+ * When your app wants to place an outgoing call it calls
+ * {@link TelecomManager#placeCall(Uri, Bundle)}.  You should specify a {@link Uri} to identify
+ * who the call is being placed to, and specify the {@link PhoneAccountHandle} associated with the
+ * {@link PhoneAccount} you registered for your app using
+ * {@link TelecomManager#EXTRA_PHONE_ACCOUNT_HANDLE} in the {@link Bundle} parameter.
+ * <p>
+ * Telecom will bind to your app's {@link ConnectionService} implementation and call either:
+ * <ul>
+ *     <li>{@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - the {@link ConnectionRequest#getAddress()} will match the address
+ *     you specified when placing the call.  You should return a new instance of your app's
+ *     {@link Connection} class to represent the outgoing call.</li>
+ *     <li>{@link ConnectionService#onCreateOutgoingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - your app should not place the call at this time; the call should be
+ *     cancelled and the user informed that the call cannot be placed.</li>
+ * </ul>
+ * <p>
+ * New outgoing calls will start in a {@link Connection#STATE_DIALING} state.  This state indicates
+ * that your app is in the process of connecting the call to the other party.
+ * <p>
+ * Once the other party answers the call (or it is set up successfully), your app should call
+ * {@link Connection#setActive()} to inform Telecom that the call is now active.
+ *
+ * <h2>How to Add Incoming Calls</h2>
+ * When your app receives an incoming call, it should call
+ * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, Bundle)}.  Set the
+ * {@link PhoneAccountHandle} parameter to the {@link PhoneAccountHandle} associated with your
+ * app's {@link PhoneAccount}.
+ * <p>
+ * Telecom will bind to your app's {@link ConnectionService} implementation and call either:
+ * <ul>
+ *     <li>{@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle,
+ *     ConnectionRequest)} - You should return a new instance of your app's
+ *     {@link Connection} class to represent the incoming call.</li>
+ *     <li>{@link ConnectionService#onCreateIncomingConnectionFailed(PhoneAccountHandle,
+ *     ConnectionRequest)} - your app should not receive the call at this time; the call should be
+ *     rejected silently; the user may be informed of a missed call.</li>
+ * </ul>
+ * <p>
+ * New incoming calls will start with a {@link Connection#STATE_RINGING} state.  This state
+ * indicates that your app has a new incoming call pending.  Telecom will NOT play a ringtone or
+ * post a notification for your app.  It is up to your app to post an incoming call notification
+ * with an associated ringtone.  Telecom will call {@link Connection#onShowIncomingCallUi()} on the
+ * {@link Connection} when your app can post its incoming call notification.  See
+ * {@link Connection#onShowIncomingCallUi() the docs} for more information on how to post the
+ * notification.
+ * <p>
+ * Your incoming call notification (or full screen UI) will typically have an "answer" and "decline"
+ * action which the user chooses.  When your app receives the "answer" or "decline"
+ * {@link android.app.PendingIntent}, you should must call either {@link Connection#setActive()} to
+ * inform Telecom that the call was answered, or
+ * {@link Connection#setDisconnected(DisconnectCause)} to inform Telecom that the call was rejected.
+ * If the call was rejected, supply an instance of {@link DisconnectCause} with
+ * {@link DisconnectCause#REJECTED}, and then call {@link Connection#destroy()}.
+ * <p>
+ * In addition to handling requests to answer or decline the call via notification actions, your
+ * app should also be implement the {@link Connection#onAnswer(int)} and
+ * {@link Connection#onAnswer()} methods on the {@link Connection}.  These will be raised if the
+ * user answers your call via a Bluetooth device or another device like a wearable or automotive
+ * calling UX.  In response, your app should call {@link Connection#setActive()} to inform Telecom
+ * that the call was answered.
+ * <p>
+ * Additionally, your app should implement {@link Connection#onReject()} to handle requests to
+ * reject the call which are raised via Bluetooth or other calling surfaces.  Your app should call
+ * {@link Connection#setDisconnected(DisconnectCause)} and supply an instance of
+ * {@link DisconnectCause} with {@link DisconnectCause#REJECTED} in this case.
+ *
+ * <h2>Ending Calls</h2>
+ * When an ongoing active call (incoming or outgoing) has ended, your app is responsible for
+ * informing Telecom that the call ended.
+ * <p>
+ * Your app calls:
+ * <ul>
+ *     <li>{@link Connection#setDisconnected(DisconnectCause)} - this informs Telecom that the
+ *     call has terminated.  You should provide a new instance of {@link DisconnectCause} with
+ *     either {@link DisconnectCause#LOCAL} or {@link DisconnectCause#REMOTE} to indicate where the
+ *     call disconnection took place.  {@link DisconnectCause#LOCAL} indicates that the call
+ *     terminated in your app on the current device (i.e. via user action), where
+ *     {@link DisconnectCause#REMOTE} indicates that the call terminates on the remote device.</li>
+ *     <li>{@link Connection#destroy()} - this informs Telecom that your call instance can be
+ *     cleaned up.  You should always call this when you are finished with a call.</li>
+ * </ul>
+ * <p>
+ * Similar to answering incoming calls, requests to disconnect your call may originate from outside
+ * your app.  You can handle these by implementing {@link Connection#onDisconnect()}.  Your app
+ * should call {@link Connection#setDisconnected(DisconnectCause)} with an instance of
+ * {@link DisconnectCause} and reason {@link DisconnectCause#LOCAL} to indicate to Telecom that your
+ * app has disconnected the call as requested based on the user's request.
+ *
+ * <h2>Holding and Unholding Calls</h2>
+ * When your app specifies {@link Connection#CAPABILITY_SUPPORT_HOLD} and
+ * {@link Connection#CAPABILITY_HOLD} on your {@link Connection} instance, it is telling Telecom
+ * that your calls can be placed into a suspended, or "held" state if required.  If your app
+ * supports holding its calls, it will be possible for the user to switch between calls in your app
+ * and holdable calls in another app or on the mobile network.  If your app does not support
+ * holding its calls, you may receive a request to disconnect the call from Telecom if the user
+ * opts to answer an incoming call in another app or on the mobile network; this ensures that the
+ * user can only be in one call at a time.
+ * <p>
+ * Your app is free to change a call between the held and active state using
+ * {@link Connection#setOnHold()} and {@link Connection#setActive()}.
+ * <p>
+ * Your app may receive a request from Telecom to hold or unhold a call via
+ * {@link Connection#onHold()} and {@link Connection#onUnhold()}.  Telecom can ask your app to
+ * hold or unhold its {@link Connection} either if the user requests this action through another
+ * calling surface such as Bluetooth, or if the user answers or switches to a call in a different
+ * app or on the mobile network.
+ * <p>
+ * When your app receives an {@link Connection#onHold()} it must call {@link Connection#setOnHold()}
+ * to inform Telecom that the call has been held successfully.
+ * <p>
+ * When your app receives an {@link Connection#onUnhold()} it must call
+ * {@link Connection#setActive()} to inform Telecom that the call has been resumed successfully.
  */
 public abstract class ConnectionService extends Service {
     /**
@@ -2476,7 +2697,7 @@
     }
 
     private void playDtmfTone(String callId, char digit) {
-        Log.i(this, "playDtmfTone %s %c", callId, digit);
+        Log.i(this, "playDtmfTone %s %s", callId, Log.pii(digit));
         if (mConnectionById.containsKey(callId)) {
             findConnectionForAction(callId, "playDtmfTone").onPlayDtmfTone(digit);
         } else {
diff --git a/telecomm/java/android/telecom/StreamingCall.java b/telecomm/java/android/telecom/StreamingCall.java
index 985cccc..4b27dd6 100644
--- a/telecomm/java/android/telecom/StreamingCall.java
+++ b/telecomm/java/android/telecom/StreamingCall.java
@@ -172,7 +172,7 @@
      * to request holding, unholding and disconnecting this {@code StreamingCall}.
      * @param state The current streaming state of the call.
      */
-    public void setStreamingState(@StreamingCallState int state) {
+    public void requestStreamingState(@StreamingCallState int state) {
         mAdapter.setStreamingState(state);
     }
 }
diff --git a/telecomm/java/android/telecom/StreamingCallAdapter.java b/telecomm/java/android/telecom/StreamingCallAdapter.java
index bd8727d..54a3e24 100644
--- a/telecomm/java/android/telecom/StreamingCallAdapter.java
+++ b/telecomm/java/android/telecom/StreamingCallAdapter.java
@@ -25,7 +25,7 @@
  * Telecom. When Telecom binds to a {@link CallStreamingService}, an instance of this class is given
  * to the general streaming app through which it can manipulate the streaming calls. Whe the general
  * streaming app is notified of new ongoing streaming calls, it can execute
- * {@link StreamingCall#setStreamingState(int)} for the ongoing streaming calls the user on the
+ * {@link StreamingCall#requestStreamingState(int)} for the ongoing streaming calls the user on the
  * receiver side would like to hold, unhold and disconnect.
  *
  * @hide
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 7c86a75a..de99ebf 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -951,6 +951,23 @@
     public static final String EXTRA_CALL_SOURCE = "android.telecom.extra.CALL_SOURCE";
 
     /**
+     * Intent action to trigger "switch to managed profile" dialog for call in SystemUI
+     *
+     * @hide
+     */
+    public static final String ACTION_SHOW_SWITCH_TO_WORK_PROFILE_FOR_CALL_DIALOG =
+            "android.telecom.action.SHOW_SWITCH_TO_WORK_PROFILE_FOR_CALL_DIALOG";
+
+    /**
+     * Extra specifying the managed profile user id.
+     * This is used with {@link TelecomManager#ACTION_SHOW_SWITCH_TO_WORK_PROFILE_FOR_CALL_DIALOG}
+     *
+     * @hide
+     */
+    public static final String EXTRA_MANAGED_PROFILE_USER_ID =
+            "android.telecom.extra.MANAGED_PROFILE_USER_ID";
+
+    /**
      * Indicating the call is initiated via emergency dialer's shortcut button.
      *
      * @hide
@@ -2652,8 +2669,10 @@
     }
 
     /**
-     * Adds a new call with the specified {@link CallAttributes} to the telecom service. This method
-     * can be used to add both incoming and outgoing calls.
+     * Reports a new call with the specified {@link CallAttributes} to the telecom service. This
+     * method can be used to report both incoming and outgoing calls.  By reporting the call, the
+     * system is aware of the call and can provide updates on services (ex. Another device wants to
+     * disconnect the call) or events (ex. a new Bluetooth route became available).
      *
      * <p>
      * The difference between this API call and {@link TelecomManager#placeCall(Uri, Bundle)} or
@@ -2676,9 +2695,20 @@
      * <pre>
      *
      *  // An app should first define their own construct of a Call that overrides all the
-     *  // {@link CallEventCallback}s
-     *  private class MyVoipCall implements CallEventCallback {
-     *    // override all the {@link CallEventCallback}s
+     *  // {@link CallControlCallback}s and {@link CallEventCallback}s
+     *  private class MyVoipCall {
+     *   public String callId = "";
+     *
+     *   public CallControlCallEventCallback handshakes = new
+     *                       CallControlCallEventCallback() {
+     *                         // override/ implement all {@link CallControlCallback}s
+     *                        }
+     *   public CallEventCallback events = new
+     *                       CallEventCallback() {
+     *                         // override/ implement all {@link CallEventCallback}s
+     *                        }
+     *   public MyVoipCall(String id){
+     *       callId = id;
      *  }
      *
      * PhoneAccountHandle handle = new PhoneAccountHandle(
@@ -2690,28 +2720,33 @@
      *                                            "John Smith", Uri.fromParts("tel", "123", null))
      *                                            .build();
      *
+     * MyVoipCall myFirstOutgoingCall = new MyVoipCall("1");
+     *
      * telecomManager.addCall(callAttributes, Runnable::run, new OutcomeReceiver() {
      *                              public void onResult(CallControl callControl) {
      *                                 // The call has been added successfully
      *                              }
-     *                           }, new MyVoipCall());
+     *                           }, myFirstOutgoingCall.handshakes, myFirstOutgoingCall.events);
      * </pre>
      *
      * @param callAttributes    attributes of the new call (incoming or outgoing, address, etc. )
      * @param executor          thread to run background CallEventCallback updates on
      * @param pendingControl    OutcomeReceiver that receives the result of addCall transaction
-     * @param callEventCallback object that overrides CallEventCallback
+     * @param handshakes        object that overrides {@link CallControlCallback}s
+     * @param events            object that overrides {@link CallEventCallback}s
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_OWN_CALLS)
     @SuppressLint("SamShouldBeLast")
     public void addCall(@NonNull CallAttributes callAttributes,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OutcomeReceiver<CallControl, CallException> pendingControl,
-            @NonNull CallEventCallback callEventCallback) {
+            @NonNull CallControlCallback handshakes,
+            @NonNull CallEventCallback events) {
         Objects.requireNonNull(callAttributes);
         Objects.requireNonNull(executor);
         Objects.requireNonNull(pendingControl);
-        Objects.requireNonNull(callEventCallback);
+        Objects.requireNonNull(handshakes);
+        Objects.requireNonNull(events);
 
         ITelecomService service = getTelecomService();
         if (service != null) {
@@ -2723,7 +2758,7 @@
 
                 // couple all the args passed by the client
                 String newCallId = transactionalServiceWrapper.trackCall(callAttributes, executor,
-                        pendingControl, callEventCallback);
+                        pendingControl, handshakes, events);
 
                 // send args to server to process new call
                 service.addCall(callAttributes, transactionalServiceWrapper.getCallEventCallback(),
diff --git a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
index b2e921b..7bba1eb 100644
--- a/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
+++ b/telecomm/java/com/android/internal/telecom/ClientTransactionalServiceWrapper.java
@@ -23,6 +23,7 @@
 import android.os.ResultReceiver;
 import android.telecom.CallAttributes;
 import android.telecom.CallControl;
+import android.telecom.CallControlCallback;
 import android.telecom.CallEndpoint;
 import android.telecom.CallEventCallback;
 import android.telecom.CallException;
@@ -37,7 +38,7 @@
 import java.util.function.Consumer;
 
 /**
- * wraps {@link CallEventCallback} and {@link CallControl} on a
+ * wraps {@link CallControlCallback}, {@link CallEventCallback}, and {@link CallControl} on a
  * per-{@link  android.telecom.PhoneAccountHandle} basis to track ongoing calls.
  *
  * @hide
@@ -86,18 +87,20 @@
      * @param callAttributes of the new call
      * @param executor       to run callbacks on
      * @param pendingControl that allows telecom to call into the client
-     * @param callback       that overrides the CallEventCallback
+     * @param handshakes     that overrides the CallControlCallback
+     * @param events         that overrides the CallStateCallback
      * @return the callId of the newly created call
      */
     public String trackCall(CallAttributes callAttributes, Executor executor,
             OutcomeReceiver<CallControl, CallException> pendingControl,
-            CallEventCallback callback) {
+            CallControlCallback handshakes,
+            CallEventCallback events) {
         // generate a new id for this new call
         String newCallId = UUID.randomUUID().toString();
 
         // couple the objects passed from the client side
         mCallIdToTransactionalCall.put(newCallId, new TransactionalCall(newCallId, callAttributes,
-                executor, pendingControl, callback));
+                executor, pendingControl, handshakes, events));
 
         return newCallId;
     }
@@ -144,16 +147,17 @@
         private static final String ON_REQ_ENDPOINT_CHANGE = "onRequestEndpointChange";
         private static final String ON_AVAILABLE_CALL_ENDPOINTS = "onAvailableCallEndpointsChanged";
         private static final String ON_MUTE_STATE_CHANGED = "onMuteStateChanged";
+        private static final String ON_CALL_STREAMING_FAILED = "onCallStreamingFailed";
 
-        private void handleCallEventCallback(String action, String callId, int code,
+        private void handleHandshakeCallback(String action, String callId, int code,
                 ResultReceiver ackResultReceiver) {
-            Log.i(TAG, TextUtils.formatSimple("hCEC: id=[%s], action=[%s]", callId, action));
+            Log.i(TAG, TextUtils.formatSimple("hHC: id=[%s], action=[%s]", callId, action));
             // lookup the callEventCallback associated with the particular call
             TransactionalCall call = mCallIdToTransactionalCall.get(callId);
 
             if (call != null) {
                 // Get the CallEventCallback interface
-                CallEventCallback callback = call.getCallEventCallback();
+                CallControlCallback callback = call.getCallControlCallback();
                 // Get Receiver to wait on client ack
                 ReceiverWrapper outcomeReceiverWrapper = new ReceiverWrapper(ackResultReceiver);
 
@@ -225,51 +229,51 @@
 
         @Override
         public void onSetActive(String callId, ResultReceiver resultReceiver) {
-            handleCallEventCallback(ON_SET_ACTIVE, callId, 0, resultReceiver);
+            handleHandshakeCallback(ON_SET_ACTIVE, callId, 0, resultReceiver);
         }
 
 
         @Override
         public void onSetInactive(String callId, ResultReceiver resultReceiver) {
-            handleCallEventCallback(ON_SET_INACTIVE, callId, 0, resultReceiver);
+            handleHandshakeCallback(ON_SET_INACTIVE, callId, 0, resultReceiver);
         }
 
         @Override
         public void onAnswer(String callId, int videoState, ResultReceiver resultReceiver) {
-            handleCallEventCallback(ON_ANSWER, callId, videoState, resultReceiver);
+            handleHandshakeCallback(ON_ANSWER, callId, videoState, resultReceiver);
         }
 
         @Override
         public void onReject(String callId, ResultReceiver resultReceiver) {
-            handleCallEventCallback(ON_REJECT, callId, 0, resultReceiver);
+            handleHandshakeCallback(ON_REJECT, callId, 0, resultReceiver);
         }
 
         @Override
         public void onDisconnect(String callId, ResultReceiver resultReceiver) {
-            handleCallEventCallback(ON_DISCONNECT, callId, 0, resultReceiver);
+            handleHandshakeCallback(ON_DISCONNECT, callId, 0, resultReceiver);
         }
 
         @Override
         public void onCallEndpointChanged(String callId, CallEndpoint endpoint) {
-            handleEndpointUpdate(callId, ON_REQ_ENDPOINT_CHANGE, endpoint);
+            handleEventCallback(callId, ON_REQ_ENDPOINT_CHANGE, endpoint);
         }
 
         @Override
         public void onAvailableCallEndpointsChanged(String callId, List<CallEndpoint> endpoints) {
-            handleEndpointUpdate(callId, ON_AVAILABLE_CALL_ENDPOINTS, endpoints);
+            handleEventCallback(callId, ON_AVAILABLE_CALL_ENDPOINTS, endpoints);
         }
 
         @Override
         public void onMuteStateChanged(String callId, boolean isMuted) {
-            handleEndpointUpdate(callId, ON_MUTE_STATE_CHANGED, isMuted);
+            handleEventCallback(callId, ON_MUTE_STATE_CHANGED, isMuted);
         }
 
-        public void handleEndpointUpdate(String callId, String action, Object arg) {
-            Log.d(TAG, TextUtils.formatSimple("[%s], callId=[%s]", action, callId));
+        public void handleEventCallback(String callId, String action, Object arg) {
+            Log.d(TAG, TextUtils.formatSimple("hEC: [%s], callId=[%s]", action, callId));
             // lookup the callEventCallback associated with the particular call
             TransactionalCall call = mCallIdToTransactionalCall.get(callId);
             if (call != null) {
-                CallEventCallback callback = call.getCallEventCallback();
+                CallEventCallback callback = call.getCallStateCallback();
                 Executor executor = call.getExecutor();
                 final long identity = Binder.clearCallingIdentity();
                 try {
@@ -284,6 +288,9 @@
                             case ON_MUTE_STATE_CHANGED:
                                 callback.onMuteStateChanged((boolean) arg);
                                 break;
+                            case ON_CALL_STREAMING_FAILED:
+                                callback.onCallStreamingFailed((int) arg /* reason */);
+                                break;
                         }
                     });
                 } finally {
@@ -299,20 +306,13 @@
 
         @Override
         public void onCallStreamingStarted(String callId, ResultReceiver resultReceiver) {
-            handleCallEventCallback(ON_STREAMING_STARTED, callId, 0, resultReceiver);
+            handleHandshakeCallback(ON_STREAMING_STARTED, callId, 0, resultReceiver);
         }
 
         @Override
         public void onCallStreamingFailed(String callId, int reason) {
-            Log.i(TAG, TextUtils.formatSimple("onCallAudioStateChanged: callId=[%s], reason=[%s]",
-                    callId, reason));
-            // lookup the callEventCallback associated with the particular call
-            TransactionalCall call = mCallIdToTransactionalCall.get(callId);
-            if (call != null) {
-                CallEventCallback callback = call.getCallEventCallback();
-                Executor executor = call.getExecutor();
-                executor.execute(() -> callback.onCallStreamingFailed(reason));
-            }
+            Log.i(TAG, TextUtils.formatSimple("oCSF: id=[%s], reason=[%s]", callId, reason));
+            handleEventCallback(callId, ON_CALL_STREAMING_FAILED, reason);
         }
     };
 }
diff --git a/telecomm/java/com/android/internal/telecom/TransactionalCall.java b/telecomm/java/com/android/internal/telecom/TransactionalCall.java
index d9c8210..75f9d35 100644
--- a/telecomm/java/com/android/internal/telecom/TransactionalCall.java
+++ b/telecomm/java/com/android/internal/telecom/TransactionalCall.java
@@ -19,6 +19,7 @@
 import android.os.OutcomeReceiver;
 import android.telecom.CallAttributes;
 import android.telecom.CallControl;
+import android.telecom.CallControlCallback;
 import android.telecom.CallEventCallback;
 import android.telecom.CallException;
 
@@ -33,19 +34,23 @@
     private final CallAttributes mCallAttributes;
     private final Executor mExecutor;
     private final OutcomeReceiver<CallControl, CallException> mPendingControl;
-    private final CallEventCallback mCallEventCallback;
+    private final CallControlCallback mCallControlCallback;
+    private final CallEventCallback mCallStateCallback;
     private CallControl mCallControl;
 
     public TransactionalCall(String callId, CallAttributes callAttributes,
-            Executor executor, OutcomeReceiver<CallControl, CallException>  pendingControl,
-            CallEventCallback callEventCallback) {
+            Executor executor, OutcomeReceiver<CallControl, CallException> pendingControl,
+            CallControlCallback callControlCallback,
+            CallEventCallback callStateCallback) {
         mCallId = callId;
         mCallAttributes = callAttributes;
         mExecutor = executor;
         mPendingControl = pendingControl;
-        mCallEventCallback = callEventCallback;
+        mCallControlCallback = callControlCallback;
+        mCallStateCallback = callStateCallback;
     }
 
+
     public void setCallControl(CallControl callControl) {
         mCallControl = callControl;
     }
@@ -70,7 +75,11 @@
         return mPendingControl;
     }
 
-    public CallEventCallback getCallEventCallback() {
-        return mCallEventCallback;
+    public CallControlCallback getCallControlCallback() {
+        return mCallControlCallback;
+    }
+
+    public CallEventCallback getCallStateCallback() {
+        return mCallStateCallback;
     }
 }
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index 061b71b..d676eee 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -110,8 +110,15 @@
             return;
         }
 
-        // Don't report if the server-side flag isn't loaded, as it implies other anomaly report
-        // related config hasn't loaded.
+        //always write atoms to statsd
+        TelephonyStatsLog.write(
+                TELEPHONY_ANOMALY_DETECTED,
+                carrierId,
+                eventId.getLeastSignificantBits(),
+                eventId.getMostSignificantBits());
+
+        // Don't report via Intent if the server-side flag isn't loaded, as it implies other anomaly
+        // report related config hasn't loaded.
         try {
             boolean isAnomalyReportEnabledFromServer = DeviceConfig.getBoolean(
                     DeviceConfig.NAMESPACE_TELEPHONY, KEY_IS_TELEPHONY_ANOMALY_REPORT_ENABLED,
@@ -122,12 +129,6 @@
             return;
         }
 
-        TelephonyStatsLog.write(
-                TELEPHONY_ANOMALY_DETECTED,
-                carrierId,
-                eventId.getLeastSignificantBits(),
-                eventId.getMostSignificantBits());
-
         // If this event has already occurred, skip sending intents for it; regardless log its
         // invocation here.
         Integer count = sEvents.containsKey(eventId) ? sEvents.get(eventId) + 1 : 1;
diff --git a/telephony/java/android/telephony/CallState.java b/telephony/java/android/telephony/CallState.java
index 51ecfb0..836cb53 100644
--- a/telephony/java/android/telephony/CallState.java
+++ b/telephony/java/android/telephony/CallState.java
@@ -285,12 +285,12 @@
     /**
      * Builder of {@link CallState}
      *
-     * <p>The example below shows how you might create a new {@code CallState}:
+     * <p>The example below shows how you might create a new {@code CallState}. A precise call state
+     * {@link PreciseCallStates} is mandatory to build a CallState.
      *
      * <pre><code>
      *
-     * CallState = new CallState.Builder()
-     *     .setCallState(3)
+     * CallState = new CallState.Builder({@link PreciseCallStates})
      *     .setNetworkType({@link TelephonyManager#NETWORK_TYPE_LTE})
      *     .setCallQuality({@link CallQuality})
      *     .setImsCallSessionId({@link String})
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index acfc194..9e2e092 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -6990,11 +6990,11 @@
 
         /**
          * Maximum Retry Count for SMS over IMS on Failure, If the Retry Count exceeds this value,
-         * and if the retry count is less than KEY_SMS_MAX_RETRY_COUNT_INT
+         * and if the retry count is less than {@link #KEY_SMS_MAX_RETRY_COUNT_INT}
          * sending SMS should fallback to CS
          */
-        public static final String KEY_SMS_MAX_RETRY_COUNT_OVER_IMS_INT =
-                KEY_PREFIX + "sms_max_retry_count_over_ims_int";
+        public static final String KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT =
+                KEY_PREFIX + "sms_max_retry_over_ims_count_int";
 
         /**
          * Delay Timer Value in milliseconds
@@ -7062,7 +7062,7 @@
             defaults.putInt(KEY_SMS_OVER_IMS_FORMAT_INT, SMS_FORMAT_3GPP);
 
             defaults.putInt(KEY_SMS_MAX_RETRY_COUNT_INT, 3);
-            defaults.putInt(KEY_SMS_MAX_RETRY_COUNT_OVER_IMS_INT, 3);
+            defaults.putInt(KEY_SMS_MAX_RETRY_OVER_IMS_COUNT_INT, 3);
             defaults.putInt(KEY_SMS_OVER_IMS_SEND_RETRY_DELAY_MILLIS_INT,
                     2000);
             defaults.putInt(KEY_SMS_TR1_TIMER_MILLIS_INT, 130000);
@@ -8989,8 +8989,9 @@
             "carrier_certificate_string_array";
 
     /**
-     * Flag specifying whether the incoming call number should be formatted to national number
-     * for Japan. @return {@code true} convert to the national format, {@code false} otherwise.
+     * Flag specifying whether the incoming call number and the conference participant number
+     * should be formatted to national number for Japan.
+     * @return {@code true} convert to the national format, {@code false} otherwise.
      * e.g. "+819012345678" -> "09012345678"
      * @hide
      */
@@ -10059,7 +10060,7 @@
         sDefaults.putAll(Bsf.getDefaults());
         sDefaults.putAll(Iwlan.getDefaults());
         sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, new String[0]);
-         sDefaults.putBoolean(KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL, false);
+        sDefaults.putBoolean(KEY_FORMAT_INCOMING_NUMBER_TO_NATIONAL_FOR_JP_BOOL, false);
         sDefaults.putIntArray(KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY,
                 new int[] {4 /* BUSY */});
         sDefaults.putBoolean(KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL, false);
@@ -10693,4 +10694,38 @@
         }
         trm.removeCarrierConfigChangedListener(listener);
     }
+
+    /**
+     * Get subset of specified carrier configuration if available or empty bundle, without throwing
+     * {@link RuntimeException} to caller.
+     *
+     * <p>This is a system internally used only utility to reduce the repetitive logic.
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}, or the calling app
+     * has carrier privileges on the specified subscription (see
+     * {@link TelephonyManager#hasCarrierPrivileges()}).
+     *
+     * @param context Context used to get the CarrierConfigManager service.
+     * @param subId The subscription ID to get the config from.
+     * @param keys The config keys the client is interested in.
+     * @return Config bundle with key/value for the specified keys or empty bundle when failed
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            Manifest.permission.READ_PHONE_STATE,
+            "carrier privileges",
+    })
+    @NonNull
+    public static PersistableBundle getCarrierConfigSubset(
+            @NonNull Context context, int subId, @NonNull String... keys) {
+        PersistableBundle configs = null;
+        CarrierConfigManager ccm = context.getSystemService(CarrierConfigManager.class);
+        try {
+            configs = ccm.getConfigForSubId(subId, keys);
+        } catch (RuntimeException exception) {
+            Rlog.w(TAG, "CarrierConfigLoader is not available.");
+        }
+        return configs != null ? configs : new PersistableBundle();
+    }
 }
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index b83b400..c4d760f 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1012,6 +1012,8 @@
     public static final int IWLAN_DNS_RESOLUTION_NAME_FAILURE = 0x4004;
     /** No response received from the DNS Server due to a timeout*/
     public static final int IWLAN_DNS_RESOLUTION_TIMEOUT = 0x4005;
+    /** Expected to update or bring down an ePDG tunnel, but no tunnel found*/
+    public static final int IWLAN_TUNNEL_NOT_FOUND = 0x4006;
 
     // OEM sepecific error codes. To be used by OEMs when they don't
     // want to reveal error code which would be replaced by ERROR_UNSPECIFIED
@@ -1505,6 +1507,7 @@
         sFailCauseMap.put(IWLAN_IKEV2_CERT_INVALID, "IWLAN_IKEV2_CERT_INVALID");
         sFailCauseMap.put(IWLAN_DNS_RESOLUTION_NAME_FAILURE, "IWLAN_DNS_RESOLUTION_NAME_FAILURE");
         sFailCauseMap.put(IWLAN_DNS_RESOLUTION_TIMEOUT, "IWLAN_DNS_RESOLUTION_TIMEOUT");
+        sFailCauseMap.put(IWLAN_TUNNEL_NOT_FOUND, "IWLAN_TUNNEL_NOT_FOUND");
         sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1");
         sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2");
         sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3");
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c238f24..819b0b2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -14894,7 +14894,10 @@
 
     /**
      * The extra used with an {@link #ACTION_NETWORK_COUNTRY_CHANGED} to specify the
-     * the country code in ISO-3166-1 alpha-2 format.
+     * the country code in ISO-3166-1 alpha-2 format. This is the same country code returned by
+     * {@link #getNetworkCountryIso()}. This might be an empty string when the country code is not
+     * available.
+     *
      * <p class="note">
      * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
      */
@@ -14903,11 +14906,11 @@
 
     /**
      * The extra used with an {@link #ACTION_NETWORK_COUNTRY_CHANGED} to specify the
-     * last known the country code in ISO-3166-1 alpha-2 format.
+     * last known the country code in ISO-3166-1 alpha-2 format. This might be an empty string when
+     * the country code was never available. The last known country code persists across reboot.
+     *
      * <p class="note">
      * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
-     *
-     * @hide
      */
     public static final String EXTRA_LAST_KNOWN_NETWORK_COUNTRY =
             "android.telephony.extra.LAST_KNOWN_NETWORK_COUNTRY";
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 1e21e9a9..ed46276 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -882,6 +882,16 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
     public static final long SHOULD_RESOLVE_PORT_INDEX_FOR_APPS = 224562872L;
 
+    /**
+     * Starting with Android U, a port is available if it is active without an enabled profile
+     * on it or calling app can activate a new profile on the selected port without any user
+     * interaction.
+     * @hide
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public static final long INACTIVE_PORT_AVAILABILITY_CHECK = 240273417L;
+
     private final Context mContext;
     private int mCardId;
 
@@ -1611,8 +1621,12 @@
 
     /**
      * Returns whether the passing portIndex is available.
-     * A port is available if it is active without an enabled profile on it or calling app can
-     * activate a new profile on the selected port without any user interaction.
+     * A port is available if it is active without enabled profile on it or
+     * calling app has carrier privilege over the profile installed on the selected port.
+     *
+     * <p> From Android U, a port is available if it is active without an enabled profile on it or
+     * calling app can activate a new profile on the selected port without any user interaction.
+     *
      * Always returns false if the cardId is a physical card.
      *
      * @param portIndex is an enumeration of the ports available on the UICC.
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 1ea7fdc..d07edeb 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -27,6 +27,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telecom.VideoProfile;
+import android.telephony.CallState;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
@@ -78,7 +79,9 @@
     public static final int SERVICE_TYPE_EMERGENCY = 2;
 
     /**
-     * Call type none
+     * This value is returned if there is no valid IMS call type defined for the call. For example,
+     * if an ongoing call is circuit-switched and {@link CallState#getImsCallType()} is called, this
+     * value will be returned.
      */
     public static final int CALL_TYPE_NONE = 0;
     /**
diff --git a/telephony/java/android/telephony/ims/MediaQualityStatus.java b/telephony/java/android/telephony/ims/MediaQualityStatus.java
index 5038aac..76394fe 100644
--- a/telephony/java/android/telephony/ims/MediaQualityStatus.java
+++ b/telephony/java/android/telephony/ims/MediaQualityStatus.java
@@ -40,7 +40,7 @@
     private final int mMediaSessionType;
     private final int mTransportType;
     private final int mRtpPacketLossRate;
-    private final int mRtpJitter;
+    private final int mRtpJitterMillis;
     private final long mRtpInactivityTimeMillis;
 
     /** @hide */
@@ -52,23 +52,26 @@
     public @interface MediaSessionType {}
 
     /**
-     * Constructor for this
+     * The constructor for MediaQualityStatus, which represents the media quality for each session
+     * type ({@link #MEDIA_SESSION_TYPE_AUDIO} or {@link #MEDIA_SESSION_TYPE_VIDEO}) of the IMS call
      *
      * @param imsCallSessionId IMS call session id of this quality status
      * @param mediaSessionType media session type of this quality status
      * @param transportType transport type of this quality status
-     * @param rtpPacketLossRate measured RTP packet loss rate
-     * @param rtpJitter measured RTP jitter value
+     * @param rtpPacketLossRate measured RTP packet loss rate in percentage
+     * @param rtpJitterMillis measured RTP jitter(RFC3550) in milliseconds
      * @param rptInactivityTimeMillis measured RTP inactivity time in milliseconds
      */
-    private MediaQualityStatus(@NonNull String imsCallSessionId,
+    public MediaQualityStatus(@NonNull String imsCallSessionId,
             @MediaSessionType int mediaSessionType, @TransportType int transportType,
-            int rtpPacketLossRate, int rtpJitter, long rptInactivityTimeMillis) {
+            @IntRange(from = 0, to = 100) int rtpPacketLossRate,
+            @IntRange(from = 0) int rtpJitterMillis,
+            @IntRange(from = 0) long rptInactivityTimeMillis) {
         mImsCallSessionId = imsCallSessionId;
         mMediaSessionType = mediaSessionType;
         mTransportType = transportType;
         mRtpPacketLossRate = rtpPacketLossRate;
-        mRtpJitter = rtpJitter;
+        mRtpJitterMillis = rtpJitterMillis;
         mRtpInactivityTimeMillis = rptInactivityTimeMillis;
     }
 
@@ -106,13 +109,15 @@
     /**
      * Retrieves measured RTP jitter(RFC3550) value in milliseconds
      */
+    @IntRange(from = 0)
     public int getRtpJitterMillis() {
-        return mRtpJitter;
+        return mRtpJitterMillis;
     }
 
     /**
      * Retrieves measured RTP inactivity time in milliseconds
      */
+    @IntRange(from = 0)
     public long getRtpInactivityMillis() {
         return mRtpInactivityTimeMillis;
     }
@@ -126,7 +131,7 @@
         mMediaSessionType = in.readInt();
         mTransportType = in.readInt();
         mRtpPacketLossRate = in.readInt();
-        mRtpJitter = in.readInt();
+        mRtpJitterMillis = in.readInt();
         mRtpInactivityTimeMillis = in.readLong();
     }
 
@@ -136,7 +141,7 @@
         dest.writeInt(mMediaSessionType);
         dest.writeInt(mTransportType);
         dest.writeInt(mRtpPacketLossRate);
-        dest.writeInt(mRtpJitter);
+        dest.writeInt(mRtpJitterMillis);
         dest.writeLong(mRtpInactivityTimeMillis);
     }
 
@@ -167,14 +172,14 @@
                 && mMediaSessionType == that.mMediaSessionType
                 && mTransportType == that.mTransportType
                 && mRtpPacketLossRate == that.mRtpPacketLossRate
-                && mRtpJitter == that.mRtpJitter
+                && mRtpJitterMillis == that.mRtpJitterMillis
                 && mRtpInactivityTimeMillis == that.mRtpInactivityTimeMillis;
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mImsCallSessionId, mMediaSessionType, mTransportType,
-                mRtpPacketLossRate, mRtpJitter, mRtpInactivityTimeMillis);
+                mRtpPacketLossRate, mRtpJitterMillis, mRtpInactivityTimeMillis);
     }
 
     @Override
@@ -188,100 +193,11 @@
         sb.append(mTransportType);
         sb.append(", mRtpPacketLossRate=");
         sb.append(mRtpPacketLossRate);
-        sb.append(", mRtpJitter=");
-        sb.append(mRtpJitter);
+        sb.append(", mRtpJitterMillis=");
+        sb.append(mRtpJitterMillis);
         sb.append(", mRtpInactivityTimeMillis=");
         sb.append(mRtpInactivityTimeMillis);
         sb.append("}");
         return sb.toString();
     }
-
-    /**
-     * Provides a convenient way to set the fields of an {@link MediaQualityStatus} when creating a
-     * new instance.
-     *
-     * <p>The example below shows how you might create a new {@code RtpQualityStatus}:
-     *
-     * <pre><code>
-     *
-     * MediaQualityStatus = new MediaQualityStatus.Builder(
-     *                                          callSessionId, mediaSessionType, transportType)
-     *     .setRtpPacketLossRate(packetLossRate)
-     *     .setRtpJitter(jitter)
-     *     .setRtpInactivityMillis(inactivityTimeMillis)
-     *     .build();
-     * </code></pre>
-     */
-    public static final class Builder {
-        private final String mImsCallSessionId;
-        private final int mMediaSessionType;
-        private final int mTransportType;
-        private int mRtpPacketLossRate;
-        private int mRtpJitter;
-        private long mRtpInactivityTimeMillis;
-
-        /**
-         * Default constructor for the Builder.
-         */
-        public Builder(
-                @NonNull String imsCallSessionId,
-                @MediaSessionType int mediaSessionType,
-                @TransportType int transportType) {
-            mImsCallSessionId = imsCallSessionId;
-            mMediaSessionType = mediaSessionType;
-            mTransportType = transportType;
-        }
-
-        /**
-         * Set RTP packet loss info.
-         *
-         * @param packetLossRate RTP packet loss rate in percentage
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public Builder setRtpPacketLossRate(@IntRange(from = 0, to = 100) int packetLossRate) {
-            this.mRtpPacketLossRate = packetLossRate;
-            return this;
-        }
-
-        /**
-         * Set calculated RTP jitter(RFC3550) value in milliseconds.
-         *
-         * @param jitter calculated RTP jitter value.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public Builder setRtpJitterMillis(int jitter) {
-            this.mRtpJitter = jitter;
-            return this;
-        }
-
-        /**
-         * Set measured RTP inactivity time.
-         *
-         * @param inactivityTimeMillis RTP inactivity time in Milliseconds.
-         * @return The same instance of the builder.
-         */
-        @NonNull
-        public Builder setRtpInactivityMillis(long inactivityTimeMillis) {
-            this.mRtpInactivityTimeMillis = inactivityTimeMillis;
-            return this;
-        }
-
-        /**
-         * Build the {@link MediaQualityStatus}
-         *
-         * @return the {@link MediaQualityStatus} object
-         */
-        @NonNull
-        public MediaQualityStatus build() {
-            return new MediaQualityStatus(
-                    mImsCallSessionId,
-                    mMediaSessionType,
-                    mTransportType,
-                    mRtpPacketLossRate,
-                    mRtpJitter,
-                    mRtpInactivityTimeMillis);
-        }
-    }
 }
diff --git a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteCapabilitiesConsumer.aidl
similarity index 65%
copy from telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
copy to telephony/java/android/telephony/satellite/ISatelliteCapabilitiesConsumer.aidl
index 5c3fa32..f3ae245 100644
--- a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
+++ b/telephony/java/android/telephony/satellite/ISatelliteCapabilitiesConsumer.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 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,13 +16,12 @@
 
 package android.telephony.satellite;
 
-import android.telephony.satellite.PointingInfo;
+import android.telephony.satellite.SatelliteCapabilities;
 
 /**
- * Callback for position updates from the satellite service.
+ * Consumer for a SatelliteCapabilities result from the satellite service.
  * @hide
  */
-oneway interface ISatellitePositionUpdateCallback {
-    void onSatellitePositionUpdate(in PointingInfo pointingInfo);
-    void onMessageTransferStateUpdate(in int state);
+oneway interface ISatelliteCapabilitiesConsumer {
+    void accept(in SatelliteCapabilities result);
 }
diff --git a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
similarity index 82%
rename from telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
rename to telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
index 5c3fa32..6fb0979 100644
--- a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
+++ b/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
@@ -19,10 +19,11 @@
 import android.telephony.satellite.PointingInfo;
 
 /**
- * Callback for position updates from the satellite service.
+ * Interface for satellite state listener.
  * @hide
  */
-oneway interface ISatellitePositionUpdateCallback {
+oneway interface ISatelliteStateListener {
+    void onSatelliteProvisionStateChanged(in int[] features, in boolean provisioned);
     void onSatellitePositionUpdate(in PointingInfo pointingInfo);
     void onMessageTransferStateUpdate(in int state);
 }
diff --git a/telephony/java/android/telephony/satellite/SatelliteCallback.java b/telephony/java/android/telephony/satellite/SatelliteCallback.java
new file mode 100644
index 0000000..1b82d06
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteCallback.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 android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.telephony.satellite.stub.SatelliteImplBase;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.Executor;
+
+/**
+ * A callback class for monitoring changes in specific satellite service states on the device,
+ * including provision state, position update, message transfer state and others.
+ * <p>
+ * To register a callback, use a {@link SatelliteCallback} which implements the interested
+ * interfaces. For example,
+ * FakeSatelliteProvisionStateCallback extends {@link SatelliteCallback} implements
+ * {@link SatelliteCallback.SatelliteProvisionStateListener}.
+ * <p>
+ * Then override the methods for the state that you wish to receive updates for, and
+ * pass your SatelliteCallback object to the corresponding register function like
+ * {@link SatelliteManager#registerForSatelliteProvisionStateChanged}.
+ * <p>
+ *
+ * @hide
+ */
+public class SatelliteCallback {
+    private ISatelliteStateListener mCallbackStub;
+
+    /**
+     * The SatelliteCallback needs an executor to execute the callback interfaces.
+     */
+    public void init(@NonNull Executor executor) {
+        if (executor == null) {
+            throw new IllegalArgumentException("SatelliteCallback executor must be non-null");
+        }
+        mCallbackStub = new ISatelliteStateListenerStub(this, executor);
+    }
+
+    public ISatelliteStateListener getCallbackStub() {
+        return mCallbackStub;
+    }
+
+    /**
+     * Interface for satellite provision state change listener.
+     */
+    public interface SatelliteProvisionStateListener {
+        /**
+         * Called when satellite provision state changes.
+         *
+         * @param features The list of provisioned features.
+         * @param provisioned The new provision state. {@code true} means satellite is provisioned
+         *                    {@code false} means satellite is not provisioned.
+         */
+        void onSatelliteProvisionStateChanged(
+                @SatelliteImplBase.Feature int[] features, boolean provisioned);
+    }
+
+    /**
+     * Interface for position update change listener.
+     */
+    public interface SatellitePositionUpdateListener {
+        /**
+         * Called when the satellite position changes.
+         *
+         * @param pointingInfo The pointing info containing the satellite location.
+         */
+        void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo);
+
+        /**
+         * Called when satellite message transfer state changes.
+         *
+         * @param state The new message transfer state.
+         */
+        void onMessageTransferStateUpdate(
+                @SatelliteManager.SatelliteMessageTransferState int state);
+    }
+
+    private static class ISatelliteStateListenerStub extends ISatelliteStateListener.Stub {
+        private WeakReference<SatelliteCallback> mSatelliteCallbackWeakRef;
+        private Executor mExecutor;
+
+        ISatelliteStateListenerStub(SatelliteCallback satelliteCallback, Executor executor) {
+            mSatelliteCallbackWeakRef = new WeakReference<>(satelliteCallback);
+            mExecutor = executor;
+        }
+
+        public void onSatelliteProvisionStateChanged(
+                @SatelliteImplBase.Feature int[] features, boolean provisioned) {
+            SatelliteProvisionStateListener listener =
+                    (SatelliteProvisionStateListener) mSatelliteCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                    () -> listener.onSatelliteProvisionStateChanged(features, provisioned)));
+        }
+
+        public void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo) {
+            SatellitePositionUpdateListener listener =
+                    (SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                    () -> listener.onSatellitePositionUpdate(pointingInfo)));
+        }
+
+        public void onMessageTransferStateUpdate(
+                @SatelliteManager.SatelliteMessageTransferState int state) {
+            SatellitePositionUpdateListener listener =
+                    (SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                    () -> listener.onMessageTransferStateUpdate(state)));
+        }
+    }
+}
diff --git a/packages/SystemUI/res/values-television/strings.xml b/telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl
similarity index 60%
rename from packages/SystemUI/res/values-television/strings.xml
rename to telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl
index 86106e6..a09306b 100644
--- a/packages/SystemUI/res/values-television/strings.xml
+++ b/telephony/java/android/telephony/satellite/SatelliteCapabilities.aidl
@@ -1,7 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
- * Copyright (c) 2022, The Android Open Source Project
+/*
+ * Copyright 2023, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- Learn more URL for the log access confirmation dialog. [DO NOT TRANSLATE]-->
-    <string name="log_access_confirmation_learn_more_url" translatable="false"></string>
-</resources>
\ No newline at end of file
+
+package android.telephony.satellite;
+
+parcelable SatelliteCapabilities;
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 7a60c58..a818b63 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -26,28 +26,28 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.CancellationSignal;
+import android.os.ICancellationSignal;
 import android.os.RemoteException;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
-import android.util.ArrayMap;
+import android.telephony.satellite.stub.SatelliteImplBase;
 
+import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.IIntArrayConsumer;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.ITelephony;
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 
 /**
  * Manages satellite operations such as provisioning, pointing, messaging, location sharing, etc.
- * To get the object, call {@link Context#getSystemService(Context.SATELLITE_SERVICE)}.
- * To create an instance of {@link SatelliteManager} associated with a specific subscription ID,
- * call {@link #createForSubscriptionId(int)}.
+ * To get the object, call {@link Context#getSystemService(String)}.
  *
  * @hide
  */
@@ -55,20 +55,6 @@
 public class SatelliteManager {
     private static final String TAG = "SatelliteManager";
 
-    /**
-     * Map of all SatellitePositionUpdateCallback and their associated callback ids.
-     */
-    private final Map<SatellitePositionUpdateCallback, Integer> mSatellitePositionUpdateCallbacks =
-            new ArrayMap<>();
-
-    /**
-     * AtomicInteger for the id of the next SatellitePositionUpdateCallback.
-     */
-    private final AtomicInteger mSatellitePositionUpdateCallbackId = new AtomicInteger(0);
-
-    /**
-     * The subscription ID for this SatelliteManager.
-     */
     private final int mSubId;
 
     /**
@@ -82,7 +68,6 @@
      * @param context The context the SatelliteManager belongs to.
      */
     public SatelliteManager(@Nullable Context context) {
-        // TODO: replace DEFAULT_SUBSCRIPTION_ID with DEFAULT_SATELLITE_SUBSCRIPTION_ID
         this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
     }
 
@@ -108,106 +93,277 @@
     }
 
     /**
-     * Successful response.
+     * The request was successfully processed.
      */
-    public static final int SATELLITE_SERVICE_SUCCESS = 0;
+    public static final int SATELLITE_ERROR_NONE = 0;
     /**
-     * Satellite server is not reachable.
+     * A generic error which should be used only when other specific errors cannot be used.
      */
-    public static final int SATELLITE_SERVICE_SERVER_NOT_REACHABLE = 1;
+    public static final int SATELLITE_ERROR = 1;
     /**
      * Error received from the satellite server.
      */
-    public static final int SATELLITE_SERVICE_SERVER_ERROR = 2;
+    public static final int SATELLITE_SERVER_ERROR = 2;
     /**
-     * Unexpected telephony internal error.
+     * Error received from the vendor service. This generic error code should be used
+     * only when the error cannot be mapped to other specific service error codes.
      */
-    public static final int SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR = 3;
+    public static final int SATELLITE_SERVICE_ERROR = 3;
     /**
-     * Modem error received from the satellite service.
+     * Error received from satellite modem. This generic error code should be used only when
+     * the error cannot be mapped to other specific modem error codes.
      */
-    public static final int SATELLITE_SERVICE_MODEM_ERROR = 4;
+    public static final int SATELLITE_MODEM_ERROR = 4;
     /**
-     * System error received from the satellite service.
+     * Error received from the satellite network. This generic error code should be used only when
+     * the error cannot be mapped to other specific network error codes.
      */
-    public static final int SATELLITE_SERVICE_SYSTEM_ERROR = 5;
+    public static final int SATELLITE_NETWORK_ERROR = 5;
     /**
-     * Invalid arguments passed.
+     * Telephony is not in a valid state to receive requests from clients.
      */
-    public static final int SATELLITE_SERVICE_INVALID_ARGUMENTS = 6;
+    public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6;
     /**
-     * Invalid modem state.
+     * Satellite modem is not in a valid state to receive requests from clients.
      */
-    public static final int SATELLITE_SERVICE_INVALID_MODEM_STATE = 7;
+    public static final int SATELLITE_INVALID_MODEM_STATE = 7;
     /**
-     * Invalid SIM state.
+     * Either vendor service, or modem, or Telephony framework has received a request with
+     * invalid arguments from its clients.
      */
-    public static final int SATELLITE_SERVICE_INVALID_SIM_STATE = 8;
+    public static final int SATELLITE_INVALID_ARGUMENTS = 8;
     /**
-     * Invalid state.
+     * Telephony framework failed to send a request to the vendor service or the satellite
+     * modem due to internal error.
      */
-    public static final int SATELLITE_SERVICE_INVALID_STATE = 9;
+    public static final int SATELLITE_REQUEST_FAILED = 9;
     /**
-     * Satellite service is unavailable.
+     * Radio did not start or is resetting.
      */
-    public static final int SATELLITE_SERVICE_NOT_AVAILABLE = 10;
+    public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10;
     /**
-     * Satellite service is not supported by the device or OS.
+     * The request is not supported by either the satellite modem or the network.
      */
-    public static final int SATELLITE_SERVICE_NOT_SUPPORTED = 11;
+    public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11;
     /**
-     * Satellite service is rate limited.
+     * Satellite modem or network has no resources available to handle requests from clients.
      */
-    public static final int SATELLITE_SERVICE_RATE_LIMITED = 12;
+    public static final int SATELLITE_NO_RESOURCES = 12;
     /**
-     * Satellite service has no memory available.
+     * Satellite service is not provisioned yet.
      */
-    public static final int SATELLITE_SERVICE_NO_MEMORY = 13;
+    public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13;
     /**
-     * Satellite service has no resources available.
+     * Satellite service provision is already in progress.
      */
-    public static final int SATELLITE_SERVICE_NO_RESOURCES = 14;
+    public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14;
     /**
-     * Failed to send a request to the satellite service.
+     * The ongoing request was aborted by either the satellite modem or the network.
      */
-    public static final int SATELLITE_SERVICE_REQUEST_FAILED = 15;
+    public static final int SATELLITE_REQUEST_ABORTED = 15;
     /**
-     * Failed to send a request to the satellite service for the given subscription ID.
+     * The device/subscriber is barred from accessing the satellite service.
      */
-    public static final int SATELLITE_SERVICE_INVALID_SUBSCRIPTION_ID = 16;
+    public static final int SATELLITE_ACCESS_BARRED = 16;
     /**
-     * Error received from satellite service.
+     * Satellite modem timeout to receive ACK or response from the satellite network after
+     * sending a request to the network.
      */
-    public static final int SATELLITE_SERVICE_ERROR = 17;
+    public static final int SATELLITE_NETWORK_TIMEOUT = 17;
     /**
-     * Satellite service is disabled on the requested subscription.
+     * Satellite network is not reachable from the modem.
      */
-    public static final int SATELLITE_SERVICE_DISABLED = 18;
+    public static final int SATELLITE_NOT_REACHABLE = 18;
+    /**
+     * The device/subscriber is not authorized to register with the satellite service provider.
+     */
+    public static final int SATELLITE_NOT_AUTHORIZED = 19;
+    /**
+     * The device does not support satellite.
+     */
+    public static final int SATELLITE_NOT_SUPPORTED = 20;
 
     /** @hide */
-    @IntDef(prefix = {"SATELLITE_SERVICE_"}, value = {
-            SATELLITE_SERVICE_SUCCESS,
-            SATELLITE_SERVICE_SERVER_NOT_REACHABLE,
-            SATELLITE_SERVICE_SERVER_ERROR,
-            SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR,
-            SATELLITE_SERVICE_MODEM_ERROR,
-            SATELLITE_SERVICE_SYSTEM_ERROR,
-            SATELLITE_SERVICE_INVALID_ARGUMENTS,
-            SATELLITE_SERVICE_INVALID_MODEM_STATE,
-            SATELLITE_SERVICE_INVALID_SIM_STATE,
-            SATELLITE_SERVICE_INVALID_STATE,
-            SATELLITE_SERVICE_NOT_AVAILABLE,
-            SATELLITE_SERVICE_NOT_SUPPORTED,
-            SATELLITE_SERVICE_RATE_LIMITED,
-            SATELLITE_SERVICE_NO_MEMORY,
-            SATELLITE_SERVICE_NO_RESOURCES,
-            SATELLITE_SERVICE_REQUEST_FAILED,
-            SATELLITE_SERVICE_INVALID_SUBSCRIPTION_ID,
+    @IntDef(prefix = {"SATELLITE_"}, value = {
+            SATELLITE_ERROR_NONE,
+            SATELLITE_ERROR,
+            SATELLITE_SERVER_ERROR,
             SATELLITE_SERVICE_ERROR,
-            SATELLITE_SERVICE_DISABLED
+            SATELLITE_MODEM_ERROR,
+            SATELLITE_NETWORK_ERROR,
+            SATELLITE_INVALID_TELEPHONY_STATE,
+            SATELLITE_INVALID_MODEM_STATE,
+            SATELLITE_INVALID_ARGUMENTS,
+            SATELLITE_REQUEST_FAILED,
+            SATELLITE_RADIO_NOT_AVAILABLE,
+            SATELLITE_REQUEST_NOT_SUPPORTED,
+            SATELLITE_NO_RESOURCES,
+            SATELLITE_SERVICE_NOT_PROVISIONED,
+            SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
+            SATELLITE_REQUEST_ABORTED,
+            SATELLITE_ACCESS_BARRED,
+            SATELLITE_NETWORK_TIMEOUT,
+            SATELLITE_NOT_REACHABLE,
+            SATELLITE_NOT_AUTHORIZED,
+            SATELLITE_NOT_SUPPORTED
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface SatelliteServiceResult {}
+    public @interface SatelliteError {}
+
+    /**
+     * Power on or off the satellite modem.
+     *
+     * @param powerOn {@code true} to power on the satellite modem and {@code false} to power off.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @return The result of the operation.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError public int setSatellitePower(boolean powerOn) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.setSatellitePower(mSubId, powerOn);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setSatellitePower RemoteException", ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
+    }
+
+    /**
+     * Check whether the satellite modem is powered on.
+     *
+     * @param executor The executor on which the result listener will be called.
+     * @param resultListener Listener with the result if the operation is successful.
+     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, the result
+     *                       listener will return {@code true} if the satellite modem is powered on
+     *                       and {@code false} otherwise.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @return The result of the operation.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError public int isSatellitePowerOn(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Boolean> resultListener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(resultListener);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                IBooleanConsumer internalCallback = new IBooleanConsumer.Stub() {
+                    @Override
+                    public void accept(boolean result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> resultListener.accept(result)));
+                    }
+                };
+
+                return telephony.isSatellitePowerOn(mSubId, internalCallback);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("isSatellitePowerOn() RemoteException:" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
+    }
+
+    /**
+     * Check whether the satellite service is supported on the device.
+     *
+     * @param executor The executor on which the result listener will be called.
+     * @param resultListener Listener with the result if the operation is successful.
+     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, the result
+     *                       listener will return {@code true} if the satellite service is supported
+     *                       and {@code false} otherwise.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @return The result of the operation.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError public int isSatelliteSupported(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<Boolean> resultListener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(resultListener);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                IBooleanConsumer internalCallback = new IBooleanConsumer.Stub() {
+                    @Override
+                    public void accept(boolean result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> resultListener.accept(result)));
+                    }
+                };
+
+                return telephony.isSatelliteSupported(mSubId, internalCallback);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("isSatelliteSupported() RemoteException:" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
+    }
+
+    /**
+     * Get the {@link SatelliteCapabilities} with all capabilities of the satellite service.
+     *
+     * @param executor The executor on which the result listener will be called.
+     * @param resultListener Listener with the result if the operation is successful.
+     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, the result
+     *                       listener will return the current {@link SatelliteCapabilities}.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @return The result of the operation.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError public int getSatelliteCapabilities(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull Consumer<SatelliteCapabilities> resultListener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(resultListener);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ISatelliteCapabilitiesConsumer internalCallback =
+                        new ISatelliteCapabilitiesConsumer.Stub() {
+                    @Override
+                    public void accept(SatelliteCapabilities result) {
+                        executor.execute(() -> Binder.withCleanCallingIdentity(
+                                () -> resultListener.accept(result)));
+                    }
+                };
+
+                return telephony.getSatelliteCapabilities(mSubId, internalCallback);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("getSatelliteCapabilities() RemoteException:" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
+    }
 
     /**
      * Message transfer is waiting to acquire.
@@ -241,73 +397,34 @@
     public @interface SatelliteMessageTransferState {}
 
     /**
-     * Callback for position updates from the satellite service.
-     */
-    public interface SatellitePositionUpdateCallback {
-        /**
-         * Called when the satellite position changes.
-         *
-         * @param pointingInfo The pointing info containing the satellite location.
-         */
-        void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo);
-
-        /**
-         * Called when satellite message transfer state changes.
-         *
-         * @param state The new message transfer state.
-         */
-        void onMessageTransferStateUpdate(@SatelliteMessageTransferState int state);
-    }
-
-    /**
      * Start receiving satellite position updates.
      * This can be called by the pointing UI when the user starts pointing to the satellite.
      * Modem should continue to report the pointing input as the device or satellite moves.
-     * Satellite position updates are started only on {@link #SATELLITE_SERVICE_SUCCESS}.
+     * Satellite position updates are started only on {@link #SATELLITE_ERROR_NONE}.
      * All other results indicate that this operation failed.
      *
-     * @param executor The executor to run callbacks on.
-     * @param callback The callback to notify of changes in satellite position.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback to notify of changes in satellite position. This
+     *                 SatelliteCallback should implement the interface
+     *                 {@link SatelliteCallback.SatellitePositionUpdateListener}.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
      * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteServiceResult public int startSatellitePositionUpdates(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull SatellitePositionUpdateCallback callback) {
+    @SatelliteError
+    public int startSatellitePositionUpdates(
+            @NonNull Executor executor, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
         Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                int id;
-                if (mSatellitePositionUpdateCallbacks.containsKey(callback)) {
-                    id = mSatellitePositionUpdateCallbacks.get(callback);
-                } else {
-                    id = mSatellitePositionUpdateCallbackId.getAndIncrement();
-                }
-                int result = telephony.startSatellitePositionUpdates(mSubId, id,
-                        new ISatellitePositionUpdateCallback.Stub() {
-                            @Override
-                            public void onSatellitePositionUpdate(
-                                    @NonNull PointingInfo pointingInfo) {
-                                logd("onSatellitePositionUpdate: pointingInfo=" + pointingInfo);
-                                executor.execute(() -> Binder.withCleanCallingIdentity(
-                                        () -> callback.onSatellitePositionUpdate(pointingInfo)));
-                            }
-
-                            @Override
-                            public void onMessageTransferStateUpdate(
-                                    @SatelliteMessageTransferState int state) {
-                                logd("onMessageTransferStateUpdate: state=" + state);
-                                executor.execute(() -> Binder.withCleanCallingIdentity(
-                                        () -> callback.onMessageTransferStateUpdate(state)));
-                            }
-                        });
-                if (result == SATELLITE_SERVICE_SUCCESS) {
-                    mSatellitePositionUpdateCallbacks.put(callback, id);
-                }
-                return result;
+                callback.init(executor);
+                return telephony.startSatellitePositionUpdates(mSubId, callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -315,40 +432,35 @@
             loge("startSatellitePositionUpdates RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_SERVICE_REQUEST_FAILED;
+        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
      * Stop receiving satellite position updates.
      * This can be called by the pointing UI when the user stops pointing to the satellite.
-     * Satellite position updates are stopped only on {@link #SATELLITE_SERVICE_SUCCESS}.
+     * Satellite position updates are stopped only on {@link #SATELLITE_ERROR_NONE}.
      * All other results indicate that this operation failed.
      *
      * @param callback The callback that was passed in {@link
-     *                 #startSatellitePositionUpdates(Executor, SatellitePositionUpdateCallback)}.
-     * @return The result of the operation.
+     *                 #startSatellitePositionUpdates(Executor, SatelliteCallback)}.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalArgumentException if the callback is invalid.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteServiceResult public int stopSatellitePositionUpdates(
-            @NonNull SatellitePositionUpdateCallback callback) {
+    @SatelliteError
+    public int stopSatellitePositionUpdates(
+            @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(callback);
 
-        if (!mSatellitePositionUpdateCallbacks.containsKey(callback)) {
-            throw new IllegalArgumentException(
-                    "startSatellitePositionUpdates was never called with the callback provided.");
-        }
-
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                int result = telephony.stopSatellitePositionUpdates(mSubId,
-                        mSatellitePositionUpdateCallbacks.get(callback));
-                if (result == SATELLITE_SERVICE_SUCCESS) {
-                    mSatellitePositionUpdateCallbacks.remove(callback);
-                    // TODO: Notify SmsHandler that pointing UI stopped
-                }
-                return result;
+                return telephony.stopSatellitePositionUpdates(mSubId, callback.getCallbackStub());
+                // TODO: Notify SmsHandler that pointing UI stopped
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -356,22 +468,23 @@
             loge("stopSatellitePositionUpdates RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_SERVICE_REQUEST_FAILED;
+        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
      * Get maximum number of characters per text message on satellite.
      * @param executor - The executor on which the result listener will be called.
      * @param resultListener - Listener that will be called when the operation is successful.
-     *                       If this method returns {@link #SATELLITE_SERVICE_SUCCESS}, listener
+     *                       If this method returns {@link #SATELLITE_ERROR_NONE}, listener
      *                       will be called with maximum characters limit.
      *
      * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
      *
-     * @return The result of the operation
+     * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteServiceResult
+    @SatelliteError
     public int getMaxCharactersPerSatelliteTextMessage(@NonNull @CallbackExecutor Executor executor,
             @NonNull Consumer<Integer> resultListener) {
         Objects.requireNonNull(executor);
@@ -396,7 +509,165 @@
             loge("getMaxCharactersPerSatelliteTextMessage() RemoteException:" + ex);
             ex.rethrowFromSystemServer();
         }
-        return SATELLITE_SERVICE_REQUEST_FAILED;
+        return SATELLITE_REQUEST_FAILED;
+    }
+
+
+    /**
+     * Register the subscription with a satellite provider. This is needed if the provider allows
+     * dynamic registration.
+     *
+     * @param features List of features to be provisioned.
+     * @param executor The optional executor to run callbacks on.
+     * @param callback The optional callback to get the error code of the request.
+     * @param cancellationSignal The optional signal used by the caller to cancel the provision
+     *                           request. Even when the cancellation is signaled, Telephony will
+     *                           still trigger the callback to return the result of this request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    public void provisionSatelliteService(
+            @NonNull @SatelliteImplBase.Feature int[] features,
+            @Nullable @CallbackExecutor Executor executor,
+            @SatelliteError @Nullable Consumer<Integer> callback,
+            @Nullable CancellationSignal cancellationSignal) {
+        Objects.requireNonNull(features);
+
+        ICancellationSignal cancelRemote = null;
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                IIntegerConsumer callbackStub = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        if (executor == null || callback == null) {
+                            logd("provisionSatelliteService: executor and/or callback is null");
+                            return;
+                        }
+                        Binder.withCleanCallingIdentity(() -> {
+                            executor.execute(() -> callback.accept(result));
+                        });
+                    }
+                };
+                cancelRemote = telephony.provisionSatelliteService(mSubId, features, callbackStub);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("provisionSatelliteService RemoteException=" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        if (cancellationSignal != null) {
+            cancellationSignal.setRemote(cancelRemote);
+        }
+    }
+
+    /**
+     * Register for the satellite provision state change.
+     *
+     * @param executor - The executor on which the callback will be called.
+     * @param callback The callback to handle the satellite provision state changed event. This
+     *                 SatelliteCallback should implement the interface
+     *                 {@link SatelliteCallback.SatelliteProvisionStateListener}.
+     * @return The error code of the request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError
+    public int registerForSatelliteProvisionStateChanged(
+            @NonNull Executor executor, @NonNull SatelliteCallback callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                callback.init(executor);
+                return telephony.registerForSatelliteProvisionStateChanged(
+                        mSubId, callback.getCallbackStub());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("registerForSatelliteProvisionStateChanged RemoteException: " + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
+    }
+
+    /**
+     * Unregister for the satellite provision state change.
+     *
+     * @param callback The callback that was passed to
+     * {@link #registerForSatelliteProvisionStateChanged(Executor, SatelliteCallback)}
+     * @return The error code of the request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError
+    public int unregisterForSatelliteProvisionStateChanged(@NonNull SatelliteCallback callback) {
+        Objects.requireNonNull(callback);
+
+        if (callback.getCallbackStub() == null) {
+            loge("unregisterForSatelliteProvisionStateChanged: callbackStub is null");
+            return SATELLITE_INVALID_ARGUMENTS;
+        }
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.unregisterForSatelliteProvisionStateChanged(
+                        mSubId, callback.getCallbackStub());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("unregisterForSatelliteProvisionStateChanged RemoteException: " + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
+    }
+
+    /**
+     * Get the list of provisioned satellite features.
+     *
+     * @param executor The executor to run callbacks on.
+     * @param resultListener The callback to get the list of provisioned features when the request
+     *                       returns success result.
+     * @return The error code of the request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteError
+    public int getProvisionedSatelliteFeatures(
+            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<int[]> resultListener) {
+        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(executor);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                IIntArrayConsumer callbackStub = new IIntArrayConsumer.Stub() {
+                    @Override
+                    public void accept(int[] result) {
+                        Binder.withCleanCallingIdentity(() -> {
+                            executor.execute(() -> resultListener.accept(result));
+                        });
+                    }
+                };
+                return telephony.getProvisionedSatelliteFeatures(mSubId, callbackStub);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("getProvisionedSatelliteFeatures() RemoteException:" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_REQUEST_FAILED;
     }
 
     private static ITelephony getITelephony() {
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
index 497c272..c208755 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
@@ -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,12 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package com.android.internal.telephony;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+// Copies consumer pattern for an operation that requires an int array result from another
+// process to finish.
+oneway interface IIntArrayConsumer {
+    void accept(in int[] result);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 5486365..baf45cd 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.os.Bundle;
+import android.os.ICancellationSignal;
 import android.os.IBinder;
 import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
@@ -66,13 +67,16 @@
 import android.telephony.ims.aidl.IImsRegistration;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.aidl.IRcsConfigCallback;
-import android.telephony.satellite.ISatellitePositionUpdateCallback;
+import android.telephony.satellite.ISatelliteStateListener;
+import android.telephony.satellite.ISatelliteCapabilitiesConsumer;
+import android.telephony.satellite.SatelliteCapabilities;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.IBooleanConsumer;
 import com.android.internal.telephony.ICallForwardingInfoCallback;
 import com.android.internal.telephony.IccLogicalChannelRequest;
 import com.android.internal.telephony.IImsStateCallback;
+import com.android.internal.telephony.IIntArrayConsumer;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.OperatorInfo;
@@ -1534,7 +1538,7 @@
      */
     CarrierRestrictionRules getAllowedCarriers();
 
-   /**
+    /**
      * Returns carrier id of the given subscription.
      * <p>To recognize carrier as a first class identity, assign each carrier with a canonical
      * integer a.k.a carrier id.
@@ -2700,18 +2704,74 @@
     void getCarrierRestrictionStatus(IIntegerConsumer internalCallback, String packageName);
 
     /**
+     * Power on or off the satellite modem.
+     */
+    int setSatellitePower(int subId, boolean powerOn);
+
+    /**
+     * Check whether the satellite modem is powered on.
+     */
+    int isSatellitePowerOn(int subId, IBooleanConsumer internalCallback);
+
+    /**
+     * Check whether the satellite service is supported on the device.
+     */
+    int isSatelliteSupported(int subId, IBooleanConsumer internalCallback);
+
+    /**
+     * Get the capabilities of the satellite service.
+     */
+    int getSatelliteCapabilities(int subId, ISatelliteCapabilitiesConsumer internalCallback);
+
+    /**
      * Start receiving satellite pointing updates.
      */
-    int startSatellitePositionUpdates(int subId, int callbackId,
-            in ISatellitePositionUpdateCallback callback);
+    int startSatellitePositionUpdates(int subId, in ISatelliteStateListener callback);
 
     /**
      * Stop receiving satellite pointing updates.
      */
-    int stopSatellitePositionUpdates(int subId, int callbackId);
+    int stopSatellitePositionUpdates(int subId, ISatelliteStateListener callback);
 
     /**
      * Get maximum number of characters per text message on satellite.
      */
     int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer internalCallback);
-}
\ No newline at end of file
+
+    /**
+     * Register the subscription with a satellite provider.
+     * This is needed to register the subscription if the provider allows dynamic registration.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param features List of features to be provisioned.
+     * @param callback The callback to get the error code of the request.
+     * @return The signal transport used by callers to cancel the provision request.
+     */
+    ICancellationSignal provisionSatelliteService(int subId, in int[] features,
+            in IIntegerConsumer callback);
+
+    /**
+     * Register for the satellite provision state change.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param callback The callback to handle the satellite provision state changed event.
+     */
+    int registerForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
+
+    /**
+     * Unregister for the satellite provision state change.
+     *
+     * @param subId The subId of the subscription associated with the satellite service.
+     * @param callback The callback that was passed to
+     *                   registerForSatelliteProvisionStateChanged.
+     */
+    int unregisterForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
+
+    /**
+     * Get the list of provisioned satellite features.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param callback The callback to get the list of provisioned satellite features.
+     */
+    int getProvisionedSatelliteFeatures(int subId, IIntArrayConsumer callback);
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 0f83a05..a9ebd5c 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -243,6 +243,13 @@
     /** The key to specify the selected domain for dialing calls. */
     public static final String EXTRA_DIAL_DOMAIN = "dial_domain";
 
+    /**
+     * Indicates that this call should be routed over Wi-Fi.
+     * An internal extension of NetworkRegistrationInfo's DOMAIN_* constants
+     * to also include NON_3GPP_PS routing for the domain selection service.
+     */
+    public static final int DOMAIN_NON_3GPP_PS = 4;
+
     /** The key to specify the emergency service category */
     public static final String EXTRA_EMERGENCY_SERVICE_CATEGORY = "emergency_service_category";
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 6e56963..45daab3 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -120,6 +120,31 @@
     int BLOCKED_DUE_TO_CALL = 69;                   /* SMS is blocked due to call control */
     int RF_HARDWARE_ISSUE = 70;                     /* RF HW issue is detected */
     int NO_RF_CALIBRATION_INFO = 71;                /* No RF calibration in device */
+    int ENCODING_NOT_SUPPORTED = 72;                /* The encoding scheme is not supported by
+                                                       either the network or the MS. */
+    int FEATURE_NOT_SUPPORTED = 73;                 /* The requesting feature is not supported by
+                                                       the service provider. */
+    int INVALID_CONTACT = 74;                       /* The contact to be added is either not
+                                                       existing or not valid. */
+    int MODEM_INCOMPATIBLE = 75;                    /* The modem of the MS is not compatible with
+                                                       the service provider. */
+    int NETWORK_TIMEOUT = 76;                       /* Modem timeout to receive ACK or response from
+                                                       network after sending a request to it. */
+    int NO_SATELLITE_SIGNAL = 77;                   /* Modem fails to communicate with the satellite
+                                                       network since there is no satellite signal.*/
+    int NOT_SUFFICIENT_ACCOUNT_BALANCE = 78;        /* The request cannot be performed since the
+                                                       subscriber's account balance is not
+                                                       sufficient. */
+    int RADIO_TECHNOLOGY_NOT_SUPPORTED = 79;        /* The radio technology is not supported by the
+                                                       service provider. */
+    int SUBSCRIBER_NOT_AUTHORIZED = 80;             /* The subscription is not authorized to
+                                                       register with the service provider. */
+    int SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL = 81; /* While processing a request from the
+                                                       Framework the satellite modem detects
+                                                       terrestrial signal, aborts the request, and
+                                                       switches to the terrestrial network. */
+    int UNIDENTIFIED_SUBSCRIBER = 82;               /* The subscriber is not registered with the
+                                                       service provider */
 
     // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
     // reveal particular replacement for Generic failure
diff --git a/tests/BinaryTransparencyHostTest/src/android/transparency/test/BaseInstallMultiple.java b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BaseInstallMultiple.java
new file mode 100644
index 0000000..3e94f25
--- /dev/null
+++ b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BaseInstallMultiple.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transparency.test;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base class for invoking the install-multiple command via ADB. Subclass this for less typing:
+ *
+ * <code> private class InstallMultiple extends BaseInstallMultiple&lt;InstallMultiple&gt; { public
+ * InstallMultiple() { super(getDevice(), null); } } </code>
+ */
+/*package*/ class BaseInstallMultiple<T extends BaseInstallMultiple<?>> {
+
+    private final ITestDevice mDevice;
+    private final IBuildInfo mBuild;
+
+    private final List<String> mArgs = new ArrayList<>();
+    private final Map<File, String> mFileToRemoteMap = new HashMap<>();
+
+    /*package*/ BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo) {
+        mDevice = device;
+        mBuild = buildInfo;
+        addArg("-g");
+    }
+
+    T addArg(String arg) {
+        mArgs.add(arg);
+        return (T) this;
+    }
+
+    T addFile(String filename) throws FileNotFoundException {
+        return addFile(filename, filename);
+    }
+
+    T addFile(String filename, String remoteName) throws FileNotFoundException {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
+        mFileToRemoteMap.put(buildHelper.getTestFile(filename), remoteName);
+        return (T) this;
+    }
+
+    T inheritFrom(String packageName) {
+        addArg("-r");
+        addArg("-p " + packageName);
+        return (T) this;
+    }
+
+    void run() throws DeviceNotAvailableException {
+        run(true);
+    }
+
+    void runExpectingFailure() throws DeviceNotAvailableException {
+        run(false);
+    }
+
+    private void run(boolean expectingSuccess) throws DeviceNotAvailableException {
+        final ITestDevice device = mDevice;
+
+        // Create an install session
+        final StringBuilder cmd = new StringBuilder();
+        cmd.append("pm install-create");
+        for (String arg : mArgs) {
+            cmd.append(' ').append(arg);
+        }
+
+        String result = device.executeShellCommand(cmd.toString());
+        TestCase.assertTrue(result, result.startsWith("Success"));
+
+        final int start = result.lastIndexOf("[");
+        final int end = result.lastIndexOf("]");
+        int sessionId = -1;
+        try {
+            if (start != -1 && end != -1 && start < end) {
+                sessionId = Integer.parseInt(result.substring(start + 1, end));
+            }
+        } catch (NumberFormatException e) {
+            throw new IllegalStateException("Failed to parse install session: " + result);
+        }
+        if (sessionId == -1) {
+            throw new IllegalStateException("Failed to create install session: " + result);
+        }
+
+        // Push our files into session. Ideally we'd use stdin streaming,
+        // but ddmlib doesn't support it yet.
+        for (final Map.Entry<File, String> entry : mFileToRemoteMap.entrySet()) {
+            final File file = entry.getKey();
+            final String remoteName  = entry.getValue();
+            final String remotePath = "/data/local/tmp/" + file.getName();
+            if (!device.pushFile(file, remotePath)) {
+                throw new IllegalStateException("Failed to push " + file);
+            }
+
+            cmd.setLength(0);
+            cmd.append("pm install-write");
+            cmd.append(' ').append(sessionId);
+            cmd.append(' ').append(remoteName);
+            cmd.append(' ').append(remotePath);
+
+            result = device.executeShellCommand(cmd.toString());
+            TestCase.assertTrue(result, result.startsWith("Success"));
+        }
+
+        // Everything staged; let's pull trigger
+        cmd.setLength(0);
+        cmd.append("pm install-commit");
+        cmd.append(' ').append(sessionId);
+
+        result = device.executeShellCommand(cmd.toString());
+        if (expectingSuccess) {
+            TestCase.assertTrue(result, result.contains("Success"));
+        } else {
+            TestCase.assertFalse(result, result.contains("Success"));
+        }
+    }
+}
diff --git a/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java
index 8db3d00..db36975 100644
--- a/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java
+++ b/tests/BinaryTransparencyHostTest/src/android/transparency/test/BinaryTransparencyHostTest.java
@@ -16,23 +16,30 @@
 
 package android.transparency.test;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.platform.test.annotations.LargeTest;
+import android.platform.test.annotations.Presubmit;
+
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
 import com.android.tradefed.util.CommandResult;
 import com.android.tradefed.util.CommandStatus;
 
-import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.concurrent.TimeUnit;
 
-// TODO: Add @Presubmit
+@Presubmit
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class BinaryTransparencyHostTest extends BaseHostJUnit4Test {
     private static final String PACKAGE_NAME = "android.transparency.test.app";
@@ -40,12 +47,11 @@
     private static final String JOB_ID = "1740526926";
 
     /** Waiting time for the job to be scheduled */
-    private static final int JOB_CREATION_MAX_SECONDS = 5;
+    private static final int JOB_CREATION_MAX_SECONDS = 30;
 
-    @After
-    public void tearDown() throws Exception {
-        uninstallPackage("com.android.egg");
-        uninstallRebootlessApex();
+    @Before
+    public void setUp() throws Exception {
+        cancelPendingJob();
     }
 
     @Test
@@ -68,35 +74,64 @@
 
     @Test
     public void testCollectAllUpdatedPreloadInfo() throws Exception {
-        installPackage("EasterEgg.apk");
-        runDeviceTest("testCollectAllUpdatedPreloadInfo");
+        try {
+            updatePreloadApp();
+            runDeviceTest("testCollectAllUpdatedPreloadInfo");
+        } finally {
+            // No need to wait until job complete, since we can't verifying very meaningfully.
+            cancelPendingJob();
+            uninstallPackage("com.android.egg");
+        }
     }
 
     @Test
-    public void testRebootlessApexUpdateTriggersJobScheduling() throws Exception {
-        cancelPendingJob();
-        installRebootlessApex();
+    public void testCollectAllSilentInstalledMbaInfo() throws Exception {
+        try {
+            new InstallMultiple()
+                .addFile("ApkVerityTestApp.apk")
+                .addFile("ApkVerityTestAppSplit.apk")
+                .run();
+            updatePreloadApp();
+            assertNotNull(getDevice().getAppPackageInfo("com.android.apkverity"));
+            assertNotNull(getDevice().getAppPackageInfo("com.android.egg"));
 
-        // Verify
-        expectJobToBeScheduled();
-        // Just cancel since we can't verifying very meaningfully.
-        cancelPendingJob();
+            assertTrue(getDevice().setProperty("debug.transparency.bg-install-apps",
+                        "com.android.apkverity,com.android.egg"));
+            runDeviceTest("testCollectAllSilentInstalledMbaInfo");
+        } finally {
+            // No need to wait until job complete, since we can't verifying very meaningfully.
+            cancelPendingJob();
+            uninstallPackage("com.android.apkverity");
+            uninstallPackage("com.android.egg");
+        }
+    }
+
+    @LargeTest
+    @Test
+    public void testRebootlessApexUpdateTriggersJobScheduling() throws Exception {
+        try {
+            installRebootlessApex();
+
+            // Verify
+            expectJobToBeScheduled();
+        } finally {
+            // No need to wait until job complete, since we can't verifying very meaningfully.
+            uninstallRebootlessApexThenReboot();
+        }
     }
 
     @Test
     public void testPreloadUpdateTriggersJobScheduling() throws Exception {
-        cancelPendingJob();
-        installPackage("EasterEgg.apk");
+        try {
+            updatePreloadApp();
 
-        // Verify
-        expectJobToBeScheduled();
-        // Just cancel since we can't verifying very meaningfully.
-        cancelPendingJob();
-    }
-
-    @Test
-    public void testMeasureMbas() throws Exception {
-        // TODO(265244016): figure out a way to install an MBA
+            // Verify
+            expectJobToBeScheduled();
+        } finally {
+            // No need to wait until job complete, since we can't verifying very meaningfully.
+            cancelPendingJob();
+            uninstallPackage("com.android.egg");
+        }
     }
 
     private void runDeviceTest(String method) throws DeviceNotAvailableException {
@@ -109,7 +144,11 @@
     private void cancelPendingJob() throws DeviceNotAvailableException {
         CommandResult result = getDevice().executeShellV2Command(
                 "cmd jobscheduler cancel android " + JOB_ID);
-        assertTrue(result.getStatus() == CommandStatus.SUCCESS);
+        if (result.getStatus() == CommandStatus.SUCCESS) {
+            CLog.d("Canceling, output: " + result.getStdout());
+        } else {
+            CLog.d("Something went wrong, error: " + result.getStderr());
+        }
     }
 
     private void expectJobToBeScheduled() throws Exception {
@@ -117,6 +156,7 @@
             CommandResult result = getDevice().executeShellV2Command(
                     "cmd jobscheduler get-job-state android " + JOB_ID);
             String state = result.getStdout().toString();
+            CLog.i("Job status: " + state);
             if (state.startsWith("unknown")) {
                 // The job hasn't been scheduled yet. So try again.
                 TimeUnit.SECONDS.sleep(1);
@@ -134,7 +174,7 @@
         installPackage("com.android.apex.cts.shim.v2_rebootless.apex", "--force-non-staged");
     }
 
-    private void uninstallRebootlessApex() throws DeviceNotAvailableException {
+    private void uninstallRebootlessApexThenReboot() throws DeviceNotAvailableException {
         // Reboot only if the APEX is not the pre-install one.
         CommandResult result = getDevice().executeShellV2Command(
                 "pm list packages -f --apex-only |grep com.android.apex.cts.shim");
@@ -148,4 +188,23 @@
             assertTrue(runResult.getStatus() == CommandStatus.SUCCESS);
         }
     }
+
+    private void updatePreloadApp() throws DeviceNotAvailableException {
+        CommandResult result = getDevice().executeShellV2Command("pm path com.android.egg");
+        assertTrue(result.getStatus() == CommandStatus.SUCCESS);
+        assertThat(result.getStdout()).startsWith("package:/system/app/");
+        String path = result.getStdout().replaceFirst("^package:", "");
+
+        result = getDevice().executeShellV2Command("pm install " + path);
+        assertTrue(result.getStatus() == CommandStatus.SUCCESS);
+    }
+
+    private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> {
+        InstallMultiple() {
+            super(getDevice(), getBuild());
+            // Needed since in getMockBackgroundInstalledPackages, getPackageInfo runs as the caller
+            // uid. This also makes it consistent with installPackage's behavior.
+            addArg("--force-queryable");
+        }
+    }
 }
diff --git a/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java b/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java
index aedb366..c087a85 100644
--- a/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java
+++ b/tests/BinaryTransparencyHostTest/test-app/src/android/transparency/test/app/BinaryTransparencyTest.java
@@ -33,8 +33,10 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.HexFormat;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 @RunWith(AndroidJUnit4.class)
@@ -56,11 +58,12 @@
         assertThat(args).isNotNull();
         int number = Integer.valueOf(args.getString("apex-number"));
         assertThat(number).isGreaterThan(0);
-        var expectedApexNames = new HashSet<String>();
+        var expectedApexNames = new ArrayList<String>();
         for (var i = 0; i < number; i++) {
             String moduleName = args.getString("apex-" + Integer.toString(i));
             expectedApexNames.add(moduleName);
         }
+        assertThat(expectedApexNames).containsNoDuplicates();
 
         // Action
         var apexInfoList = mBt.collectAllApexInfo(/* includeTestOnly */ true);
@@ -109,4 +112,35 @@
         assertThat(updatedPreload.mbaStatus).isEqualTo(/* MBA_STATUS_UPDATED_PRELOAD */ 2);
         assertThat(updatedPreload.signerDigests).asList().containsNoneOf(null, "");
     }
+
+    @Test
+    public void testCollectAllSilentInstalledMbaInfo() {
+        // Action
+        var appInfoList = mBt.collectAllSilentInstalledMbaInfo(new Bundle());
+
+        // Verify
+        assertThat(appInfoList).isNotEmpty();  // because we just installed from the host side
+
+        var expectedAppNames = Set.of("com.android.apkverity", "com.android.egg");
+        var actualAppNames = appInfoList.stream().map((appInfo) -> appInfo.packageName)
+                .collect(Collectors.toList());
+        assertThat(actualAppNames).containsAtLeastElementsIn(expectedAppNames);
+
+        var actualSplitNames = new ArrayList<String>();
+        for (var appInfo : appInfoList) {
+            Log.d(TAG, "Received " + appInfo.packageName + " as a silent install");
+            if (expectedAppNames.contains(appInfo.packageName)) {
+                assertThat(appInfo.longVersion).isGreaterThan(0);
+                assertThat(appInfo.digestAlgorithm).isGreaterThan(0);
+                assertThat(appInfo.digest).isNotEmpty();
+                assertThat(appInfo.mbaStatus).isEqualTo(/* MBA_STATUS_NEW_INSTALL */ 3);
+                assertThat(appInfo.signerDigests).asList().containsNoneOf(null, "");
+
+                if (appInfo.splitName != null) {
+                    actualSplitNames.add(appInfo.splitName);
+                }
+            }
+        }
+        assertThat(actualSplitNames).containsExactly("feature_x");  // Name of ApkVerityTestAppSplit
+    }
 }
diff --git a/tests/ChoreographerTests/Android.bp b/tests/ChoreographerTests/Android.bp
new file mode 100644
index 0000000..ca30267
--- /dev/null
+++ b/tests/ChoreographerTests/Android.bp
@@ -0,0 +1,49 @@
+// Copyright 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+    name: "ChoreographerTests",
+    srcs: ["src/**/*.java"],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "compatibility-device-util-axt",
+        "com.google.android.material_material",
+        "truth-prebuilt",
+    ],
+    jni_libs: [
+        "libchoreographertests_jni",
+    ],
+    resource_dirs: ["src/main/res"],
+    certificate: "platform",
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    optimize: {
+        enabled: false,
+    },
+}
diff --git a/tests/ChoreographerTests/AndroidManifest.xml b/tests/ChoreographerTests/AndroidManifest.xml
new file mode 100644
index 0000000..3283c90
--- /dev/null
+++ b/tests/ChoreographerTests/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.view.choreographertests">
+
+    <application android:debuggable="true" android:testOnly="true">
+        <uses-library android:name="android.test.runner"/>
+        <activity
+            android:name=".GraphicsActivity"
+            android:exported="false">
+        </activity>
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.view.choreographertests"
+        android:label="Tests of android.view.ChoreographerTests">
+    </instrumentation>
+</manifest>
\ No newline at end of file
diff --git a/tests/ChoreographerTests/AndroidTest.xml b/tests/ChoreographerTests/AndroidTest.xml
new file mode 100644
index 0000000..e717699
--- /dev/null
+++ b/tests/ChoreographerTests/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<configuration description="Config for ChoreographerTests cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="test-tag" value="ChoreographerTests"/>
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="install-arg" value="-t" />
+        <option name="test-file-name" value="ChoreographerTests.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.view.choreographertests" />
+        <option name="hidden-api-checks" value="false" />
+        <option name="isolated-storage" value="false" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/ChoreographerTests/OWNERS b/tests/ChoreographerTests/OWNERS
new file mode 100644
index 0000000..2b7de25
--- /dev/null
+++ b/tests/ChoreographerTests/OWNERS
@@ -0,0 +1,2 @@
+include platform/frameworks/base:/graphics/java/android/graphics/OWNERS
+include platform/frameworks/native:/services/surfaceflinger/OWNERS
\ No newline at end of file
diff --git a/tests/ChoreographerTests/TEST_MAPPING b/tests/ChoreographerTests/TEST_MAPPING
new file mode 100644
index 0000000..16a48ea
--- /dev/null
+++ b/tests/ChoreographerTests/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "ChoreographerTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/ChoreographerTests/jni/Android.bp b/tests/ChoreographerTests/jni/Android.bp
new file mode 100644
index 0000000..7198c51
--- /dev/null
+++ b/tests/ChoreographerTests/jni/Android.bp
@@ -0,0 +1,44 @@
+// Copyright 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test_library {
+    name: "libchoreographertests_jni",
+    cflags: [
+        "-Werror",
+        "-Wthread-safety",
+    ],
+
+    gtest: false,
+
+    srcs: [
+        "ChoreographerTestsJniOnLoad.cpp",
+        "android_view_tests_ChoreographerNativeTest.cpp",
+    ],
+
+    shared_libs: [
+        "libandroid",
+        "libnativehelper",
+        "liblog",
+    ],
+
+    header_libs: [
+        "libandroid_headers_private",
+    ],
+
+    stl: "c++_static",
+}
diff --git a/tests/ChoreographerTests/jni/ChoreographerTestsJniOnLoad.cpp b/tests/ChoreographerTests/jni/ChoreographerTestsJniOnLoad.cpp
new file mode 100644
index 0000000..447376f
--- /dev/null
+++ b/tests/ChoreographerTests/jni/ChoreographerTestsJniOnLoad.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <jni.h>
+
+#define LOG_TAG "ChoreographerTestsJniOnLoad"
+
+extern int register_android_android_view_tests_ChoreographerNativeTest(JNIEnv* env);
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv* env = NULL;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        return JNI_ERR;
+    }
+
+    if (register_android_android_view_tests_ChoreographerNativeTest(env)) {
+        return JNI_ERR;
+    }
+
+    return JNI_VERSION_1_6;
+}
\ No newline at end of file
diff --git a/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp b/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp
new file mode 100644
index 0000000..27f4bae
--- /dev/null
+++ b/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <android/choreographer.h>
+#include <android/log.h>
+#include <android/surface_control_jni.h>
+#include <jni.h>
+#include <private/surface_control_private.h>
+#include <time.h>
+#include <utils/Log.h>
+#include <utils/Mutex.h>
+
+#include <chrono>
+#include <cmath>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+#undef LOG_TAG
+#define LOG_TAG "AttachedChoreographerNativeTest"
+
+// Copied from cts/tests/tests/view/jni/jniAssert.h, to be removed when integrated in CTS.
+#define ASSERT(condition, format, args...) \
+    if (!(condition)) {                    \
+        fail(env, format, ##args);         \
+        return;                            \
+    }
+
+using namespace std::chrono_literals;
+
+static constexpr std::chrono::nanoseconds kMaxRuntime{1s};
+static constexpr float kFpsTolerance = 5.0f;
+
+static constexpr int kNumOfFrames = 20;
+
+struct {
+    struct {
+        jclass clazz;
+        jmethodID endTest;
+    } attachedChoreographerNativeTest;
+} gJni;
+
+struct CallbackData {
+    std::mutex mutex;
+
+    // Condition to signal callbacks are done running and test can be verified.
+    std::condition_variable_any condition;
+
+    // Flag to ensure not to lock on the condition if notify is called before wait_for.
+    bool callbacksComplete = false;
+
+    AChoreographer* choreographer = nullptr;
+    int count GUARDED_BY(mutex){0};
+    std::chrono::nanoseconds frameTime GUARDED_BY(mutex){0};
+    std::chrono::nanoseconds startTime;
+    std::chrono::nanoseconds endTime GUARDED_BY(mutex){0};
+};
+
+static std::chrono::nanoseconds now() {
+    return std::chrono::steady_clock::now().time_since_epoch();
+}
+
+static void vsyncCallback(const AChoreographerFrameCallbackData* callbackData, void* data) {
+    ALOGI("%s: Vsync callback running", __func__);
+    long frameTimeNanos = AChoreographerFrameCallbackData_getFrameTimeNanos(callbackData);
+
+    auto* cb = static_cast<CallbackData*>(data);
+    {
+        std::lock_guard<std::mutex> _l(cb->mutex);
+        cb->count++;
+        cb->endTime = now();
+        cb->frameTime = std::chrono::nanoseconds{frameTimeNanos};
+
+        ALOGI("%s: ran callback now %ld, frameTimeNanos %ld, new count %d", __func__,
+              static_cast<long>(cb->endTime.count()), frameTimeNanos, cb->count);
+        if (cb->endTime - cb->startTime > kMaxRuntime) {
+            cb->callbacksComplete = true;
+            cb->condition.notify_all();
+            return;
+        }
+    }
+
+    ALOGI("%s: Posting next callback", __func__);
+    AChoreographer_postVsyncCallback(cb->choreographer, vsyncCallback, data);
+}
+
+static void fail(JNIEnv* env, const char* format, ...) {
+    va_list args;
+
+    va_start(args, format);
+    char* msg;
+    int rc = vasprintf(&msg, format, args);
+    va_end(args);
+
+    jclass exClass;
+    const char* className = "java/lang/AssertionError";
+    exClass = env->FindClass(className);
+    env->ThrowNew(exClass, msg);
+    free(msg);
+}
+
+jlong SurfaceControl_getChoreographer(JNIEnv* env, jclass, jobject surfaceControlObj) {
+    return reinterpret_cast<jlong>(
+            ASurfaceControl_getChoreographer(ASurfaceControl_fromJava(env, surfaceControlObj)));
+}
+
+static bool frameRateEquals(float fr1, float fr2) {
+    return std::abs(fr1 - fr2) <= kFpsTolerance;
+}
+
+static void endTest(JNIEnv* env, jobject clazz) {
+    env->CallVoidMethod(clazz, gJni.attachedChoreographerNativeTest.endTest);
+}
+
+static void android_view_ChoreographerNativeTest_testPostVsyncCallbackAtFrameRate(
+        JNIEnv* env, jobject clazz, jlong choreographerPtr, jfloat expectedFrameRate) {
+    AChoreographer* choreographer = reinterpret_cast<AChoreographer*>(choreographerPtr);
+    CallbackData cb;
+    cb.choreographer = choreographer;
+    cb.startTime = now();
+    ALOGI("%s: Post first callback at %ld", __func__, static_cast<long>(cb.startTime.count()));
+    AChoreographer_postVsyncCallback(choreographer, vsyncCallback, &cb);
+
+    std::scoped_lock<std::mutex> conditionLock(cb.mutex);
+    ASSERT(cb.condition.wait_for(cb.mutex, 2 * kMaxRuntime, [&cb] { return cb.callbacksComplete; }),
+           "Never received callbacks!");
+
+    float actualFrameRate = static_cast<float>(cb.count) /
+            (static_cast<double>((cb.endTime - cb.startTime).count()) / 1'000'000'000.0);
+    ALOGI("%s: callback called %d times with final start time %ld, end time %ld, effective "
+          "frame rate %f",
+          __func__, cb.count, static_cast<long>(cb.startTime.count()),
+          static_cast<long>(cb.endTime.count()), actualFrameRate);
+    ASSERT(frameRateEquals(actualFrameRate, expectedFrameRate),
+           "Effective frame rate is %f but expected to be %f", actualFrameRate, expectedFrameRate);
+
+    endTest(env, clazz);
+}
+
+static JNINativeMethod gMethods[] = {
+        {"nativeSurfaceControl_getChoreographer", "(Landroid/view/SurfaceControl;)J",
+         (void*)SurfaceControl_getChoreographer},
+        {"nativeTestPostVsyncCallbackAtFrameRate", "(JF)V",
+         (void*)android_view_ChoreographerNativeTest_testPostVsyncCallbackAtFrameRate},
+};
+
+int register_android_android_view_tests_ChoreographerNativeTest(JNIEnv* env) {
+    jclass clazz =
+            env->FindClass("android/view/choreographertests/AttachedChoreographerNativeTest");
+    gJni.attachedChoreographerNativeTest.clazz = static_cast<jclass>(env->NewGlobalRef(clazz));
+    gJni.attachedChoreographerNativeTest.endTest = env->GetMethodID(clazz, "endTest", "()V");
+    return env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/ChoreographerTests/src/main/java/android/view/choreographertests/AttachedChoreographerNativeTest.java b/tests/ChoreographerTests/src/main/java/android/view/choreographertests/AttachedChoreographerNativeTest.java
new file mode 100644
index 0000000..1118eb3
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/java/android/view/choreographertests/AttachedChoreographerNativeTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.choreographertests;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.Manifest;
+import android.hardware.display.DisplayManager;
+import android.support.test.uiautomator.UiDevice;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class AttachedChoreographerNativeTest {
+    private static final String TAG = "AttachedChoreographerNativeTest";
+
+    static {
+        System.loadLibrary("choreographertests_jni");
+    }
+
+    private final CountDownLatch mSurfaceCreationCountDown = new CountDownLatch(1);
+    private CountDownLatch mTestCompleteSignal;
+    private long mChoreographerPtr;
+    private SurfaceView mSurfaceView;
+    private SurfaceHolder mSurfaceHolder;
+    private ActivityScenario<GraphicsActivity> mScenario;
+    private int mInitialMatchContentFrameRate;
+    private DisplayManager mDisplayManager;
+
+    private static native long nativeSurfaceControl_getChoreographer(SurfaceControl surfaceControl);
+    private native void nativeTestPostVsyncCallbackAtFrameRate(
+            long choreographerPtr, float expectedFrameRate);
+
+    @Before
+    public void setup() throws Exception {
+        mScenario = ActivityScenario.launch(GraphicsActivity.class);
+        mScenario.moveToState(Lifecycle.State.CREATED);
+        mScenario.onActivity(activity -> {
+            mSurfaceView = activity.findViewById(R.id.surface);
+            mSurfaceHolder = mSurfaceView.getHolder();
+            mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+                @Override
+                public void surfaceChanged(
+                        SurfaceHolder holder, int format, int width, int height) {}
+
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    mSurfaceCreationCountDown.countDown();
+                }
+
+                @Override
+                public void surfaceDestroyed(SurfaceHolder holder) {}
+            });
+        });
+
+        mScenario.moveToState(Lifecycle.State.RESUMED);
+        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        uiDevice.wakeUp();
+        uiDevice.executeShellCommand("wm dismiss-keyguard");
+
+        InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+                android.Manifest.permission.LOG_COMPAT_CHANGE,
+                android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
+                android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
+                android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
+                Manifest.permission.MANAGE_GAME_MODE);
+        mScenario.onActivity(activity -> {
+            mDisplayManager = activity.getSystemService(DisplayManager.class);
+            mInitialMatchContentFrameRate =
+                    toSwitchingType(mDisplayManager.getMatchContentFrameRateUserPreference());
+            mDisplayManager.setRefreshRateSwitchingType(
+                    DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY);
+            mDisplayManager.setShouldAlwaysRespectAppRequestedMode(true);
+        });
+    }
+
+    @After
+    public void tearDown() {
+        mDisplayManager.setRefreshRateSwitchingType(mInitialMatchContentFrameRate);
+        mDisplayManager.setShouldAlwaysRespectAppRequestedMode(false);
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    @Test
+    public void test_choreographer_callbacksForVariousFrameRates() {
+        for (int divisor : new int[] {2, 3}) {
+            mTestCompleteSignal = new CountDownLatch(1);
+            mScenario.onActivity(activity -> {
+                if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds= */ 1L)) {
+                    fail("Unable to create surface within 1 Second");
+                }
+
+                SurfaceControl surfaceControl = mSurfaceView.getSurfaceControl();
+                mChoreographerPtr = nativeSurfaceControl_getChoreographer(surfaceControl);
+                Log.i(TAG, "mChoreographerPtr value " + mChoreographerPtr);
+
+                float displayRefreshRate = activity.getDisplay().getMode().getRefreshRate();
+                float expectedFrameRate = displayRefreshRate / divisor;
+
+                SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+                transaction
+                        .setFrameRate(surfaceControl, expectedFrameRate,
+                                Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
+                        .addTransactionCommittedListener(Runnable::run,
+                                () -> {
+                                    assertTrue(mChoreographerPtr != 0L);
+                                    Log.i(TAG, "Testing frame rate of " + expectedFrameRate);
+                                    nativeTestPostVsyncCallbackAtFrameRate(
+                                            mChoreographerPtr, expectedFrameRate);
+                                })
+                        .apply();
+            });
+            // wait for the previous callbacks to finish before moving to the next divisor
+            if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds= */ 5L)) {
+                fail("Test for divisor " + divisor + " not finished in 5 seconds");
+            }
+        }
+    }
+
+    /** Call from native to trigger test completion. */
+    private void endTest() {
+        Log.i(TAG, "Signal test completion!");
+        mTestCompleteSignal.countDown();
+    }
+
+    private boolean waitForCountDown(CountDownLatch countDownLatch, long timeoutInSeconds) {
+        try {
+            return !countDownLatch.await(timeoutInSeconds, TimeUnit.SECONDS);
+        } catch (InterruptedException ex) {
+            throw new AssertionError("Test interrupted", ex);
+        }
+    }
+
+    private int toSwitchingType(int matchContentFrameRateUserPreference) {
+        switch (matchContentFrameRateUserPreference) {
+            case DisplayManager.MATCH_CONTENT_FRAMERATE_NEVER:
+                return DisplayManager.SWITCHING_TYPE_NONE;
+            case DisplayManager.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY:
+                return DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
+            case DisplayManager.MATCH_CONTENT_FRAMERATE_ALWAYS:
+                return DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
+            default:
+                return -1;
+        }
+    }
+}
diff --git a/tests/ChoreographerTests/src/main/java/android/view/choreographertests/AttachedChoreographerTest.java b/tests/ChoreographerTests/src/main/java/android/view/choreographertests/AttachedChoreographerTest.java
new file mode 100644
index 0000000..3ea9651
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/java/android/view/choreographertests/AttachedChoreographerTest.java
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.choreographertests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.Manifest;
+import android.app.compat.CompatChanges;
+import android.hardware.display.DisplayManager;
+import android.os.Looper;
+import android.support.test.uiautomator.UiDevice;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class AttachedChoreographerTest {
+    private static final String TAG = "AttachedChoreographerTest";
+    private static final long DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE_CHANGEID = 170503758;
+    private static final long THRESHOLD_MS = 10;
+    private static final int FRAME_ITERATIONS = 21;
+    private static final int CALLBACK_MISSED_THRESHOLD = 2;
+
+    private final CountDownLatch mTestCompleteSignal = new CountDownLatch(2);
+    private final CountDownLatch mSurfaceCreationCountDown = new CountDownLatch(1);
+    private final CountDownLatch mNoCallbackSignal = new CountDownLatch(1);
+
+    private ActivityScenario<GraphicsActivity> mScenario;
+    private int mInitialMatchContentFrameRate;
+    private DisplayManager mDisplayManager;
+    private SurfaceView mSurfaceView;
+    private SurfaceHolder mSurfaceHolder;
+    private boolean mIsFirstCallback = true;
+    private int mCallbackMissedCounter = 0;
+
+    @Before
+    public void setUp() throws Exception {
+        mScenario = ActivityScenario.launch(GraphicsActivity.class);
+        mScenario.moveToState(Lifecycle.State.CREATED);
+        mScenario.onActivity(activity -> {
+            mSurfaceView = activity.findViewById(R.id.surface);
+            mSurfaceHolder = mSurfaceView.getHolder();
+            mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
+
+                @Override
+                public void surfaceCreated(SurfaceHolder holder) {
+                    mSurfaceCreationCountDown.countDown();
+                }
+
+                @Override
+                public void surfaceChanged(SurfaceHolder holder, int format, int width,
+                        int height) {
+                }
+
+                @Override
+                public void surfaceDestroyed(SurfaceHolder holder) {
+                }
+            });
+        });
+
+        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        uiDevice.wakeUp();
+        uiDevice.executeShellCommand("wm dismiss-keyguard");
+        mScenario.moveToState(Lifecycle.State.RESUMED);
+
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity(Manifest.permission.LOG_COMPAT_CHANGE,
+                        Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
+                        Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
+                        Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
+                        Manifest.permission.MANAGE_GAME_MODE);
+        mScenario.onActivity(activity -> {
+            mDisplayManager = activity.getSystemService(DisplayManager.class);
+            mInitialMatchContentFrameRate = toSwitchingType(
+                    mDisplayManager.getMatchContentFrameRateUserPreference());
+            mDisplayManager.setRefreshRateSwitchingType(
+                    DisplayManager.SWITCHING_TYPE_RENDER_FRAME_RATE_ONLY);
+            mDisplayManager.setShouldAlwaysRespectAppRequestedMode(true);
+            boolean changeIsEnabled =
+                    CompatChanges.isChangeEnabled(
+                            DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE_CHANGEID);
+            Log.i(TAG, "DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE_CHANGE_ID is "
+                    + (changeIsEnabled ? "enabled" : "disabled"));
+        });
+    }
+
+    @After
+    public void tearDown() {
+        mDisplayManager.setRefreshRateSwitchingType(mInitialMatchContentFrameRate);
+        mDisplayManager.setShouldAlwaysRespectAppRequestedMode(false);
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .dropShellPermissionIdentity();
+    }
+
+    @Test
+    public void testCreateChoreographer() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            mTestCompleteSignal.countDown();
+            SurfaceControl sc1 = new SurfaceControl(sc, "AttachedChoreographerTests");
+            // Create attached choreographer with getChoreographer
+            sc1.getChoreographer();
+            assertTrue(sc1.hasChoreographer());
+            assertTrue(sc1.isValid());
+            sc1.release();
+
+            SurfaceControl sc2 = new SurfaceControl(sc, "AttachedChoreographerTests");
+            // Create attached choreographer with Looper.myLooper
+            sc2.getChoreographer(Looper.myLooper());
+            assertTrue(sc2.hasChoreographer());
+            assertTrue(sc2.isValid());
+            sc2.release();
+
+            SurfaceControl sc3 = new SurfaceControl(sc, "AttachedChoreographerTests");
+            // Create attached choreographer with Looper.myLooper
+            sc3.getChoreographer(Looper.getMainLooper());
+            assertTrue(sc3.hasChoreographer());
+            assertTrue(sc3.isValid());
+            sc3.release();
+            mTestCompleteSignal.countDown();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testCopySurfaceControl() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            // Create attached choreographer
+            sc.getChoreographer();
+            assertTrue(sc.hasChoreographer());
+
+            // Use copy constructor
+            SurfaceControl copyConstructorSc = new SurfaceControl(sc, "AttachedChoreographerTests");
+            //Choreographer isn't copied over.
+            assertFalse(copyConstructorSc.hasChoreographer());
+            copyConstructorSc.getChoreographer();
+            assertTrue(copyConstructorSc.hasChoreographer());
+            mTestCompleteSignal.countDown();
+
+            // Use copyFrom
+            SurfaceControl copyFromSc = new SurfaceControl();
+            copyFromSc.copyFrom(sc, "AttachedChoreographerTests");
+            //Choreographer isn't copied over.
+            assertFalse(copyFromSc.hasChoreographer());
+            copyFromSc.getChoreographer();
+            assertTrue(copyFromSc.hasChoreographer());
+            mTestCompleteSignal.countDown();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testMirrorSurfaceControl() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            // Create attached choreographer
+            sc.getChoreographer();
+            assertTrue(sc.hasChoreographer());
+            mTestCompleteSignal.countDown();
+
+            // Use mirrorSurface
+            SurfaceControl mirrorSc = SurfaceControl.mirrorSurface(sc);
+            //Choreographer isn't copied over.
+            assertFalse(mirrorSc.hasChoreographer());
+            mirrorSc.getChoreographer();
+            assertTrue(mirrorSc.hasChoreographer());
+            // make SurfaceControl invalid by releasing it.
+            mirrorSc.release();
+
+            assertTrue(sc.isValid());
+            assertFalse(mirrorSc.isValid());
+            assertFalse(mirrorSc.hasChoreographer());
+            assertThrows(NullPointerException.class, mirrorSc::getChoreographer);
+            mTestCompleteSignal.countDown();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testPostFrameCallback() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            sc.getChoreographer().postFrameCallback(
+                    frameTimeNanos -> mTestCompleteSignal.countDown());
+
+            SurfaceControl copySc = new SurfaceControl(sc, "AttachedChoreographerTests");
+            Choreographer copyChoreographer = copySc.getChoreographer();
+            // make SurfaceControl invalid by releasing it.
+            copySc.release();
+
+            assertTrue(sc.isValid());
+            assertFalse(copySc.isValid());
+            copyChoreographer.postFrameCallback(frameTimeNanos -> mNoCallbackSignal.countDown());
+            assertDoesReceiveCallback();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testPostFrameCallbackDelayed() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            sc.getChoreographer(Looper.getMainLooper()).postFrameCallbackDelayed(
+                    callback -> mTestCompleteSignal.countDown(),
+                    /* delayMillis */ 5);
+
+            SurfaceControl copySc = new SurfaceControl(sc, "AttachedChoreographerTests");
+            Choreographer copyChoreographer = copySc.getChoreographer();
+            // make SurfaceControl invalid by releasing it.
+            copySc.release();
+
+            assertTrue(sc.isValid());
+            assertFalse(copySc.isValid());
+            copyChoreographer.postFrameCallbackDelayed(
+                    frameTimeNanos -> mNoCallbackSignal.countDown(), /* delayMillis */5);
+            assertDoesReceiveCallback();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testPostCallback() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            sc.getChoreographer().postCallback(Choreographer.CALLBACK_COMMIT,
+                    mTestCompleteSignal::countDown, /* token */ this);
+
+            SurfaceControl copySc = new SurfaceControl(sc, "AttachedChoreographerTests");
+            Choreographer copyChoreographer = copySc.getChoreographer();
+            // make SurfaceControl invalid by releasing it.
+            copySc.release();
+
+            assertTrue(sc.isValid());
+            assertFalse(copySc.isValid());
+            copyChoreographer.postCallback(Choreographer.CALLBACK_COMMIT,
+                    mNoCallbackSignal::countDown, /* token */ this);
+            assertDoesReceiveCallback();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testPostCallbackDelayed() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            sc.getChoreographer().postCallbackDelayed(Choreographer.CALLBACK_COMMIT,
+                    mTestCompleteSignal::countDown, /* token */ this, /* delayMillis */ 5);
+
+            SurfaceControl copySc = new SurfaceControl(sc, "AttachedChoreographerTests");
+            Choreographer copyChoreographer = copySc.getChoreographer();
+            // make SurfaceControl invalid by releasing it.
+            copySc.release();
+
+            assertTrue(sc.isValid());
+            assertFalse(copySc.isValid());
+            copyChoreographer.postCallbackDelayed(Choreographer.CALLBACK_COMMIT,
+                    mNoCallbackSignal::countDown, /* token */ this, /* delayMillis */ 5);
+            assertDoesReceiveCallback();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testPostVsyncCallback() {
+        mScenario.onActivity(activity -> {
+            if (waitForCountDown(mSurfaceCreationCountDown, /* timeout */ 1L)) {
+                fail("Unable to create surface within 1 Second");
+            }
+            SurfaceControl sc = mSurfaceView.getSurfaceControl();
+            sc.getChoreographer().postVsyncCallback(data -> mTestCompleteSignal.countDown());
+
+            SurfaceControl copySc = new SurfaceControl(sc, "AttachedChoreographerTests");
+            Choreographer copyChoreographer = copySc.getChoreographer();
+            // make SurfaceControl invalid by releasing it.
+            copySc.release();
+
+            assertTrue(sc.isValid());
+            assertFalse(copySc.isValid());
+            copyChoreographer.postVsyncCallback(data -> mNoCallbackSignal.countDown());
+            assertDoesReceiveCallback();
+        });
+        if (waitForCountDown(mTestCompleteSignal, /* timeoutInSeconds */ 2L)) {
+            fail("Test not finished in 2 Seconds");
+        }
+    }
+
+    @Test
+    public void testChoreographerDivisorRefreshRate() {
+        for (int divisor : new int[]{2, 3}) {
+            CountDownLatch continueLatch = new CountDownLatch(1);
+            mScenario.onActivity(activity -> {
+                if (waitForCountDown(mSurfaceCreationCountDown, /* timeoutInSeconds */ 1L)) {
+                    fail("Unable to create surface within 1 Second");
+                }
+                SurfaceControl sc = mSurfaceView.getSurfaceControl();
+                Choreographer choreographer = sc.getChoreographer();
+                SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+                float displayRefreshRate = activity.getDisplay().getMode().getRefreshRate();
+                float fps = displayRefreshRate / divisor;
+                long callbackDurationMs = Math.round(1000 / fps);
+                mCallbackMissedCounter = 0;
+                transaction.setFrameRate(sc, fps, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE)
+                        .addTransactionCommittedListener(Runnable::run,
+                                () -> verifyVsyncCallbacks(choreographer,
+                                        callbackDurationMs, continueLatch, FRAME_ITERATIONS))
+                        .apply();
+            });
+            // wait for the previous callbacks to finish before moving to the next divisor
+            if (waitForCountDown(continueLatch, /* timeoutInSeconds */ 5L)) {
+                fail("Test not finished in 5 Seconds");
+            }
+        }
+    }
+
+    private void verifyVsyncCallbacks(Choreographer choreographer, long callbackDurationMs,
+            CountDownLatch continueLatch, int frameCount) {
+        long callbackRequestedTimeNs = System.nanoTime();
+        choreographer.postVsyncCallback(frameData -> {
+            if (frameCount > 0) {
+                if (!mIsFirstCallback) {
+                    // Skip the first callback as it takes 1 frame
+                    // to reflect the new refresh rate
+                    long callbackDurationDiffMs = getCallbackDurationDiffInMs(
+                            frameData.getFrameTimeNanos(),
+                            callbackRequestedTimeNs, callbackDurationMs);
+                    if (callbackDurationDiffMs < 0 || callbackDurationDiffMs > THRESHOLD_MS) {
+                        mCallbackMissedCounter++;
+                        Log.e(TAG, "Frame #" + Math.abs(frameCount - FRAME_ITERATIONS)
+                                + " vsync callback failed, expected callback in "
+                                + callbackDurationMs
+                                + " With threshold of " + THRESHOLD_MS
+                                + " but actual duration difference is " + callbackDurationDiffMs);
+                    }
+                }
+                mIsFirstCallback = false;
+                verifyVsyncCallbacks(choreographer, callbackDurationMs,
+                        continueLatch, frameCount - 1);
+            } else {
+                assertTrue("Missed timeline for " + mCallbackMissedCounter + " callbacks, while "
+                                + CALLBACK_MISSED_THRESHOLD + " missed callbacks are allowed",
+                        mCallbackMissedCounter <= CALLBACK_MISSED_THRESHOLD);
+                continueLatch.countDown();
+            }
+        });
+    }
+
+    private long getCallbackDurationDiffInMs(long callbackTimeNs, long requestedTimeNs,
+            long expectedCallbackMs) {
+        long actualTimeMs = TimeUnit.NANOSECONDS.toMillis(callbackTimeNs)
+                - TimeUnit.NANOSECONDS.toMillis(requestedTimeNs);
+        return Math.abs(expectedCallbackMs - actualTimeMs);
+    }
+
+    private boolean waitForCountDown(CountDownLatch countDownLatch, long timeoutInSeconds) {
+        try {
+            return !countDownLatch.await(timeoutInSeconds, TimeUnit.SECONDS);
+        } catch (InterruptedException ex) {
+            throw new AssertionError("Test interrupted", ex);
+        }
+    }
+
+    private int toSwitchingType(int matchContentFrameRateUserPreference) {
+        switch (matchContentFrameRateUserPreference) {
+            case DisplayManager.MATCH_CONTENT_FRAMERATE_NEVER:
+                return DisplayManager.SWITCHING_TYPE_NONE;
+            case DisplayManager.MATCH_CONTENT_FRAMERATE_SEAMLESSS_ONLY:
+                return DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS;
+            case DisplayManager.MATCH_CONTENT_FRAMERATE_ALWAYS:
+                return DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
+            default:
+                return -1;
+        }
+    }
+
+    private void assertDoesReceiveCallback() {
+        try {
+            if (mNoCallbackSignal.await(/* timeout */ 50L, TimeUnit.MILLISECONDS)) {
+                fail("Callback not supposed to be generated");
+            } else {
+                mTestCompleteSignal.countDown();
+            }
+        } catch (InterruptedException e) {
+            fail("Callback wait is interrupted " + e);
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl b/tests/ChoreographerTests/src/main/java/android/view/choreographertests/GraphicsActivity.java
similarity index 64%
copy from telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
copy to tests/ChoreographerTests/src/main/java/android/view/choreographertests/GraphicsActivity.java
index 5c3fa32..50a6850 100644
--- a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
+++ b/tests/ChoreographerTests/src/main/java/android/view/choreographertests/GraphicsActivity.java
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package android.telephony.satellite;
+package android.view.choreographertests;
 
-import android.telephony.satellite.PointingInfo;
+import android.app.Activity;
+import android.os.Bundle;
 
-/**
- * Callback for position updates from the satellite service.
- * @hide
- */
-oneway interface ISatellitePositionUpdateCallback {
-    void onSatellitePositionUpdate(in PointingInfo pointingInfo);
-    void onMessageTransferStateUpdate(in int state);
+public class GraphicsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_attached_choreographer);
+    }
 }
diff --git a/tests/ChoreographerTests/src/main/res/layout/activity_attached_choreographer.xml b/tests/ChoreographerTests/src/main/res/layout/activity_attached_choreographer.xml
new file mode 100644
index 0000000..d6c8212
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/res/layout/activity_attached_choreographer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <SurfaceView
+        android:id="@+id/surface"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"/>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/tests/ChoreographerTests/src/main/res/mipmap-hdpi/ic_launcher.png b/tests/ChoreographerTests/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/ChoreographerTests/src/main/res/mipmap-mdpi/ic_launcher.png b/tests/ChoreographerTests/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/ChoreographerTests/src/main/res/mipmap-xhdpi/ic_launcher.png b/tests/ChoreographerTests/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/ChoreographerTests/src/main/res/mipmap-xxhdpi/ic_launcher.png b/tests/ChoreographerTests/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/ChoreographerTests/src/main/res/values/strings.xml b/tests/ChoreographerTests/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e66b001
--- /dev/null
+++ b/tests/ChoreographerTests/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <string name="app_name">ChoreographerTests</string>
+</resources>
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
index 64ed453..87bfdeb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -22,7 +22,7 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.junit.FlickerBuilderProvider
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Assume
 import org.junit.AssumptionViolatedException
 import org.junit.Test
@@ -184,12 +184,12 @@
     }
 
     open fun cujCompleted() {
-        entireScreenCovered()
-        statusBarLayerIsVisibleAtStartAndEnd()
-        statusBarLayerPositionAtStartAndEnd()
-        statusBarWindowIsAlwaysVisible()
-        visibleLayersShownMoreThanOneConsecutiveEntry()
-        visibleWindowsShownMoreThanOneConsecutiveEntry()
+        runAndIgnoreAssumptionViolation { entireScreenCovered() }
+        runAndIgnoreAssumptionViolation { statusBarLayerIsVisibleAtStartAndEnd() }
+        runAndIgnoreAssumptionViolation { statusBarLayerPositionAtStartAndEnd() }
+        runAndIgnoreAssumptionViolation { statusBarWindowIsAlwaysVisible() }
+        runAndIgnoreAssumptionViolation { visibleLayersShownMoreThanOneConsecutiveEntry() }
+        runAndIgnoreAssumptionViolation { visibleWindowsShownMoreThanOneConsecutiveEntry() }
         runAndIgnoreAssumptionViolation { taskBarLayerIsVisibleAtStartAndEnd() }
         runAndIgnoreAssumptionViolation { taskBarWindowIsAlwaysVisible() }
         runAndIgnoreAssumptionViolation { navBarLayerIsVisibleAtStartAndEnd() }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index f26ce25..e3dc699 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -20,8 +20,8 @@
 
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.ComponentNameMatcher
-import com.android.server.wm.traces.common.IComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.IComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.server.wm.traces.common.windowmanager.WindowManagerTrace
 
@@ -259,7 +259,7 @@
                     snapshotLayers
                         .mapNotNull { snapshotLayer -> snapshotLayer.layer?.visibleRegion }
                         .toTypedArray()
-                val snapshotRegion = RegionSubject.assertThat(visibleAreas, this, timestamp)
+                val snapshotRegion = RegionSubject(visibleAreas, this, timestamp)
                 val appVisibleRegion = it.visibleRegion(component)
                 if (snapshotRegion.region.isNotEmpty) {
                     snapshotRegion.coversExactly(appVisibleRegion.region)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplitTest.kt
similarity index 63%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplitTest.kt
index ea67729..7f2e057f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplitTest.kt
@@ -33,13 +33,13 @@
  * Test opening an activity that will launch another activity as ActivityEmbedding placeholder in
  * split.
  *
- * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplit`
+ * To run this test: `atest FlickerTests:OpenActivityEmbeddingPlaceholderSplitTest`
  */
 @RequiresDevice
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenActivityEmbeddingPlaceholderSplit(flicker: FlickerTest) :
+class OpenActivityEmbeddingPlaceholderSplitTest(flicker: FlickerTest) :
     ActivityEmbeddingTestBase(flicker) {
 
     /** {@inheritDoc} */
@@ -55,9 +55,21 @@
         }
     }
 
+    /** Main activity should become invisible after launching the placeholder primary activity. */
     @Presubmit
     @Test
-    fun mainActivityBecomesInvisible() {
+    fun mainActivityWindowBecomesInvisible() {
+        flicker.assertWm {
+            isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+                .then()
+                .isAppWindowInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /** Main activity should become invisible after launching the placeholder primary activity. */
+    @Presubmit
+    @Test
+    fun mainActivityLayerBecomesInvisible() {
         flicker.assertLayers {
             isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
                 .then()
@@ -65,76 +77,41 @@
         }
     }
 
+    /**
+     * Placeholder primary and secondary should become visible after launch. The windows are not
+     * necessarily to become visible at the same time.
+     */
     @Presubmit
     @Test
-    fun placeholderSplitBecomesVisible() {
-        flicker.assertLayers {
-            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+    fun placeholderSplitWindowsBecomeVisible() {
+        flicker.assertWm {
+            notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
                 .then()
-                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+                .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+                .then()
+                .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
         }
-        flicker.assertLayers {
-            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+        flicker.assertWm {
+            notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
                 .then()
-                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+                .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+                .then()
+                .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
         }
     }
 
-    /** {@inheritDoc} */
-    @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
-
-    /** {@inheritDoc} */
+    /** Placeholder primary and secondary should become visible together after launch. */
     @Presubmit
     @Test
-    override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun navBarLayerIsVisibleAtStartAndEnd() = super.navBarLayerIsVisibleAtStartAndEnd()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun statusBarLayerIsVisibleAtStartAndEnd() =
-        super.statusBarLayerIsVisibleAtStartAndEnd()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun statusBarLayerPositionAtStartAndEnd() = super.statusBarLayerPositionAtStartAndEnd()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
-        super.visibleWindowsShownMoreThanOneConsecutiveEntry()
-
-    /** {@inheritDoc} */
-    @Presubmit
-    @Test
-    override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
-        super.visibleLayersShownMoreThanOneConsecutiveEntry()
+    fun placeholderSplitLayersBecomeVisible() {
+        flicker.assertLayers {
+            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+            isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+                .then()
+                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+                .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+        }
+    }
 
     companion object {
         /**
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
new file mode 100644
index 0000000..20259a7
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.activityembedding
+
+import android.platform.test.annotations.Presubmit
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.FlickerBuilder
+import com.android.server.wm.flicker.FlickerTest
+import com.android.server.wm.flicker.FlickerTestFactory
+import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
+import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test opening a secondary activity that will split with the main activity.
+ *
+ * To run this test: `atest FlickerTests:OpenActivityEmbeddingSecondaryToSplitTest`
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenActivityEmbeddingSecondaryToSplitTest(flicker: FlickerTest) :
+    ActivityEmbeddingTestBase(flicker) {
+
+    /** {@inheritDoc} */
+    override val transition: FlickerBuilder.() -> Unit = {
+        setup {
+            tapl.setExpectedRotationCheckEnabled(false)
+            testApp.launchViaIntent(wmHelper)
+        }
+        transitions { testApp.launchSecondaryActivity(wmHelper) }
+        teardown {
+            tapl.goHome()
+            testApp.exit(wmHelper)
+        }
+    }
+
+    /** Main activity should remain visible when enter split from fullscreen. */
+    @Presubmit
+    @Test
+    fun mainActivityWindowIsAlwaysVisible() {
+        flicker.assertWm {
+            isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /**
+     * Main activity surface is animated from fullscreen to ActivityEmbedding split.
+     * During the transition, there is a period of time that it is covered by a snapshot of itself.
+     */
+    @Presubmit
+    @Test
+    fun mainActivityLayerIsAlwaysVisible() {
+        flicker.assertLayers {
+            isVisible(
+                ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT.or(
+                    ComponentNameMatcher.TRANSITION_SNAPSHOT
+                )
+            )
+        }
+        flicker.assertLayersEnd {
+            isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+                .isInvisible(ComponentNameMatcher.TRANSITION_SNAPSHOT)
+        }
+    }
+
+    /** Secondary activity should become visible after launching into split. */
+    @Presubmit
+    @Test
+    fun secondaryActivityWindowBecomesVisible() {
+        flicker.assertWm {
+            notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                .then()
+                .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                .then()
+                .isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+        }
+    }
+
+    /** Secondary activity should become visible after launching into split. */
+    @Presubmit
+    @Test
+    fun secondaryActivityLayerBecomesVisible() {
+        flicker.assertLayers {
+            isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+                .then()
+                .isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+        }
+    }
+
+    companion object {
+        /**
+         * Creates the test configurations.
+         *
+         * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+         * navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<FlickerTest> {
+            return FlickerTestFactory.nonRotationTests()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index 23503d2..4d72729 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.traces.common.ComponentNameMatcher.Companion.LAUNCHER
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher.Companion.LAUNCHER
 import org.junit.Test
 
 /** Base test class for transitions that close an app back to the launcher screen */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
index 368cc56..65d0fa9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
@@ -24,7 +24,7 @@
 import androidx.window.extensions.WindowExtensionsProvider
 import androidx.window.extensions.embedding.ActivityEmbeddingComponent
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.windowmanager.WindowManagerState.Companion.STATE_RESUMED
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
@@ -39,6 +39,25 @@
 ) : StandardAppHelper(instr, launcherName, component) {
 
     /**
+     * Clicks the button to launch the secondary activity, which should split with the main activity
+     * based on the split pair rule.
+     */
+    fun launchSecondaryActivity(wmHelper: WindowManagerStateHelper) {
+        val launchButton =
+            uiDevice.wait(
+                Until.findObject(By.res(getPackage(), "launch_secondary_activity_button")),
+                FIND_TIMEOUT
+            )
+        require(launchButton != null) { "Can't find launch secondary activity button on screen." }
+        launchButton.click()
+        wmHelper
+            .StateSyncBuilder()
+            .withActivityState(SECONDARY_ACTIVITY_COMPONENT, STATE_RESUMED)
+            .withActivityState(MAIN_ACTIVITY_COMPONENT, STATE_RESUMED)
+            .waitForAndVerify()
+    }
+
+    /**
      * Clicks the button to launch the placeholder primary activity, which should launch the
      * placeholder secondary activity based on the placeholder rule.
      */
@@ -63,6 +82,9 @@
         val MAIN_ACTIVITY_COMPONENT =
             ActivityOptions.ActivityEmbedding.MainActivity.COMPONENT.toFlickerComponent()
 
+        val SECONDARY_ACTIVITY_COMPONENT =
+            ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT.toFlickerComponent()
+
         val PLACEHOLDER_PRIMARY_COMPONENT =
             ActivityOptions.ActivityEmbedding.PlaceholderPrimaryActivity.COMPONENT
                 .toFlickerComponent()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt
index 4ff4e31..73018a0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt
@@ -17,7 +17,7 @@
 package com.android.server.wm.flicker.helpers
 
 import android.app.Instrumentation
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 
 class AppPairsHelper(
     instrumentation: Instrumentation,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/CameraAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/CameraAppHelper.kt
deleted file mode 100644
index a2d4d3a..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/CameraAppHelper.kt
+++ /dev/null
@@ -1,61 +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.server.wm.flicker.helpers
-
-import android.app.Instrumentation
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.content.pm.ResolveInfo
-import android.provider.MediaStore
-import com.android.server.wm.traces.common.ComponentNameMatcher
-
-class CameraAppHelper
-@JvmOverloads
-constructor(
-    instrumentation: Instrumentation,
-    pkgManager: PackageManager = instrumentation.context.packageManager
-) :
-    StandardAppHelper(
-        instrumentation,
-        getCameraLauncherName(pkgManager),
-        getCameraComponent(pkgManager)
-    ) {
-    companion object {
-        private fun getCameraIntent(): Intent {
-            return Intent(MediaStore.ACTION_IMAGE_CAPTURE)
-        }
-
-        private fun getResolveInfo(pkgManager: PackageManager): ResolveInfo {
-            val intent = getCameraIntent()
-            return pkgManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)
-                ?: error("unable to resolve camera activity")
-        }
-
-        private fun getCameraComponent(pkgManager: PackageManager): ComponentNameMatcher {
-            val resolveInfo = getResolveInfo(pkgManager)
-            return ComponentNameMatcher(
-                resolveInfo.activityInfo.packageName,
-                className = resolveInfo.activityInfo.name
-            )
-        }
-
-        private fun getCameraLauncherName(pkgManager: PackageManager): String {
-            val resolveInfo = getResolveInfo(pkgManager)
-            return resolveInfo.activityInfo.name
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
index 05b50f0..cdf7ae5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class FixedOrientationAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt
index d583bba..f5aed41 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt
@@ -21,7 +21,7 @@
 import androidx.test.uiautomator.Direction
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 3bb7f4e..a433b15 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -20,7 +20,7 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
index 871b66e..fb0242e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
@@ -20,7 +20,7 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
index 67d3195..fb04b32 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
@@ -23,9 +23,10 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.Condition
 import com.android.server.wm.traces.common.DeviceStateDump
+import com.android.server.wm.traces.common.component.matchers.IComponentMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
@@ -48,12 +49,13 @@
 
     override fun launchViaIntent(
         wmHelper: WindowManagerStateHelper,
-        expectedWindowName: String,
+        launchedAppComponentMatcherOverride: IComponentMatcher?,
         action: String?,
         stringExtras: Map<String, String>,
         waitConditions: Array<Condition<DeviceStateDump>>
     ) {
-        super.launchViaIntent(wmHelper, expectedWindowName, action, stringExtras, waitConditions)
+        super.launchViaIntent(
+            wmHelper, launchedAppComponentMatcherOverride, action, stringExtras, waitConditions)
         waitIMEShown(wmHelper)
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
index 69d6a47..8a25e36 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class ImeStateInitializeHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt
index d0935ef..d6ed24a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt
@@ -22,7 +22,7 @@
 import androidx.test.uiautomator.UiObject2
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class MailAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt
index e0f6fb0..ae42232 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt
@@ -21,7 +21,7 @@
 import android.provider.Settings
 import android.util.Log
 import com.android.compatibility.common.util.SystemUtil
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import java.io.IOException
 
 class MultiWindowUtils(
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
index 8b3fa18..5c1eca3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
@@ -21,7 +21,7 @@
 import androidx.test.uiautomator.UiDevice
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
index 992a1a1..58da2d8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class NonResizeableAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
index c29c752..d7f0830 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
@@ -20,7 +20,7 @@
 import androidx.test.uiautomator.By
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index d9aec10..0c8589d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -26,6 +26,7 @@
 import com.android.server.wm.flicker.testapp.ActivityOptions
 import com.android.server.wm.traces.common.Rect
 import com.android.server.wm.traces.common.WindowManagerConditionsFactory
+import com.android.server.wm.traces.common.component.matchers.IComponentMatcher
 import com.android.server.wm.traces.common.region.Region
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
@@ -157,13 +158,13 @@
     @JvmOverloads
     fun launchViaIntentAndWaitForPip(
         wmHelper: WindowManagerStateHelper,
-        expectedWindowName: String = "",
+        launchedAppComponentMatcherOverride: IComponentMatcher? = null,
         action: String? = null,
         stringExtras: Map<String, String>
     ) {
         launchViaIntentAndWaitShown(
             wmHelper,
-            expectedWindowName,
+            launchedAppComponentMatcherOverride,
             action,
             stringExtras,
             waitConditions = arrayOf(WindowManagerConditionsFactory.hasPipWindow())
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
index c51754c..8f54000 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class SeamlessRotationAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
index 9318f20..61dabfc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class ShowWhenLockedAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
index b46ff2c..9ed9d28e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
@@ -18,7 +18,7 @@
 
 import android.app.Instrumentation
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 
 class SimpleAppHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
index 720d962..8f7049a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
@@ -21,7 +21,7 @@
 import androidx.test.uiautomator.UiDevice
 import androidx.test.uiautomator.Until
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
index 0f59d81..092a4fd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.helpers.ImeEditorPopupDialogAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -90,7 +90,7 @@
                                 imeSnapshotLayer.layer?.visibleRegion
                             }
                             .toTypedArray()
-                    val imeVisibleRegion = RegionSubject.assertThat(visibleAreas, this, timestamp)
+                    val imeVisibleRegion = RegionSubject(visibleAreas, this, timestamp)
                     val appVisibleRegion = it.visibleRegion(imeTestApp)
                     if (imeVisibleRegion.region.isNotEmpty) {
                         imeVisibleRegion.coversAtMost(appVisibleRegion.region)
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 b40720b..0870cec 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
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.ImeAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -100,6 +100,7 @@
         flicker.assertLayers { this.isVisible(testApp).then().isInvisible(testApp) }
     }
 
+    @Presubmit
     @Test
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
index aa1e772..48dbf25 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
index dfbfde8..7b935ff 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
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 f6838f4..1a0c959 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
@@ -27,7 +27,7 @@
 import com.android.server.wm.flicker.helpers.ImeAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -102,6 +102,7 @@
         flicker.assertWm { this.isAppWindowOnTop(testApp) }
     }
 
+    @Presubmit
     @Test
     @IwTest(focusArea = "ime")
     override fun 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 a744cd7..0b7b165 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
@@ -79,6 +79,7 @@
         super.visibleLayersShownMoreThanOneConsecutiveEntry()
     }
 
+    @Presubmit
     @Test
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
index 3edc15f..dcffa47 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
@@ -19,7 +19,7 @@
 package com.android.server.wm.flicker.ime
 
 import com.android.server.wm.flicker.FlickerTest
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 
 fun FlickerTest.imeLayerBecomesVisible() {
     assertLayers {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
index 09ef54f..defb437 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.traces.region.RegionSubject
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
index 8b25d7a..c72e4e4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.reopenAppFromOverview
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
index 1e908d6..167689c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
@@ -28,7 +28,7 @@
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
 import org.junit.Before
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
index 0fced8c..e7cfb9e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.ImeStateInitializeHelper
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.FixMethodOrder
 import org.junit.Test
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 36747cc7..851651e 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
@@ -50,6 +50,7 @@
         }
     }
 
+    @Presubmit
     @Test
     @IwTest(focusArea = "ime")
     override fun cujCompleted() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
index 7ef09c7..6058212 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
@@ -27,7 +27,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
index fd420454..5d96346 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
@@ -27,7 +27,7 @@
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
 import com.android.server.wm.flicker.statusBarLayerIsVisibleAtStartAndEnd
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.WindowManagerConditionsFactory
 import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 import org.junit.Assume
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index 1baff37..7979cf9b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.helpers.TwoActivitiesAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt
index baa2750..0942287 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTest.kt
@@ -49,8 +49,9 @@
                 // 1. Open camera - cold -> close it first
                 cameraApp.exit(wmHelper)
                 cameraApp.launchViaIntent(wmHelper)
-                // 2. Press home button (button nav mode) / swipe up to home (gesture nav mode)
-                tapl.goHome()
+                // Can't use TAPL due to Recents not showing in 3 Button Nav in full screen mode
+                device.pressHome()
+                tapl.getWorkspace()
             }
             teardown { testApp.exit(wmHelper) }
             transitions { testApp.launchViaIntent(wmHelper) }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
index b234ec7..2f0e56f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
@@ -19,7 +19,7 @@
 import android.platform.test.annotations.Presubmit
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.replacesLayer
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Test
 
 /** Base class for app launch tests */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index 991cd1c..08786d3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Ignore
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index 60b0f9b..a5d85cc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Ignore
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
index 75de476..ff39611 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.ShowWhenLockedAppHelper
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
index 718c6e9..aa054a9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
@@ -22,7 +22,7 @@
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.navBarLayerPositionAtEnd
 import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Assume
 import org.junit.Ignore
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
index 90c18c4..0ed3bba 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Ignore
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
index efca6ab..af6c81d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
@@ -35,7 +35,7 @@
 import com.android.server.wm.flicker.navBarWindowIsVisibleAtEnd
 import com.android.server.wm.flicker.taskBarLayerIsVisibleAtEnd
 import com.android.server.wm.flicker.taskBarWindowIsVisibleAtEnd
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Assume
 import org.junit.FixMethodOrder
 import org.junit.Ignore
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index 7cfe879..55e7a99 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -25,7 +25,7 @@
 import com.android.server.wm.flicker.annotation.FlickerServiceCompatible
 import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
 import org.junit.FixMethodOrder
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index 2adb0b4..618fb8a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.setRotation
 import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Test
 
 /** Base class for app launch tests */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
index b9594a1..c78d0e9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
@@ -33,7 +33,7 @@
 import com.android.server.wm.flicker.junit.FlickerBuilderProvider
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.WindowManagerConditionsFactory
 import org.junit.FixMethodOrder
 import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index 959ab3d..94afd81 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -31,12 +31,12 @@
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
-import com.android.server.wm.traces.common.ComponentNameMatcher.Companion.DEFAULT_TASK_DISPLAY_AREA
-import com.android.server.wm.traces.common.ComponentNameMatcher.Companion.SPLASH_SCREEN
-import com.android.server.wm.traces.common.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER
-import com.android.server.wm.traces.common.ComponentSplashScreenMatcher
-import com.android.server.wm.traces.common.IComponentMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher.Companion.DEFAULT_TASK_DISPLAY_AREA
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher.Companion.SPLASH_SCREEN
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER
+import com.android.server.wm.traces.common.component.matchers.ComponentSplashScreenMatcher
+import com.android.server.wm.traces.common.component.matchers.IComponentMatcher
 import com.android.server.wm.traces.parser.toFlickerComponent
 import org.junit.Assume
 import org.junit.FixMethodOrder
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index be3b0bf..b7faf83 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.Rect
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 18d1d3c..6294761 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -26,7 +26,7 @@
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.Rect
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index e06a8d6..c03cd29 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -26,8 +26,8 @@
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
 import com.android.server.wm.traces.common.Rect
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import com.android.server.wm.traces.common.service.PlatformConsts
 import org.junit.Assume
 import org.junit.FixMethodOrder
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 8b250c3..e7e39c6 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
@@ -24,7 +24,7 @@
 import com.android.server.wm.flicker.FlickerTestFactory
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index 4ef9eaf..74ecdde 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -22,7 +22,7 @@
 import com.android.server.wm.flicker.FlickerTest
 import com.android.server.wm.flicker.helpers.StandardAppHelper
 import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.Test
 
 /** Base class for app rotation tests */
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 d76c94d..1a69344 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
@@ -27,7 +27,7 @@
 import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
 import com.android.server.wm.flicker.junit.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.testapp.ActivityOptions
-import com.android.server.wm.traces.common.ComponentNameMatcher
+import com.android.server.wm.traces.common.component.matchers.ComponentNameMatcher
 import org.junit.FixMethodOrder
 import org.junit.Ignore
 import org.junit.Test
@@ -111,9 +111,9 @@
                 val appWindow = it.windowState(testApp.`package`)
                 val flags = appWindow.windowState?.attributes?.flags ?: 0
                 appWindow
-                    .verify("isFullScreen")
+                    .check { "isFullScreen" }
                     .that(flags.and(WindowManager.LayoutParams.FLAG_FULLSCREEN))
-                    .isGreaterThan(0)
+                    .isGreater(0)
             }
         }
     }
@@ -127,13 +127,13 @@
                 val appWindow = it.windowState(testApp.`package`)
                 val rotationAnimation = appWindow.windowState?.attributes?.rotationAnimation ?: 0
                 appWindow
-                    .verify("isRotationSeamless")
+                    .check { "isRotationSeamless" }
                     .that(
                         rotationAnimation.and(
                             WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
                         )
                     )
-                    .isGreaterThan(0)
+                    .isGreater(0)
             }
         }
     }
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index cd47f60..5361d73f 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -179,6 +179,13 @@
             </intent-filter>
         </activity>
         <activity
+            android:name=".ActivityEmbeddingSecondaryActivity"
+            android:label="ActivityEmbedding Secondary"
+            android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
+            android:theme="@style/CutoutShortEdges"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+            android:exported="false"/>
+        <activity
             android:name=".ActivityEmbeddingPlaceholderPrimaryActivity"
             android:label="ActivityEmbedding Placeholder Primary"
             android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
index 19c81a8..d78b9a8 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_embedding_main_layout.xml
@@ -22,6 +22,14 @@
     android:background="@android:color/holo_orange_light">
 
     <Button
+        android:id="@+id/launch_secondary_activity_button"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:layout_centerHorizontal="true"
+        android:onClick="launchSecondaryActivity"
+        android:text="Launch Secondary Activity" />
+
+    <Button
         android:id="@+id/launch_placeholder_split_button"
         android:layout_width="wrap_content"
         android:layout_height="48dp"
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
index 04a590d..6a7a2cc 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingMainActivity.java
@@ -25,6 +25,7 @@
 
 import androidx.window.extensions.embedding.ActivityEmbeddingComponent;
 import androidx.window.extensions.embedding.EmbeddingRule;
+import androidx.window.extensions.embedding.SplitPairRule;
 import androidx.window.extensions.embedding.SplitPlaceholderRule;
 
 import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper;
@@ -40,20 +41,23 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_embedding_main_layout);
+    }
 
-        initializeSplitRules();
+    /** R.id.launch_secondary_activity_button onClick */
+    public void launchSecondaryActivity(View view) {
+        initializeSplitRules(createSplitPairRules());
+        startActivity(new Intent().setComponent(
+                ActivityOptions.ActivityEmbedding.SecondaryActivity.COMPONENT));
     }
 
     /** R.id.launch_placeholder_split_button onClick */
     public void launchPlaceholderSplit(View view) {
-        startActivity(
-                new Intent().setComponent(
-                        ActivityOptions.ActivityEmbedding.PlaceholderPrimaryActivity.COMPONENT
-                )
-        );
+        initializeSplitRules(createSplitPlaceholderRules());
+        startActivity(new Intent().setComponent(
+                ActivityOptions.ActivityEmbedding.PlaceholderPrimaryActivity.COMPONENT));
     }
 
-    private void initializeSplitRules() {
+    private void initializeSplitRules(Set<EmbeddingRule> rules) {
         ActivityEmbeddingComponent embeddingComponent =
                 ActivityEmbeddingAppHelper.getActivityEmbeddingComponent();
         if (embeddingComponent == null) {
@@ -62,14 +66,28 @@
             finish();
             return;
         }
-
-        embeddingComponent.setEmbeddingRules(getSplitRules());
+        embeddingComponent.setEmbeddingRules(rules);
     }
 
-    private Set<EmbeddingRule> getSplitRules() {
+    private Set<EmbeddingRule> createSplitPairRules() {
         final Set<EmbeddingRule> rules = new ArraySet<>();
+        final SplitPairRule rule = new SplitPairRule.Builder(
+                activitiesPair -> activitiesPair.first instanceof ActivityEmbeddingMainActivity
+                        && activitiesPair.second instanceof ActivityEmbeddingSecondaryActivity,
+                activityIntentPair ->
+                        activityIntentPair.first instanceof ActivityEmbeddingMainActivity
+                                && activityIntentPair.second.getComponent().equals(ActivityOptions
+                                .ActivityEmbedding.SecondaryActivity.COMPONENT),
+                windowMetrics -> true)
+                .setSplitRatio(DEFAULT_SPLIT_RATIO)
+                .build();
+        rules.add(rule);
+        return rules;
+    }
 
-        final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule.Builder(
+    private Set<EmbeddingRule> createSplitPlaceholderRules() {
+        final Set<EmbeddingRule> rules = new ArraySet<>();
+        final SplitPlaceholderRule rule = new SplitPlaceholderRule.Builder(
                 new Intent().setComponent(
                         ActivityOptions.ActivityEmbedding.PlaceholderSecondaryActivity.COMPONENT),
                 activity -> activity instanceof ActivityEmbeddingPlaceholderPrimaryActivity,
@@ -78,7 +96,7 @@
                 windowMetrics -> true)
                 .setSplitRatio(DEFAULT_SPLIT_RATIO)
                 .build();
-        rules.add(placeholderRule);
+        rules.add(rule);
         return rules;
     }
 }
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingSecondaryActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingSecondaryActivity.java
new file mode 100644
index 0000000..00f4c25
--- /dev/null
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityEmbeddingSecondaryActivity.java
@@ -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.server.wm.flicker.testapp;
+
+import android.graphics.Color;
+
+/**
+ * Activity to be used as the secondary activity to split with
+ * {@link ActivityEmbeddingMainActivity}.
+ */
+public class ActivityEmbeddingSecondaryActivity extends ActivityEmbeddingBaseActivity {
+    @Override
+    int getBackgroundColor() {
+        return Color.YELLOW;
+    }
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index 00684de..b61bc0c 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -87,6 +87,12 @@
                     FLICKER_APP_PACKAGE + ".ActivityEmbeddingMainActivity");
         }
 
+        public static class SecondaryActivity {
+            public static final String LABEL = "ActivityEmbeddingSecondaryActivity";
+            public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
+                    FLICKER_APP_PACKAGE + ".ActivityEmbeddingSecondaryActivity");
+        }
+
         public static class PlaceholderPrimaryActivity {
             public static final String LABEL = "ActivityEmbeddingPlaceholderPrimaryActivity";
             public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java
index d3a5885..ae3dcb8 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MeshActivity.java
@@ -26,13 +26,12 @@
 import android.graphics.MeshSpecification.Attribute;
 import android.graphics.MeshSpecification.Varying;
 import android.graphics.Paint;
-import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Bundle;
 import android.view.View;
 
 import java.nio.FloatBuffer;
 import java.nio.ShortBuffer;
-import java.util.ArrayList;
 
 public class MeshActivity extends Activity {
     @Override
@@ -64,8 +63,8 @@
             vertexBuffer.put(4, 0.0f);
             vertexBuffer.put(5, 400.0f);
             vertexBuffer.rewind();
-            Mesh mesh = Mesh.make(
-                    meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, new Rect(0, 0, 1000, 1000));
+            Mesh mesh = new Mesh(
+                    meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, new RectF(0, 0, 1000, 1000));
 
             canvas.drawMesh(mesh, BlendMode.COLOR, new Paint());
 
@@ -98,8 +97,8 @@
             }
             iVertexBuffer.rewind();
             indexBuffer.rewind();
-            Mesh mesh2 = Mesh.makeIndexed(meshSpec, Mesh.TRIANGLES, iVertexBuffer, 102, indexBuffer,
-                    new Rect(0, 0, 1000, 1000));
+            Mesh mesh2 = new Mesh(meshSpec, Mesh.TRIANGLES, iVertexBuffer, 102, indexBuffer,
+                    new RectF(0, 0, 1000, 1000));
             Paint paint = new Paint();
             paint.setColor(Color.RED);
             canvas.drawMesh(mesh2, BlendMode.COLOR, paint);
@@ -115,9 +114,11 @@
                     + "      color = vec4(1.0, 0.0, 0.0, 1.0);"
                     + "      return varyings.position;\n"
                     + "}";
-            ArrayList<Attribute> attList = new ArrayList<>();
-            attList.add(new Attribute(MeshSpecification.FLOAT2, 0, "position"));
-            ArrayList<Varying> varyList = new ArrayList<>();
+            Attribute[] attList = new Attribute[]{
+                    new Attribute(MeshSpecification.TYPE_FLOAT2, 0, "position"),
+
+            };
+            Varying[] varyList = new Varying[0];
             return MeshSpecification.make(attList, 8, varyList, vs, fs);
         }
     }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MeshLargeActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MeshLargeActivity.java
index f97d942..01ca2fc 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/MeshLargeActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MeshLargeActivity.java
@@ -26,13 +26,12 @@
 import android.graphics.MeshSpecification.Attribute;
 import android.graphics.MeshSpecification.Varying;
 import android.graphics.Paint;
-import android.graphics.Rect;
+import android.graphics.RectF;
 import android.os.Bundle;
 import android.view.View;
 
 import java.nio.FloatBuffer;
 import java.nio.ShortBuffer;
-import java.util.ArrayList;
 
 public class MeshLargeActivity extends Activity {
     @Override
@@ -109,9 +108,9 @@
             }
             vertexBuffer.rewind();
             indexBuffer.rewind();
-            Mesh mesh = Mesh.makeIndexed(
+            Mesh mesh = new Mesh(
                     meshSpec, Mesh.TRIANGLES, vertexBuffer, numTriangles + 2, indexBuffer,
-                    new Rect(0, 0, 1000, 1000)
+                    new RectF(0, 0, 1000, 1000)
             );
             mesh.setFloatUniform("test", 1.0f, 2.0f);
             Paint paint = new Paint();
@@ -131,44 +130,37 @@
                     + "      color = vec4(1.0, 0.0, 0.0, 1.0);"
                     + "      return varyings.position;\n"
                     + "}";
-            ArrayList<Attribute> attList = new ArrayList<>();
-            attList.add(new Attribute(MeshSpecification.FLOAT2, 0, "position"));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    8,
-                    "test"
-            ));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    24,
-                    "test2"
-            ));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    40,
-                    "test3"
-            ));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    56,
-                    "test4"
-            ));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    72,
-                    "test5"
-            ));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    88,
-                    "test6"
-            ));
-            attList.add(new Attribute(
-                    MeshSpecification.FLOAT4,
-                    104,
-                    "test7"
-            ));
-            ArrayList<Varying> varyList = new ArrayList<>();
+            Attribute[] attList = new Attribute[]{
+                    new Attribute(MeshSpecification.TYPE_FLOAT2, 0, "position"),
+                    new Attribute(MeshSpecification.TYPE_FLOAT4, 8, "test"),
+                    new Attribute(MeshSpecification.TYPE_FLOAT4, 24, "test2"),
+                    new Attribute(
+                            MeshSpecification.TYPE_FLOAT4,
+                            40,
+                            "test3"
+                    ),
+                    new Attribute(
+                            MeshSpecification.TYPE_FLOAT4,
+                            56,
+                            "test4"
+                    ),
+                    new Attribute(
+                            MeshSpecification.TYPE_FLOAT4,
+                            72,
+                            "test5"
+                    ),
+                    new Attribute(
+                            MeshSpecification.TYPE_FLOAT4,
+                            88,
+                            "test6"
+                    ),
+                    new Attribute(
+                            MeshSpecification.TYPE_FLOAT4,
+                            104,
+                            "test7"
+                    )
+            };
+            Varying[] varyList = new Varying[0];
             return MeshSpecification.make(attList, 120, varyList, vs, fs);
         }
     }
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
index 9b0f952..0c7e452 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/AutoShowTest.java
@@ -60,12 +60,15 @@
 @RunWith(Parameterized.class)
 public final class AutoShowTest {
 
-    @Rule public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
-    @Rule public ScreenCaptureRule mScreenCaptureRule =
-            new ScreenCaptureRule("/sdcard/InputMethodStressTest");
-    @Rule public DisableLockScreenRule mDisableLockScreenRule = new DisableLockScreenRule();
-    @Rule public ScreenOrientationRule mScreenOrientationRule =
+    @Rule(order = 0) public DisableLockScreenRule mDisableLockScreenRule =
+            new DisableLockScreenRule();
+    @Rule(order = 1) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule(order = 2) public ScreenOrientationRule mScreenOrientationRule =
             new ScreenOrientationRule(true /* isPortrait */);
+    @Rule(order = 3) public PressHomeBeforeTestRule mPressHomeBeforeTestRule =
+            new PressHomeBeforeTestRule();
+    @Rule(order = 4) public ScreenCaptureRule mScreenCaptureRule =
+            new ScreenCaptureRule("/sdcard/InputMethodStressTest");
 
     // TODO(b/240359838): add test case {@code Configuration.SCREENLAYOUT_SIZE_LARGE}.
     @Parameterized.Parameters(
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index e348184..9d4aefb 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -68,12 +68,15 @@
     private static final String TAG = "ImeOpenCloseStressTest";
     private static final int NUM_TEST_ITERATIONS = 10;
 
-    @Rule public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
-    @Rule public ScreenCaptureRule mScreenCaptureRule =
-            new ScreenCaptureRule("/sdcard/InputMethodStressTest");
-    @Rule public DisableLockScreenRule mDisableLockScreenRule = new DisableLockScreenRule();
-    @Rule public ScreenOrientationRule mScreenOrientationRule =
+    @Rule(order = 0) public DisableLockScreenRule mDisableLockScreenRule =
+            new DisableLockScreenRule();
+    @Rule(order = 1) public UnlockScreenRule mUnlockScreenRule = new UnlockScreenRule();
+    @Rule(order = 2) public ScreenOrientationRule mScreenOrientationRule =
             new ScreenOrientationRule(true /* isPortrait */);
+    @Rule(order = 3) public PressHomeBeforeTestRule mPressHomeBeforeTestRule =
+            new PressHomeBeforeTestRule();
+    @Rule(order = 4) public ScreenCaptureRule mScreenCaptureRule =
+            new ScreenCaptureRule("/sdcard/InputMethodStressTest");
 
     private final Instrumentation mInstrumentation;
     private final int mSoftInputFlags;
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/PressHomeBeforeTestRule.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/PressHomeBeforeTestRule.java
new file mode 100644
index 0000000..6586f63
--- /dev/null
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/PressHomeBeforeTestRule.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.inputmethod.stresstest;
+
+import android.support.test.uiautomator.UiDevice;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+/** This rule will press home before a test case. */
+public class PressHomeBeforeTestRule extends TestWatcher {
+    private final UiDevice mUiDevice =
+            UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+
+    @Override
+    protected void starting(Description description) {
+        mUiDevice.pressHome();
+    }
+}
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
index 6d4ffcf..3567c08 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestService.java
@@ -92,7 +92,7 @@
         super.onCreate();
         IntentFilter filter = new IntentFilter();
         filter.addAction(INTENT_ACTION);
-        registerReceiver(mBroadcastReceiver, filter);
+        registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
 
         // Make sure the data directory exists, and we're the owner of it.
         try {
diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt b/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt
index b67dc380..7a8d949 100644
--- a/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt
+++ b/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt
@@ -15,7 +15,7 @@
  */
 package com.android.test
 
-import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
+import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
 import junit.framework.Assert.assertEquals
 import junit.framework.Assert.assertTrue
 import org.junit.Test
@@ -37,7 +37,7 @@
                     1000 /* ms */))
         }
 
-        assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
+        LayersTraceSubject(trace).hasFrameSequence("SurfaceView", 1..numFrames)
     }
 
     @Test
@@ -51,7 +51,7 @@
             assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(2, 5000 /* ms */))
         }
 
-        assertThat(trace).hasFrameSequence("SurfaceView", 1..2L)
+        LayersTraceSubject(trace).hasFrameSequence("SurfaceView", 1..2L)
     }
 
     @Test
@@ -69,7 +69,7 @@
                     5000 /* ms */))
         }
 
-        assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
+        LayersTraceSubject(trace).hasFrameSequence("SurfaceView", 1..numFrames)
     }
 
     @Test
@@ -92,7 +92,7 @@
                     5000 /* ms */))
         }
 
-        assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
+        LayersTraceSubject(trace).hasFrameSequence("SurfaceView", 1..numFrames)
     }
 
     @Test
diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/BufferRejectionTests.kt b/tests/SurfaceViewBufferTests/src/com/android/test/BufferRejectionTests.kt
index e9e0246..da53387 100644
--- a/tests/SurfaceViewBufferTests/src/com/android/test/BufferRejectionTests.kt
+++ b/tests/SurfaceViewBufferTests/src/com/android/test/BufferRejectionTests.kt
@@ -16,7 +16,7 @@
 package com.android.test
 
 import android.graphics.Point
-import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
+import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
 import com.android.test.SurfaceViewBufferTestBase.Companion.ScalingMode
 import com.android.test.SurfaceViewBufferTestBase.Companion.Transform
 import junit.framework.Assert.assertEquals
@@ -45,10 +45,10 @@
             activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */)
         }
         // Verify we reject buffers since scaling mode == NATIVE_WINDOW_SCALING_MODE_FREEZE
-        assertThat(trace).layer("SurfaceView", 2).doesNotExist()
+        LayersTraceSubject(trace).layer("SurfaceView", 2).doesNotExist()
 
         // Verify the next buffer is submitted with the correct size
-        assertThat(trace).layer("SurfaceView", 3).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 3).also {
             it.hasBufferSize(defaultBufferSize)
             // scaling mode is not passed down to the layer for blast
             if (useBlastAdapter) {
@@ -81,9 +81,9 @@
         }
 
         // verify buffer size is reset to default buffer size
-        assertThat(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
-        assertThat(trace).layer("SurfaceView", 2).doesNotExist()
-        assertThat(trace).layer("SurfaceView", 3).hasBufferSize(bufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 2).doesNotExist()
+        LayersTraceSubject(trace).layer("SurfaceView", 3).hasBufferSize(bufferSize)
     }
 
     @Test
@@ -109,10 +109,11 @@
         }
 
         // verify buffer size is reset to default buffer size
-        assertThat(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
-        assertThat(trace).layer("SurfaceView", 2).doesNotExist()
-        assertThat(trace).layer("SurfaceView", 3).hasBufferSize(rotatedBufferSize)
-        assertThat(trace).layer("SurfaceView", 3).hasBufferOrientation(Transform.ROT_90.value)
+        LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 2).doesNotExist()
+        LayersTraceSubject(trace).layer("SurfaceView", 3).hasBufferSize(rotatedBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 3)
+                .hasBufferOrientation(Transform.ROT_90.value)
     }
 
     @Test
@@ -141,11 +142,11 @@
         }
 
         for (count in 0 until 5) {
-            assertThat(trace).layer("SurfaceView", (count * 3) + 1L)
+            LayersTraceSubject(trace).layer("SurfaceView", (count * 3) + 1L)
                     .hasBufferSize(defaultBufferSize)
-            assertThat(trace).layer("SurfaceView", (count * 3) + 2L)
+            LayersTraceSubject(trace).layer("SurfaceView", (count * 3) + 2L)
                     .doesNotExist()
-            assertThat(trace).layer("SurfaceView", (count * 3) + 3L)
+            LayersTraceSubject(trace).layer("SurfaceView", (count * 3) + 3L)
                     .hasBufferSize(bufferSize)
         }
     }
diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/GeometryTests.kt b/tests/SurfaceViewBufferTests/src/com/android/test/GeometryTests.kt
index 0802990..2d6c664 100644
--- a/tests/SurfaceViewBufferTests/src/com/android/test/GeometryTests.kt
+++ b/tests/SurfaceViewBufferTests/src/com/android/test/GeometryTests.kt
@@ -19,7 +19,7 @@
 import android.graphics.Point
 import android.graphics.Rect
 import android.os.SystemClock
-import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
+import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
 import com.android.test.SurfaceViewBufferTestBase.Companion.ScalingMode
 import com.android.test.SurfaceViewBufferTestBase.Companion.Transform
 import junit.framework.Assert.assertEquals
@@ -43,7 +43,7 @@
         }
 
         // verify buffer size is reset to default buffer size
-        assertThat(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
     }
 
     @Test
@@ -56,7 +56,7 @@
             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
         }
 
-        assertThat(trace).layer("SurfaceView", 1).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 1).also {
             it.hasBufferSize(bufferSize)
             it.hasLayerSize(defaultBufferSize)
             it.hasScalingMode(ScalingMode.SCALE_TO_WINDOW.ordinal)
@@ -73,7 +73,7 @@
             activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
         }
 
-        assertThat(trace).layer("SurfaceView", 1).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 1).also {
             it.hasBufferSize(bufferSize)
             it.hasLayerSize(defaultBufferSize)
             it.hasScalingMode(ScalingMode.SCALE_TO_WINDOW.ordinal)
@@ -102,9 +102,9 @@
         }
 
         // verify buffer size is reset to default buffer size
-        assertThat(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
-        assertThat(trace).layer("SurfaceView", 2).doesNotExist()
-        assertThat(trace).layer("SurfaceView", 3).hasBufferSize(bufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 2).doesNotExist()
+        LayersTraceSubject(trace).layer("SurfaceView", 3).hasBufferSize(bufferSize)
     }
 
     @Test
@@ -118,7 +118,7 @@
                 activity.mSurfaceProxy.waitUntilBufferDisplayed(index + 1L, 500 /* ms */)
             }
 
-            assertThat(trace).layer("SurfaceView", index + 1L).also {
+            LayersTraceSubject(trace).layer("SurfaceView", index + 1L).also {
                 it.hasBufferSize(defaultBufferSize)
                 it.hasLayerSize(defaultBufferSize)
                 it.hasBufferOrientation(transform.value)
@@ -145,7 +145,7 @@
         }
 
         // check that the layer and buffer starts with the default size
-        assertThat(trace).layer("SurfaceView", 1).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 1).also {
             it.hasBufferSize(defaultBufferSize)
             it.hasLayerSize(defaultBufferSize)
         }
@@ -169,7 +169,7 @@
             checkPixels(svBounds, Color.BLUE)
         }
 
-        assertThat(trace).layer("SurfaceView", 1).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 1).also {
             it.hasLayerSize(newSize)
             it.hasBufferSize(defaultBufferSize)
         }
@@ -193,7 +193,7 @@
         }
 
         // check that the layer and buffer starts with the default size
-        assertThat(trace).layer("SurfaceView", 1).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 1).also {
             it.hasBufferSize(defaultBufferSize)
             it.hasLayerSize(defaultBufferSize)
         }
@@ -216,7 +216,7 @@
             checkPixels(svBounds, Color.BLUE)
         }
 
-        assertThat(trace).layer("SurfaceView", 1).also {
+        LayersTraceSubject(trace).layer("SurfaceView", 1).also {
             it.hasLayerSize(defaultBufferSize)
             it.hasBufferSize(defaultBufferSize)
         }
diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/InverseDisplayTransformTests.kt b/tests/SurfaceViewBufferTests/src/com/android/test/InverseDisplayTransformTests.kt
index 69012bd..cf4186d 100644
--- a/tests/SurfaceViewBufferTests/src/com/android/test/InverseDisplayTransformTests.kt
+++ b/tests/SurfaceViewBufferTests/src/com/android/test/InverseDisplayTransformTests.kt
@@ -16,7 +16,7 @@
 package com.android.test
 
 import android.graphics.Point
-import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
+import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
 import com.android.test.SurfaceViewBufferTestBase.Companion.Transform
 import junit.framework.Assert.assertEquals
 import org.junit.Assume.assumeFalse
@@ -69,8 +69,8 @@
         }
 
         // verify buffer size is reset to default buffer size
-        assertThat(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
-        assertThat(trace).layer("SurfaceView", 2).doesNotExist()
-        assertThat(trace).layer("SurfaceView", 3).hasBufferSize(rotatedBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 1).hasBufferSize(defaultBufferSize)
+        LayersTraceSubject(trace).layer("SurfaceView", 2).doesNotExist()
+        LayersTraceSubject(trace).layer("SurfaceView", 3).hasBufferSize(rotatedBufferSize)
     }
 }
\ No newline at end of file
diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/SharedBufferModeTests.kt b/tests/SurfaceViewBufferTests/src/com/android/test/SharedBufferModeTests.kt
index ee41d79..61d4095 100644
--- a/tests/SurfaceViewBufferTests/src/com/android/test/SharedBufferModeTests.kt
+++ b/tests/SurfaceViewBufferTests/src/com/android/test/SharedBufferModeTests.kt
@@ -17,7 +17,7 @@
 
 import android.graphics.Color
 import android.graphics.Rect
-import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
+import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
 import junit.framework.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -39,7 +39,7 @@
             }
         }
 
-        assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
+        LayersTraceSubject(trace).hasFrameSequence("SurfaceView", 1..numFrames)
     }
 
     /** Submit buffers as fast as possible testing that we are not blocked when dequeuing the buffer
@@ -57,7 +57,7 @@
                     5000 /* ms */))
         }
 
-        assertThat(trace).hasFrameSequence("SurfaceView", numFrames..numFrames)
+        LayersTraceSubject(trace).hasFrameSequence("SurfaceView", numFrames..numFrames)
     }
 
     /** Keep overwriting the buffer without queuing buffers and check that we present the latest
diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt b/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt
index 03b43cc..722e671 100644
--- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt
+++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt
@@ -23,7 +23,7 @@
 import androidx.test.runner.AndroidJUnit4
 import com.android.server.wm.flicker.monitor.LayersTraceMonitor
 import com.android.server.wm.flicker.monitor.withSFTracing
-import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
+import com.android.server.wm.flicker.traces.layers.LayersTraceSubject
 import org.junit.After
 import org.junit.Before
 import org.junit.FixMethodOrder
@@ -90,13 +90,13 @@
         secondBounds.offsetTo(0, 0)
 
         // verify buffer size should be changed to expected values.
-        assertThat(trace).layer(FIRST_ACTIVITY, frame.toLong()).also {
+        LayersTraceSubject(trace).layer(FIRST_ACTIVITY, frame.toLong()).also {
             val firstTaskSize = Point(firstBounds.width(), firstBounds.height())
             it.hasLayerSize(firstTaskSize)
             it.hasBufferSize(firstTaskSize)
         }
 
-        assertThat(trace).layer(SECOND_ACTIVITY, frame.toLong()).also {
+        LayersTraceSubject(trace).layer(SECOND_ACTIVITY, frame.toLong()).also {
             val secondTaskSize = Point(secondBounds.width(), secondBounds.height())
             it.hasLayerSize(secondTaskSize)
             it.hasBufferSize(secondTaskSize)
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
index 4103ca7..210e3ea 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
@@ -148,6 +148,10 @@
         public void getUsbSpeedCb(int speed){
         }
 
+        @Override
+        public void resetCb(int status){
+        }
+
     }
 
     @Before
diff --git a/tests/testables/src/android/testing/TestableSettingsProvider.java b/tests/testables/src/android/testing/TestableSettingsProvider.java
index fd92c65..c6f18fd 100644
--- a/tests/testables/src/android/testing/TestableSettingsProvider.java
+++ b/tests/testables/src/android/testing/TestableSettingsProvider.java
@@ -49,14 +49,15 @@
     }
 
     void clearValuesAndCheck(Context context) {
-        int userId = UserHandle.myUserId();
-        mValues.put(key("global", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
-        mValues.put(key("secure", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
-        mValues.put(key("system", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
-
+        // Ensure we swapped over to use TestableSettingsProvider
         Settings.Global.clearProviderForTest();
         Settings.Secure.clearProviderForTest();
         Settings.System.clearProviderForTest();
+
+        // putString will eventually invoking the mocked call() method and update mValues
+        Settings.Global.putString(context.getContentResolver(), MY_UNIQUE_KEY, MY_UNIQUE_KEY);
+        Settings.Secure.putString(context.getContentResolver(), MY_UNIQUE_KEY, MY_UNIQUE_KEY);
+        Settings.System.putString(context.getContentResolver(), MY_UNIQUE_KEY, MY_UNIQUE_KEY);
         // Verify that if any test is using TestableContext, they all have the correct settings
         // provider.
         assertEquals("Incorrect settings provider, test using incorrect Context?", MY_UNIQUE_KEY,
diff --git a/tools/lint/framework/Android.bp b/tools/lint/framework/Android.bp
index b752503..30a6daa 100644
--- a/tools/lint/framework/Android.bp
+++ b/tools/lint/framework/Android.bp
@@ -37,12 +37,6 @@
 
 java_test_host {
     name: "AndroidFrameworkLintCheckerTest",
-    // TODO(b/239881504): Since this test was written, Android
-    // Lint was updated, and now includes classes that were
-    // compiled for java 15. The soong build doesn't support
-    // java 15 yet, so we can't compile against "lint". Disable
-    // the test until java 15 is supported.
-    enabled: false,
     srcs: ["checks/src/test/java/**/*.kt"],
     static_libs: [
         "AndroidFrameworkLintChecker",
@@ -52,5 +46,19 @@
     ],
     test_options: {
         unit_test: true,
+        tradefed_options: [
+            {
+                // lint bundles in some classes that were built with older versions
+                // of libraries, and no longer load. Since tradefed tries to load
+                // all classes in the jar to look for tests, it crashes loading them.
+                // Exclude these classes from tradefed's search.
+                name: "exclude-paths",
+                value: "org/apache",
+            },
+            {
+                name: "exclude-paths",
+                value: "META-INF",
+            },
+        ],
     },
 }
diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
index b76342a..7c0ebca 100644
--- a/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
+++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
@@ -105,37 +105,38 @@
                 .expectClean()
     }
 
-    fun testSubsequentFilterModification() {
-        lint().files(
-                java(
-                        """
-                    package test.pkg;
-                    import android.content.BroadcastReceiver;
-                    import android.content.Context;
-                    import android.content.Intent;
-                    import android.content.IntentFilter;
-                    public class TestClass1 {
-                        public void testMethod(Context context, BroadcastReceiver receiver) {
-                            IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-                            filter.addAction(Intent.ACTION_BATTERY_LOW);
-                            filter.addAction(Intent.ACTION_BATTERY_OKAY);
-                            context.registerReceiver(receiver, filter);
-                            filter.addAction("querty");
-                            context.registerReceiver(receiver, filter);
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.java:13: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter);
-                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testSubsequentFilterModification() {
+    //     lint().files(
+    //             java(
+    //                     """
+    //                 package test.pkg;
+    //                 import android.content.BroadcastReceiver;
+    //                 import android.content.Context;
+    //                 import android.content.Intent;
+    //                 import android.content.IntentFilter;
+    //                 public class TestClass1 {
+    //                     public void testMethod(Context context, BroadcastReceiver receiver) {
+    //                         IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+    //                         filter.addAction(Intent.ACTION_BATTERY_LOW);
+    //                         filter.addAction(Intent.ACTION_BATTERY_OKAY);
+    //                         context.registerReceiver(receiver, filter);
+    //                         filter.addAction("querty");
+    //                         context.registerReceiver(receiver, filter);
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.java:13: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter);
+    //                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
     fun testNullReceiver() {
         lint().files(
@@ -207,61 +208,63 @@
                 .expectClean()
     }
 
-    fun testFlagArgumentAbsent() {
-        lint().files(
-                java(
-                        """
-                    package test.pkg;
-                    import android.content.BroadcastReceiver;
-                    import android.content.Context;
-                    import android.content.Intent;
-                    import android.content.IntentFilter;
-                    public class TestClass1 {
-                        public void testMethod(Context context, BroadcastReceiver receiver) {
-                            IntentFilter filter = new IntentFilter("qwerty");
-                            context.registerReceiver(receiver, filter);
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter);
-                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testFlagArgumentAbsent() {
+    //     lint().files(
+    //             java(
+    //                     """
+    //                 package test.pkg;
+    //                 import android.content.BroadcastReceiver;
+    //                 import android.content.Context;
+    //                 import android.content.Intent;
+    //                 import android.content.IntentFilter;
+    //                 public class TestClass1 {
+    //                     public void testMethod(Context context, BroadcastReceiver receiver) {
+    //                         IntentFilter filter = new IntentFilter("qwerty");
+    //                         context.registerReceiver(receiver, filter);
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter);
+    //                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
-    fun testExportedFlagsAbsent() {
-        lint().files(
-                java(
-                        """
-                    package test.pkg;
-                    import android.content.BroadcastReceiver;
-                    import android.content.Context;
-                    import android.content.Intent;
-                    import android.content.IntentFilter;
-                    public class TestClass1 {
-                        public void testMethod(Context context, BroadcastReceiver receiver) {
-                            IntentFilter filter = new IntentFilter("qwerty");
-                            context.registerReceiver(receiver, filter, 0);
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter, 0);
-                                                                   ~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testExportedFlagsAbsent() {
+    //     lint().files(
+    //             java(
+    //                     """
+    //                 package test.pkg;
+    //                 import android.content.BroadcastReceiver;
+    //                 import android.content.Context;
+    //                 import android.content.Intent;
+    //                 import android.content.IntentFilter;
+    //                 public class TestClass1 {
+    //                     public void testMethod(Context context, BroadcastReceiver receiver) {
+    //                         IntentFilter filter = new IntentFilter("qwerty");
+    //                         context.registerReceiver(receiver, filter, 0);
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter, 0);
+    //                                                                ~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
     fun testExportedFlagVariable() {
         lint().files(
@@ -287,62 +290,64 @@
                 .expectClean()
     }
 
-    fun testUnknownFilter() {
-        lint().files(
-                java(
-                        """
-                    package test.pkg;
-                    import android.content.BroadcastReceiver;
-                    import android.content.Context;
-                    import android.content.Intent;
-                    import android.content.IntentFilter;
-                    public class TestClass1 {
-                        public void testMethod(Context context, BroadcastReceiver receiver,
-                                IntentFilter filter) {
-                            context.registerReceiver(receiver, filter);
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter);
-                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testUnknownFilter() {
+    //     lint().files(
+    //             java(
+    //                     """
+    //                 package test.pkg;
+    //                 import android.content.BroadcastReceiver;
+    //                 import android.content.Context;
+    //                 import android.content.Intent;
+    //                 import android.content.IntentFilter;
+    //                 public class TestClass1 {
+    //                     public void testMethod(Context context, BroadcastReceiver receiver,
+    //                             IntentFilter filter) {
+    //                         context.registerReceiver(receiver, filter);
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter);
+    //                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
-    fun testFilterEscapes() {
-        lint().files(
-                java(
-                        """
-                    package test.pkg;
-                    import android.content.BroadcastReceiver;
-                    import android.content.Context;
-                    import android.content.Intent;
-                    import android.content.IntentFilter;
-                    public class TestClass1 {
-                        public void testMethod(Context context, BroadcastReceiver receiver) {
-                            IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
-                            updateFilter(filter);
-                            context.registerReceiver(receiver, filter);
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.java:10: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter);
-                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testFilterEscapes() {
+    //     lint().files(
+    //             java(
+    //                     """
+    //                 package test.pkg;
+    //                 import android.content.BroadcastReceiver;
+    //                 import android.content.Context;
+    //                 import android.content.Intent;
+    //                 import android.content.IntentFilter;
+    //                 public class TestClass1 {
+    //                     public void testMethod(Context context, BroadcastReceiver receiver) {
+    //                         IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+    //                         updateFilter(filter);
+    //                         context.registerReceiver(receiver, filter);
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.java:10: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter);
+    //                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
     fun testInlineFilter() {
         lint().files(
@@ -367,135 +372,139 @@
                 .expectClean()
     }
 
-    fun testInlineFilterApply() {
-        lint().files(
-                kotlin(
-                        """
-                    package test.pkg
-                    import android.content.BroadcastReceiver
-                    import android.content.Context
-                    import android.content.Intent
-                    import android.content.IntentFilter
-                    class TestClass1 {
-                        fun test(context: Context, receiver: BroadcastReceiver) {
-                            context.registerReceiver(receiver,
-                                    IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
-                                        addAction("qwerty")
-                                    })
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.kt:8: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver,
-                        ^
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testInlineFilterApply() {
+    //     lint().files(
+    //             kotlin(
+    //                     """
+    //                 package test.pkg
+    //                 import android.content.BroadcastReceiver
+    //                 import android.content.Context
+    //                 import android.content.Intent
+    //                 import android.content.IntentFilter
+    //                 class TestClass1 {
+    //                     fun test(context: Context, receiver: BroadcastReceiver) {
+    //                         context.registerReceiver(receiver,
+    //                                 IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
+    //                                     addAction("qwerty")
+    //                                 })
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.kt:8: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver,
+    //                     ^
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
-    fun testFilterVariableApply() {
-        lint().files(
-                kotlin(
-                        """
-                    package test.pkg
-                    import android.content.BroadcastReceiver
-                    import android.content.Context
-                    import android.content.Intent
-                    import android.content.IntentFilter
-                    class TestClass1 {
-                        fun test(context: Context, receiver: BroadcastReceiver) {
-                            val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
-                                addAction("qwerty")
-                            }
-                            context.registerReceiver(receiver, filter)
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.kt:11: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter)
-                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testFilterVariableApply() {
+    //     lint().files(
+    //             kotlin(
+    //                     """
+    //                 package test.pkg
+    //                 import android.content.BroadcastReceiver
+    //                 import android.content.Context
+    //                 import android.content.Intent
+    //                 import android.content.IntentFilter
+    //                 class TestClass1 {
+    //                     fun test(context: Context, receiver: BroadcastReceiver) {
+    //                         val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
+    //                             addAction("qwerty")
+    //                         }
+    //                         context.registerReceiver(receiver, filter)
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.kt:11: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter)
+    //                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
-    fun testFilterVariableApply2() {
-        lint().files(
-                kotlin(
-                        """
-                    package test.pkg
-                    import android.content.BroadcastReceiver
-                    import android.content.Context
-                    import android.content.Intent
-                    import android.content.IntentFilter
-                    class TestClass1 {
-                        fun test(context: Context, receiver: BroadcastReceiver) {
-                            val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
-                                addAction(Intent.ACTION_BATTERY_OKAY)
-                            }
-                            context.registerReceiver(receiver, filter.apply {
-                                addAction("qwerty")
-                            })
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.kt:11: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter.apply {
-                        ^
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testFilterVariableApply2() {
+    //     lint().files(
+    //             kotlin(
+    //                     """
+    //                 package test.pkg
+    //                 import android.content.BroadcastReceiver
+    //                 import android.content.Context
+    //                 import android.content.Intent
+    //                 import android.content.IntentFilter
+    //                 class TestClass1 {
+    //                     fun test(context: Context, receiver: BroadcastReceiver) {
+    //                         val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
+    //                             addAction(Intent.ACTION_BATTERY_OKAY)
+    //                         }
+    //                         context.registerReceiver(receiver, filter.apply {
+    //                             addAction("qwerty")
+    //                         })
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.kt:11: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter.apply {
+    //                     ^
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
-    fun testFilterComplexChain() {
-        lint().files(
-                kotlin(
-                        """
-                    package test.pkg
-                    import android.content.BroadcastReceiver
-                    import android.content.Context
-                    import android.content.Intent
-                    import android.content.IntentFilter
-                    class TestClass1 {
-                        fun test(context: Context, receiver: BroadcastReceiver) {
-                            val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
-                                addAction(Intent.ACTION_BATTERY_OKAY)
-                            }
-                            val filter2 = filter
-                            val filter3 = filter2.apply {
-                                addAction(Intent.ACTION_BATTERY_LOW)
-                            }
-                            context.registerReceiver(receiver, filter3)
-                            val filter4 = filter3.apply {
-                                addAction("qwerty")
-                            }
-                            context.registerReceiver(receiver, filter4)
-                        }
-                    }
-                   """
-                ).indented(),
-                *stubs
-        )
-                .run()
-                .expect("""
-                src/test/pkg/TestClass1.kt:19: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
-                        context.registerReceiver(receiver, filter4)
-                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-                0 errors, 1 warnings
-            """.trimIndent())
-    }
+    // TODO(b/267510341): Reenable this test
+    // fun testFilterComplexChain() {
+    //     lint().files(
+    //             kotlin(
+    //                     """
+    //                 package test.pkg
+    //                 import android.content.BroadcastReceiver
+    //                 import android.content.Context
+    //                 import android.content.Intent
+    //                 import android.content.IntentFilter
+    //                 class TestClass1 {
+    //                     fun test(context: Context, receiver: BroadcastReceiver) {
+    //                         val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
+    //                             addAction(Intent.ACTION_BATTERY_OKAY)
+    //                         }
+    //                         val filter2 = filter
+    //                         val filter3 = filter2.apply {
+    //                             addAction(Intent.ACTION_BATTERY_LOW)
+    //                         }
+    //                         context.registerReceiver(receiver, filter3)
+    //                         val filter4 = filter3.apply {
+    //                             addAction("qwerty")
+    //                         }
+    //                         context.registerReceiver(receiver, filter4)
+    //                     }
+    //                 }
+    //                """
+    //             ).indented(),
+    //             *stubs
+    //     )
+    //             .run()
+    //             .expect("""
+    //             src/test/pkg/TestClass1.kt:19: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
+    //                     context.registerReceiver(receiver, filter4)
+    //                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //             0 errors, 1 warnings
+    //         """.trimIndent())
+    // }
 
     private val broadcastReceiverStub: TestFile = java(
             """
diff --git a/wifi/java/Android.bp b/wifi/java/Android.bp
index 225e750..434226d 100644
--- a/wifi/java/Android.bp
+++ b/wifi/java/Android.bp
@@ -27,7 +27,10 @@
 
 filegroup {
     name: "framework-wifi-non-updatable-sources-internal",
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.aidl",
+    ],
     path: "src",
     visibility: ["//visibility:private"],
 }
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS b/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS
new file mode 100644
index 0000000..2a4acc1
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1216021
+
+asapperstein@google.com
+etancohen@google.com
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/wifi/java/src/android/net/wifi/sharedconnectivity/app/DeviceInfo.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to wifi/java/src/android/net/wifi/sharedconnectivity/app/DeviceInfo.aidl
index 497c272..35d5c15 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/DeviceInfo.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.net.wifi.sharedconnectivity.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable DeviceInfo;
\ No newline at end of file
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/DeviceInfo.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/DeviceInfo.java
new file mode 100644
index 0000000..9aad9aa
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/DeviceInfo.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A data class representing a device providing connectivity.
+ * This class is used in IPC calls between the implementer of {@link SharedConnectivityService} and
+ * the consumers of {@link com.android.wifitrackerlib}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class DeviceInfo implements Parcelable {
+
+    /**
+     * Device type providing connectivity is unknown.
+     */
+    public static final int DEVICE_TYPE_UNKNOWN = 0;
+
+    /**
+     * Device providing connectivity is a mobile phone.
+     */
+    public static final int DEVICE_TYPE_PHONE = 1;
+
+    /**
+     * Device providing connectivity is a tablet.
+     */
+    public static final int DEVICE_TYPE_TABLET = 2;
+
+    /**
+     * Device providing connectivity is a laptop.
+     */
+    public static final int DEVICE_TYPE_LAPTOP = 3;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            DEVICE_TYPE_UNKNOWN,
+            DEVICE_TYPE_PHONE,
+            DEVICE_TYPE_TABLET,
+            DEVICE_TYPE_LAPTOP
+    })
+    public @interface DeviceType {}
+
+    @DeviceType private final int mDeviceType;
+    private final String mDeviceName;
+    private final String mModelName;
+    private final int mBatteryPercentage;
+    private final int mConnectionStrength;
+
+    /**
+     * Builder class for {@link DeviceInfo}.
+     */
+    public static final class Builder {
+        private int mDeviceType;
+        private String mDeviceName;
+        private String mModelName;
+        private int mBatteryPercentage;
+        private int mConnectionStrength;
+
+        public Builder() {}
+
+        /**
+         * Sets the device type that provides connectivity.
+         *
+         * @param deviceType Device type as represented by IntDef {@link DeviceType}.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setDeviceType(@DeviceType int deviceType) {
+            mDeviceType = deviceType;
+            return this;
+        }
+
+        /**
+         * Sets the device name of the remote device.
+         *
+         * @param deviceName The user configurable device name.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setDeviceName(@NonNull String deviceName) {
+            mDeviceName = deviceName;
+            return this;
+        }
+
+        /**
+         * Sets the model name of the remote device.
+         *
+         * @param modelName The OEM configured name for the device model.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setModelName(@NonNull String modelName) {
+            mModelName = modelName;
+            return this;
+        }
+
+        /**
+         * Sets the battery charge percentage of the remote device.
+         *
+         * @param batteryPercentage The battery charge percentage in the range 0 to 100.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setBatteryPercentage(@IntRange(from = 0, to = 100) int batteryPercentage) {
+            mBatteryPercentage = batteryPercentage;
+            return this;
+        }
+
+        /**
+         * Sets the displayed connection strength of the remote device to the internet.
+         *
+         * @param connectionStrength Connection strength in range 0 to 3.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setConnectionStrength(@IntRange(from = 0, to = 3) int connectionStrength) {
+            mConnectionStrength = connectionStrength;
+            return this;
+        }
+
+        /**
+         * Builds the {@link DeviceInfo} object.
+         *
+         * @return Returns the built {@link DeviceInfo} object.
+         */
+        @NonNull
+        public DeviceInfo build() {
+            return new DeviceInfo(mDeviceType, mDeviceName, mModelName, mBatteryPercentage,
+                    mConnectionStrength);
+        }
+    }
+
+    private static void validate(int deviceType, String deviceName, String modelName,
+            int batteryPercentage, int connectionStrength) {
+        if (deviceType != DEVICE_TYPE_UNKNOWN && deviceType != DEVICE_TYPE_PHONE
+                && deviceType != DEVICE_TYPE_TABLET && deviceType != DEVICE_TYPE_LAPTOP) {
+            throw new IllegalArgumentException("Illegal device type");
+        }
+        if (Objects.isNull(deviceName)) {
+            throw new IllegalArgumentException("DeviceName must be set");
+        }
+        if (Objects.isNull(modelName)) {
+            throw new IllegalArgumentException("ModelName must be set");
+        }
+        if (batteryPercentage < 0 || batteryPercentage > 100) {
+            throw new IllegalArgumentException("BatteryPercentage must be in range 0-100");
+        }
+        if (connectionStrength < 0 || connectionStrength > 3) {
+            throw new IllegalArgumentException("ConnectionStrength must be in range 0-3");
+        }
+    }
+
+    private DeviceInfo(@DeviceType int deviceType, @NonNull String deviceName,
+            @NonNull String modelName, int batteryPercentage, int connectionStrength) {
+        validate(deviceType, deviceName, modelName, batteryPercentage, connectionStrength);
+        mDeviceType = deviceType;
+        mDeviceName = deviceName;
+        mModelName = modelName;
+        mBatteryPercentage = batteryPercentage;
+        mConnectionStrength = connectionStrength;
+    }
+
+    /**
+     * Gets the device type that provides connectivity.
+     *
+     * @return Returns the device type as represented by IntDef {@link DeviceType}.
+     */
+    @DeviceType
+    public int getDeviceType() {
+        return mDeviceType;
+    }
+
+    /**
+     * Gets the device name of the remote device.
+     *
+     * @return Returns the user configurable device name.
+     */
+    @NonNull
+    public String getDeviceName() {
+        return mDeviceName;
+    }
+
+    /**
+     * Gets the model name of the remote device.
+     *
+     * @return Returns the OEM configured name for the device model.
+     */
+    @NonNull
+    public String getModelName() {
+        return mModelName;
+    }
+
+    /**
+     * Gets the battery charge percentage of the remote device.
+     *
+     * @return Returns the battery charge percentage in the range 0 to 100.
+     */
+    @IntRange(from = 0, to = 100)
+    public int getBatteryPercentage() {
+        return mBatteryPercentage;
+    }
+
+    /**
+     * Gets the displayed connection strength of the remote device to the internet.
+     *
+     * @return Returns the connection strength in range 0 to 3.
+     */
+    @IntRange(from = 0, to = 3)
+    public int getConnectionStrength() {
+        return mConnectionStrength;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof DeviceInfo)) return false;
+        DeviceInfo other = (DeviceInfo) obj;
+        return mDeviceType == other.getDeviceType()
+                && Objects.equals(mDeviceName, other.mDeviceName)
+                && Objects.equals(mModelName, other.mModelName)
+                && mBatteryPercentage == other.mBatteryPercentage
+                && mConnectionStrength == other.mConnectionStrength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDeviceType, mDeviceName, mModelName, mBatteryPercentage,
+                mConnectionStrength);
+    }
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mDeviceType);
+        dest.writeString(mDeviceName);
+        dest.writeString(mModelName);
+        dest.writeInt(mBatteryPercentage);
+        dest.writeInt(mConnectionStrength);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    public static final Creator<DeviceInfo> CREATOR = new Creator<DeviceInfo>() {
+        @Override
+        public DeviceInfo createFromParcel(Parcel in) {
+            return new DeviceInfo(in.readInt(), in.readString(), in.readString(), in.readInt(),
+                    in.readInt());
+        }
+
+        @Override
+        public DeviceInfo[] newArray(int size) {
+            return new DeviceInfo[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return new StringBuilder("DeviceInfo[")
+                .append("deviceType=").append(mDeviceType)
+                .append(", deviceName=").append(mDeviceName)
+                .append(", modelName=").append(mModelName)
+                .append(", batteryPercentage=").append(mBatteryPercentage)
+                .append(", connectionStrength=").append(mConnectionStrength)
+                .append("]").toString();
+    }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.aidl
index 497c272..140d72a 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.net.wifi.sharedconnectivity.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable KnownNetwork;
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java
new file mode 100644
index 0000000..b219e86
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import static android.net.wifi.WifiAnnotations.SecurityType;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A data class representing a known Wi-Fi network.
+ *
+ * @hide
+ */
+@SystemApi
+public final class KnownNetwork implements Parcelable {
+    /**
+     * Network is known by a nearby device with the same user account.
+     */
+    public static final int NETWORK_SOURCE_NEARBY_SELF = 0;
+
+    /**
+     * Network is known via cloud storage associated with this device's user account.
+     */
+    public static final int NETWORK_SOURCE_CLOUD_SELF = 1;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            NETWORK_SOURCE_NEARBY_SELF,
+            NETWORK_SOURCE_CLOUD_SELF
+    })
+    public @interface NetworkSource {}
+
+    @NetworkSource private final int mNetworkSource;
+    private final String mSsid;
+    @SecurityType private final int[] mSecurityTypes;
+    private final DeviceInfo mDeviceInfo;
+
+    /**
+     * Builder class for {@link KnownNetwork}.
+     */
+    public static final class Builder {
+        @NetworkSource private int mNetworkSource = -1;
+        private String mSsid;
+        @SecurityType private int[] mSecurityTypes;
+        private android.net.wifi.sharedconnectivity.app.DeviceInfo mDeviceInfo;
+
+        public Builder() {}
+
+        /**
+         * Sets the indicated source of the known network.
+         *
+         * @param networkSource The network source as defined by IntDef {@link NetworkSource}.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setNetworkSource(@NetworkSource int networkSource) {
+            mNetworkSource = networkSource;
+            return this;
+        }
+
+        /**
+         * Sets the SSID of the known network.
+         *
+         * @param ssid The SSID of the known network. Surrounded by double quotes if UTF-8.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setSsid(@NonNull String ssid) {
+            mSsid = ssid;
+            return this;
+        }
+
+        /**
+         * Sets the security types of the known network.
+         *
+         * @param securityTypes The array of security types supported by the known network.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setSecurityTypes(@NonNull @SecurityType int[] securityTypes) {
+            mSecurityTypes = securityTypes;
+            return this;
+        }
+
+        /**
+         * Sets the device information of the device providing connectivity.
+         *
+         * @param deviceInfo The device information object.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setDeviceInfo(@NonNull DeviceInfo deviceInfo) {
+            mDeviceInfo = deviceInfo;
+            return this;
+        }
+
+        /**
+         * Builds the {@link KnownNetwork} object.
+         *
+         * @return Returns the built {@link KnownNetwork} object.
+         */
+        @NonNull
+        public KnownNetwork build() {
+            return new KnownNetwork(
+                    mNetworkSource,
+                    mSsid,
+                    mSecurityTypes,
+                    mDeviceInfo);
+        }
+    }
+
+    private static void validate(int networkSource, String ssid, int [] securityTypes) {
+        if (networkSource != NETWORK_SOURCE_CLOUD_SELF && networkSource
+                != NETWORK_SOURCE_NEARBY_SELF) {
+            throw new IllegalArgumentException("Illegal network source");
+        }
+        if (TextUtils.isEmpty(ssid)) {
+            throw new IllegalArgumentException("SSID must be set");
+        }
+        if (securityTypes == null || securityTypes.length == 0) {
+            throw new IllegalArgumentException("SecurityTypes must be set");
+        }
+    }
+
+    private KnownNetwork(
+            @NetworkSource int networkSource,
+            @NonNull String ssid,
+            @NonNull @SecurityType int[] securityTypes,
+            @NonNull DeviceInfo deviceInfo) {
+        validate(networkSource, ssid, securityTypes);
+        mNetworkSource = networkSource;
+        mSsid = ssid;
+        mSecurityTypes = securityTypes;
+        mDeviceInfo = deviceInfo;
+    }
+
+    /**
+     * Gets the indicated source of the known network.
+     *
+     * @return Returns the network source as defined by IntDef {@link NetworkSource}.
+     */
+    @NetworkSource
+    public int getNetworkSource() {
+        return mNetworkSource;
+    }
+
+    /**
+     * Gets the SSID of the known network.
+     *
+     * @return Returns the SSID of the known network. Surrounded by double quotes if UTF-8.
+     */
+    @NonNull
+    public String getSsid() {
+        return mSsid;
+    }
+
+    /**
+     * Gets the security types of the known network.
+     *
+     * @return Returns the array of security types supported by the known network.
+     */
+    @NonNull
+    @SecurityType
+    public int[] getSecurityTypes() {
+        return mSecurityTypes;
+    }
+
+    /**
+     * Gets the device information of the device providing connectivity.
+     *
+     * @return Returns the information of the device providing the known network.
+     */
+    @NonNull
+    public DeviceInfo getDeviceInfo() {
+        return mDeviceInfo;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof KnownNetwork)) return false;
+        KnownNetwork other = (KnownNetwork) obj;
+        return mNetworkSource == other.getNetworkSource()
+                && Objects.equals(mSsid, other.getSsid())
+                && Arrays.equals(mSecurityTypes, other.getSecurityTypes())
+                && Objects.equals(mDeviceInfo, other.getDeviceInfo());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mNetworkSource, mSsid, Arrays.hashCode(mSecurityTypes),
+                mDeviceInfo.hashCode());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mNetworkSource);
+        dest.writeString(mSsid);
+        dest.writeIntArray(mSecurityTypes);
+        dest.writeTypedObject(mDeviceInfo, 0);
+    }
+
+    @NonNull
+    public static final Creator<KnownNetwork> CREATOR = new Creator<>() {
+        @Override
+        public KnownNetwork createFromParcel(Parcel in) {
+            return new KnownNetwork(in.readInt(), in.readString(), in.createIntArray(),
+                    in.readTypedObject(DeviceInfo.CREATOR));
+        }
+
+        @Override
+        public KnownNetwork[] newArray(int size) {
+            return new KnownNetwork[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return new StringBuilder("KnownNetwork[")
+                .append("NetworkSource=").append(mNetworkSource)
+                .append(", ssid=").append(mSsid)
+                .append(", securityTypes=").append(Arrays.toString(mSecurityTypes))
+                .append(", deviceInfo=").append(mDeviceInfo.toString())
+                .append("]").toString();
+    }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.aidl
index 497c272..df43508 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.net.wifi.sharedconnectivity.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable KnownNetworkConnectionStatus;
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java
new file mode 100644
index 0000000..2cefb8e
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.app;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * The status of a connection to a known network after the client called
+ * {@link SharedConnectivityManager#connectKnownNetwork}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class KnownNetworkConnectionStatus implements Parcelable {
+
+    /**
+     * Connection status is unknown.
+     */
+    public static final int CONNECTION_STATUS_UNKNOWN  = 0;
+
+    /**
+     * The connection's data was saved successfully in the Wi-Fi configuration.
+     */
+    public static final int CONNECTION_STATUS_SAVED  = 1;
+
+    /**
+     * Failed to save the connection's data in the Wi-Fi configuration.
+     */
+    public static final int CONNECTION_STATUS_SAVE_FAILED = 2;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            CONNECTION_STATUS_UNKNOWN,
+            CONNECTION_STATUS_SAVED,
+            CONNECTION_STATUS_SAVE_FAILED,
+    })
+    public @interface ConnectionStatus {}
+
+    @ConnectionStatus private final int mStatus;
+    private final Bundle mExtras;
+
+    /**
+     * Builder class for {@link KnownNetworkConnectionStatus}.
+     */
+    public static final class Builder {
+        @ConnectionStatus private int mStatus;
+        private Bundle mExtras;
+
+        public Builder() {}
+
+        /**
+         * Sets the status of the connection
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setStatus(@ConnectionStatus int status) {
+            mStatus = status;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link KnownNetworkConnectionStatus} object.
+         *
+         * @return Returns the built {@link KnownNetworkConnectionStatus} object.
+         */
+        @NonNull
+        public KnownNetworkConnectionStatus build() {
+            return new KnownNetworkConnectionStatus(mStatus, mExtras);
+        }
+    }
+
+    private KnownNetworkConnectionStatus(@ConnectionStatus int status, Bundle extras) {
+        mStatus = status;
+        mExtras = extras;
+    }
+
+    /**
+     * Gets the status of the connection
+     *
+     * @return Returns true for enabled, false otherwise.
+     */
+    @ConnectionStatus
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof KnownNetworkConnectionStatus)) return false;
+        KnownNetworkConnectionStatus other = (KnownNetworkConnectionStatus) obj;
+        return mStatus == other.getStatus();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStatus);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mStatus);
+        dest.writeBundle(mExtras);
+    }
+
+    @NonNull
+    public static final Creator<KnownNetworkConnectionStatus> CREATOR = new Creator<>() {
+                @Override
+                public KnownNetworkConnectionStatus createFromParcel(Parcel in) {
+                    return new KnownNetworkConnectionStatus(in.readInt(),
+                            in.readBundle(getClass().getClassLoader()));
+                }
+
+                @Override
+                public KnownNetworkConnectionStatus[] newArray(int size) {
+                    return new KnownNetworkConnectionStatus[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return new StringBuilder("KnownNetworkConnectionStatus[")
+                .append("status=").append(mStatus)
+                .append("extras=").append(mExtras.toString())
+                .append("]").toString();
+    }
+}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityClientCallback.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityClientCallback.java
new file mode 100644
index 0000000..f62bfd4
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityClientCallback.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.app;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
+
+import java.util.List;
+
+/**
+ * Interface for clients of {@link SharedConnectivityManager} to register for changes in network
+ * status.
+ *
+ * @hide
+ */
+@SystemApi
+public interface SharedConnectivityClientCallback {
+    /**
+     * This method is being called by {@link SharedConnectivityService} to notify of a change in the
+     * list of available Tether Networks.
+     * @param networks Updated Tether Network list.
+     */
+    void onTetherNetworksUpdated(@NonNull List<TetherNetwork> networks);
+
+    /**
+     * This method is being called by {@link SharedConnectivityService} to notify of a change in the
+     * list of available Known Networks.
+     * @param networks Updated Known Network list.
+     */
+    void onKnownNetworksUpdated(@NonNull List<KnownNetwork> networks);
+
+    /**
+     * This method is being called by {@link SharedConnectivityService} to notify of a change in the
+     * state of share connectivity settings.
+     * @param state The new state.
+     */
+    void onSharedConnectivitySettingsChanged(@NonNull SharedConnectivitySettingsState state);
+
+    /**
+     * This method is being called by {@link SharedConnectivityService} to notify of a change in the
+     * status of the current tether network connection.
+     * @param status The new status.
+     */
+    void onTetherNetworkConnectionStatusChanged(@NonNull TetherNetworkConnectionStatus status);
+
+    /**
+     * This method is being called by {@link SharedConnectivityService} to notify of a change in the
+     * status of the current known network connection.
+     * @param status The new status.
+     */
+    void onKnownNetworkConnectionStatusChanged(@NonNull KnownNetworkConnectionStatus status);
+}
+
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
new file mode 100644
index 0000000..c298189
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.res.Resources;
+import android.net.wifi.sharedconnectivity.service.ISharedConnectivityCallback;
+import android.net.wifi.sharedconnectivity.service.ISharedConnectivityService;
+import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * This class is the library used by consumers of Shared Connectivity data to bind to the service,
+ * receive callbacks from, and send user actions to the service.
+ *
+ * @hide
+ */
+@SystemApi
+public class SharedConnectivityManager {
+    private static final String TAG = SharedConnectivityManager.class.getSimpleName();
+    private static final boolean DEBUG = true;
+    private static final String SERVICE_PACKAGE_NAME = "sharedconnectivity_service_package";
+    private static final String SERVICE_CLASS_NAME = "sharedconnectivity_service_class";
+
+    private static final class SharedConnectivityCallbackProxy extends
+            ISharedConnectivityCallback.Stub {
+        private final Executor mExecutor;
+        private final SharedConnectivityClientCallback mCallback;
+
+        SharedConnectivityCallbackProxy(
+                @NonNull @CallbackExecutor Executor executor,
+                @NonNull SharedConnectivityClientCallback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        @Override
+        public void onTetherNetworksUpdated(@NonNull List<TetherNetwork> networks) {
+            if (mCallback != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mCallback.onTetherNetworksUpdated(networks));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        }
+
+        @Override
+        public void onKnownNetworksUpdated(@NonNull List<KnownNetwork> networks) {
+            if (mCallback != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mCallback.onKnownNetworksUpdated(networks));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        }
+
+        @Override
+        public void onSharedConnectivitySettingsChanged(
+                @NonNull SharedConnectivitySettingsState state) {
+            if (mCallback != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mCallback.onSharedConnectivitySettingsChanged(state));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        };
+
+        @Override
+        public void onTetherNetworkConnectionStatusChanged(
+                @NonNull TetherNetworkConnectionStatus status) {
+            if (mCallback != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() ->
+                            mCallback.onTetherNetworkConnectionStatusChanged(status));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        };
+
+        @Override
+        public void onKnownNetworkConnectionStatusChanged(
+                @NonNull KnownNetworkConnectionStatus status) {
+            if (mCallback != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() ->
+                            mCallback.onKnownNetworkConnectionStatusChanged(status));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        };
+    }
+
+    private ISharedConnectivityService mService;
+    private final Map<SharedConnectivityClientCallback, SharedConnectivityCallbackProxy>
+            mProxyMap = new HashMap<>();
+
+    /**
+     * Constructor for new instance of {@link SharedConnectivityManager}.
+     *
+     * Automatically binds to implementation of {@link SharedConnectivityService} specified in
+     * device overlay.
+     *
+     * @hide
+     */
+    public SharedConnectivityManager(@NonNull Context context) {
+        ServiceConnection serviceConnection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                mService = ISharedConnectivityService.Stub.asInterface(service);
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                if (DEBUG) Log.i(TAG, "onServiceDisconnected");
+                mService = null;
+                mProxyMap.clear();
+            }
+        };
+        bind(context, serviceConnection);
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public void setService(@Nullable IInterface service) {
+        mService = (ISharedConnectivityService) service;
+    }
+
+    private void bind(Context context, ServiceConnection serviceConnection) {
+        Resources resources = context.getResources();
+        int packageNameId = resources.getIdentifier(SERVICE_PACKAGE_NAME, "string",
+                context.getPackageName());
+        int classNameId = resources.getIdentifier(SERVICE_CLASS_NAME, "string",
+                context.getPackageName());
+        if (packageNameId == 0 || classNameId == 0) {
+            throw new Resources.NotFoundException("Package and class names for"
+                    + " shared connectivity service must be defined");
+        }
+
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(resources.getString(packageNameId),
+                resources.getString(classNameId)));
+        context.bindService(
+                intent,
+                serviceConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    /**
+     * Registers a callback for receiving updates to the list of Tether Networks and Known Networks.
+     *
+     * @param executor The Executor used to invoke the callback.
+     * @param callback The callback of type {@link SharedConnectivityClientCallback} that is invoked
+     *                 when the service updates either the list of Tether Networks or Known
+     *                 Networks.
+     * @return Returns true if the registration was successful, false otherwise.
+     */
+    public boolean registerCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull SharedConnectivityClientCallback callback) {
+        Objects.requireNonNull(executor, "executor cannot be null");
+        Objects.requireNonNull(callback, "callback cannot be null");
+        if (mService == null || mProxyMap.containsKey(callback)) return false;
+        try {
+            SharedConnectivityCallbackProxy proxy =
+                    new SharedConnectivityCallbackProxy(executor, callback);
+            mService.registerCallback(proxy);
+            mProxyMap.put(callback, proxy);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in registerCallback", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Unregisters a callback.
+     *
+     * @return Returns true if the callback was successfully unregistered, false otherwise.
+     */
+    public boolean unregisterCallback(
+            @NonNull SharedConnectivityClientCallback callback) {
+        Objects.requireNonNull(callback, "callback cannot be null");
+        if (mService == null || !mProxyMap.containsKey(callback)) return false;
+        try {
+            mService.unregisterCallback(mProxyMap.get(callback));
+            mProxyMap.remove(callback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in unregisterCallback", e);
+            return false;
+        }
+        return true;
+    }
+
+     /**
+     * Send command to the implementation of {@link SharedConnectivityService} requesting connection
+     * to the specified Tether Network.
+     *
+     * @param network {@link TetherNetwork} object representing the network the user has requested
+     *                a connection to.
+     * @return Returns true if the service received the command. Does not guarantee that the
+     *         connection was successful.
+     */
+    public boolean connectTetherNetwork(@NonNull TetherNetwork network) {
+        if (mService == null) return false;
+        try {
+            mService.connectTetherNetwork(network);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in connectTetherNetwork", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Send command to the implementation of {@link SharedConnectivityService} requesting
+     * disconnection from the active Tether Network.
+     *
+     * @return Returns true if the service received the command. Does not guarantee that the
+     *         disconnection was successful.
+     */
+    public boolean disconnectTetherNetwork() {
+        if (mService == null) return false;
+        try {
+            mService.disconnectTetherNetwork();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in disconnectTetherNetwork", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Send command to the implementation of {@link SharedConnectivityService} requesting connection
+     * to the specified Known Network.
+     *
+     * @param network {@link KnownNetwork} object representing the network the user has requested
+     *                a connection to.
+     * @return Returns true if the service received the command. Does not guarantee that the
+     *         connection was successful.
+     */
+    public boolean connectKnownNetwork(@NonNull KnownNetwork network) {
+        if (mService == null) return false;
+        try {
+            mService.connectKnownNetwork(network);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in connectKnownNetwork", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Send command to the implementation of {@link SharedConnectivityService} requesting removal of
+     * the specified Known Network from the list of Known Networks.
+     *
+     * @return Returns true if the service received the command. Does not guarantee that the
+     *         forget action was successful.
+     */
+    public boolean forgetKnownNetwork(@NonNull KnownNetwork network) {
+        if (mService == null) return false;
+        try {
+            mService.forgetKnownNetwork(network);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in forgetKnownNetwork", e);
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.aidl
similarity index 64%
rename from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
rename to wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.aidl
index 497c272..289afac 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.net.wifi.sharedconnectivity.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable SharedConnectivitySettingsState;
\ No newline at end of file
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java
new file mode 100644
index 0000000..87f5efd
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java
@@ -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 android.net.wifi.sharedconnectivity.app;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+
+/**
+ * A data class representing the shared connectivity settings state.
+ *
+ * This class represents a snapshot of the settings and can be out of date if the settings changed
+ * after receiving an object of this class.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SharedConnectivitySettingsState implements Parcelable {
+
+    private final boolean mInstantTetherEnabled;
+    private final Bundle mExtras;
+
+    /**
+     * Builder class for {@link SharedConnectivitySettingsState}.
+     */
+    public static final class Builder {
+        private boolean mInstantTetherEnabled;
+        private Bundle mExtras;
+
+        public Builder() {}
+
+        /**
+         * Sets the state of Instant Tether in settings
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setInstantTetherEnabled(boolean instantTetherEnabled) {
+            mInstantTetherEnabled = instantTetherEnabled;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link SharedConnectivitySettingsState} object.
+         *
+         * @return Returns the built {@link SharedConnectivitySettingsState} object.
+         */
+        @NonNull
+        public SharedConnectivitySettingsState build() {
+            return new SharedConnectivitySettingsState(mInstantTetherEnabled, mExtras);
+        }
+    }
+
+    private SharedConnectivitySettingsState(boolean instantTetherEnabled, Bundle extras) {
+        mInstantTetherEnabled = instantTetherEnabled;
+        mExtras = extras;
+    }
+
+    /**
+     * Gets the state of Instant Tether in settings
+     *
+     * @return Returns true for enabled, false otherwise.
+     */
+    public boolean isInstantTetherEnabled() {
+        return mInstantTetherEnabled;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof SharedConnectivitySettingsState)) return false;
+        SharedConnectivitySettingsState other = (SharedConnectivitySettingsState) obj;
+        return mInstantTetherEnabled == other.isInstantTetherEnabled();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mInstantTetherEnabled);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeBoolean(mInstantTetherEnabled);
+        dest.writeBundle(mExtras);
+    }
+
+    @NonNull
+    public static final Creator<SharedConnectivitySettingsState> CREATOR = new Creator<>() {
+                @Override
+                public SharedConnectivitySettingsState createFromParcel(Parcel in) {
+                    return new SharedConnectivitySettingsState(in.readBoolean(),
+                            in.readBundle(getClass().getClassLoader()));
+                }
+
+                @Override
+                public SharedConnectivitySettingsState[] newArray(int size) {
+                    return new SharedConnectivitySettingsState[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return new StringBuilder("SharedConnectivitySettingsState[")
+                .append("instantTetherEnabled=").append(mInstantTetherEnabled)
+                .append("extras=").append(mExtras.toString())
+                .append("]").toString();
+    }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetwork.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetwork.aidl
index 497c272..6cc4cfe 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetwork.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.net.wifi.sharedconnectivity.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable TetherNetwork;
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetwork.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetwork.java
new file mode 100644
index 0000000..3eff724
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetwork.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import static android.net.wifi.WifiAnnotations.SecurityType;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A data class representing an Instant Tether network.
+ * This class is used in IPC calls between the implementer of {@link SharedConnectivityService} and
+ * the consumers of {@link com.android.wifitrackerlib}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TetherNetwork implements Parcelable {
+    /**
+     * Remote device is connected to the internet via an unknown connection.
+     */
+    public static final int NETWORK_TYPE_UNKNOWN = 0;
+
+    /**
+     * Remote device is connected to the internet via a cellular connection.
+     */
+    public static final int NETWORK_TYPE_CELLULAR = 1;
+
+    /**
+     * Remote device is connected to the internet via a Wi-Fi connection.
+     */
+    public static final int NETWORK_TYPE_WIFI = 2;
+
+    /**
+     * Remote device is connected to the internet via an ethernet connection.
+     */
+    public static final int NETWORK_TYPE_ETHERNET = 3;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            NETWORK_TYPE_UNKNOWN,
+            NETWORK_TYPE_CELLULAR,
+            NETWORK_TYPE_WIFI,
+            NETWORK_TYPE_ETHERNET
+    })
+    public @interface NetworkType {}
+
+    private final long mDeviceId;
+    private final DeviceInfo mDeviceInfo;
+    @NetworkType private final int mNetworkType;
+    private final String mNetworkName;
+    @Nullable private final String mHotspotSsid;
+    @Nullable private final String mHotspotBssid;
+    @Nullable @SecurityType private final int[] mHotspotSecurityTypes;
+
+    /**
+     * Builder class for {@link TetherNetwork}.
+     */
+    public static final class Builder {
+        private long mDeviceId = -1;
+        private DeviceInfo mDeviceInfo;
+        @NetworkType private int mNetworkType;
+        private String mNetworkName;
+        @Nullable private String mHotspotSsid;
+        @Nullable private String mHotspotBssid;
+        @Nullable @SecurityType private int[] mHotspotSecurityTypes;
+
+        public Builder() {}
+
+        /**
+         * Set the remote device ID.
+         *
+         * @param deviceId Locally unique ID for this Instant Tether network.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setDeviceId(long deviceId) {
+            mDeviceId = deviceId;
+            return this;
+        }
+
+        /**
+         * Sets information about the device providing connectivity.
+         *
+         * @param deviceInfo The device information object.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setDeviceInfo(@NonNull DeviceInfo deviceInfo) {
+            mDeviceInfo = deviceInfo;
+            return this;
+        }
+
+        /**
+         * Sets the network type that the remote device is connected to.
+         *
+         * @param networkType Network type as represented by IntDef {@link NetworkType}.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setNetworkType(@NetworkType int networkType) {
+            mNetworkType = networkType;
+            return this;
+        }
+
+        /**
+         * Sets the display name of the network the remote device is connected to.
+         *
+         * @param networkName Network display name. (e.g. "Google Fi", "Hotel WiFi", "Ethernet")
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setNetworkName(@NonNull String networkName) {
+            mNetworkName = networkName;
+            return this;
+        }
+
+        /**
+         * Sets the hotspot SSID being broadcast by the remote device, or null if hotspot is off.
+         *
+         * @param hotspotSsid The SSID of the hotspot. Surrounded by double quotes if UTF-8.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setHotspotSsid(@NonNull String hotspotSsid) {
+            mHotspotSsid = hotspotSsid;
+            return this;
+        }
+
+        /**
+         * Sets the hotspot BSSID being broadcast by the remote device, or null if hotspot is off.
+         *
+         * @param hotspotBssid The BSSID of the hotspot.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setHotspotBssid(@NonNull String hotspotBssid) {
+            mHotspotBssid = hotspotBssid;
+            return this;
+        }
+
+        /**
+         * Sets the hotspot security types supported by the remote device, or null if hotspot is
+         * off.
+         *
+         * @param hotspotSecurityTypes The array of security types supported by the hotspot.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setHotspotSecurityTypes(@NonNull @SecurityType int[] hotspotSecurityTypes) {
+            mHotspotSecurityTypes = hotspotSecurityTypes;
+            return this;
+        }
+
+        /**
+         * Builds the {@link TetherNetwork} object.
+         *
+         * @return Returns the built {@link TetherNetwork} object.
+         */
+        @NonNull
+        public TetherNetwork build() {
+            return new TetherNetwork(
+                    mDeviceId,
+                    mDeviceInfo,
+                    mNetworkType,
+                    mNetworkName,
+                    mHotspotSsid,
+                    mHotspotBssid,
+                    mHotspotSecurityTypes);
+        }
+    }
+
+    private static void validate(long deviceId, int networkType, String networkName) {
+        if (deviceId < 0) {
+            throw new IllegalArgumentException("DeviceId must be set");
+        }
+        if (networkType != NETWORK_TYPE_CELLULAR && networkType != NETWORK_TYPE_WIFI
+                && networkType != NETWORK_TYPE_ETHERNET && networkType != NETWORK_TYPE_UNKNOWN) {
+            throw new IllegalArgumentException("Illegal network type");
+        }
+        if (Objects.isNull(networkName)) {
+            throw new IllegalArgumentException("NetworkName must be set");
+        }
+    }
+
+    private TetherNetwork(
+            long deviceId,
+            DeviceInfo deviceInfo,
+            @NetworkType int networkType,
+            @NonNull String networkName,
+            @Nullable String hotspotSsid,
+            @Nullable String hotspotBssid,
+            @Nullable @SecurityType int[] hotspotSecurityTypes) {
+        validate(deviceId,
+                networkType,
+                networkName);
+        mDeviceId = deviceId;
+        mDeviceInfo = deviceInfo;
+        mNetworkType = networkType;
+        mNetworkName = networkName;
+        mHotspotSsid = hotspotSsid;
+        mHotspotBssid = hotspotBssid;
+        mHotspotSecurityTypes = hotspotSecurityTypes;
+    }
+
+    /**
+     * Gets the remote device ID.
+     *
+     * @return Returns the locally unique ID for this Instant Tether network.
+     */
+    public long getDeviceId() {
+        return mDeviceId;
+    }
+
+    /**
+     * Gets information about the device providing connectivity.
+     *
+     * @return Returns the information of the device providing the Instant Tether network.
+     */
+    @NonNull
+    public DeviceInfo getDeviceInfo() {
+        return mDeviceInfo;
+    }
+
+    /**
+     * Gets the network type that the remote device is connected to.
+     *
+     * @return Returns the network type as represented by IntDef {@link NetworkType}.
+     */
+    @NetworkType
+    public int getNetworkType() {
+        return mNetworkType;
+    }
+
+    /**
+     * Gets the display name of the network the remote device is connected to.
+     *
+     * @return Returns the network display name. (e.g. "Google Fi", "Hotel WiFi", "Ethernet")
+     */
+    @NonNull
+    public String getNetworkName() {
+        return mNetworkName;
+    }
+
+    /**
+     * Gets the hotspot SSID being broadcast by the remote device, or null if hotspot is off.
+     *
+     * @return Returns the SSID of the hotspot. Surrounded by double quotes if UTF-8.
+     */
+    @Nullable
+    public String getHotspotSsid() {
+        return mHotspotSsid;
+    }
+
+    /**
+     * Gets the hotspot BSSID being broadcast by the remote device, or null if hotspot is off.
+     *
+     * @return Returns the BSSID of the hotspot.
+     */
+    @Nullable
+    public String getHotspotBssid() {
+        return mHotspotBssid;
+    }
+
+    /**
+     * Gets the hotspot security types supported by the remote device.
+     *
+     * @return Returns the array of security types supported by the hotspot.
+     */
+    @Nullable
+    @SecurityType
+    public int[] getHotspotSecurityTypes() {
+        return mHotspotSecurityTypes;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof TetherNetwork)) return false;
+        TetherNetwork other = (TetherNetwork) obj;
+        return mDeviceId == other.getDeviceId()
+                && Objects.equals(mDeviceInfo, other.getDeviceInfo())
+                && mNetworkType == other.getNetworkType()
+                && Objects.equals(mNetworkName, other.getNetworkName())
+                && Objects.equals(mHotspotSsid, other.getHotspotSsid())
+                && Objects.equals(mHotspotBssid, other.getHotspotBssid())
+                && Arrays.equals(mHotspotSecurityTypes, other.getHotspotSecurityTypes());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDeviceId, mDeviceInfo, mNetworkName, mHotspotSsid, mHotspotBssid,
+                Arrays.hashCode(mHotspotSecurityTypes));
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeLong(mDeviceId);
+        dest.writeTypedObject(mDeviceInfo, 0);
+        dest.writeInt(mNetworkType);
+        dest.writeString(mNetworkName);
+        dest.writeString(mHotspotSsid);
+        dest.writeString(mHotspotBssid);
+        dest.writeIntArray(mHotspotSecurityTypes);
+    }
+
+    @NonNull
+    public static final Creator<TetherNetwork> CREATOR = new Creator<>() {
+        @Override
+        public TetherNetwork createFromParcel(Parcel in) {
+            return new TetherNetwork(in.readLong(), in.readTypedObject(
+                    android.net.wifi.sharedconnectivity.app.DeviceInfo.CREATOR),
+                    in.readInt(), in.readString(), in.readString(), in.readString(),
+                    in.createIntArray());
+        }
+
+        @Override
+        public TetherNetwork[] newArray(int size) {
+            return new TetherNetwork[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return new StringBuilder("TetherNetwork[")
+                .append("deviceId=").append(mDeviceId)
+                .append(", networkType=").append(mNetworkType)
+                .append(", deviceInfo=").append(mDeviceInfo.toString())
+                .append(", networkName=").append(mNetworkName)
+                .append(", hotspotSsid=").append(mHotspotSsid)
+                .append(", hotspotBssid=").append(mHotspotBssid)
+                .append(", hotspotSecurityTypes=").append(Arrays.toString(mHotspotSecurityTypes))
+                .append("]").toString();
+    }
+}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetworkConnectionStatus.aidl
similarity index 64%
copy from packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
copy to wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetworkConnectionStatus.aidl
index 497c272..c677a6c 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/jetpack/developer/FrameworkClassParsingException.kt
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetworkConnectionStatus.aidl
@@ -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,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.credentialmanager.jetpack.developer
+package android.net.wifi.sharedconnectivity.app;
 
-/**
- * Internal exception used to indicate a parsing error while converting from a framework type to
- * a jetpack type.
- *
- * @hide
- */
-internal class FrameworkClassParsingException : Exception()
\ No newline at end of file
+parcelable TetherNetworkConnectionStatus;
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetworkConnectionStatus.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetworkConnectionStatus.java
new file mode 100644
index 0000000..86202bb
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/TetherNetworkConnectionStatus.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * The status of a connection to an instant tether network after the client called
+ * {@link SharedConnectivityManager#connectTetherNetwork}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TetherNetworkConnectionStatus implements Parcelable {
+
+    /**
+     * Connection status is unknown.
+     */
+    public static final int CONNECTION_STATUS_UNKNOWN  = 0;
+
+    /**
+     * The connection is being initiated.
+     */
+    public static final int CONNECTION_STATUS_ENABLING_HOTSPOT  = 1;
+
+    /**
+     * Device providing the hotspot failed to initiate it.
+     */
+    public static final int CONNECTION_STATUS_UNKNOWN_ERROR = 2;
+
+    /**
+     * Failed to provision tethering.
+     */
+    public static final int CONNECTION_STATUS_PROVISIONING_FAILED = 3;
+
+    /**
+     * Timeout while trying to provision tethering.
+     */
+    public static final int CONNECTION_STATUS_TETHERING_TIMEOUT = 4;
+
+    /**
+     * Device doesn't support tethering.
+     */
+    public static final int CONNECTION_STATUS_TETHERING_UNSUPPORTED = 5;
+
+    /**
+     * Device has no cell data.
+     */
+    public static final int CONNECTION_STATUS_NO_CELL_DATA = 6;
+
+    /**
+     * Device failed to enable hotspot
+     */
+    public static final int CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED = 7;
+
+    /**
+     * Timeout while trying to enable hotspot
+     */
+    public static final int CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT = 8;
+
+    /**
+     * Failed to connect to hotspot
+     */
+    public static final int CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED = 9;
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            CONNECTION_STATUS_UNKNOWN,
+            CONNECTION_STATUS_ENABLING_HOTSPOT,
+            CONNECTION_STATUS_UNKNOWN_ERROR,
+            CONNECTION_STATUS_PROVISIONING_FAILED,
+            CONNECTION_STATUS_TETHERING_TIMEOUT,
+            CONNECTION_STATUS_TETHERING_UNSUPPORTED,
+            CONNECTION_STATUS_NO_CELL_DATA,
+            CONNECTION_STATUS_ENABLING_HOTSPOT_FAILED,
+            CONNECTION_STATUS_ENABLING_HOTSPOT_TIMEOUT,
+            CONNECTION_STATUS_CONNECT_TO_HOTSPOT_FAILED,
+    })
+    public @interface ConnectionStatus {}
+
+    @ConnectionStatus private final int mStatus;
+    private final Bundle mExtras;
+
+    /**
+     * Builder class for {@link TetherNetworkConnectionStatus}.
+     */
+    public static final class Builder {
+        @ConnectionStatus private int mStatus;
+        private Bundle mExtras;
+
+        public Builder() {}
+
+        /**
+         * Sets the status of the connection
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setStatus(@ConnectionStatus int status) {
+            mStatus = status;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link TetherNetworkConnectionStatus} object.
+         *
+         * @return Returns the built {@link TetherNetworkConnectionStatus} object.
+         */
+        @NonNull
+        public TetherNetworkConnectionStatus build() {
+            return new TetherNetworkConnectionStatus(mStatus, mExtras);
+        }
+    }
+
+    private TetherNetworkConnectionStatus(@ConnectionStatus int status, Bundle extras) {
+        mStatus = status;
+        mExtras = extras;
+    }
+
+    /**
+     * Gets the status of the connection
+     *
+     * @return Returns true for enabled, false otherwise.
+     */
+    @ConnectionStatus
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof TetherNetworkConnectionStatus)) return false;
+        TetherNetworkConnectionStatus other = (TetherNetworkConnectionStatus) obj;
+        return mStatus == other.getStatus();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStatus);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mStatus);
+        dest.writeBundle(mExtras);
+    }
+
+    @NonNull
+    public static final Creator<TetherNetworkConnectionStatus> CREATOR = new Creator<>() {
+                @Override
+                public TetherNetworkConnectionStatus createFromParcel(Parcel in) {
+                    return new TetherNetworkConnectionStatus(in.readInt(),
+                            in.readBundle(getClass().getClassLoader()));
+                }
+
+                @Override
+                public TetherNetworkConnectionStatus[] newArray(int size) {
+                    return new TetherNetworkConnectionStatus[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return new StringBuilder("TetherNetworkConnectionStatus[")
+                .append("status=").append(mStatus)
+                .append("extras=").append(mExtras.toString())
+                .append("]").toString();
+    }
+}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/ISharedConnectivityCallback.aidl b/wifi/java/src/android/net/wifi/sharedconnectivity/service/ISharedConnectivityCallback.aidl
new file mode 100644
index 0000000..6f6f162
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/ISharedConnectivityCallback.aidl
@@ -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 android.net.wifi.sharedconnectivity.service;
+
+import android.net.wifi.sharedconnectivity.app.KnownNetwork;
+import android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus;
+import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
+import android.net.wifi.sharedconnectivity.app.TetherNetwork;
+import android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus;
+
+/*
+ * @hide
+ */
+interface ISharedConnectivityCallback {
+    oneway void onTetherNetworksUpdated(in List<TetherNetwork> networks);
+    oneway void onTetherNetworkConnectionStatusChanged(in TetherNetworkConnectionStatus status);
+    oneway void onKnownNetworksUpdated(in List<KnownNetwork> networks);
+    oneway void onKnownNetworkConnectionStatusChanged(in KnownNetworkConnectionStatus status);
+    oneway void onSharedConnectivitySettingsChanged(in SharedConnectivitySettingsState state);
+}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/ISharedConnectivityService.aidl b/wifi/java/src/android/net/wifi/sharedconnectivity/service/ISharedConnectivityService.aidl
new file mode 100644
index 0000000..5d79405
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/ISharedConnectivityService.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.service;
+
+import android.net.wifi.sharedconnectivity.app.KnownNetwork;
+import android.net.wifi.sharedconnectivity.app.TetherNetwork;
+import android.net.wifi.sharedconnectivity.service.ISharedConnectivityCallback;
+
+/*
+ * @hide
+ */
+interface ISharedConnectivityService {
+    void registerCallback(in ISharedConnectivityCallback callback);
+    void unregisterCallback(in ISharedConnectivityCallback callback);
+    void connectTetherNetwork(in TetherNetwork network);
+    void disconnectTetherNetwork();
+    void connectKnownNetwork(in KnownNetwork network);
+    void forgetKnownNetwork(in KnownNetwork network);
+}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
new file mode 100644
index 0000000..a40049b
--- /dev/null
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.service;
+
+import static android.Manifest.permission.NETWORK_SETTINGS;
+import static android.Manifest.permission.NETWORK_SETUP_WIZARD;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.wifi.sharedconnectivity.app.KnownNetwork;
+import android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus;
+import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager;
+import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
+import android.net.wifi.sharedconnectivity.app.TetherNetwork;
+import android.net.wifi.sharedconnectivity.app.TetherNetworkConnectionStatus;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * This class is the partly implemented service for injecting Shared Connectivity networks into the
+ * Wi-Fi Pickers and other relevant UI surfaces.
+ *
+ * Implementing application should extend this service and override the indicated methods.
+ * Callers to the service should use {@link SharedConnectivityManager} to bind to the implemented
+ * service as specified in the configuration overlay.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class SharedConnectivityService extends Service {
+    private static final String TAG = SharedConnectivityService.class.getSimpleName();
+    private static final boolean DEBUG = true;
+
+    private  final Handler mHandler;
+    private final List<ISharedConnectivityCallback> mCallbacks = new ArrayList<>();
+    // Used to find DeathRecipient when unregistering a callback to call unlinkToDeath.
+    private final Map<ISharedConnectivityCallback, DeathRecipient> mDeathRecipientMap =
+            new HashMap<>();
+
+    private List<TetherNetwork> mTetherNetworks = Collections.emptyList();
+    private List<KnownNetwork> mKnownNetworks = Collections.emptyList();
+    private SharedConnectivitySettingsState mSettingsState;
+    private TetherNetworkConnectionStatus mTetherNetworkConnectionStatus;
+    private KnownNetworkConnectionStatus mKnownNetworkConnectionStatus;
+
+    public SharedConnectivityService() {
+        mHandler = new Handler(getMainLooper());
+    }
+
+    public SharedConnectivityService(@NonNull Handler handler) {
+        mHandler = handler;
+    }
+
+    private final class DeathRecipient implements IBinder.DeathRecipient {
+        ISharedConnectivityCallback mCallback;
+
+        DeathRecipient(ISharedConnectivityCallback callback) {
+            mCallback = callback;
+        }
+
+        @Override
+        public void binderDied() {
+            mCallbacks.remove(mCallback);
+            mDeathRecipientMap.remove(mCallback);
+        }
+    }
+
+    @Override
+    @Nullable
+    public IBinder onBind(@NonNull Intent intent) {
+        if (DEBUG) Log.i(TAG, "onBind intent=" + intent);
+        return new ISharedConnectivityService.Stub() {
+            @Override
+            public void registerCallback(ISharedConnectivityCallback callback) {
+                checkPermissions();
+                mHandler.post(() -> registerCallback(callback));
+            }
+
+            @Override
+            public void unregisterCallback(ISharedConnectivityCallback callback) {
+                checkPermissions();
+                mHandler.post(() -> unregisterCallback(callback));
+            }
+
+            @Override
+            public void connectTetherNetwork(TetherNetwork network) {
+                checkPermissions();
+                mHandler.post(() -> onConnectTetherNetwork(network));
+            }
+
+            @Override
+            public void disconnectTetherNetwork() {
+                checkPermissions();
+                mHandler.post(() -> onDisconnectTetherNetwork());
+            }
+
+            @Override
+            public void connectKnownNetwork(KnownNetwork network) {
+                checkPermissions();
+                mHandler.post(() -> onConnectKnownNetwork(network));
+            }
+
+            @Override
+            public void forgetKnownNetwork(KnownNetwork network) {
+                checkPermissions();
+                mHandler.post(() -> onForgetKnownNetwork(network));
+            }
+
+            @RequiresPermission(anyOf = {android.Manifest.permission.NETWORK_SETTINGS,
+                    android.Manifest.permission.NETWORK_SETUP_WIZARD})
+            private void checkPermissions() {
+                if (checkCallingPermission(NETWORK_SETTINGS) != PackageManager.PERMISSION_GRANTED
+                        && checkCallingPermission(NETWORK_SETUP_WIZARD)
+                                != PackageManager.PERMISSION_GRANTED) {
+                    throw new SecurityException("Calling process must have NETWORK_SETTINGS or"
+                            + " NETWORK_SETUP_WIZARD permission");
+                }
+            }
+        };
+    }
+
+    private void registerCallback(ISharedConnectivityCallback callback) {
+        // Listener gets triggered on first register using cashed data
+        if (!notifyTetherNetworkUpdate(callback) || !notifyKnownNetworkUpdate(callback)
+                || !notifySettingsStateUpdate(callback)
+                || !notifyTetherNetworkConnectionStatusChanged(callback)
+                || !notifyKnownNetworkConnectionStatusChanged(callback)) {
+            if (DEBUG) Log.w(TAG, "Failed to notify client");
+            return;
+        }
+
+        DeathRecipient deathRecipient = new DeathRecipient(callback);
+        try {
+            callback.asBinder().linkToDeath(deathRecipient, 0);
+            mCallbacks.add(callback);
+            mDeathRecipientMap.put(callback, deathRecipient);
+        } catch (RemoteException e) {
+            if (DEBUG) Log.w(TAG, "Exception in registerCallback", e);
+        }
+    }
+
+    private void unregisterCallback(ISharedConnectivityCallback callback) {
+        DeathRecipient deathRecipient = mDeathRecipientMap.get(callback);
+        if (deathRecipient != null) {
+            callback.asBinder().unlinkToDeath(deathRecipient, 0);
+            mDeathRecipientMap.remove(callback);
+        }
+        mCallbacks.remove(callback);
+    }
+
+    private boolean notifyTetherNetworkUpdate(ISharedConnectivityCallback callback) {
+        try {
+            callback.onTetherNetworksUpdated(mTetherNetworks);
+        } catch (RemoteException e) {
+            if (DEBUG) Log.w(TAG, "Exception in notifyTetherNetworkUpdate", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean notifyKnownNetworkUpdate(ISharedConnectivityCallback callback) {
+        try {
+            callback.onKnownNetworksUpdated(mKnownNetworks);
+        } catch (RemoteException e) {
+            if (DEBUG) Log.w(TAG, "Exception in notifyKnownNetworkUpdate", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean notifySettingsStateUpdate(ISharedConnectivityCallback callback) {
+        try {
+            callback.onSharedConnectivitySettingsChanged(mSettingsState);
+        } catch (RemoteException e) {
+            if (DEBUG) Log.w(TAG, "Exception in notifySettingsStateUpdate", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean notifyTetherNetworkConnectionStatusChanged(
+            ISharedConnectivityCallback callback) {
+        try {
+            callback.onTetherNetworkConnectionStatusChanged(mTetherNetworkConnectionStatus);
+        } catch (RemoteException e) {
+            if (DEBUG) Log.w(TAG, "Exception in notifyTetherNetworkConnectionStatusChanged", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean notifyKnownNetworkConnectionStatusChanged(
+            ISharedConnectivityCallback callback) {
+        try {
+            callback.onKnownNetworkConnectionStatusChanged(mKnownNetworkConnectionStatus);
+        } catch (RemoteException e) {
+            if (DEBUG) Log.w(TAG, "Exception in notifyKnownNetworkConnectionStatusChanged", e);
+            return false;
+        }
+        return true;
+    }
+    /**
+     * Implementing application should call this method to provide an up-to-date list of Tether
+     * Networks to be displayed to the user.
+     *
+     * This method updates the cached list and notifies all registered callbacks. Any callbacks that
+     * are inaccessible will be unregistered.
+     *
+     * @param networks The updated list of {@link TetherNetwork} objects.
+     */
+    public final void setTetherNetworks(@NonNull List<TetherNetwork> networks) {
+        mTetherNetworks = networks;
+
+        for (ISharedConnectivityCallback callback:mCallbacks) {
+            notifyTetherNetworkUpdate(callback);
+        }
+    }
+
+    /**
+     * Implementing application should call this method to provide an up-to-date list of Known
+     * Networks to be displayed to the user.
+     *
+     * This method updates the cached list and notifies all registered callbacks. Any callbacks that
+     * are inaccessible will be unregistered.
+     *
+     * @param networks The updated list of {@link KnownNetwork} objects.
+     */
+    public final void setKnownNetworks(@NonNull List<KnownNetwork> networks) {
+        mKnownNetworks = networks;
+
+        for (ISharedConnectivityCallback callback:mCallbacks) {
+            notifyKnownNetworkUpdate(callback);
+        }
+    }
+
+    /**
+     * Implementing application should call this method to provide an up-to-date state of Shared
+     * connectivity settings state.
+     *
+     * This method updates the cached state and notifies all registered callbacks. Any callbacks
+     * that are inaccessible will be unregistered.
+     *
+     * @param settingsState The updated state {@link SharedConnectivitySettingsState}
+     *                 objects.
+     */
+    public final void setSettingsState(@NonNull SharedConnectivitySettingsState settingsState) {
+        mSettingsState = settingsState;
+
+        for (ISharedConnectivityCallback callback:mCallbacks) {
+            notifySettingsStateUpdate(callback);
+        }
+    }
+
+    /**
+     * Implementing application should call this method to provide an up-to-date status of enabling
+     * and connecting to the tether network.
+     *
+     * @param status The updated status {@link TetherNetworkConnectionStatus} of the connection.
+     *
+     */
+    public final void updateTetherNetworkConnectionStatus(
+            @NonNull TetherNetworkConnectionStatus status) {
+        mTetherNetworkConnectionStatus = status;
+        for (ISharedConnectivityCallback callback:mCallbacks) {
+            notifyTetherNetworkConnectionStatusChanged(callback);
+        }
+    }
+
+    /**
+     * Implementing application should call this method to provide an up-to-date status of
+     * connecting to a known network.
+     *
+     * @param status The updated status {@link KnownNetworkConnectionStatus} of the connection.
+     *
+     */
+    public final void updateKnownNetworkConnectionStatus(
+            @NonNull KnownNetworkConnectionStatus status) {
+        mKnownNetworkConnectionStatus = status;
+
+        for (ISharedConnectivityCallback callback:mCallbacks) {
+            notifyKnownNetworkConnectionStatusChanged(callback);
+        }
+    }
+
+    /**
+     * Implementing application should implement this method.
+     *
+     * Implementation should initiate a connection to the Tether Network indicated.
+     *
+     * @param network Object identifying the Tether Network the user has requested a connection to.
+     */
+    public abstract void onConnectTetherNetwork(@NonNull TetherNetwork network);
+
+    /**
+     * Implementing application should implement this method.
+     *
+     * Implementation should initiate a disconnection from the active Tether Network.
+     */
+    public abstract void onDisconnectTetherNetwork();
+
+    /**
+     * Implementing application should implement this method.
+     *
+     * Implementation should initiate a connection to the Known Network indicated.
+     *
+     * @param network Object identifying the Known Network the user has requested a connection to.
+     */
+    public abstract void onConnectKnownNetwork(@NonNull KnownNetwork network);
+
+    /**
+     * Implementing application should implement this method.
+     *
+     * Implementation should remove the Known Network indicated from the synced list of networks.
+     *
+     * @param network Object identifying the Known Network the user has requested to forget.
+     */
+    public abstract void onForgetKnownNetwork(@NonNull KnownNetwork network);
+}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/OWNERS b/wifi/tests/src/android/net/wifi/sharedconnectivity/OWNERS
new file mode 100644
index 0000000..8873d07
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/OWNERS
@@ -0,0 +1 @@
+file:/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/DeviceInfoTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/DeviceInfoTest.java
new file mode 100644
index 0000000..f8f0700
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/DeviceInfoTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_LAPTOP;
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_PHONE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.app.sharedconnectivity.DeviceInfo}.
+ */
+@SmallTest
+public class DeviceInfoTest {
+
+    private static final int DEVICE_TYPE = DEVICE_TYPE_PHONE;
+    private static final String DEVICE_NAME = "TEST_NAME";
+    private static final String DEVICE_MODEL = "TEST_MODEL";
+    private static final int BATTERY_PERCENTAGE = 50;
+    private static final int CONNECTION_STRENGTH = 2;
+
+    private static final int DEVICE_TYPE_1 = DEVICE_TYPE_LAPTOP;
+    private static final String DEVICE_NAME_1 = "TEST_NAME1";
+    private static final String DEVICE_MODEL_1 = "TEST_MODEL1";
+    private static final int BATTERY_PERCENTAGE_1 = 30;
+    private static final int CONNECTION_STRENGTH_1 = 1;
+
+    /**
+     * Verifies parcel serialization/deserialization.
+     */
+    @Test
+    public void testParcelOperation() {
+        DeviceInfo info = buildDeviceInfoBuilder().build();
+
+        Parcel parcelW = Parcel.obtain();
+        info.writeToParcel(parcelW, 0);
+        byte[] bytes = parcelW.marshall();
+        parcelW.recycle();
+
+        Parcel parcelR = Parcel.obtain();
+        parcelR.unmarshall(bytes, 0, bytes.length);
+        parcelR.setDataPosition(0);
+        DeviceInfo fromParcel = DeviceInfo.CREATOR.createFromParcel(parcelR);
+
+        assertEquals(info, fromParcel);
+        assertEquals(info.hashCode(), fromParcel.hashCode());
+    }
+
+    /**
+     * Verifies the Equals operation
+     */
+    @Test
+    public void testEqualsOperation() {
+        DeviceInfo info1 = buildDeviceInfoBuilder().build();
+        DeviceInfo info2 = buildDeviceInfoBuilder().build();
+        assertEquals(info1, info2);
+
+        DeviceInfo.Builder builder = buildDeviceInfoBuilder().setDeviceType(DEVICE_TYPE_1);
+        assertNotEquals(info1, builder.build());
+
+        builder = buildDeviceInfoBuilder().setDeviceName(DEVICE_NAME_1);
+        assertNotEquals(info1, builder.build());
+
+        builder = buildDeviceInfoBuilder().setModelName(DEVICE_MODEL_1);
+        assertNotEquals(info1, builder.build());
+
+        builder = buildDeviceInfoBuilder()
+                .setBatteryPercentage(BATTERY_PERCENTAGE_1);
+        assertNotEquals(info1, builder.build());
+
+        builder = buildDeviceInfoBuilder()
+                .setConnectionStrength(CONNECTION_STRENGTH_1);
+        assertNotEquals(info1, builder.build());
+    }
+
+    /**
+     * Verifies the get methods return the expected data.
+     */
+    @Test
+    public void testGetMethods() {
+        DeviceInfo info = buildDeviceInfoBuilder().build();
+        assertEquals(info.getDeviceType(), DEVICE_TYPE);
+        assertEquals(info.getDeviceName(), DEVICE_NAME);
+        assertEquals(info.getModelName(), DEVICE_MODEL);
+        assertEquals(info.getBatteryPercentage(), BATTERY_PERCENTAGE);
+        assertEquals(info.getConnectionStrength(), CONNECTION_STRENGTH);
+        assertEquals(info.getConnectionStrength(), CONNECTION_STRENGTH);
+    }
+
+    private DeviceInfo.Builder buildDeviceInfoBuilder() {
+        return new DeviceInfo.Builder().setDeviceType(DEVICE_TYPE).setDeviceName(DEVICE_NAME)
+                .setModelName(DEVICE_MODEL).setBatteryPercentage(BATTERY_PERCENTAGE)
+                .setConnectionStrength(CONNECTION_STRENGTH);
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
new file mode 100644
index 0000000..266afcc
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.app;
+
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_PHONE;
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_TABLET;
+import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_CLOUD_SELF;
+import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.app.sharedconnectivity.KnownNetwork}.
+ */
+@SmallTest
+public class KnownNetworkTest {
+
+    private static final int NETWORK_SOURCE = NETWORK_SOURCE_NEARBY_SELF;
+    private static final String SSID = "TEST_SSID";
+    private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP};
+    private static final DeviceInfo DEVICE_INFO = new DeviceInfo.Builder()
+            .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
+            .setConnectionStrength(2).setBatteryPercentage(50).build();
+    private static final int NETWORK_SOURCE_1 = NETWORK_SOURCE_CLOUD_SELF;
+    private static final String SSID_1 = "TEST_SSID1";
+    private static final int[] SECURITY_TYPES_1 = {SECURITY_TYPE_PSK};
+    private static final DeviceInfo DEVICE_INFO_1 = new DeviceInfo.Builder()
+            .setDeviceType(DEVICE_TYPE_PHONE).setDeviceName("TEST_NAME_1")
+            .setModelName("TEST_MODEL_1").setConnectionStrength(3).setBatteryPercentage(33).build();
+
+    /**
+     * Verifies parcel serialization/deserialization.
+     */
+    @Test
+    public void testParcelOperation() {
+        KnownNetwork network = buildKnownNetworkBuilder().build();
+
+        Parcel parcelW = Parcel.obtain();
+        network.writeToParcel(parcelW, 0);
+        byte[] bytes = parcelW.marshall();
+        parcelW.recycle();
+
+        Parcel parcelR = Parcel.obtain();
+        parcelR.unmarshall(bytes, 0, bytes.length);
+        parcelR.setDataPosition(0);
+        KnownNetwork fromParcel = KnownNetwork.CREATOR.createFromParcel(parcelR);
+
+        assertEquals(network, fromParcel);
+        assertEquals(network.hashCode(), fromParcel.hashCode());
+    }
+
+    /**
+     * Verifies the Equals operation
+     */
+    @Test
+    public void testEqualsOperation() {
+        KnownNetwork network1 = buildKnownNetworkBuilder().build();
+        KnownNetwork network2 = buildKnownNetworkBuilder().build();
+        assertEquals(network1, network2);
+
+        KnownNetwork.Builder builder = buildKnownNetworkBuilder()
+                .setNetworkSource(NETWORK_SOURCE_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildKnownNetworkBuilder().setSsid(SSID_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildKnownNetworkBuilder().setSecurityTypes(SECURITY_TYPES_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildKnownNetworkBuilder().setDeviceInfo(DEVICE_INFO_1);
+        assertNotEquals(network1, builder.build());
+    }
+
+    /**
+     * Verifies the get methods return the expected data.
+     */
+    @Test
+    public void testGetMethods() {
+        KnownNetwork network = buildKnownNetworkBuilder().build();
+        assertEquals(network.getNetworkSource(), NETWORK_SOURCE);
+        assertEquals(network.getSsid(), SSID);
+        assertArrayEquals(network.getSecurityTypes(), SECURITY_TYPES);
+        assertEquals(network.getDeviceInfo(), DEVICE_INFO);
+    }
+
+    private KnownNetwork.Builder buildKnownNetworkBuilder() {
+        return new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE).setSsid(SSID)
+                .setSecurityTypes(SECURITY_TYPES).setDeviceInfo(DEVICE_INFO);
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
new file mode 100644
index 0000000..9aeccac
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi.sharedconnectivity.app;
+
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_EAP;
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_TABLET;
+import static android.net.wifi.sharedconnectivity.app.KnownNetwork.NETWORK_SOURCE_NEARBY_SELF;
+import static android.net.wifi.sharedconnectivity.app.TetherNetwork.NETWORK_TYPE_CELLULAR;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.wifi.sharedconnectivity.service.ISharedConnectivityService;
+import android.os.RemoteException;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Unit tests for {@link SharedConnectivityManager}.
+ */
+@SmallTest
+public class SharedConnectivityManagerTest {
+    private static final long DEVICE_ID = 11L;
+    private static final DeviceInfo DEVICE_INFO = new DeviceInfo.Builder()
+            .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
+            .setConnectionStrength(2).setBatteryPercentage(50).build();
+    private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
+    private static final String NETWORK_NAME = "TEST_NETWORK";
+    private static final String HOTSPOT_SSID = "TEST_SSID";
+    private static final int[] HOTSPOT_SECURITY_TYPES = {SECURITY_TYPE_WEP, SECURITY_TYPE_EAP};
+
+    private static final int NETWORK_SOURCE = NETWORK_SOURCE_NEARBY_SELF;
+    private static final String SSID = "TEST_SSID";
+    private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP};
+
+    private static final int SERVICE_PACKAGE_ID = 1;
+    private static final int SERVICE_CLASS_ID = 2;
+
+    private static final String SERVICE_PACKAGE_NAME = "TEST_PACKAGE";
+    private static final String SERVICE_CLASS_NAME = "TEST_CLASS";
+    private static final String PACKAGE_NAME = "TEST_PACKAGE";
+
+    @Mock Context mContext;
+    @Mock
+    ISharedConnectivityService mService;
+    @Mock Executor mExecutor;
+    @Mock
+    SharedConnectivityClientCallback mClientCallback;
+    @Mock Resources mResources;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        setResources(mContext);
+    }
+
+    /**
+     * Verifies constructor is binding to service.
+     */
+    @Test
+    public void testBindingToService() {
+        new SharedConnectivityManager(mContext);
+        verify(mContext).bindService(any(), any(), anyInt());
+    }
+
+    /**
+     * Verifies callback is registered in the service only once and only when service is not null.
+     */
+    @Test
+    public void testRegisterCallback() throws Exception {
+        SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
+        manager.setService(null);
+        assertFalse(manager.registerCallback(mExecutor, mClientCallback));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        assertTrue(manager.registerCallback(mExecutor, mClientCallback));
+        verify(mService).registerCallback(any());
+
+        // Registering the same callback twice should fail.
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.registerCallback(mExecutor, mClientCallback);
+        assertFalse(manager.registerCallback(mExecutor, mClientCallback));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        doThrow(new RemoteException()).when(mService).registerCallback(any());
+        assertFalse(manager.registerCallback(mExecutor, mClientCallback));
+    }
+
+    /**
+     * Verifies callback is unregistered from the service if it was registered before and only when
+     * service is not null.
+     */
+    @Test
+    public void testUnregisterCallback() throws Exception {
+        SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
+        manager.setService(null);
+        assertFalse(manager.unregisterCallback(mClientCallback));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.registerCallback(mExecutor, mClientCallback);
+        assertTrue(manager.unregisterCallback(mClientCallback));
+        verify(mService).unregisterCallback(any());
+
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.registerCallback(mExecutor, mClientCallback);
+        manager.unregisterCallback(mClientCallback);
+        assertFalse(manager.unregisterCallback(mClientCallback));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        doThrow(new RemoteException()).when(mService).unregisterCallback(any());
+        assertFalse(manager.unregisterCallback(mClientCallback));
+    }
+
+    /**
+     * Verifies service is called when not null and exceptions are handles when calling
+     * connectTetherNetwork.
+     */
+    @Test
+    public void testConnectTetherNetwork() throws RemoteException {
+        TetherNetwork network = buildTetherNetwork();
+
+        SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
+        manager.setService(null);
+        assertFalse(manager.connectTetherNetwork(network));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.connectTetherNetwork(network);
+        verify(mService).connectTetherNetwork(network);
+
+        doThrow(new RemoteException()).when(mService).connectTetherNetwork(network);
+        assertFalse(manager.connectTetherNetwork(network));
+    }
+
+    /**
+     * Verifies service is called when not null and exceptions are handles when calling
+     * disconnectTetherNetwork.
+     */
+    @Test
+    public void testDisconnectTetherNetwork() throws RemoteException {
+        SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
+        manager.setService(null);
+        assertFalse(manager.disconnectTetherNetwork());
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.disconnectTetherNetwork();
+        verify(mService).disconnectTetherNetwork();
+
+        doThrow(new RemoteException()).when(mService).disconnectTetherNetwork();
+        assertFalse(manager.disconnectTetherNetwork());
+    }
+
+    /**
+     * Verifies service is called when not null and exceptions are handles when calling
+     * connectKnownNetwork.
+     */
+    @Test
+    public void testConnectKnownNetwork() throws RemoteException {
+        KnownNetwork network = buildKnownNetwork();
+
+        SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
+        manager.setService(null);
+        assertFalse(manager.connectKnownNetwork(network));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.connectKnownNetwork(network);
+        verify(mService).connectKnownNetwork(network);
+
+        doThrow(new RemoteException()).when(mService).connectKnownNetwork(network);
+        assertFalse(manager.connectKnownNetwork(network));
+    }
+
+    /**
+     * Verifies service is called when not null and exceptions are handles when calling
+     * forgetKnownNetwork.
+     */
+    @Test
+    public void testForgetKnownNetwork() throws RemoteException {
+        KnownNetwork network = buildKnownNetwork();
+
+        SharedConnectivityManager manager = new SharedConnectivityManager(mContext);
+        manager.setService(null);
+        assertFalse(manager.forgetKnownNetwork(network));
+
+        manager = new SharedConnectivityManager(mContext);
+        manager.setService(mService);
+        manager.forgetKnownNetwork(network);
+        verify(mService).forgetKnownNetwork(network);
+
+        doThrow(new RemoteException()).when(mService).forgetKnownNetwork(network);
+        assertFalse(manager.forgetKnownNetwork(network));
+    }
+
+    private void setResources(@Mock Context context) {
+        when(context.getResources()).thenReturn(mResources);
+        when(context.getPackageName()).thenReturn(PACKAGE_NAME);
+        when(mResources.getIdentifier(anyString(), anyString(), anyString()))
+                .thenReturn(SERVICE_PACKAGE_ID, SERVICE_CLASS_ID);
+        when(mResources.getString(SERVICE_PACKAGE_ID)).thenReturn(SERVICE_PACKAGE_NAME);
+        when(mResources.getString(SERVICE_CLASS_ID)).thenReturn(SERVICE_CLASS_NAME);
+    }
+
+    private TetherNetwork buildTetherNetwork() {
+        return new TetherNetwork.Builder()
+                .setDeviceId(DEVICE_ID)
+                .setDeviceInfo(DEVICE_INFO)
+                .setNetworkType(NETWORK_TYPE)
+                .setNetworkName(NETWORK_NAME)
+                .setHotspotSsid(HOTSPOT_SSID)
+                .setHotspotSecurityTypes(HOTSPOT_SECURITY_TYPES)
+                .build();
+    }
+
+    private KnownNetwork buildKnownNetwork() {
+        return new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE).setSsid(SSID)
+                .setSecurityTypes(SECURITY_TYPES).build();
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java
new file mode 100644
index 0000000..3137c72
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.app;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState}.
+ */
+@SmallTest
+public class SharedConnectivitySettingsStateTest {
+    private static final boolean INSTANT_TETHER_STATE = true;
+
+    private static final boolean INSTANT_TETHER_STATE_1 = false;
+    /**
+     * Verifies parcel serialization/deserialization.
+     */
+    @Test
+    public void testParcelOperation() {
+        SharedConnectivitySettingsState state = buildSettingsStateBuilder().build();
+
+        Parcel parcelW = Parcel.obtain();
+        state.writeToParcel(parcelW, 0);
+        byte[] bytes = parcelW.marshall();
+        parcelW.recycle();
+
+        Parcel parcelR = Parcel.obtain();
+        parcelR.unmarshall(bytes, 0, bytes.length);
+        parcelR.setDataPosition(0);
+        SharedConnectivitySettingsState fromParcel =
+                SharedConnectivitySettingsState.CREATOR.createFromParcel(parcelR);
+
+        assertEquals(state, fromParcel);
+        assertEquals(state.hashCode(), fromParcel.hashCode());
+    }
+
+    /**
+     * Verifies the Equals operation
+     */
+    @Test
+    public void testEqualsOperation() {
+        SharedConnectivitySettingsState state1 = buildSettingsStateBuilder().build();
+        SharedConnectivitySettingsState state2 = buildSettingsStateBuilder().build();
+        assertEquals(state1, state2);
+
+        SharedConnectivitySettingsState.Builder builder = buildSettingsStateBuilder()
+                .setInstantTetherEnabled(INSTANT_TETHER_STATE_1);
+        assertNotEquals(state1, builder.build());
+    }
+
+    /**
+     * Verifies the get methods return the expected data.
+     */
+    @Test
+    public void testGetMethods() {
+        SharedConnectivitySettingsState state = buildSettingsStateBuilder().build();
+        assertEquals(state.isInstantTetherEnabled(), INSTANT_TETHER_STATE);
+    }
+
+    private SharedConnectivitySettingsState.Builder buildSettingsStateBuilder() {
+        return new SharedConnectivitySettingsState.Builder()
+                .setInstantTetherEnabled(INSTANT_TETHER_STATE);
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/TetherNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/TetherNetworkTest.java
new file mode 100644
index 0000000..b01aec4
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/TetherNetworkTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.app;
+
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_EAP;
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_PSK;
+import static android.net.wifi.WifiInfo.SECURITY_TYPE_WEP;
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_PHONE;
+import static android.net.wifi.sharedconnectivity.app.DeviceInfo.DEVICE_TYPE_TABLET;
+import static android.net.wifi.sharedconnectivity.app.TetherNetwork.NETWORK_TYPE_CELLULAR;
+import static android.net.wifi.sharedconnectivity.app.TetherNetwork.NETWORK_TYPE_WIFI;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.sharedconnectivity.app.TetherNetwork}.
+ */
+@SmallTest
+public class TetherNetworkTest {
+    private static final long DEVICE_ID = 11L;
+    private static final DeviceInfo DEVICE_INFO = new DeviceInfo.Builder()
+            .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
+            .setConnectionStrength(2).setBatteryPercentage(50).build();
+    private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
+    private static final String NETWORK_NAME = "TEST_NETWORK";
+    private static final String HOTSPOT_SSID = "TEST_SSID";
+    private static final String HOTSPOT_BSSID = "TEST _BSSID";
+    private static final int[] HOTSPOT_SECURITY_TYPES = {SECURITY_TYPE_WEP, SECURITY_TYPE_EAP};
+
+    private static final long DEVICE_ID_1 = 111L;
+    private static final DeviceInfo DEVICE_INFO_1 = new DeviceInfo.Builder()
+            .setDeviceType(DEVICE_TYPE_PHONE).setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
+            .setConnectionStrength(2).setBatteryPercentage(50).build();
+    private static final int NETWORK_TYPE_1 = NETWORK_TYPE_WIFI;
+    private static final String NETWORK_NAME_1 = "TEST_NETWORK1";
+    private static final String HOTSPOT_SSID_1 = "TEST_SSID1";
+    private static final String HOTSPOT_BSSID_1 = "TEST _BSSID1";
+    private static final int[] HOTSPOT_SECURITY_TYPES_1 = {SECURITY_TYPE_PSK, SECURITY_TYPE_EAP};
+
+    /**
+     * Verifies parcel serialization/deserialization.
+     */
+    @Test
+    public void testParcelOperation() {
+        TetherNetwork network = buildTetherNetworkBuilder().build();
+
+        Parcel parcelW = Parcel.obtain();
+        network.writeToParcel(parcelW, 0);
+        byte[] bytes = parcelW.marshall();
+        parcelW.recycle();
+
+        Parcel parcelR = Parcel.obtain();
+        parcelR.unmarshall(bytes, 0, bytes.length);
+        parcelR.setDataPosition(0);
+        TetherNetwork fromParcel = TetherNetwork.CREATOR.createFromParcel(parcelR);
+
+        assertEquals(network, fromParcel);
+        assertEquals(network.hashCode(), fromParcel.hashCode());
+    }
+
+    /**
+     * Verifies the Equals operation
+     */
+    @Test
+    public void testEqualsOperation() {
+        TetherNetwork network1 = buildTetherNetworkBuilder().build();
+        TetherNetwork network2 = buildTetherNetworkBuilder().build();
+        assertEquals(network1, network2);
+
+        TetherNetwork.Builder builder = buildTetherNetworkBuilder().setDeviceId(DEVICE_ID_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildTetherNetworkBuilder().setDeviceInfo(DEVICE_INFO_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildTetherNetworkBuilder().setNetworkType(NETWORK_TYPE_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildTetherNetworkBuilder().setNetworkName(NETWORK_NAME_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildTetherNetworkBuilder().setHotspotSsid(HOTSPOT_SSID_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildTetherNetworkBuilder().setHotspotBssid(HOTSPOT_BSSID_1);
+        assertNotEquals(network1, builder.build());
+
+        builder = buildTetherNetworkBuilder().setHotspotSecurityTypes(HOTSPOT_SECURITY_TYPES_1);
+        assertNotEquals(network1, builder.build());
+    }
+
+    /**
+     * Verifies the get methods return the expected data.
+     */
+    @Test
+    public void testGetMethods() {
+        TetherNetwork network = buildTetherNetworkBuilder().build();
+        assertEquals(network.getDeviceId(), DEVICE_ID);
+        assertEquals(network.getDeviceInfo(), DEVICE_INFO);
+        assertEquals(network.getNetworkType(), NETWORK_TYPE);
+        assertEquals(network.getNetworkName(), NETWORK_NAME);
+        assertEquals(network.getHotspotSsid(), HOTSPOT_SSID);
+        assertEquals(network.getHotspotBssid(), HOTSPOT_BSSID);
+        assertArrayEquals(network.getHotspotSecurityTypes(), HOTSPOT_SECURITY_TYPES);
+    }
+
+    private TetherNetwork.Builder buildTetherNetworkBuilder() {
+        return new TetherNetwork.Builder()
+                .setDeviceId(DEVICE_ID)
+                .setDeviceInfo(DEVICE_INFO)
+                .setNetworkType(NETWORK_TYPE)
+                .setNetworkName(NETWORK_NAME)
+                .setHotspotSsid(HOTSPOT_SSID)
+                .setHotspotBssid(HOTSPOT_BSSID)
+                .setHotspotSecurityTypes(HOTSPOT_SECURITY_TYPES);
+    }
+}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
new file mode 100644
index 0000000..e15be8b
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.sharedconnectivity.service;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Intent;
+import android.net.wifi.sharedconnectivity.app.KnownNetwork;
+import android.net.wifi.sharedconnectivity.app.TetherNetwork;
+import android.os.Handler;
+import android.os.test.TestLooper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.sharedconnectivity.service.SharedConnectivityService}.
+ */
+@SmallTest
+public class SharedConnectivityServiceTest {
+
+    /**
+     * Verifies service returns
+     */
+    @Test
+    public void testOnBind() {
+        SharedConnectivityService service = createService();
+        assertNotNull(service.onBind(new Intent()));
+    }
+
+    @Test
+    public void testCallbacks() {
+        SharedConnectivityService service = createService();
+        ISharedConnectivityService.Stub binder =
+                (ISharedConnectivityService.Stub) service.onBind(new Intent());
+    }
+
+    private SharedConnectivityService createService() {
+        return new SharedConnectivityService(new Handler(new TestLooper().getLooper())) {
+            @Override
+            public void onConnectTetherNetwork(TetherNetwork network) {}
+
+            @Override
+            public void onDisconnectTetherNetwork() {}
+
+            @Override
+            public void onConnectKnownNetwork(KnownNetwork network) {}
+
+            @Override
+            public void onForgetKnownNetwork(KnownNetwork network) {}
+        };
+    }
+}